@graphprotocol/graph-cli 0.22.2 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/examples/basic-event-handlers/yarn.lock +4 -4
  2. package/examples/example-subgraph/yarn.lock +4 -4
  3. package/examples/near/.gitkeep +0 -0
  4. package/manifest-schema.graphql +35 -2
  5. package/package.json +1 -1
  6. package/src/codegen/schema.js +1 -2
  7. package/src/codegen/template.js +9 -51
  8. package/src/codegen/typescript.js +7 -0
  9. package/src/command-helpers/compiler.js +6 -2
  10. package/src/command-helpers/data-sources.js +38 -0
  11. package/src/command-helpers/fs.js +8 -0
  12. package/src/commands/build.js +14 -0
  13. package/src/commands/codegen.js +8 -0
  14. package/src/commands/deploy.js +11 -8
  15. package/src/commands/init.js +5 -8
  16. package/src/commands/test.js +8 -3
  17. package/src/compiler/index.js +93 -76
  18. package/src/{abi.js → protocols/ethereum/abi.js} +0 -0
  19. package/src/{codegen → protocols/ethereum/codegen}/abi.js +47 -40
  20. package/src/{codegen → protocols/ethereum/codegen}/abi.test.js +1 -1
  21. package/src/protocols/ethereum/codegen/template.js +42 -0
  22. package/src/protocols/ethereum/subgraph.js +205 -0
  23. package/src/protocols/ethereum/type-generator.js +203 -0
  24. package/src/protocols/index.js +97 -0
  25. package/src/protocols/near/subgraph.js +42 -0
  26. package/src/scaffold.js +3 -2
  27. package/src/scaffold.test.js +1 -1
  28. package/src/subgraph.js +30 -252
  29. package/src/type-generator.js +31 -211
  30. package/src/validation/index.js +1 -0
  31. package/src/validation/manifest.js +73 -23
  32. package/src/validation/schema.js +6 -0
  33. package/subgraph-ethereum.yaml +134 -0
  34. package/subgraph-near.yaml +134 -0
  35. package/tests/cli/init/from-contract/abis/Contract.json +69 -0
  36. package/tests/cli/init/from-contract/package.json +16 -0
  37. package/tests/cli/init/from-contract/schema.graphql +6 -0
  38. package/tests/cli/init/from-contract/src/mapping.ts +49 -0
  39. package/tests/cli/init/from-contract/subgraph.yaml +26 -0
  40. package/tests/cli/validation/near-is-valid/mapping.ts +0 -0
  41. package/tests/cli/validation/near-is-valid/schema.graphql +8 -0
  42. package/tests/cli/validation/near-is-valid/subgraph.yaml +21 -0
  43. package/tests/cli/validation.test.js +8 -0
package/src/subgraph.js CHANGED
@@ -5,7 +5,6 @@ let yaml = require('yaml')
5
5
  let { strOptions } = require('yaml/types')
6
6
  let graphql = require('graphql/language')
7
7
  let validation = require('./validation')
8
- let ABI = require('./abi')
9
8
 
