Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: validation for event handlers #1545

Merged
merged 5 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/@graphprotocol_graph-cli-1545-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@graphprotocol/graph-cli": patch
---
dependencies updates:
- Removed dependency [`@babel/core@^7.20.5` ↗︎](https://www.npmjs.com/package/@babel/core/v/7.20.5) (from `dependencies`)
- Removed dependency [`@babel/preset-typescript@^7.18.6` ↗︎](https://www.npmjs.com/package/@babel/preset-typescript/v/7.18.6) (from `dependencies`)
- Removed dependency [`memoizee@^0.4.15` ↗︎](https://www.npmjs.com/package/memoizee/v/0.4.15) (from `dependencies`)
5 changes: 5 additions & 0 deletions .changeset/rich-turtles-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphprotocol/graph-cli': patch
---

fix call handler validation
5 changes: 0 additions & 5 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"@babel/core": "^7.20.5",
"@babel/preset-typescript": "^7.18.6",
"@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4",
"@oclif/core": "2.8.6",
"@oclif/plugin-autocomplete": "^2.3.6",
Expand All @@ -50,7 +48,6 @@
"ipfs-http-client": "55.0.0",
"jayson": "4.0.0",
"js-yaml": "3.14.1",
"memoizee": "^0.4.15",
"prettier": "1.19.1",
"request": "2.88.2",
"semver": "7.4.0",
Expand All @@ -61,12 +58,10 @@
"yaml": "1.10.2"
},
"devDependencies": {
"@types/babel__core": "^7.20.5",
"@types/debug": "^4.1.7",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.0.0",
"@types/js-yaml": "^3.12.7",
"@types/memoizee": "^0.4.11",
"@types/semver": "^7.3.13",
"@types/which": "^2.0.1",
"copyfiles": "^2.4.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default class BuildCommand extends Command {
if (watch) {
await compiler.watchAndCompile();
} else {
const result = await compiler.compile({ validate: false });
const result = await compiler.compile({ validate: true });
if (result === false) {
this.exit(1);
}
Expand Down
57 changes: 2 additions & 55 deletions packages/cli/src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import * as toolbox from 'gluegun';
import immutable from 'immutable';
import type { IPFSHTTPClient } from 'ipfs-http-client';
import yaml from 'js-yaml';
import memo from 'memoizee';
import { parseSync } from '@babel/core';
import { Spinner, step, withSpinner } from '../command-helpers/spinner';
import debug from '../debug';
import { applyMigrations } from '../migrations';
Expand All @@ -18,18 +16,6 @@ import * as asc from './asc';

const compilerDebug = debug('graph-cli:compiler');

/** memoize the reading of the file so we don't have to read it every time */
const readFile = memo((filename: string) => fs.readFileSync(filename, 'utf-8'));

/** Memoized parser for Babel, so we can simply just read from cache */
const babelAst = memo((filename: string) => {
const data = readFile(filename);
return parseSync(data, {
presets: ['@babel/preset-typescript'],
filename,
});
});

interface CompilerOptions {
ipfs: any;
subgraphManifest: string;
Expand Down Expand Up @@ -364,19 +350,12 @@ export default class Compiler {

try {
const dataSourceName = dataSource.getIn(['name']);

const baseDir = this.sourceDir;
const absoluteMappingPath = path.resolve(baseDir, mappingPath);
const inputFile = path.relative(baseDir, absoluteMappingPath);

this._validateMappingContent(absoluteMappingPath);

const eventHandlers = dataSource.getIn(['mapping', 'eventHandlers']);
// TODO: improve the types
for (const eventHandler of (eventHandlers as any).toJS()) {
compilerDebug('Validating Event Handler %s', eventHandler.handler);
this._validateHandler(absoluteMappingPath, eventHandler.handler);
}

// If the file has already been compiled elsewhere, just use that output
// file and return early
const inputCacheKey = this.cacheKeyForFile(absoluteMappingPath);
Expand Down Expand Up @@ -452,13 +431,6 @@ export default class Compiler {
const inputFile = path.relative(baseDir, absoluteMappingPath);
this._validateMappingContent(absoluteMappingPath);

const eventHandlers = template.getIn(['mapping', 'eventHandlers']);
// TODO: improve the types
for (const eventHandler of (eventHandlers as any).toJS()) {
compilerDebug('Validating Template handler %s', eventHandler.handler);
this._validateHandler(absoluteMappingPath, eventHandler.handler);
}

// If the file has already been compiled elsewhere, just use that output
// file and return early
const inputCacheKey = this.cacheKeyForFile(absoluteMappingPath);
Expand Down Expand Up @@ -517,7 +489,7 @@ export default class Compiler {
}

_validateMappingContent(filePath: string) {
const data = readFile(filePath);
const data = fs.readFileSync(filePath);
if (this.blockIpfsMethods && (data.includes('ipfs.cat') || data.includes('ipfs.map'))) {
throw Error(`
Subgraph Studio does not support mappings with ipfs methods.
Expand All @@ -527,31 +499,6 @@ export default class Compiler {
}
}

_validateHandler(filePath: string, handlerName: string) {
const baselAst = babelAst(filePath);

const body = baselAst?.program.body;

if (!body) {
throw Error(`Could not parse ${filePath}`);
}

const exportedFunctionNames = body
.map(statement => {
if (
statement.type === 'ExportNamedDeclaration' &&
statement?.declaration?.type === 'FunctionDeclaration'
) {
return statement.declaration.id?.name;
}
})
.filter(Boolean);

if (!exportedFunctionNames.includes(handlerName)) {
throw Error(`Could not find handler '${handlerName}' in ${filePath}`);
}
}

async writeSubgraphToOutputDirectory(protocol: Protocol, subgraph: immutable.Map<any, any>) {
const displayDir = `${this.displayPath(this.options.outputDir)}${toolbox.filesystem.separator}`;

Expand Down
Loading