@graphprotocol/graph-cli 0.49.0-alpha-20230505152117-ef48fdf → 0.49.0-alpha-20230505181403-af18bf2

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @graphprotocol/graph-cli
2
2
 
3
- ## 0.49.0-alpha-20230505152117-ef48fdf
3
+ ## 0.49.0-alpha-20230505181403-af18bf2
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -9,23 +9,48 @@
9
9
  Thanks [@saihaj](https://github.com/saihaj)! - do not generate types, instead show a message to
10
10
  user to use substreams CLI for codegen.
11
11
 
12
+ - [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
13
+ [`6bd042b`](https://github.com/graphprotocol/graph-tooling/commit/6bd042bb5dd8facff02450c874e8811aebc83fcc)
14
+ Thanks [@saihaj](https://github.com/saihaj)! - For substreams generate the directory tree as
15
+ follows
16
+
17
+ ```
18
+ .
19
+ ├── package.json
20
+ ├── schema.graphql
21
+ └── subgraph.yaml
22
+ ```
23
+
24
+ In the `package.json` we only depend on the CLI since that is what developer will use to deploy
25
+ the subgraph. The `schema.graphql` is the schema of the subgraph and the `subgraph.yaml` is the
26
+ manifest file for the subgraph.
27
+
28
+ - [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
29
+ [`affcb14`](https://github.com/graphprotocol/graph-tooling/commit/affcb1492f29affdb2426e57a154f132362f24ef)
30
+ Thanks [@saihaj](https://github.com/saihaj)! - respect --abi flag instead of loading from
31
+ etherscan
32
+
33
+ - [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
34
+ [`f90dd75`](https://github.com/graphprotocol/graph-tooling/commit/f90dd757a558f4e66cc46780f13612309f45646a)
35
+ Thanks [@saihaj](https://github.com/saihaj)! - remove index events as entities for substreams
36
+
12
37
  - [#1306](https://github.com/graphprotocol/graph-tooling/pull/1306)
13
38
  [`f5e4b58`](https://github.com/graphprotocol/graph-tooling/commit/f5e4b58989edc5f3bb8211f1b912449e77832de8)
14
39
  Thanks [@saihaj](https://github.com/saihaj)! - Add loadInBlock function for entities as part of
15
40
  codegen
16
41
 
17
- - [#1339](https://github.com/graphprotocol/graph-tooling/pull/1339)
18
- [`214cd71`](https://github.com/graphprotocol/graph-tooling/commit/214cd7153aabd427b52c87f5f3643212cb615913)
19
- Thanks [@saihaj](https://github.com/saihaj)! - allow deploy optimism and optimism-goerli on studio
42
+ - [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
43
+ [`f90dd75`](https://github.com/graphprotocol/graph-tooling/commit/f90dd757a558f4e66cc46780f13612309f45646a)
44
+ Thanks [@saihaj](https://github.com/saihaj)! - remove start block selection for substreams
20
45
 
21
46
  ### Patch Changes
22
47
 
23
- - [#1328](https://github.com/graphprotocol/graph-tooling/pull/1328)
24
- [`4963215`](https://github.com/graphprotocol/graph-tooling/commit/4963215564797393424c563ea0b51aabbfd8e33e)
25
- Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
48
+ - [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
49
+ [`aac26c9`](https://github.com/graphprotocol/graph-tooling/commit/aac26c97b5427156f8d61311924bac215155b4cb)
50
+ Thanks [@saihaj](https://github.com/saihaj)! - dependencies updates:
26
51
 
27
- - Updated dependency [`@oclif/core@2.8.4` ↗︎](https://www.npmjs.com/package/@oclif/core/v/2.8.4)
28
- (from `2.8.2`, in `dependencies`)
52
+ - Updated dependency [`gluegun@5.1.2` ↗︎](https://www.npmjs.com/package/gluegun/v/5.1.2) (from
53
+ `https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep`, in `dependencies`)
29
54
 
30
55
  - [#1331](https://github.com/graphprotocol/graph-tooling/pull/1331)
31
56
  [`b2c8dec`](https://github.com/graphprotocol/graph-tooling/commit/b2c8decb7806d25df6ca4e07f6dfdf7941516435)
@@ -14,6 +14,14 @@ export declare const generateScaffold: ({ protocolInstance, abi, contract, netwo
14
14
  startBlock?: string | undefined;
15
15
  node?: string | undefined;
16
16
  }, spinner: Spinner) => Promise<{
17
+ 'subgraph.yaml': string;
18
+ 'schema.graphql': string;
19
+ 'package.json': string;
20
+ 'tsconfig.json'?: undefined;
21
+ src?: undefined;
22
+ abis?: undefined;
23
+ tests?: undefined;
24
+ } | {
17
25
  'package.json': string;
18
26
  'subgraph.yaml': string;
19
27
  'schema.graphql': string;
@@ -1,4 +1,4 @@
1
- export declare const allowedStudioNetworks: readonly ["mainnet", "rinkeby", "goerli", "gnosis", "chapel", "optimism-goerli", "clover", "fantom", "matic", "fantom-testnet", "arbitrum-goerli", "fuji", "celo-alfajores", "mumbai", "aurora-testnet", "near-testnet", "optimism", "optimism-goerli", "theta-testnet-001", "osmo-test-4", "base-testnet", "celo", "arbitrum-one", "avalanche", "zksync-era", "sepolia", "polygon-zkevm-testnet", "polygon-zkevm"];
1
+ export declare const allowedStudioNetworks: readonly ["mainnet", "rinkeby", "goerli", "gnosis", "chapel", "optimism-goerli", "clover", "fantom", "matic", "fantom-testnet", "arbitrum-goerli", "fuji", "celo-alfajores", "mumbai", "aurora-testnet", "near-testnet", "theta-testnet-001", "osmo-test-4", "base-testnet", "celo", "arbitrum-one", "avalanche", "zksync-era", "sepolia", "polygon-zkevm-testnet", "polygon-zkevm"];
2
2
  export declare const validateStudioNetwork: ({ studio, product, network, }: {
3
3
  studio?: string | boolean | undefined;
4
4
  product?: string | undefined;
@@ -18,8 +18,6 @@ exports.allowedStudioNetworks = [
18
18
  'mumbai',
19
19
  'aurora-testnet',
20
20
  'near-testnet',
21
- 'optimism',
22
- 'optimism-goerli',
23
21
  'theta-testnet-001',
24
22
  'osmo-test-4',
25
23
  'base-testnet',
@@ -39,12 +39,10 @@ const scaffold_1 = require("../command-helpers/scaffold");
39
39
  const spinner_1 = require("../command-helpers/spinner");
40
40
  const studio_1 = require("../command-helpers/studio");
41
41
  const subgraph_1 = require("../command-helpers/subgraph");
42
- const debug_1 = __importDefault(require("../debug"));
43
42
  const protocols_1 = __importDefault(require("../protocols"));
44
43
  const schema_1 = require("../scaffold/schema");
45
44
  const validation_1 = require("../validation");
46
45
  const add_1 = __importDefault(require("./add"));
47
- const initDebug = (0, debug_1.default)('graph-cli:init');
48
46
  const protocolChoices = Array.from(protocols_1.default.availableProtocols().keys());
49
47
  const availableNetworks = protocols_1.default.availableNetworks();
50
48
  const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum/gravatar';
@@ -85,8 +83,18 @@ class InitCommand extends core_1.Command {
85
83
  };
86
84
  // If all parameters are provided from the command-line,
87
85
  // go straight to creating the subgraph from the example
88
- if (fromExample && subgraphName && directory) {
89
- return await initSubgraphFromExample.bind(this)({ fromExample, allowSimpleName, directory, subgraphName, studio, product }, { commands });
86
+ if (fromExample && subgraphName && directory && protocol) {
87
+ await initSubgraphFromExample.bind(this)({
88
+ fromExample,
89
+ allowSimpleName,
90
+ directory,
91
+ subgraphName,
92
+ studio,
93
+ product,
94
+ protocolInstance: new protocols_1.default(protocol),
95
+ }, { commands });
96
+ // Exit with success
97
+ return this.exit(0);
90
98
  }
91
99
  // Will be assigned below if ethereum
92
100
  let abi;
@@ -122,7 +130,7 @@ class InitCommand extends core_1.Command {
122
130
  }
123
131
  }
124
132
  }
125
- return await initSubgraphFromContract.bind(this)({
133
+ await initSubgraphFromContract.bind(this)({
126
134
  protocolInstance,
127
135
  abi,
128
136
  allowSimpleName,
@@ -137,6 +145,8 @@ class InitCommand extends core_1.Command {
137
145
  product,
138
146
  startBlock,
139
147
  }, { commands, addContract: false });
148
+ // Exit with success
149
+ return this.exit(0);
140
150
  }
141
151
  // Otherwise, take the user through the interactive form
142
152
  const answers = await processInitForm.bind(this)({
@@ -145,6 +155,7 @@ class InitCommand extends core_1.Command {
145
155
  studio,
146
156
  node,
147
157
  abi,
158
+ abiPath,
148
159
  allowSimpleName,
149
160
  directory,
150
161
  contract: fromContract,
@@ -166,6 +177,7 @@ class InitCommand extends core_1.Command {
166
177
  directory: answers.directory,
167
178
  studio: answers.studio,
168
179
  product: answers.product,
180
+ protocolInstance: answers.protocolInstance,
169
181
  }, { commands });
170
182
  }
171
183
  else {
@@ -191,6 +203,8 @@ class InitCommand extends core_1.Command {
191
203
  startBlock: answers.startBlock,
192
204
  }, { commands, addContract: true });
193
205
  }
206
+ // Exit with success
207
+ this.exit(0);
194
208
  }
195
209
  }
196
210
  InitCommand.description = 'Creates a new subgraph with basic scaffolding.';
@@ -265,227 +279,255 @@ InitCommand.flags = {
265
279
  }),
266
280
  };
267
281
  exports.default = InitCommand;
268
- async function processInitForm({ protocol, product, studio, node, abi, allowSimpleName, directory, contract, indexEvents, fromExample, network, subgraphName, contractName, startBlock, }) {
282
+ async function processInitForm({ protocol: initProtocol, product: initProduct, studio: initStudio, node: initNode, abi: initAbi, abiPath: initAbiPath, directory: initDirectory, contract: initContract, indexEvents: initIndexEvents, fromExample: initFromExample, network: initNetwork, subgraphName: initSubgraphName, contractName: initContractName, startBlock: initStartBlock, allowSimpleName: initAllowSimpleName, }) {
269
283
  let abiFromEtherscan = undefined;
270
- let abiFromFile = undefined;
271
- let protocolInstance;
272
- let ProtocolContract;
273
- let ABI;
274
- const questions = [
275
- {
284
+ try {
285
+ const { protocol } = await gluegun_1.prompt.ask({
276
286
  type: 'select',
277
287
  name: 'protocol',
278
288
  message: 'Protocol',
279
289
  choices: protocolChoices,
280
- skip: protocolChoices.includes(String(protocol)),
281
- result: (value) => {
282
- // eslint-disable-next-line -- prettier has problems with ||=
283
- protocol = protocol || value;
284
- protocolInstance = new protocols_1.default(protocol);
285
- return protocol;
286
- },
287
- },
288
- {
289
- type: 'select',
290
- name: 'product',
291
- message: 'Product for which to initialize',
292
- choices: ['subgraph-studio', 'hosted-service'],
293
- skip: () => protocol === 'arweave' ||
294
- protocol === 'cosmos' ||
295
- protocol === 'near' ||
296
- product === 'subgraph-studio' ||
297
- product === 'hosted-service' ||
298
- studio !== undefined ||
299
- node !== undefined,
300
- result: (value) => {
301
- // For now we only support NEAR subgraphs in the Hosted Service
302
- if (protocol === 'near') {
303
- // Can be overwritten because the question will be skipped (product === undefined)
304
- product = 'hosted-service';
305
- return product;
306
- }
307
- if (value == 'subgraph-studio') {
308
- allowSimpleName = true;
309
- }
310
- product = value;
311
- return value;
290
+ skip: protocolChoices.includes(String(initProtocol)),
291
+ });
292
+ const protocolInstance = new protocols_1.default(protocol);
293
+ const isSubstreams = protocol === 'substreams';
294
+ const { product } = await gluegun_1.prompt.ask([
295
+ {
296
+ type: 'select',
297
+ name: 'product',
298
+ message: 'Product for which to initialize',
299
+ choices: ['subgraph-studio', 'hosted-service'],
300
+ skip: protocol === 'arweave' ||
301
+ protocol === 'cosmos' ||
302
+ protocol === 'near' ||
303
+ initProduct === 'subgraph-studio' ||
304
+ initProduct === 'hosted-service' ||
305
+ initStudio !== undefined ||
306
+ initNode !== undefined,
307
+ result: value => {
308
+ if (initProduct)
309
+ return initProduct;
310
+ if (initStudio)
311
+ return 'subgraph-studio';
312
+ // For now we only support NEAR subgraphs in the Hosted Service
313
+ if (protocol === 'near') {
314
+ return 'hosted-service';
315
+ }
316
+ if (value == 'subgraph-studio') {
317
+ initAllowSimpleName = true;
318
+ }
319
+ return value;
320
+ },
312
321
  },
313
- },
314
- {
315
- type: 'input',
316
- name: 'subgraphName',
317
- message: () => (product == 'subgraph-studio' || studio ? 'Subgraph slug' : 'Subgraph name'),
318
- initial: subgraphName,
319
- validate: (name) => {
320
- try {
321
- (0, subgraph_1.validateSubgraphName)(name, { allowSimpleName });
322
- return true;
323
- }
324
- catch (e) {
325
- return `${e.message}
322
+ ]);
323
+ const { subgraphName } = await gluegun_1.prompt.ask([
324
+ {
325
+ type: 'input',
326
+ name: 'subgraphName',
327
+ message: () => (product == 'subgraph-studio' ? 'Subgraph slug' : 'Subgraph name'),
328
+ initial: initSubgraphName,
329
+ validate: name => {
330
+ try {
331
+ (0, subgraph_1.validateSubgraphName)(name, { allowSimpleName: initAllowSimpleName });
332
+ return true;
333
+ }
334
+ catch (e) {
335
+ return `${e.message}
326
336
 
327
- Examples:
337
+ Examples:
328
338
 
329
- $ graph init ${os_1.default.userInfo().username}/${name}
330
- $ graph init ${name} --allow-simple-name`;
331
- }
339
+ $ graph init ${os_1.default.userInfo().username}/${name}
340
+ $ graph init ${name} --allow-simple-name`;
341
+ }
342
+ },
332
343
  },
333
- result: (value) => {
334
- subgraphName = value;
335
- return value;
344
+ ]);
345
+ const { directory } = await gluegun_1.prompt.ask([
346
+ {
347
+ type: 'input',
348
+ name: 'directory',
349
+ message: 'Directory to create the subgraph in',
350
+ initial: () => initDirectory || (0, subgraph_1.getSubgraphBasename)(subgraphName),
351
+ validate: value => gluegun_1.filesystem.exists(value || initDirectory || (0, subgraph_1.getSubgraphBasename)(subgraphName))
352
+ ? 'Directory already exists'
353
+ : true,
336
354
  },
337
- },
338
- {
339
- type: 'input',
340
- name: 'directory',
341
- message: 'Directory to create the subgraph in',
342
- initial: () => directory ||
343
- (0, subgraph_1.getSubgraphBasename)(
344
- // @ts-expect-error will be set by previous question
345
- subgraphName),
346
- validate: (value) => gluegun_1.filesystem.exists(value ||
347
- directory ||
348
- (0, subgraph_1.getSubgraphBasename)(
349
- // @ts-expect-error will be set by previous question
350
- subgraphName))
351
- ? 'Directory already exists'
352
- : true,
353
- },
354
- {
355
- type: 'select',
356
- name: 'network',
357
- message: () => `${protocolInstance.displayName()} network`,
358
- choices: () => {
359
- initDebug('Generating list of available networks for protocol "%s" (%M)', protocol, availableNetworks.get(protocol));
360
- return (
361
- // @ts-expect-error TODO: wait what?
362
- availableNetworks
355
+ ]);
356
+ const { network } = await gluegun_1.prompt.ask([
357
+ {
358
+ type: 'select',
359
+ name: 'network',
360
+ message: () => `${protocolInstance.displayName()} network`,
361
+ choices: availableNetworks
363
362
  .get(protocol) // Get networks related to the chosen protocol.
364
- .toArray()); // Needed because of gluegun. It can't even receive a JS iterable.
365
- },
366
- skip: fromExample !== undefined,
367
- initial: network || 'mainnet',
368
- result: (value) => {
369
- network = value;
370
- return value;
371
- },
372
- },
373
- // TODO:
374
- //
375
- // protocols that don't support contract
376
- // - arweave
377
- // - cosmos
378
- {
379
- type: 'input',
380
- name: 'contract',
381
- message: () => {
382
- ProtocolContract = protocolInstance.getContract();
383
- return `Contract ${ProtocolContract.identifierName()}`;
384
- },
385
- skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
386
- initial: contract,
387
- validate: async (value) => {
388
- if (fromExample !== undefined || !protocolInstance.hasContract()) {
389
- return true;
390
- }
391
- // Validate whether the contract is valid
392
- const { valid, error } = (0, validation_1.validateContract)(value, ProtocolContract);
393
- return valid ? true : error;
363
+ ?.toArray() || ['mainnet'],
364
+ skip: initFromExample !== undefined,
365
+ result: value => {
366
+ if (initNetwork)
367
+ return initNetwork;
368
+ return value;
369
+ },
394
370
  },
395
- result: async (value) => {
396
- if (fromExample !== undefined) {
371
+ ]);
372
+ const { contract } = await gluegun_1.prompt.ask([
373
+ // TODO:
374
+ // protocols that don't support contract
375
+ // - arweave
376
+ // - cosmos
377
+ {
378
+ type: 'input',
379
+ name: 'contract',
380
+ message: `Contract ${protocolInstance.getContract()?.identifierName()}`,
381
+ skip: () => initFromExample !== undefined || !protocolInstance.hasContract() || isSubstreams,
382
+ initial: initContract,
383
+ validate: async (value) => {
384
+ if (initFromExample !== undefined || !protocolInstance.hasContract()) {
385
+ return true;
386
+ }
387
+ const protocolContract = protocolInstance.getContract();
388
+ if (!protocolContract) {
389
+ return 'Contract not found.';
390
+ }
391
+ // Validate whether the contract is valid
392
+ const { valid, error } = (0, validation_1.validateContract)(value, protocolContract);
393
+ return valid ? true : error;
394
+ },
395
+ result: async (value) => {
396
+ if (initFromExample !== undefined || isSubstreams || initAbiPath) {
397
+ return value;
398
+ }
399
+ const ABI = protocolInstance.getABI();
400
+ // Try loading the ABI from Etherscan, if none was provided
401
+ if (protocolInstance.hasABIs() && !initAbi) {
402
+ try {
403
+ if (network === 'poa-core') {
404
+ // TODO: this variable is never used anywhere, what happens?
405
+ // abiFromBlockScout = await loadAbiFromBlockScout(ABI, network, value)
406
+ }
407
+ else {
408
+ abiFromEtherscan = await (0, abi_1.loadAbiFromEtherscan)(ABI, network, value);
409
+ }
410
+ }
411
+ catch (e) {
412
+ // noop
413
+ }
414
+ }
415
+ // If startBlock is not set, try to load it.
416
+ if (!initStartBlock) {
417
+ try {
418
+ // Load startBlock for this contract
419
+ initStartBlock = Number(await (0, abi_1.loadStartBlockForContract)(network, value)).toString();
420
+ }
421
+ catch (error) {
422
+ // noop
423
+ }
424
+ }
397
425
  return value;
398
- }
399
- ABI = protocolInstance.getABI();
400
- // Try loading the ABI from Etherscan, if none was provided
401
- if (protocolInstance.hasABIs() && !abi) {
402
- try {
403
- if (network === 'poa-core') {
404
- // TODO: this variable is never used anywhere, what happens?
405
- // abiFromBlockScout = await loadAbiFromBlockScout(ABI, network, value)
426
+ },
427
+ },
428
+ ]);
429
+ const { abi: abiFromFile } = await gluegun_1.prompt.ask([
430
+ {
431
+ type: 'input',
432
+ name: 'abi',
433
+ message: 'ABI file (path)',
434
+ initial: initAbi,
435
+ skip: () => !protocolInstance.hasABIs() ||
436
+ initFromExample !== undefined ||
437
+ abiFromEtherscan !== undefined ||
438
+ isSubstreams ||
439
+ !!initAbiPath,
440
+ validate: async (value) => {
441
+ if (initFromExample || abiFromEtherscan || !protocolInstance.hasABIs()) {
442
+ return true;
443
+ }
444
+ const ABI = protocolInstance.getABI();
445
+ if (initAbiPath) {
446
+ try {
447
+ loadAbiFromFile(ABI, initAbiPath);
448
+ return true;
406
449
  }
407
- else {
408
- abiFromEtherscan = await (0, abi_1.loadAbiFromEtherscan)(ABI, network, value);
450
+ catch (e) {
451
+ this.error(e.message);
409
452
  }
410
453
  }
454
+ try {
455
+ loadAbiFromFile(ABI, value);
456
+ return true;
457
+ }
411
458
  catch (e) {
412
- // noop
459
+ this.error(e.message);
460
+ }
461
+ },
462
+ result: async (value) => {
463
+ if (initFromExample || abiFromEtherscan || !protocolInstance.hasABIs()) {
464
+ return null;
465
+ }
466
+ const ABI = protocolInstance.getABI();
467
+ if (initAbiPath) {
468
+ try {
469
+ return loadAbiFromFile(ABI, initAbiPath);
470
+ }
471
+ catch (e) {
472
+ return e.message;
473
+ }
413
474
  }
414
- }
415
- // If startBlock is not set, try to load it.
416
- if (!startBlock) {
417
475
  try {
418
- // Load startBlock for this contract
419
- startBlock = Number(await (0, abi_1.loadStartBlockForContract)(network, value)).toString();
476
+ return loadAbiFromFile(ABI, value);
420
477
  }
421
- catch (error) {
422
- // noop
478
+ catch (e) {
479
+ return e.message;
423
480
  }
424
- }
425
- return value;
426
- },
427
- },
428
- {
429
- type: 'input',
430
- name: 'abi',
431
- message: 'ABI file (path)',
432
- initial: abi,
433
- skip: () => !protocolInstance.hasABIs() || fromExample !== undefined || abiFromEtherscan !== undefined,
434
- validate: async (value) => {
435
- if (fromExample || abiFromEtherscan || !protocolInstance.hasABIs()) {
436
- return true;
437
- }
438
- try {
439
- abiFromFile = loadAbiFromFile(ABI, value);
440
- return true;
441
- }
442
- catch (e) {
443
- return e.message;
444
- }
481
+ },
445
482
  },
446
- },
447
- {
448
- type: 'input',
449
- name: 'startBlock',
450
- message: 'Start Block',
451
- initial: () => startBlock || '0',
452
- skip: () => fromExample !== undefined,
453
- validate: (value) => parseInt(value) >= 0,
454
- result: (value) => {
455
- startBlock = value;
456
- return value;
483
+ ]);
484
+ const { startBlock } = await gluegun_1.prompt.ask([
485
+ {
486
+ type: 'input',
487
+ name: 'startBlock',
488
+ message: 'Start Block',
489
+ initial: initStartBlock || '0',
490
+ skip: () => initFromExample !== undefined || isSubstreams,
491
+ validate: value => parseInt(value) >= 0,
492
+ result(value) {
493
+ if (initStartBlock)
494
+ return initStartBlock;
495
+ return value;
496
+ },
457
497
  },
458
- },
459
- {
460
- type: 'input',
461
- name: 'contractName',
462
- message: 'Contract Name',
463
- initial: contractName || 'Contract',
464
- skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
465
- validate: (value) => value && value.length > 0,
466
- result: (value) => {
467
- contractName = value;
468
- return value;
498
+ ]);
499
+ const { contractName } = await gluegun_1.prompt.ask([
500
+ {
501
+ type: 'input',
502
+ name: 'contractName',
503
+ message: 'Contract Name',
504
+ initial: initContractName || 'Contract' || isSubstreams,
505
+ skip: () => initFromExample !== undefined || !protocolInstance.hasContract(),
506
+ validate: value => value && value.length > 0,
469
507
  },
470
- },
471
- {
472
- type: 'confirm',
473
- name: 'indexEvents',
474
- message: 'Index contract events as entities',
475
- initial: true,
476
- skip: () => !!indexEvents,
477
- result: (value) => {
478
- indexEvents = value;
479
- return value;
508
+ ]);
509
+ const { indexEvents } = await gluegun_1.prompt.ask([
510
+ {
511
+ type: 'confirm',
512
+ name: 'indexEvents',
513
+ message: 'Index contract events as entities',
514
+ initial: true,
515
+ skip: () => !!initIndexEvents || isSubstreams,
480
516
  },
481
- },
482
- ];
483
- try {
484
- const answers = await gluegun_1.prompt.ask(questions);
517
+ ]);
485
518
  return {
486
- ...answers,
487
519
  abi: abiFromEtherscan || abiFromFile,
488
520
  protocolInstance,
521
+ subgraphName,
522
+ directory,
523
+ studio: product === 'subgraph-studio',
524
+ startBlock,
525
+ fromExample: !!initFromExample,
526
+ product,
527
+ network,
528
+ contractName,
529
+ contract,
530
+ indexEvents,
489
531
  };
490
532
  }
491
533
  catch (e) {
@@ -563,7 +605,8 @@ Subgraph ${subgraphName} created in ${relativeDir}
563
605
 
564
606
  Make sure to visit the documentation on https://thegraph.com/docs/ for further information.`);
565
607
  }
566
- async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphName, directory, studio, product, }, { commands, }) {
608
+ async function initSubgraphFromExample({ protocolInstance, fromExample, allowSimpleName, subgraphName, directory, studio, product, }, { commands, }) {
609
+ const isSubstreams = protocolInstance.name === 'substreams';
567
610
  // Fail if the subgraph name is invalid
568
611
  if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
569
612
  process.exitCode = 1;
@@ -656,15 +699,18 @@ async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphN
656
699
  this.exit(1);
657
700
  return;
658
701
  }
659
- // Run code-generation
660
- const codegen = await runCodegen(directory, commands.codegen);
661
- if (codegen !== true) {
662
- this.exit(1);
663
- return;
702
+ if (!isSubstreams) {
703
+ // Run code-generation
704
+ const codegen = await runCodegen(directory, commands.codegen);
705
+ if (codegen !== true) {
706
+ this.exit(1);
707
+ return;
708
+ }
664
709
  }
665
710
  printNextSteps.bind(this)({ subgraphName, directory }, { commands });
666
711
  }
667
712
  async function initSubgraphFromContract({ protocolInstance, allowSimpleName, subgraphName, directory, abi, network, contract, indexEvents, contractName, node, studio, product, startBlock, }, { commands, addContract, }) {
713
+ const isSubstreams = protocolInstance.name === 'substreams';
668
714
  // Fail if the subgraph name is invalid
669
715
  if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
670
716
  this.exit(1);
@@ -730,14 +776,17 @@ async function initSubgraphFromContract({ protocolInstance, allowSimpleName, sub
730
776
  this.exit(1);
731
777
  return;
732
778
  }
733
- // Run code-generation
734
- const codegen = await runCodegen(directory, commands.codegen);
735
- if (codegen !== true) {
736
- this.exit(1);
737
- return;
738
- }
739
- while (addContract) {
740
- addContract = await addAnotherContract.bind(this)({ protocolInstance, directory });
779
+ // Substreams we have nothing to install or generate
780
+ if (!isSubstreams) {
781
+ // Run code-generation
782
+ const codegen = await runCodegen(directory, commands.codegen);
783
+ if (codegen !== true) {
784
+ this.exit(1);
785
+ return;
786
+ }
787
+ while (addContract) {
788
+ addContract = await addAnotherContract.bind(this)({ protocolInstance, directory });
789
+ }
741
790
  }
742
791
  printNextSteps.bind(this)({ subgraphName, directory }, { commands });
743
792
  }
@@ -23,6 +23,7 @@ export default class Scaffold {
23
23
  startBlock?: string;
24
24
  constructor(options: ScaffoldOptions);
25
25
  generatePackageJson(): string;
26
+ generatePackageJsonForSubstreams(): string;
26
27
  generateManifest(): string;
27
28
  generateSchema(): string;
28
29
  generateTsConfig(): string;
@@ -37,6 +38,14 @@ export default class Scaffold {
37
38
  [x: string]: string;
38
39
  } | undefined;
39
40
  generate(): {
41
+ 'subgraph.yaml': string;
42
+ 'schema.graphql': string;
43
+ 'package.json': string;
44
+ 'tsconfig.json'?: undefined;
45
+ src?: undefined;
46
+ abis?: undefined;
47
+ tests?: undefined;
48
+ } | {
40
49
  'package.json': string;
41
50
  'subgraph.yaml': string;
42
51
  'schema.graphql': string;
@@ -51,6 +51,26 @@ class Scaffold {
51
51
  devDependencies: this.protocol.hasEvents() ? { 'matchstick-as': `0.5.0` } : undefined,
52
52
  }), { parser: 'json' });
53
53
  }
54
+ generatePackageJsonForSubstreams() {
55
+ return prettier_1.default.format(JSON.stringify({
56
+ name: (0, subgraph_1.getSubgraphBasename)(String(this.subgraphName)),
57
+ license: 'UNLICENSED',
58
+ scripts: {
59
+ build: 'graph build',
60
+ deploy: `graph deploy ` + `--node ${this.node} ` + this.subgraphName,
61
+ 'create-local': `graph create --node http://localhost:8020/ ${this.subgraphName}`,
62
+ 'remove-local': `graph remove --node http://localhost:8020/ ${this.subgraphName}`,
63
+ 'deploy-local': `graph deploy ` +
64
+ `--node http://localhost:8020/ ` +
65
+ `--ipfs http://localhost:5001 ` +
66
+ this.subgraphName,
67
+ test: 'graph test',
68
+ },
69
+ dependencies: {
70
+ '@graphprotocol/graph-cli': GRAPH_CLI_VERSION,
71
+ },
72
+ }), { parser: 'json' });
73
+ }
54
74
  generateManifest() {
55
75
  const protocolManifest = this.protocol.getManifestScaffold();
56
76
  return prettier_1.default.format(`
@@ -115,6 +135,13 @@ dataSources:
115
135
  : undefined;
116
136
  }
117
137
  generate() {
138
+ if (this.protocol.name === 'substreams') {
139
+ return {
140
+ 'subgraph.yaml': this.generateManifest(),
141
+ 'schema.graphql': this.generateSchema(),
142
+ 'package.json': this.generatePackageJsonForSubstreams(),
143
+ };
144
+ }
118
145
  return {
119
146
  'package.json': this.generatePackageJson(),
120
147
  'subgraph.yaml': this.generateManifest(),
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.49.0-alpha-20230505152117-ef48fdf",
2
+ "version": "0.49.0-alpha-20230505181403-af18bf2",
3
3
  "commands": {
4
4
  "add": {
5
5
  "id": "add",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.49.0-alpha-20230505152117-ef48fdf",
3
+ "version": "0.49.0-alpha-20230505181403-af18bf2",
4
4
  "description": "CLI for building for and deploying to The Graph",
5
5
  "license": "(Apache-2.0 OR MIT)",
6
6
  "engines": {
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4",
23
- "@oclif/core": "2.8.4",
23
+ "@oclif/core": "2.8.2",
24
24
  "@whatwg-node/fetch": "^0.8.4",
25
25
  "assemblyscript": "0.19.23",
26
26
  "binary-install-raw": "0.0.13",
@@ -31,7 +31,7 @@
31
31
  "dockerode": "2.5.8",
32
32
  "fs-extra": "9.1.0",
33
33
  "glob": "9.3.5",
34
- "gluegun": "https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep",
34
+ "gluegun": "5.1.2",
35
35
  "graphql": "15.5.0",
36
36
  "immutable": "4.2.1",
37
37
  "ipfs-http-client": "55.0.0",