10
9
  const throwCombinedError = (filename, errors) => {
11
10
  throw new Error(
@@ -39,7 +38,7 @@ const buildCombinedWarning = (filename, warnings) =>
39
38
  : null
40
39
 
41
40
  module.exports = class Subgraph {
42
- static async validate(data, { resolveFile }) {
41
+ static async validate(data, protocol, { resolveFile }) {
43
42
  // Parse the default subgraph schema
44
43
  let schema = graphql.parse(
45
44
  await fs.readFile(path.join(__dirname, '..', 'manifest-schema.graphql'), 'utf-8'),
@@ -51,7 +50,7 @@ module.exports = class Subgraph {
51
50
  })
52
51
 
53
52
  // Validate the subgraph manifest using this schema
54
- return validation.validateManifest(data, rootType, schema, { resolveFile })
53
+ return validation.validateManifest(data, rootType, schema, protocol, { resolveFile })
55
54
  }
56
55
 
57
56
  static validateSchema(manifest, { resolveFile }) {
@@ -88,235 +87,6 @@ module.exports = class Subgraph {
88
87
  }
89
88
  }
90
89
 
91
- static collectDataSources(manifest) {
92
- return manifest
93
- .get('dataSources')
94
- .reduce(
95
- (dataSources, dataSource, dataSourceIndex) =>
96
- dataSource.get('kind') === 'ethereum/contract'
97
- ? dataSources.push(
98
- immutable.Map({ path: ['dataSources', dataSourceIndex], dataSource }),
99
- )
100
- : dataSources,
101
- immutable.List(),
102
- )
103
- }
104
-
105
- static collectDataSourceTemplates(manifest) {
106
- return manifest.get('templates', immutable.List()).reduce(
107
- (templates, template, templateIndex) =>
108
- template.get('kind') === 'ethereum/contract'
109
- ? templates.push(
110
- immutable.Map({
111
- path: ['templates', templateIndex],
112
- dataSource: template,
113
- }),
114
- )
115
- : templates,
116
- immutable.List(),
117
- )
118
- }
119
-
120
- static validateDataSourceAbis(dataSource, { resolveFile, path }) {
121
- // Validate that the the "source > abi" reference of all data sources
122
- // points to an existing ABI in the data source ABIs
123
- let abiName = dataSource.getIn(['source', 'abi'])
124
- let abiNames = dataSource.getIn(['mapping', 'abis']).map(abi => abi.get('name'))
125
- let nameErrors = abiNames.includes(abiName)
126
- ? immutable.List()
127
- : immutable.fromJS([
128
- {
129
- path: [...path, 'source', 'abi'],
130
- message: `\
131
- ABI name '${abiName}' not found in mapping > abis.
132
- Available ABIs:
133
- ${abiNames
134
- .sort()
135
- .map(name => `- ${name}`)
136
- .join('\n')}`,
137
- },
138
- ])
139
-
140
- // Validate that all ABI files are valid
141
- let fileErrors = dataSource
142
- .getIn(['mapping', 'abis'])
143
- .reduce((errors, abi, abiIndex) => {
144
- try {
145
- ABI.load(abi.get('name'), resolveFile(abi.get('file')))
146
- return errors
147
- } catch (e) {
148
- return errors.push(
149
- immutable.fromJS({
150
- path: [...path, 'mapping', 'abis', abiIndex, 'file'],
151
- message: e.message,
152
- }),
153
- )
154
- }
155
- }, immutable.List())
156
-
157
- return nameErrors.concat(fileErrors)
158
- }
159
-
160
- static validateAbis(manifest, { resolveFile }) {
161
- let dataSources = Subgraph.collectDataSources(manifest)
162
- let dataSourceTemplates = Subgraph.collectDataSourceTemplates(manifest)
163
-
164
- return dataSources.concat(dataSourceTemplates).reduce(
165
- (errors, dataSourceOrTemplate) =>
166
- errors.concat(
167
- Subgraph.validateDataSourceAbis(dataSourceOrTemplate.get('dataSource'), {
168
- resolveFile,
169
- path: dataSourceOrTemplate.get('path'),
170
- }),
171
- ),
172
- immutable.List(),
173
- )
174
- }
175
-
176
- static validateContractAddresses(manifest) {
177
- return manifest
178
- .get('dataSources')
179
- .filter(dataSource => dataSource.get('kind') === 'ethereum/contract')
180
- .reduce((errors, dataSource, dataSourceIndex) => {
181
- let path = ['dataSources', dataSourceIndex, 'source', 'address']
182
-
183
- // No need to validate if the source has no contract address
184
- if (!dataSource.get('source').has('address')) {
185
- return errors
186
- }
187
-
188
- let address = dataSource.getIn(['source', 'address'])
189
-
190
- // Validate whether the address is valid
191
- let pattern = /^(0x)?[0-9a-fA-F]{40}$/
192
- if (pattern.test(address)) {
193
- return errors
194
- } else {
195
- return errors.push(
196
- immutable.fromJS({
197
- path,
198
- message: `\
199
- Contract address is invalid: ${address}
200
- Must be 40 hexadecimal characters, with an optional '0x' prefix.`,
201
- }),
202
- )
203
- }
204
- }, immutable.List())
205
- }
206
-
207
- static validateDataSourceEvents(dataSource, { resolveFile, path }) {
208
- let abi
209
- try {
210
- // Resolve the source ABI name into a real ABI object
211
- let abiName = dataSource.getIn(['source', 'abi'])
212
- let abiEntry = dataSource
213
- .getIn(['mapping', 'abis'])
214
- .find(abi => abi.get('name') === abiName)
215
- abi = ABI.load(abiEntry.get('name'), resolveFile(abiEntry.get('file')))
216
- } catch (_) {
217
- // Ignore errors silently; we can't really say anything about
218
- // the events if the ABI can't even be loaded
219
- return immutable.List()
220
- }
221
-
222
- // Obtain event signatures from the mapping
223
- let manifestEvents = dataSource
224
- .getIn(['mapping', 'eventHandlers'], immutable.List())
225
- .map(handler => handler.get('event'))
226
-
227
- // Obtain event signatures from the ABI
228
- let abiEvents = abi.eventSignatures()
229
-
230
- // Add errors for every manifest event signature that is not
231
- // present in the ABI
232
- return manifestEvents.reduce(
233
- (errors, manifestEvent, index) =>
234
- abiEvents.includes(manifestEvent)
235
- ? errors
236
- : errors.push(
237
- immutable.fromJS({
238
- path: [...path, 'eventHandlers', index],
239
- message: `\
240
- Event with signature '${manifestEvent}' not present in ABI '${abi.name}'.
241
- Available events:
242
- ${abiEvents
243
- .sort()
244
- .map(event => `- ${event}`)
245
- .join('\n')}`,
246
- }),
247
- ),
248
- immutable.List(),
249
- )
250
- }
251
-
252
- static validateEvents(manifest, { resolveFile }) {
253
- let dataSources = Subgraph.collectDataSources(manifest)
254
- let dataSourceTemplates = Subgraph.collectDataSourceTemplates(manifest)
255
-
256
- return dataSources
257
- .concat(dataSourceTemplates)
258
- .reduce((errors, dataSourceOrTemplate) => {
259
- return errors.concat(
260
- Subgraph.validateDataSourceEvents(dataSourceOrTemplate.get('dataSource'), {
261
- resolveFile,
262
- path: dataSourceOrTemplate.get('path'),
263
- }),
264
- )
265
- }, immutable.List())
266
- }
267
-
268
- static validateCallFunctions(manifest, { resolveFile }) {
269
- return manifest
270
- .get('dataSources')
271
- .filter(dataSource => dataSource.get('kind') === 'ethereum/contract')
272
- .reduce((errors, dataSource, dataSourceIndex) => {
273
- let path = ['dataSources', dataSourceIndex, 'callHandlers']
274
-
275
- let abi
276
- try {
277
- // Resolve the source ABI name into a real ABI object
278
- let abiName = dataSource.getIn(['source', 'abi'])
279
- let abiEntry = dataSource
280
- .getIn(['mapping', 'abis'])
281
- .find(abi => abi.get('name') === abiName)
282
- abi = ABI.load(abiEntry.get('name'), resolveFile(abiEntry.get('file')))
283
- } catch (e) {
284
- // Ignore errors silently; we can't really say anything about
285
- // the call functions if the ABI can't even be loaded
286
- return errors
287
- }
288
-
289
- // Obtain event signatures from the mapping
290
- let manifestFunctions = dataSource
291
- .getIn(['mapping', 'callHandlers'], immutable.List())
292
- .map(handler => handler.get('function'))
293
-
294
- // Obtain event signatures from the ABI
295
- let abiFunctions = abi.callFunctionSignatures()
296
-
297
- // Add errors for every manifest event signature that is not
298
- // present in the ABI
299
- return manifestFunctions.reduce(
300
- (errors, manifestFunction, index) =>
301
- abiFunctions.includes(manifestFunction)
302
- ? errors
303
- : errors.push(
304
- immutable.fromJS({
305
- path: [...path, index],
306
- message: `\
307
- Call function with signature '${manifestFunction}' not present in ABI '${abi.name}'.
308
- Available call functions:
309
- ${abiFunctions
310
- .sort()
311
- .map(tx => `- ${tx}`)
312
- .join('\n')}`,
313
- }),
314
- ),
315
- errors,
316
- )
317
- }, immutable.List())
318
- }
319
-
320
90
  static validateRepository(manifest, { resolveFile }) {
321
91
  return manifest.get('repository') !==
322
92
  'https://github.com/graphprotocol/example-subgraph'
@@ -332,9 +102,9 @@ Please replace it with a link to your subgraph source code.`,
332
102
  }
333
103
 
334
104
  static validateDescription(manifest, { resolveFile }) {
335
- return manifest.get('description') !== 'Gravatar for Ethereum'
336
- ? immutable.List()
337
- : immutable.List().push(
105
+ // TODO: Maybe implement this in the future for each protocol example description
106
+ return manifest.get('description', '').startsWith('Gravatar for ')
107
+ ? immutable.List().push(
338
108
  immutable.fromJS({
339
109
  path: ['description'],
340
110
  message: `\
@@ -342,28 +112,32 @@ The description is still the one from the example subgraph.
342
112
  Please update it to tell users more about your subgraph.`,
343
113
  }),
344
114
  )
115
+ : immutable.List()
345
116
  }
346
117
 
347
- static validateEthereumContractHandlers(manifest) {
118
+ static validateHandlers(manifest, protocol, protocolSubgraph) {
348
119
  return manifest
349
120
  .get('dataSources')
350
- .filter(dataSource => dataSource.get('kind') === 'ethereum/contract')
121
+ .filter(dataSource => protocol.isValidKindName(dataSource.get('kind')))
351
122
  .reduce((errors, dataSource, dataSourceIndex) => {
352
123
  let path = ['dataSources', dataSourceIndex, 'mapping']
353
124
 
354
125
  let mapping = dataSource.get('mapping')
355
- let blockHandlers = mapping.get('blockHandlers', immutable.List())
356
- let callHandlers = mapping.get('callHandlers', immutable.List())
357
- let eventHandlers = mapping.get('eventHandlers', immutable.List())
358
126
 
359
- return blockHandlers.isEmpty() &&
360
- callHandlers.isEmpty() &&
361
- eventHandlers.isEmpty()
127
+ const handlerTypes = protocolSubgraph.handlerTypes()
128
+
129
+ const areAllHandlersEmpty = handlerTypes
130
+ .map(handlerType => mapping.get(handlerType, immutable.List()))
131
+ .every(handlers => handlers.isEmpty())
132
+
133
+ const handlerNamesWithoutLast = handlerTypes.pop().join(', ')
134
+
135
+ return areAllHandlersEmpty
362
136
  ? errors.push(
363
137
  immutable.fromJS({
364
138
  path: path,
365
139
  message: `\
366
- Mapping has no blockHandlers, callHandlers or eventHandlers.
140
+ Mapping has no ${handlerNamesWithoutLast} or ${handlerTypes.get(-1)}.
367
141
  At least one such handler must be defined.`,
368
142
  }),
369
143
  )
@@ -419,7 +193,10 @@ More than one template named '${name}', template names must be unique.`,
419
193
  return yaml.stringify(manifest.toJS())
420
194
  }
421
195
 
422
- static async load(filename, { skipValidation } = { skipValidation: false }) {
196
+ static async load(
197
+ filename,
198
+ { protocol, skipValidation } = { skipValidation: false }
199
+ ) {
423
200
  // Load and validate the manifest
424
201
  let data = null
425
202
 
@@ -434,7 +211,7 @@ More than one template named '${name}', template names must be unique.`,
434
211
  let resolveFile = maybeRelativeFile =>
435
212
  path.resolve(path.dirname(filename), maybeRelativeFile)
436
213
 
437
- let manifestErrors = await Subgraph.validate(data, { resolveFile })
214
+ let manifestErrors = await Subgraph.validate(data, protocol, { resolveFile })
438
215
  if (manifestErrors.size > 0) {
439
216
  throwCombinedError(filename, manifestErrors)
440
217
  }
@@ -445,16 +222,18 @@ More than one template named '${name}', template names must be unique.`,
445
222
  Subgraph.validateSchema(manifest, { resolveFile })
446
223
 
447
224
  // Perform other validations
225
+ const protocolSubgraph = protocol.getSubgraph({
226
+ manifest,
227
+ resolveFile,
228
+ })
229
+
448
230
  let errors = skipValidation
449
231
  ? immutable.List()
450
232
  : immutable.List.of(
451
- ...Subgraph.validateAbis(manifest, { resolveFile }),
452
- ...Subgraph.validateContractAddresses(manifest),
453
- ...Subgraph.validateEthereumContractHandlers(manifest),
454
- ...Subgraph.validateEvents(manifest, { resolveFile }),
455
- ...Subgraph.validateCallFunctions(manifest, { resolveFile }),
233
+ ...protocolSubgraph.validateManifest(),
456
234
  ...Subgraph.validateUniqueDataSourceNames(manifest),
457
235
  ...Subgraph.validateUniqueTemplateNames(manifest),
236
+ ...Subgraph.validateHandlers(manifest, protocol, protocolSubgraph),
458
237
  )
459
238
 
460
239
  if (errors.size > 0) {
@@ -467,7 +246,6 @@ More than one template named '${name}', template names must be unique.`,
467
246
  : immutable.List.of(
468
247
  ...Subgraph.validateRepository(manifest, { resolveFile }),
469
248
  ...Subgraph.validateDescription(manifest, { resolveFile }),
470
- ...Subgraph.validateEthereumContractHandlers(manifest),
471
249
  )
472
250
 
473
251
  return {
@@ -6,17 +6,14 @@ const graphql = require('graphql/language')
6
6
  const chalk = require('chalk')
7
7
  const toolbox = require('gluegun/toolbox')
8
8
 
9
- const ABI = require('./abi')
10
9
  const Schema = require('./schema')
11
10
  const Subgraph = require('./subgraph')
12
11
  const DataSourceTemplateCodeGenerator = require('./codegen/template')
13
12
  const Watcher = require('./watcher')
14
13
  const { step, withSpinner } = require('./command-helpers/spinner')
15
14
  const { applyMigrations } = require('./migrations')
16
-
17
- const GENERATED_FILE_NOTE = `
18
- // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
19
- `
15
+ const { GENERATED_FILE_NOTE } = require('./codegen/typescript')
16
+ const { displayPath } = require('./command-helpers/fs')
20
17
 
21
18
  module.exports = class TypeGenerator {
22
19
  constructor(options) {
@@ -25,15 +22,17 @@ module.exports = class TypeGenerator {
25
22
  this.options.sourceDir ||
26
23
  (this.options.subgraphManifest && path.dirname(this.options.subgraphManifest))
27
24
 
25
+ this.protocol = this.options.protocol
26
+ this.protocolTypeGenerator = this.protocol.getTypeGenerator({
27
+ sourceDir: this.sourceDir,
28
+ outputDir: this.options.outputDir,
29
+ })
30
+
28
31
  process.on('uncaughtException', function(e) {
29
32
  toolbox.print.error(`UNCAUGHT EXCEPTION: ${e}`)
30
33
  })
31
34
  }
32
35
 
33
- displayPath(p) {
34
- return path.relative(process.cwd(), p)
35
- }
36
-
37
36
  async generateTypes() {
38
37
  try {
39
38
  if (!this.options.skipMigrations && this.options.subgraphManifest) {
@@ -43,13 +42,20 @@ module.exports = class TypeGenerator {
43
42
  })
44
43
  }
45
44
  let subgraph = await this.loadSubgraph()
46
- let abis = await this.loadABIs(subgraph)
47
- await this.generateTypesForABIs(abis)
45
+
46
+ // Not all protocols support/have ABIs.
47
+ if (this.protocol.hasABIs()) {
48
+ const abis = await this.protocolTypeGenerator.loadABIs(subgraph)
49
+ await this.protocolTypeGenerator.generateTypesForABIs(abis)
50
+ }
48
51
 
49
52
  await this.generateTypesForDataSourceTemplates(subgraph)
50
53
 
51
- let templateAbis = await this.loadDataSourceTemplateABIs(subgraph)
52
- await this.generateTypesForDataSourceTemplateABIs(templateAbis)
54
+ // Not all protocols support/have ABIs.
55
+ if (this.protocol.hasABIs()) {
56
+ const templateAbis = await this.protocolTypeGenerator.loadDataSourceTemplateABIs(subgraph)
57
+ await this.protocolTypeGenerator.generateTypesForDataSourceTemplateABIs(templateAbis)
58
+ }
53
59
 
54
60
  let schema = await this.loadSchema(subgraph)
55
61
  await this.generateTypesForSchema(schema)
@@ -62,12 +68,14 @@ module.exports = class TypeGenerator {
62
68
  }
63
69
 
64
70
  async loadSubgraph({ quiet } = { quiet: false }) {
71
+ const subgraphLoadOptions = { protocol: this.protocol, skipValidation: false }
72
+
65
73
  if (quiet) {
66
74
  return this.options.subgraph
67
75
  ? this.options.subgraph
68
- : Subgraph.load(this.options.subgraphManifest).result
76
+ : Subgraph.load(this.options.subgraphManifest, subgraphLoadOptions).result
69
77
  } else {
70
- const manifestPath = this.displayPath(this.options.subgraphManifest)
78
+ const manifestPath = displayPath(this.options.subgraphManifest)
71
79
 
72
80
  return await withSpinner(
73
81
  `Load subgraph from ${manifestPath}`,
@@ -76,167 +84,19 @@ module.exports = class TypeGenerator {
76
84
  async spinner => {
77
85
  return this.options.subgraph
78
86
  ? this.options.subgraph
79
- : Subgraph.load(this.options.subgraphManifest)
87
+ : Subgraph.load(this.options.subgraphManifest, subgraphLoadOptions)
80
88
  },
81
89
  )
82
90
  }
83
91
  }
84
92
 
85
- async loadABIs(subgraph) {
86
- return await withSpinner(
87
- 'Load contract ABIs',
88
- 'Failed to load contract ABIs',
89
- `Warnings while loading contract ABIs`,
90
- async spinner => {
91
- try {
92
- return subgraph
93
- .get('dataSources')
94
- .reduce(
95
- (abis, dataSource) =>
96
- dataSource
97
- .getIn(['mapping', 'abis'])
98
- .reduce(
99
- (abis, abi) =>
100
- abis.push(
101
- this._loadABI(
102
- dataSource,
103
- abi.get('name'),
104
- abi.get('file'),
105
- spinner,
106
- ),
107
- ),
108
- abis,
109
- ),
110
- immutable.List(),
111
- )
112
- } catch (e) {
113
- throw Error(`Failed to load contract ABIs: ${e.message}`)
114
- }
115
- },
116
- )
117
- }
118
-
119
- _loadABI(dataSource, name, maybeRelativePath, spinner) {
120
- try {
121
- if (this.sourceDir) {
122
- let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
123
- step(spinner, `Load contract ABI from`, this.displayPath(absolutePath))
124
- return { dataSource: dataSource, abi: ABI.load(name, absolutePath) }
125
- } else {
126
- return { dataSource: dataSource, abi: ABI.load(name, maybeRelativePath) }
127
- }
128
- } catch (e) {
129
- throw Error(`Failed to load contract ABI: ${e.message}`)
130
- }
131
- }
132
-
133
- _loadDataSourceTemplateABI(template, name, maybeRelativePath, spinner) {
134
- try {
135
- if (this.sourceDir) {
136
- let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
137
- step(
138
- spinner,
139
- `Load data source template ABI from`,
140
- this.displayPath(absolutePath),
141
- )
142
- return { template, abi: ABI.load(name, absolutePath) }
143
- } else {
144
- return { template, abi: ABI.load(name, maybeRelativePath) }
145
- }
146
- } catch (e) {
147
- throw Error(`Failed to load data source template ABI: ${e.message}`)
148
- }
149
- }
150
-
151
- generateTypesForABIs(abis) {
152
- return withSpinner(
153
- `Generate types for contract ABIs`,
154
- `Failed to generate types for contract ABIs`,
155
- `Warnings while generating types for contract ABIs`,
156
- async spinner => {
157
- return await Promise.all(
158
- abis.map(async (abi, name) => await this._generateTypesForABI(abi, spinner)),
159
- )
160
- },
161
- )
162
- }
163
-
164
- async _generateTypesForABI(abi, spinner) {
165
- try {
166
- step(
167
- spinner,
168
- `Generate types for contract ABI:`,
169
- `${abi.abi.name} (${this.displayPath(abi.abi.file)})`,
170
- )
171
-
172
- let codeGenerator = abi.abi.codeGenerator()
173
- let code = prettier.format(
174
- [
175
- GENERATED_FILE_NOTE,
176
- ...codeGenerator.generateModuleImports(),
177
- ...codeGenerator.generateTypes(),
178
- ].join('\n'),
179
- {
180
- parser: 'typescript',
181
- },
182
- )
183
-
184
- let outputFile = path.join(
185
- this.options.outputDir,
186
- abi.dataSource.get('name'),
187
- `${abi.abi.name}.ts`,
188
- )
189
- step(spinner, `Write types to`, this.displayPath(outputFile))
190
- await fs.mkdirs(path.dirname(outputFile))
191
- await fs.writeFile(outputFile, code)
192
- } catch (e) {
193
- throw Error(`Failed to generate types for contract ABI: ${e.message}`)
194
- }
195
- }
196
-
197
- async _generateTypesForDataSourceTemplateABI(abi, spinner) {
198
- try {
199
- step(
200
- spinner,
201
- `Generate types for data source template ABI:`,
202
- `${abi.template.get('name')} > ${abi.abi.name} (${this.displayPath(
203
- abi.abi.file,
204
- )})`,
205
- )
206
-
207
- let codeGenerator = abi.abi.codeGenerator()
208
- let code = prettier.format(
209
- [
210
- GENERATED_FILE_NOTE,
211
- ...codeGenerator.generateModuleImports(),
212
- ...codeGenerator.generateTypes(),
213
- ].join('\n'),
214
- {
215
- parser: 'typescript',
216
- },
217
- )
218
-
219
- let outputFile = path.join(
220
- this.options.outputDir,
221
- 'templates',
222
- abi.template.get('name'),
223
- `${abi.abi.name}.ts`,
224
- )
225
- step(spinner, `Write types to`, this.displayPath(outputFile))
226
- await fs.mkdirs(path.dirname(outputFile))
227
- await fs.writeFile(outputFile, code)
228
- } catch (e) {
229
- throw Error(`Failed to generate types for data source template ABI: ${e.message}`)
230
- }
231
- }
232
-
233
93
  async loadSchema(subgraph) {
234
94
  let maybeRelativePath = subgraph.getIn(['schema', 'file'])
235
95
  let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
236
96
  return await withSpinner(
237
- `Load GraphQL schema from ${this.displayPath(absolutePath)}`,
238
- `Failed to load GraphQL schema from ${this.displayPath(absolutePath)}`,
239
- `Warnings while loading GraphQL schema from ${this.displayPath(absolutePath)}`,
97
+ `Load GraphQL schema from ${displayPath(absolutePath)}`,
98
+ `Failed to load GraphQL schema from ${displayPath(absolutePath)}`,
99
+ `Warnings while loading GraphQL schema from ${displayPath(absolutePath)}`,
240
100
  async spinner => {
241
101
  let maybeRelativePath = subgraph.getIn(['schema', 'file'])
242
102
  let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
@@ -265,7 +125,7 @@ module.exports = class TypeGenerator {
265
125
  )
266
126
 
267
127
  let outputFile = path.join(this.options.outputDir, 'schema.ts')
268
- step(spinner, 'Write types to', this.displayPath(outputFile))
128
+ step(spinner, 'Write types to', displayPath(outputFile))
269
129
  await fs.mkdirs(path.dirname(outputFile))
270
130
  await fs.writeFile(outputFile, code)
271
131
  },
@@ -288,7 +148,7 @@ module.exports = class TypeGenerator {
288
148
  `${template.get('name')}`,
289
149
  )
290
150
 
291
- let codeGenerator = new DataSourceTemplateCodeGenerator(template)
151
+ let codeGenerator = new DataSourceTemplateCodeGenerator(template, this.protocol)
292
152
 
293
153
  // Only generate module imports once, because they are identical for
294
154
  // all types generated for data source templates.
@@ -305,7 +165,7 @@ module.exports = class TypeGenerator {
305
165
  })
306
166
 
307
167
  let outputFile = path.join(this.options.outputDir, 'templates.ts')
308
- step(spinner, `Write types for templates to`, this.displayPath(outputFile))
168
+ step(spinner, `Write types for templates to`, displayPath(outputFile))
309
169
  await fs.mkdirs(path.dirname(outputFile))
310
170
  await fs.writeFile(outputFile, code)
311
171
  }
@@ -313,46 +173,6 @@ module.exports = class TypeGenerator {
313
173
  )
314
174
  }
315
175
 
316
- async loadDataSourceTemplateABIs(subgraph) {
317
- return await withSpinner(
318
- `Load data source template ABIs`,
319
- `Failed to load data source template ABIs`,
320
- `Warnings while loading data source template ABIs`,
321
- async spinner => {
322
- let abis = []
323
- for (let template of subgraph.get('templates', immutable.List())) {
324
- for (let abi of template.getIn(['mapping', 'abis'])) {
325
- abis.push(
326
- this._loadDataSourceTemplateABI(
327
- template,
328
- abi.get('name'),
329
- abi.get('file'),
330
- spinner,
331
- ),
332
- )
333
- }
334
- }
335
- return abis
336
- },
337
- )
338
- }
339
-
340
- async generateTypesForDataSourceTemplateABIs(abis) {
341
- return await withSpinner(
342
- `Generate types for data source template ABIs`,
343
- `Failed to generate types for data source template ABIs`,
344
- `Warnings while generating types for data source template ABIs`,
345
- async spinner => {
346
- return await Promise.all(
347
- abis.map(
348
- async (abi, name) =>
349
- await this._generateTypesForDataSourceTemplateABI(abi, spinner),
350
- ),
351
- )
352
- },
353
- )
354
- }
355
-
356
176
  async getFilesToWatch() {
357
177
  try {
358
178
  let files = []
@@ -387,7 +207,7 @@ module.exports = class TypeGenerator {
387
207
  onReady: () => (spinner = toolbox.print.spin('Watching subgraph files')),
388
208
  onTrigger: async changedFile => {
389
209
  if (changedFile !== undefined) {
390
- spinner.info(`File change detected: ${this.displayPath(changedFile)}\n`)
210
+ spinner.info(`File change detected: ${displayPath(changedFile)}\n`)
391
211
  }
392
212
  await generator.generateTypes()
393
213
  spinner.start()