diff --git a/manifest-schema.graphql b/manifest-schema.graphql index 5c0416261..5fb89323f 100644 --- a/manifest-schema.graphql +++ b/manifest-schema.graphql @@ -6,6 +6,7 @@ type Schema { } union DataSource = EthereumContractDataSource +union DataSourceTemplate = EthereumContractDataSourceTemplate type EthereumContractDataSource { kind: String! @@ -13,7 +14,6 @@ type EthereumContractDataSource { network: String source: EthereumContractSource! mapping: EthereumContractMapping! - templates: [EthereumContractDataSourceTemplate!] } type EthereumContractSource { @@ -64,6 +64,7 @@ type SubgraphManifest { description: String repository: String dataSources: [DataSource!]! + templates: [DataSourceTemplate!] } type EthereumContractDataSourceTemplate { diff --git a/src/compiler.js b/src/compiler.js index 14e2d501e..7710865b3 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -169,29 +169,22 @@ class Compiler { async spinner => { subgraph = subgraph.update('dataSources', dataSources => dataSources.map(dataSource => - dataSource - .updateIn(['mapping', 'file'], mappingPath => - this._compileDataSourceMapping(dataSource, mappingPath, spinner), - ) - .update( - 'templates', - templates => - templates === undefined - ? templates - : templates.map(template => - template.updateIn(['mapping', 'file'], mappingPath => - this._compileDataSourceTemplateMapping( - dataSource, - template, - mappingPath, - spinner, - ), - ), - ), - ), + dataSource.updateIn(['mapping', 'file'], mappingPath => + this._compileDataSourceMapping(dataSource, mappingPath, spinner), + ), ), ) + subgraph = subgraph.update('templates', templates => + templates === undefined + ? templates + : templates.map(template => + template.updateIn(['mapping', 'file'], mappingPath => + this._compileTemplateMapping(template, mappingPath, spinner), + ), + ), + ) + return subgraph }, ) @@ -230,7 +223,17 @@ class Compiler { global = path.relative(baseDir, global) asc.main( - [inputFile, global, '--baseDir', baseDir, '--lib', libs, '--outFile', outputFile, '--optimize'], + [ + inputFile, + global, + '--baseDir', + baseDir, + '--lib', + libs, + '--outFile', + outputFile, + '--optimize', + ], { stdout: process.stdout, stderr: process.stdout, @@ -247,13 +250,12 @@ class Compiler { } } - _compileDataSourceTemplateMapping(dataSource, template, mappingPath, spinner) { + _compileTemplateMapping(template, mappingPath, spinner) { try { - let dataSourceName = dataSource.get('name') let templateName = template.get('name') let outFile = path.join( - this.subgraphDir(this.options.outputDir, dataSource), + this.options.outputDir, 'templates', templateName, this.options.outputFormat == 'wasm' @@ -264,7 +266,7 @@ class Compiler { step( spinner, 'Compile data source template:', - `${dataSourceName} > ${templateName} => ${this.displayPath(outFile)}`, + `${templateName} => ${this.displayPath(outFile)}`, ) let baseDir = this.sourceDir @@ -283,7 +285,17 @@ class Compiler { global = path.relative(baseDir, global) asc.main( - [inputFile, global, '--baseDir', baseDir, '--lib', libs, '--outFile', outputFile, '--optimize'], + [ + inputFile, + global, + '--baseDir', + baseDir, + '--lib', + libs, + '--outFile', + outputFile, + '--optimize', + ], { stdout: process.stdout, stderr: process.stdout, @@ -350,51 +362,43 @@ class Compiler { // directory by the AssemblyScript compiler .updateIn(['mapping', 'file'], mappingFile => path.relative(this.options.outputDir, mappingFile), - ) - - .update( - 'templates', - templates => - templates === undefined - ? templates - : templates.map(template => - template - // Write data source template ABIs to the output directory - .updateIn(['mapping', 'abis'], abis => - abis.map(abi => - abi.update('file', abiFile => { - let abiData = ABI.load(abi.get('name'), abiFile) - return path.relative( - this.options.outputDir, - this._writeSubgraphFile( - abiFile, - JSON.stringify(abiData.data.toJS(), null, 2), - this.sourceDir, - path.join( - this.subgraphDir( - this.options.outputDir, - dataSource, - ), - 'templates', - template.get('name'), - ), - spinner, - ), - ) - }), - ), - ) - - // The mapping file is already being written to the output - // directory by the AssemblyScript compiler - .updateIn(['mapping', 'file'], mappingFile => - path.relative(this.options.outputDir, mappingFile), - ), - ), ), ) }) + // Copy template files and update their paths + subgraph = subgraph.update('templates', templates => { + return templates === undefined + ? templates + : templates.map(template => + template + // Write template ABIs to the output directory + .updateIn(['mapping', 'abis'], abis => + abis.map(abi => + abi.update('file', abiFile => { + let abiData = ABI.load(abi.get('name'), abiFile) + return path.relative( + this.options.outputDir, + this._writeSubgraphFile( + abiFile, + JSON.stringify(abiData.data.toJS(), null, 2), + this.sourceDir, + this.subgraphDir(this.options.outputDir, template), + spinner, + ), + ) + }), + ), + ) + + // The mapping file is already being written to the output + // directory by the AssemblyScript compiler + .updateIn(['mapping', 'file'], mappingFile => + path.relative(this.options.outputDir, mappingFile), + ), + ) + }) + // Write the subgraph manifest itself let outputFilename = path.join(this.options.outputDir, 'subgraph.yaml') step(spinner, 'Write subgraph manifest', this.displayPath(outputFilename)) @@ -453,38 +457,27 @@ class Compiler { }) } - // Upload the ABIs of all data source templates to IPFS - for (let [i, dataSource] of subgraph.get('dataSources').entries()) { - for (let [j, template] of dataSource - .get('templates', immutable.List()) - .entries()) { - for (let [k, abi] of template.getIn(['mapping', 'abis']).entries()) { - updates.push({ - keyPath: ['dataSources', i, 'templates', j, 'mapping', 'abis', k, 'file'], - value: await this._uploadFileToIPFS( - abi.get('file'), - uploadedFiles, - spinner, - ), - }) - } - } - } - - // Upload all template mappings - for (let [i, dataSource] of subgraph.get('dataSources').entries()) { - for (let [j, template] of dataSource - .get('templates', immutable.List()) - .entries()) { + // Upload the mapping and ABIs of all data source templates + for (let [i, template] of subgraph.get('templates', immutable.List()).entries()) { + for (let [j, abi] of template.getIn(['mapping', 'abis']).entries()) { updates.push({ - keyPath: ['dataSources', i, 'templates', j, 'mapping', 'file'], + keyPath: ['templates', i, 'mapping', 'abis', j, 'file'], value: await this._uploadFileToIPFS( - template.getIn(['mapping', 'file']), + abi.get('file'), uploadedFiles, spinner, ), }) } + + updates.push({ + keyPath: ['templates', i, 'mapping', 'file'], + value: await this._uploadFileToIPFS( + template.getIn(['mapping', 'file']), + uploadedFiles, + spinner, + ), + }) } // Apply all updates to the subgraph diff --git a/src/migrations.js b/src/migrations.js index 22cf79703..e38199855 100644 --- a/src/migrations.js +++ b/src/migrations.js @@ -3,6 +3,7 @@ const { withSpinner, step } = require('./command-helpers/spinner') const MIGRATIONS = [ require('./migrations/mapping_api_version_0_0_1'), require('./migrations/mapping_api_version_0_0_2'), + require('./migrations/spec_version_0_0_2'), ] const applyMigrations = async options => diff --git a/src/migrations/spec_version_0_0_2.js b/src/migrations/spec_version_0_0_2.js new file mode 100644 index 000000000..6816f5631 --- /dev/null +++ b/src/migrations/spec_version_0_0_2.js @@ -0,0 +1,35 @@ +const fs = require('fs-extra') +const toolbox = require('gluegun/toolbox') +const yaml = require('js-yaml') + +// Spec version to 0.0.2 uses top level templates. graph-cli no longer supports +// 0.0.1 which used nested templates. +module.exports = { + name: 'Bump mapping specVersion from 0.0.1 to 0.0.2', + predicate: async ({ sourceDir, manifestFile }) => { + let manifest = yaml.safeLoad(fs.readFileSync(manifestFile, 'utf-8')) + return ( + manifest && + typeof manifest === 'object' && + manifest.specVersion && + manifest.specVersion === '0.0.1' + ) + }, + apply: async ({ manifestFile }) => { + await toolbox.patching.replace( + manifestFile, + 'specVersion: 0.0.1', + 'specVersion: 0.0.2', + ) + await toolbox.patching.replace( + manifestFile, + "specVersion: '0.0.1'", + "specVersion: '0.0.2'", + ) + await toolbox.patching.replace( + manifestFile, + 'specVersion: "0.0.1"', + 'specVersion: "0.0.2"', + ) + }, +} diff --git a/src/subgraph.js b/src/subgraph.js index 9921f52e9..798b2107d 100644 --- a/src/subgraph.js +++ b/src/subgraph.js @@ -6,7 +6,6 @@ let { strOptions } = require('yaml/types') let graphql = require('graphql/language') let validation = require('./validation') let ABI = require('./abi') -const toolbox = require('gluegun/toolbox') const throwCombinedError = (filename, errors) => { throw new Error( @@ -98,20 +97,16 @@ module.exports = class Subgraph { } static collectDataSourceTemplates(manifest) { - return manifest.get('dataSources').reduce( - (templates, dataSource, dataSourceIndex) => - dataSource.get('templates', immutable.List()).reduce( - (templates, template, templateIndex) => - template.get('kind') === 'ethereum/contract' - ? templates.push( - immutable.Map({ - path: ['dataSources', dataSourceIndex, 'templates', templateIndex], - dataSource: template, - }), - ) - : templates, - templates, - ), + return manifest.get('templates', immutable.List()).reduce( + (templates, template, templateIndex) => + template.get('kind') === 'ethereum/contract' + ? templates.push( + immutable.Map({ + path: ['templates', templateIndex], + dataSource: template, + }), + ) + : templates, immutable.List(), ) } diff --git a/src/type-generator.js b/src/type-generator.js index 0c00441e6..a829e6a23 100644 --- a/src/type-generator.js +++ b/src/type-generator.js @@ -46,10 +46,9 @@ module.exports = class TypeGenerator { let abis = await this.loadABIs(subgraph) await this.generateTypesForABIs(abis) - let dataSources = subgraph.get('dataSources') - await this.generateTypesForAllDataSourceTemplates(dataSources) + await this.generateTypesForDataSourceTemplates(subgraph) - let templateAbis = await this.loadDataSourceTemplateABIs(dataSources) + let templateAbis = await this.loadDataSourceTemplateABIs(subgraph) await this.generateTypesForDataSourceTemplateABIs(templateAbis) let schema = await this.loadSchema(subgraph) @@ -131,7 +130,7 @@ module.exports = class TypeGenerator { } } - _loadDataSourceTemplateABI(dataSource, template, name, maybeRelativePath, spinner) { + _loadDataSourceTemplateABI(template, name, maybeRelativePath, spinner) { try { if (this.sourceDir) { let absolutePath = path.resolve(this.sourceDir, maybeRelativePath) @@ -140,9 +139,9 @@ module.exports = class TypeGenerator { `Load data source template ABI from`, this.displayPath(absolutePath), ) - return { dataSource, template, abi: ABI.load(name, absolutePath) } + return { template, abi: ABI.load(name, absolutePath) } } else { - return { dataSource, template, abi: ABI.load(name, maybeRelativePath) } + return { template, abi: ABI.load(name, maybeRelativePath) } } } catch (e) { throw Error(`Failed to load data source template ABI: ${e.message}`) @@ -200,9 +199,9 @@ module.exports = class TypeGenerator { step( spinner, `Generate types for data source template ABI:`, - `${abi.dataSource.get('name')} > ${abi.template.get('name')} > ${ - abi.abi.name - } (${this.displayPath(abi.abi.file)})`, + `${abi.template.get('name')} > ${abi.abi.name} (${this.displayPath( + abi.abi.file, + )})`, ) let codeGenerator = abi.abi.codeGenerator() @@ -219,7 +218,6 @@ module.exports = class TypeGenerator { let outputFile = path.join( this.options.outputDir, - abi.dataSource.get('name'), 'templates', abi.template.get('name'), `${abi.abi.name}.ts`, @@ -274,94 +272,67 @@ module.exports = class TypeGenerator { ) } - async generateTypesForDataSourceTemplates(dataSource, spinner) { - // Combine the generated code for all templates in the date source - let codeSegments = dataSource - .get('templates', immutable.List()) - .reduce((codeSegments, template) => { - step( - spinner, - 'Generate types for data source template', - `${dataSource.get('name')} > ${template.get('name')}`, - ) - - let codeGenerator = new DataSourceTemplateCodeGenerator(template) - - // Only generate module imports once, because they are identical for all - // types generate for data source templates - if (codeSegments.isEmpty()) { - codeSegments = codeSegments.concat(codeGenerator.generateModuleImports()) - } - - return codeSegments.concat(codeGenerator.generateTypes()) - }, immutable.List()) - - if (!codeSegments.isEmpty()) { - let code = prettier.format([GENERATED_FILE_NOTE, ...codeSegments].join('\n'), { - parser: 'typescript', - }) - - let outputFile = path.join( - this.options.outputDir, - dataSource.get('name'), - 'templates.ts', - ) - step( - spinner, - `Write types templates of data source ${dataSource.get('name')} to`, - this.displayPath(outputFile), - ) - fs.mkdirsSync(path.dirname(outputFile)) - fs.writeFileSync(outputFile, code) - } - } - - async generateTypesForAllDataSourceTemplates(dataSources) { + async generateTypesForDataSourceTemplates(subgraph) { return await withSpinner( `Generate types for data source templates`, `Failed to generate types for data source templates`, `Warnings while generating types for data source templates`, async spinner => { - await Promise.all( - dataSources.map(async dataSource => { - await this.generateTypesForDataSourceTemplates(dataSource, spinner) - }), - ) + // Combine the generated code for all templates + let codeSegments = subgraph + .get('templates', immutable.List()) + .reduce((codeSegments, template) => { + step( + spinner, + 'Generate types for data source template', + `${template.get('name')}`, + ) + + let codeGenerator = new DataSourceTemplateCodeGenerator(template) + + // Only generate module imports once, because they are identical for + // all types generated for data source templates. + if (codeSegments.isEmpty()) { + codeSegments = codeSegments.concat(codeGenerator.generateModuleImports()) + } + + return codeSegments.concat(codeGenerator.generateTypes()) + }, immutable.List()) + + if (!codeSegments.isEmpty()) { + let code = prettier.format([GENERATED_FILE_NOTE, ...codeSegments].join('\n'), { + parser: 'typescript', + }) + + let outputFile = path.join(this.options.outputDir, 'templates.ts') + step(spinner, `Write types for templates to`, this.displayPath(outputFile)) + fs.mkdirsSync(path.dirname(outputFile)) + fs.writeFileSync(outputFile, code) + } }, ) } - async loadDataSourceTemplateABIs(dataSources) { + async loadDataSourceTemplateABIs(subgraph) { return await withSpinner( `Load data source template ABIs`, `Failed to load data source template ABIs`, `Warnings while loading data source template ABIs`, async spinner => { - return dataSources.reduce( - (abis, dataSource) => - dataSource - .get('templates', immutable.List()) - .reduce( - (abis, template) => - template - .getIn(['mapping', 'abis']) - .reduce( - (abis, abi) => - abis.push( - this._loadDataSourceTemplateABI( - dataSource, - template, - abi.get('name'), - abi.get('file'), - spinner, - ), - ), - abis, - ), - abis, + let abis = [] + for (let template of subgraph.get('templates', immutable.List())) { + for (let abi of template.getIn(['mapping', 'abis'])) { + abis.push( + this._loadDataSourceTemplateABI( + template, + abi.get('name'), + abi.get('file'), + spinner, ), - immutable.List(), - ) + ) + } + } + return abis }, ) } diff --git a/src/validation/manifest.js b/src/validation/manifest.js index 7c1fec9a1..458749b2b 100644 --- a/src/validation/manifest.js +++ b/src/validation/manifest.js @@ -39,10 +39,10 @@ const resolveType = (schema, type) => type.has('type') ? resolveType(schema, type.get('type')) : type.get('kind') === 'NamedType' - ? schema - .get('definitions') - .find(def => def.getIn(['name', 'value']) === type.getIn(['name', 'value'])) - : 'resolveType: unimplemented' + ? schema + .get('definitions') + .find(def => def.getIn(['name', 'value']) === type.getIn(['name', 'value'])) + : 'resolveType: unimplemented' /** * A map of supported validators. @@ -56,13 +56,13 @@ const validators = immutable.fromJS({ .getIn(['type', 'types']) .reduce( (errors, type) => errors.concat(validateValue(value, ctx.set('type', type))), - List() + List(), ), NamedType: (value, ctx) => validateValue( value, - ctx.update('type', type => resolveType(ctx.get('schema'), type)) + ctx.update('type', type => resolveType(ctx.get('schema'), type)), ), NonNullType: (value, ctx) => @@ -84,10 +84,10 @@ const validators = immutable.fromJS({ value, ctx .update('path', path => path.push(i)) - .update('type', type => type.get('type')) - ) + .update('type', type => type.get('type')), + ), ), - List() + List(), ) : immutable.fromJS([ { @@ -111,16 +111,23 @@ const validators = immutable.fromJS({ value.get(key), ctx .update('path', path => path.push(key)) - .set('type', getFieldType(ctx.get('type'), key)) - ) + .set('type', getFieldType(ctx.get('type'), key)), + ), ) : errors.push( - immutable.fromJS({ - path: ctx.get('path'), - message: `Unexpected key in map: ${key}`, - }) + key == 'templates' + ? immutable.fromJS({ + path: ctx.get('path'), + message: `The way to declare data source templates has changed, ` + + `please move the templates from inside data sources to ` + + `a \`templates:\` field at the top level of the manifest.`, + }) + : immutable.fromJS({ + path: ctx.get('path'), + message: `Unexpected key in map: ${key}`, + }), ), - List() + List(), ) : immutable.fromJS([ { @@ -191,7 +198,7 @@ const validateManifest = (value, type, schema, { resolveFile }) => path: [], errors: [], resolveFile, - }) + }), ) : immutable.fromJS([ { diff --git a/tests/cli/validation.test.js b/tests/cli/validation.test.js index d01c57ab8..7d8a9bedc 100644 --- a/tests/cli/validation.test.js +++ b/tests/cli/validation.test.js @@ -128,4 +128,12 @@ describe('Validation', () => { exitCode: 1, }, ) + cliTest( + 'Deprecated template format gives nice error', + ['codegen', '--skip-migrations'], + 'validation/nested-template-nice-error', + { + exitCode: 1, + }, + ) }) diff --git a/tests/cli/validation/abi-not-found.stderr b/tests/cli/validation/abi-not-found.stderr index 8ce91ded4..4a5df61ef 100644 --- a/tests/cli/validation/abi-not-found.stderr +++ b/tests/cli/validation/abi-not-found.stderr @@ -7,7 +7,7 @@ - FirstAbi - SecondAbi - Path: dataSources > 0 > templates > 0 > eventHandlers > 0 + Path: templates > 0 > eventHandlers > 0 Event with signature 'ExampleEvent(string,uint256)' not present in ABI 'ExampleContract'. Available events: - ExampleEvent(string) diff --git a/tests/cli/validation/abi-not-found/subgraph.yaml b/tests/cli/validation/abi-not-found/subgraph.yaml index 05ecb0841..f4d3fedf4 100644 --- a/tests/cli/validation/abi-not-found/subgraph.yaml +++ b/tests/cli/validation/abi-not-found/subgraph.yaml @@ -22,21 +22,21 @@ dataSources: eventHandlers: - event: ExampleEvent(string) handler: handleExampleEvent - templates: - - kind: ethereum/contract - name: ExampleTemplate - source: - abi: ExampleContract - mapping: - kind: ethereum/events - apiVersion: 0.0.1 - language: wasm/assemblyscript - file: ./mapping.ts - entities: - - ExampleEntity - abis: - - name: ExampleContract - file: ./Abi.json - eventHandlers: - - event: ExampleEvent(string,uint256) - handler: handleExampleEvent +templates: + - kind: ethereum/contract + name: ExampleTemplate + source: + abi: ExampleContract + mapping: + kind: ethereum/events + apiVersion: 0.0.1 + language: wasm/assemblyscript + file: ./mapping.ts + entities: + - ExampleEntity + abis: + - name: ExampleContract + file: ./Abi.json + eventHandlers: + - event: ExampleEvent(string,uint256) + handler: handleExampleEvent diff --git a/tests/cli/validation/event-not-found.stderr b/tests/cli/validation/event-not-found.stderr index 7abe3bd16..2abaaf993 100644 --- a/tests/cli/validation/event-not-found.stderr +++ b/tests/cli/validation/event-not-found.stderr @@ -6,7 +6,7 @@ Available events: - ExampleEvent(string) - Path: dataSources > 0 > templates > 0 > eventHandlers > 0 + Path: templates > 0 > eventHandlers > 0 Event with signature 'ExampleEvent(string,uint256)' not present in ABI 'ExampleContract'. Available events: - ExampleEvent(string) diff --git a/tests/cli/validation/event-not-found/subgraph.yaml b/tests/cli/validation/event-not-found/subgraph.yaml index ac79ed38a..70fdd507a 100644 --- a/tests/cli/validation/event-not-found/subgraph.yaml +++ b/tests/cli/validation/event-not-found/subgraph.yaml @@ -20,21 +20,21 @@ dataSources: eventHandlers: - event: ExampleEvent(string,uint256) handler: handleExampleEvent - templates: - - kind: ethereum/contract - name: ExampleTemplate - source: - abi: ExampleContract - mapping: - kind: ethereum/events - apiVersion: 0.0.1 - language: wasm/assemblyscript - file: ./mapping.ts - entities: - - ExampleEntity - abis: - - name: ExampleContract - file: ./Abi.json - eventHandlers: - - event: ExampleEvent(string,uint256) - handler: handleExampleEvent +templates: + - kind: ethereum/contract + name: ExampleTemplate + source: + abi: ExampleContract + mapping: + kind: ethereum/events + apiVersion: 0.0.1 + language: wasm/assemblyscript + file: ./mapping.ts + entities: + - ExampleEntity + abis: + - name: ExampleContract + file: ./Abi.json + eventHandlers: + - event: ExampleEvent(string,uint256) + handler: handleExampleEvent diff --git a/tests/cli/validation/example-values-found/generated/ExampleSubgraph/ExampleContract.ts b/tests/cli/validation/example-values-found/generated/ExampleSubgraph/ExampleContract.ts index 133155879..680a1c507 100644 --- a/tests/cli/validation/example-values-found/generated/ExampleSubgraph/ExampleContract.ts +++ b/tests/cli/validation/example-values-found/generated/ExampleSubgraph/ExampleContract.ts @@ -1,3 +1,5 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + import { EthereumCall, EthereumEvent, diff --git a/tests/cli/validation/example-values-found/generated/schema.ts b/tests/cli/validation/example-values-found/generated/schema.ts index a21336407..beee560b9 100644 --- a/tests/cli/validation/example-values-found/generated/schema.ts +++ b/tests/cli/validation/example-values-found/generated/schema.ts @@ -1,3 +1,5 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + import { TypedMap, Entity, diff --git a/tests/cli/validation/invalid-data-source-template.stderr b/tests/cli/validation/invalid-data-source-template.stderr index 43e9d18e7..631888b97 100644 --- a/tests/cli/validation/invalid-data-source-template.stderr +++ b/tests/cli/validation/invalid-data-source-template.stderr @@ -4,27 +4,27 @@ Path: dataSources > 0 > mapping > abis > 0 > file File does not exist: Abi.json - Path: dataSources > 0 > templates > 0 > kind + Path: templates > 0 > kind No value provided - Path: dataSources > 0 > templates > 0 > name + Path: templates > 0 > name Expected string, found number: 5 - Path: dataSources > 0 > templates > 0 > source + Path: templates > 0 > source Unexpected key in map: address - Path: dataSources > 0 > templates > 0 > mapping > entities + Path: templates > 0 > mapping > entities No value provided - Path: dataSources > 0 > templates > 0 > mapping > abis > 0 > file + Path: templates > 0 > mapping > abis > 0 > file File does not exist: NonexistentAbi.json - Path: dataSources > 0 > templates > 0 > mapping > language + Path: templates > 0 > mapping > language No value provided - Path: dataSources > 0 > templates > 0 > mapping > file + Path: templates > 0 > mapping > file No value provided - Path: dataSources > 0 > templates > 0 > mapping > apiVersion + Path: templates > 0 > mapping > apiVersion No value provided diff --git a/tests/cli/validation/invalid-data-source-template/subgraph.yaml b/tests/cli/validation/invalid-data-source-template/subgraph.yaml index 6c3ae8fca..7e0db9f11 100644 --- a/tests/cli/validation/invalid-data-source-template/subgraph.yaml +++ b/tests/cli/validation/invalid-data-source-template/subgraph.yaml @@ -20,13 +20,13 @@ dataSources: eventHandlers: - event: ExampleEvent(string,uint256) handler: handleExampleEvent - templates: - - name: 5 - source: - abi: SomeAbi - address: '0x22843e74c59580b3eaf6c233fa67d8b7c561a835' - mapping: - kind: ethereum/foo - abis: - - name: SomeAbi - file: ./NonexistentAbi.json +templates: + - name: 5 + source: + abi: SomeAbi + address: '0x22843e74c59580b3eaf6c233fa67d8b7c561a835' + mapping: + kind: ethereum/foo + abis: + - name: SomeAbi + file: ./NonexistentAbi.json diff --git a/tests/cli/validation/invalid-manifest.stderr b/tests/cli/validation/invalid-manifest.stderr index e9368a256..f7794fb77 100644 --- a/tests/cli/validation/invalid-manifest.stderr +++ b/tests/cli/validation/invalid-manifest.stderr @@ -23,9 +23,9 @@ - 13 - 14 - Path: dataSources > 0 > templates - Expected list, found map: - field: foo - Path: dataSources > 0 Unexpected key in map: abis + + Path: templates + Expected list, found map: + field: foo diff --git a/tests/cli/validation/invalid-manifest/subgraph.yaml b/tests/cli/validation/invalid-manifest/subgraph.yaml index 63ee3896c..d4fa4ee08 100644 --- a/tests/cli/validation/invalid-manifest/subgraph.yaml +++ b/tests/cli/validation/invalid-manifest/subgraph.yaml @@ -8,5 +8,5 @@ dataSources: - 12 - 13 - 14 - templates: - field: foo +templates: + field: foo diff --git a/tests/cli/validation/nested-template-nice-error.stderr b/tests/cli/validation/nested-template-nice-error.stderr new file mode 100644 index 000000000..b3a2f93b6 --- /dev/null +++ b/tests/cli/validation/nested-template-nice-error.stderr @@ -0,0 +1,5 @@ +- Load subgraph from subgraph.yaml +✖ Failed to load subgraph from subgraph.yaml: Error in subgraph.yaml: + + Path: dataSources > 0 > mapping + The way to declare data source templates has changed, please move the templates from inside data sources to a `templates:` field at the top level of the manifest. diff --git a/tests/cli/validation/nested-template-nice-error/Abi.json b/tests/cli/validation/nested-template-nice-error/Abi.json new file mode 100644 index 000000000..4d05f5839 --- /dev/null +++ b/tests/cli/validation/nested-template-nice-error/Abi.json @@ -0,0 +1,7 @@ +[ + { + "type": "event", + "name": "ExampleEvent", + "inputs": [{ "type": "string" }] + } +] diff --git a/tests/cli/validation/nested-template-nice-error/mapping.ts b/tests/cli/validation/nested-template-nice-error/mapping.ts new file mode 100644 index 000000000..e69de29bb diff --git a/tests/cli/validation/nested-template-nice-error/schema.graphql b/tests/cli/validation/nested-template-nice-error/schema.graphql new file mode 100644 index 000000000..2fa61d542 --- /dev/null +++ b/tests/cli/validation/nested-template-nice-error/schema.graphql @@ -0,0 +1,3 @@ +type MyEntity @entity { + id: ID! +} diff --git a/tests/cli/validation/nested-template-nice-error/subgraph.yaml b/tests/cli/validation/nested-template-nice-error/subgraph.yaml new file mode 100644 index 000000000..715d5f981 --- /dev/null +++ b/tests/cli/validation/nested-template-nice-error/subgraph.yaml @@ -0,0 +1,35 @@ +specVersion: 0.0.1 +repository: https://github.com/graphprotocol/test-subgraph +description: Test subgraph +schema: + file: ./schema.graphql +dataSources: + - kind: ethereum/contract + name: ExampleSubgraph + source: + abi: ExampleContract + mapping: + kind: ethereum/events + apiVersion: 0.0.1 + language: wasm/assemblyscript + file: ./mapping.ts + entities: + - ExampleEntity + abis: + - name: ExampleContract + file: ./Abi.json + templates: + - kind: ethereum/contract + name: ExampleSubgraph + source: + abi: ExampleContract + mapping: + kind: ethereum/events + apiVersion: 0.0.1 + language: wasm/assemblyscript + file: ./mapping.ts + entities: + - ExampleEntity + abis: + - name: ExampleContract + file: ./Abi.json diff --git a/tests/cli/validation/source-without-address-is-valid/generated/ExampleSubgraph/ExampleContract.ts b/tests/cli/validation/source-without-address-is-valid/generated/ExampleSubgraph/ExampleContract.ts index 133155879..680a1c507 100644 --- a/tests/cli/validation/source-without-address-is-valid/generated/ExampleSubgraph/ExampleContract.ts +++ b/tests/cli/validation/source-without-address-is-valid/generated/ExampleSubgraph/ExampleContract.ts @@ -1,3 +1,5 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + import { EthereumCall, EthereumEvent, diff --git a/tests/cli/validation/source-without-address-is-valid/generated/schema.ts b/tests/cli/validation/source-without-address-is-valid/generated/schema.ts index a21336407..beee560b9 100644 --- a/tests/cli/validation/source-without-address-is-valid/generated/schema.ts +++ b/tests/cli/validation/source-without-address-is-valid/generated/schema.ts @@ -1,3 +1,5 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + import { TypedMap, Entity,