@graphprotocol/graph-cli 0.73.0 → 0.74.0-alpha-20240608081136-69147a6

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,5 +1,27 @@
1
1
  # @graphprotocol/graph-cli
2
2
 
3
+ ## 0.74.0-alpha-20240608081136-69147a6
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1680](https://github.com/graphprotocol/graph-tooling/pull/1680)
8
+ [`69147a6`](https://github.com/graphprotocol/graph-tooling/commit/69147a64b35622d423936145fc0b2465a2afab17)
9
+ Thanks [@saihaj](https://github.com/saihaj)! - Breaking changes to the CLI to prepare for the
10
+ sunset of the hosted service.
11
+
12
+ - `graph auth`
13
+ - Removed `--product` flag
14
+ - Removed `--studio` flag
15
+ - Removed `node` argument
16
+ - `graph deploy`
17
+ - Removed `--product` flag
18
+ - Removed `--studio` flag
19
+ - Removed `--from-hosted-service` flag
20
+ - `graph init`
21
+ - Removed `--product` flag
22
+ - Removed `--studio` flag
23
+ - Removed `--allow-simple-name` flag
24
+
3
25
  ## 0.73.0
4
26
 
5
27
  ### Minor Changes
@@ -3,19 +3,8 @@ import { URL } from 'url';
3
3
  export declare const SUBGRAPH_STUDIO_URL = "https://api.studio.thegraph.com/deploy/";
4
4
  export declare const validateNodeUrl: (node: string) => URL;
5
5
  export declare const normalizeNodeUrl: (node: string) => string;
6
- export declare function chooseNodeUrl({ product, studio, node, allowSimpleName, }: {
7
- product: string | undefined;
8
- studio: boolean | undefined;
6
+ export declare function chooseNodeUrl({ node, }: {
9
7
  node?: string;
10
- allowSimpleName?: boolean;
11
8
  }): {
12
- node: string | undefined;
13
- allowSimpleName: boolean | undefined;
9
+ node: string;
14
10
  };
15
- export declare function getHostedServiceSubgraphId({ subgraphName, }: {
16
- subgraphName: string;
17
- }): Promise<{
18
- subgraph: string;
19
- synced: boolean;
20
- health: 'healthy' | 'unhealthy' | 'failed';
21
- }>;
@@ -1,74 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getHostedServiceSubgraphId = exports.chooseNodeUrl = exports.normalizeNodeUrl = exports.validateNodeUrl = exports.SUBGRAPH_STUDIO_URL = void 0;
3
+ exports.chooseNodeUrl = exports.normalizeNodeUrl = exports.validateNodeUrl = exports.SUBGRAPH_STUDIO_URL = void 0;
4
4
  const url_1 = require("url");
5
5
  const gluegun_1 = require("gluegun");
6
- const constants_1 = require("../constants");
7
6
  exports.SUBGRAPH_STUDIO_URL = 'https://api.studio.thegraph.com/deploy/';
8
- const HOSTED_SERVICE_URL = 'https://api.thegraph.com/deploy/';
9
- const HOSTED_SERVICE_INDEX_NODE_URL = 'https://api.thegraph.com/index-node/graphql';
10
7
  const validateNodeUrl = (node) => new url_1.URL(node);
11
8
  exports.validateNodeUrl = validateNodeUrl;
12
9
  const normalizeNodeUrl = (node) => new url_1.URL(node).toString();
13
10
  exports.normalizeNodeUrl = normalizeNodeUrl;
14
- function chooseNodeUrl({ product, studio, node, allowSimpleName, }) {
11
+ function chooseNodeUrl({ node, }) {
15
12
  if (node) {
16
13
  try {
17
14
  (0, exports.validateNodeUrl)(node);
15
+ return { node };
18
16
  }
19
17
  catch (e) {
20
18
  gluegun_1.print.error(`Graph node "${node}" is invalid: ${e.message}`);
21
19
  process.exit(1);
22
20
  }
23
21
  }
24
- else {
25
- if (studio) {
26
- product = 'subgraph-studio';
27
- }
28
- switch (product) {
29
- case 'subgraph-studio':
30
- node = exports.SUBGRAPH_STUDIO_URL;
31
- break;
32
- case 'hosted-service':
33
- node = HOSTED_SERVICE_URL;
34
- break;
35
- }
36
- }
37
- if (node?.match(/studio/) || product === 'subgraph-studio') {
38
- allowSimpleName = true;
39
- }
40
- return { node, allowSimpleName };
22
+ return { node: exports.SUBGRAPH_STUDIO_URL };
41
23
  }
42
24
  exports.chooseNodeUrl = chooseNodeUrl;
43
- async function getHostedServiceSubgraphId({ subgraphName, }) {
44
- const response = await fetch(HOSTED_SERVICE_INDEX_NODE_URL, {
45
- method: 'POST',
46
- body: JSON.stringify({
47
- query: /* GraphQL */ `
48
- query GraphCli_getSubgraphId($subgraphName: String!) {
49
- indexingStatusForCurrentVersion(subgraphName: $subgraphName) {
50
- subgraph
51
- synced
52
- health
53
- }
54
- }
55
- `,
56
- variables: {
57
- subgraphName,
58
- },
59
- }),
60
- headers: {
61
- 'content-type': 'application/json',
62
- ...constants_1.GRAPH_CLI_SHARED_HEADERS,
63
- },
64
- });
65
- const { data, errors } = await response.json();
66
- if (errors) {
67
- throw new Error(errors[0].message);
68
- }
69
- if (!data.indexingStatusForCurrentVersion) {
70
- throw new Error(`Subgraph "${subgraphName}" not found on the hosted service`);
71
- }
72
- return data.indexingStatusForCurrentVersion;
73
- }
74
- exports.getHostedServiceSubgraphId = getHostedServiceSubgraphId;
@@ -1,4 +1 @@
1
- export declare const validateSubgraphName: (name: string, { allowSimpleName }: {
2
- allowSimpleName?: boolean | undefined;
3
- }) => string | undefined;
4
1
  export declare const getSubgraphBasename: (name: string) => string;
@@ -1,20 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSubgraphBasename = exports.validateSubgraphName = void 0;
4
- const validateSubgraphName = (name, { allowSimpleName }) => {
5
- if (allowSimpleName) {
6
- return name;
7
- }
8
- if (name.split('/').length !== 2) {
9
- throw new Error(`Subgraph name "${name}" needs to have the format "<PREFIX>/${name}".
10
-
11
- When using the Hosted Service at https://thegraph.com, <PREFIX> is the
12
- name of your GitHub user or organization.
13
-
14
- You can bypass this check with --allow-simple-name.`);
15
- }
16
- };
17
- exports.validateSubgraphName = validateSubgraphName;
3
+ exports.getSubgraphBasename = void 0;
18
4
  const getSubgraphBasename = (name) => {
19
5
  const segments = name.split('/', 2);
20
6
  return segments[segments.length - 1];
@@ -2,13 +2,10 @@ import { Command } from '@oclif/core';
2
2
  export default class AuthCommand extends Command {
3
3
  static description: string;
4
4
  static args: {
5
- node: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
6
5
  'deploy-key': import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
7
6
  };
8
7
  static flags: {
9
8
  help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
10
- product: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- studio: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
9
  };
13
10
  run(): Promise<void>;
14
11
  }
@@ -6,23 +6,8 @@ const auth_1 = require("../command-helpers/auth");
6
6
  const node_1 = require("../command-helpers/node");
7
7
  class AuthCommand extends core_1.Command {
8
8
  async run() {
9
- const { args: { node: nodeOrDeployKey, 'deploy-key': deployKeyFlag }, flags: { product, studio }, } = await this.parse(AuthCommand);
10
- // if user specifies --product or --studio then deployKey is the first parameter
11
- let node;
12
- let deployKey = deployKeyFlag;
13
- if (product || studio) {
14
- ({ node } = (0, node_1.chooseNodeUrl)({ product, studio, node }));
15
- deployKey = nodeOrDeployKey;
16
- }
17
- else {
18
- node = nodeOrDeployKey;
19
- }
20
- // eslint-disable-next-line -- prettier has problems with ||=
21
- node =
22
- node ||
23
- (await core_1.ux.prompt('Which product to initialize?', {
24
- required: true,
25
- }));
9
+ let { args: { 'deploy-key': deployKey }, } = await this.parse(AuthCommand);
10
+ const { node } = (0, node_1.chooseNodeUrl)({});
26
11
  // eslint-disable-next-line -- prettier has problems with ||=
27
12
  deployKey =
28
13
  deployKey ||
@@ -44,26 +29,11 @@ class AuthCommand extends core_1.Command {
44
29
  }
45
30
  AuthCommand.description = 'Sets the deploy key to use when deploying to a Graph node.';
46
31
  AuthCommand.args = {
47
- node: core_1.Args.string(),
48
32
  'deploy-key': core_1.Args.string(),
49
33
  };
50
34
  AuthCommand.flags = {
51
35
  help: core_1.Flags.help({
52
36
  char: 'h',
53
37
  }),
54
- product: core_1.Flags.string({
55
- summary: 'Select a product for which to authenticate.',
56
- options: ['subgraph-studio', 'hosted-service'],
57
- deprecated: {
58
- message: 'In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/',
59
- },
60
- }),
61
- studio: core_1.Flags.boolean({
62
- summary: 'Shortcut for "--product subgraph-studio".',
63
- exclusive: ['product'],
64
- deprecated: {
65
- message: 'In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/',
66
- },
67
- }),
68
38
  };
69
39
  exports.default = AuthCommand;
@@ -7,8 +7,6 @@ export default class DeployCommand extends Command {
7
7
  };
8
8
  static flags: {
9
9
  help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
10
- product: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- studio: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
10
  node: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
13
11
  'deploy-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
14
12
  'access-token': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
@@ -22,7 +20,6 @@ export default class DeployCommand extends Command {
22
20
  watch: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
21
  network: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
24
22
  'network-file': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
25
- 'from-hosted-service': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
26
23
  };
27
24
  run(): Promise<void>;
28
25
  }
@@ -48,138 +48,15 @@ const headersFlag = core_1.Flags.custom({
48
48
  parse: val => JSON.parse(val),
49
49
  default: {},
50
50
  });
51
- const productOptions = ['subgraph-studio', 'hosted-service'];
52
51
  const deployDebugger = (0, debug_1.default)('graph-cli:deploy');
53
52
  class DeployCommand extends core_1.Command {
54
53
  async run() {
55
- const { args: { 'subgraph-name': subgraphNameArg, 'subgraph-manifest': manifest }, flags: { product: productFlag, studio, 'deploy-key': deployKeyFlag, 'access-token': accessToken, 'version-label': versionLabelFlag, ipfs, headers, node: nodeFlag, 'output-dir': outputDir, 'skip-migrations': skipMigrations, watch, 'debug-fork': debugFork, network, 'network-file': networkFile, 'ipfs-hash': ipfsHash, 'from-hosted-service': hostedServiceSubgraphName, }, } = await this.parse(DeployCommand);
56
- if (hostedServiceSubgraphName) {
57
- const { health, subgraph: subgraphIpfsHash } = await (0, node_1.getHostedServiceSubgraphId)({
58
- subgraphName: hostedServiceSubgraphName,
59
- });
60
- const safeToDeployFailedSubgraph = health === 'failed'
61
- ? await core_1.ux.confirm('This subgraph has failed indexing on hosted service. Do you wish to continue the deploy?')
62
- : true;
63
- if (!safeToDeployFailedSubgraph)
64
- return;
65
- const safeToDeployUnhealthySubgraph = health === 'unhealthy'
66
- ? await core_1.ux.confirm('This subgraph is not healthy on hosted service. Do you wish to continue the deploy?')
67
- : true;
68
- if (!safeToDeployUnhealthySubgraph)
69
- return;
70
- const { node } = (0, node_1.chooseNodeUrl)({ studio: true, product: undefined });
71
- // shouldn't happen, but we need to satisfy the compiler
72
- if (!node) {
73
- this.error('No node URL available');
74
- }
75
- const requestUrl = new url_1.URL(node);
76
- const client = (0, jsonrpc_1.createJsonRpcClient)(requestUrl);
77
- // Exit with an error code if the client couldn't be created
78
- if (!client) {
79
- this.error('Failed to create RPC client');
80
- }
81
- // Use the deploy key, if one is set
82
- let deployKey = deployKeyFlag;
83
- if (!deployKey && accessToken) {
84
- deployKey = accessToken; // backwards compatibility
85
- }
86
- deployKey = await (0, auth_1.identifyDeployKey)(node, deployKey);
87
- if (!deployKey) {
88
- this.error('No deploy key available');
89
- }
90
- // @ts-expect-error options property seems to exist
91
- client.options.headers = {
92
- ...constants_1.GRAPH_CLI_SHARED_HEADERS,
93
- Authorization: 'Bearer ' + deployKey,
94
- };
95
- const subgraphName = await core_1.ux.prompt('What is the name of the subgraph you want to deploy?', {
96
- required: true,
97
- });
98
- // Ask for label if not on hosted service
99
- const versionLabel = versionLabelFlag ||
100
- (await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
101
- required: true,
102
- }));
103
- const spinner = gluegun_1.print.spin(`Deploying to Graph node ${requestUrl}`);
104
- client.request('subgraph_deploy', {
105
- name: subgraphName,
106
- ipfs_hash: subgraphIpfsHash,
107
- version_label: versionLabel,
108
- debug_fork: debugFork,
109
- }, async (
110
- // @ts-expect-error TODO: why are the arguments not typed?
111
- requestError,
112
- // @ts-expect-error TODO: why are the arguments not typed?
113
- jsonRpcError,
114
- // @ts-expect-error TODO: why are the arguments not typed?
115
- res) => {
116
- deployDebugger('requestError: %O', requestError);
117
- deployDebugger('jsonRpcError: %O', jsonRpcError);
118
- if (jsonRpcError) {
119
- const message = jsonRpcError?.message || jsonRpcError?.code?.toString();
120
- deployDebugger('message: %O', message);
121
- let errorMessage = `Failed to deploy to Graph node ${requestUrl}: ${message}`;
122
- // Provide helpful advice when the subgraph has not been created yet
123
- if (message?.match(/subgraph name not found/)) {
124
- errorMessage += `
125
- Make sure to create the subgraph first by running the following command:
126
- $ graph create --node ${node} ${subgraphName}`;
127
- }
128
- if (message?.match(/auth failure/)) {
129
- errorMessage += '\nYou may need to authenticate first.';
130
- }
131
- spinner.fail(errorMessage);
132
- process.exit(1);
133
- }
134
- else if (requestError) {
135
- spinner.fail(`HTTP error deploying the subgraph ${requestError.code}`);
136
- process.exit(1);
137
- }
138
- else {
139
- spinner.stop();
140
- const base = requestUrl.protocol + '//' + requestUrl.hostname;
141
- let playground = res.playground;
142
- let queries = res.queries;
143
- // Add a base URL if graph-node did not return the full URL
144
- if (playground.charAt(0) === ':') {
145
- playground = base + playground;
146
- }
147
- if (queries.charAt(0) === ':') {
148
- queries = base + queries;
149
- }
150
- gluegun_1.print.success(`Deployed to ${playground}`);
151
- gluegun_1.print.info('\nSubgraph endpoints:');
152
- gluegun_1.print.info(`Queries (HTTP): ${queries}`);
153
- gluegun_1.print.info(``);
154
- process.exit(0);
155
- }
156
- });
157
- return;
158
- }
54
+ const { args: { 'subgraph-name': subgraphNameArg, 'subgraph-manifest': manifest }, flags: { 'deploy-key': deployKeyFlag, 'access-token': accessToken, 'version-label': versionLabelFlag, ipfs, headers, node: nodeFlag, 'output-dir': outputDir, 'skip-migrations': skipMigrations, watch, 'debug-fork': debugFork, network, 'network-file': networkFile, 'ipfs-hash': ipfsHash, }, } = await this.parse(DeployCommand);
159
55
  const subgraphName = subgraphNameArg ||
160
56
  (await core_1.ux.prompt('What is the subgraph name?', {
161
57
  required: true,
162
58
  }));
163
- // We are given a node URL, so we prioritize that over the product flag
164
- const product = nodeFlag
165
- ? productFlag
166
- : studio
167
- ? 'subgraph-studio'
168
- : productFlag ||
169
- (await gluegun_1.prompt
170
- .ask([
171
- {
172
- name: 'product',
173
- message: 'Which product to deploy for?',
174
- required: true,
175
- type: 'select',
176
- choices: productOptions,
177
- },
178
- ])
179
- .then(({ product }) => product));
180
59
  const { node } = (0, node_1.chooseNodeUrl)({
181
- product,
182
- studio,
183
60
  node: nodeFlag,
184
61
  });
185
62
  if (!node) {
@@ -187,7 +64,6 @@ class DeployCommand extends core_1.Command {
187
64
  this.error('No Graph node provided');
188
65
  }
189
66
  const isStudio = node.match(/studio/);
190
- const isHostedService = node.match(/thegraph.com/) && !isStudio;
191
67
  const requestUrl = new url_1.URL(node);
192
68
  const client = (0, jsonrpc_1.createJsonRpcClient)(requestUrl);
193
69
  // Exit with an error code if the client couldn't be created
@@ -210,11 +86,9 @@ class DeployCommand extends core_1.Command {
210
86
  }
211
87
  // Ask for label if not on hosted service
212
88
  let versionLabel = versionLabelFlag;
213
- if (!versionLabel && !isHostedService) {
214
- versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
215
- required: true,
216
- });
217
- }
89
+ versionLabel || (versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
90
+ required: true,
91
+ }));
218
92
  const deploySubgraph = async (ipfsHash) => {
219
93
  const spinner = gluegun_1.print.spin(`Deploying to Graph node ${requestUrl}`);
220
94
  client.request('subgraph_deploy', {
@@ -235,18 +109,6 @@ class DeployCommand extends core_1.Command {
235
109
  const message = jsonRpcError?.message || jsonRpcError?.code?.toString();
236
110
  deployDebugger('message: %O', message);
237
111
  let errorMessage = `Failed to deploy to Graph node ${requestUrl}: ${message}`;
238
- // Provide helpful advice when the subgraph has not been created yet
239
- if (message?.match(/subgraph name not found/)) {
240
- if (isHostedService) {
241
- errorMessage +=
242
- '\nYou may need to create it at https://thegraph.com/explorer/dashboard.';
243
- }
244
- else {
245
- errorMessage += `
246
- Make sure to create the subgraph first by running the following command:
247
- $ graph create --node ${node} ${subgraphName}`;
248
- }
249
- }
250
112
  if (message?.match(/auth failure/)) {
251
113
  errorMessage += '\nYou may need to authenticate first.';
252
114
  }
@@ -269,12 +131,7 @@ class DeployCommand extends core_1.Command {
269
131
  if (queries.charAt(0) === ':') {
270
132
  queries = base + queries;
271
133
  }
272
- if (isHostedService) {
273
- gluegun_1.print.success(`Deployed to https://thegraph.com/explorer/subgraph/${subgraphName}`);
274
- }
275
- else {
276
- gluegun_1.print.success(`Deployed to ${playground}`);
277
- }
134
+ gluegun_1.print.success(`Deployed to ${playground}`);
278
135
  gluegun_1.print.info('\nSubgraph endpoints:');
279
136
  gluegun_1.print.info(`Queries (HTTP): ${queries}`);
280
137
  gluegun_1.print.info(``);
@@ -368,14 +225,6 @@ DeployCommand.flags = {
368
225
  help: core_1.Flags.help({
369
226
  char: 'h',
370
227
  }),
371
- product: core_1.Flags.string({
372
- summary: 'Select a product for which to authenticate.',
373
- options: productOptions,
374
- }),
375
- studio: core_1.Flags.boolean({
376
- summary: 'Shortcut for "--product subgraph-studio".',
377
- exclusive: ['product'],
378
- }),
379
228
  node: core_1.Flags.string({
380
229
  summary: 'Graph node for which to initialize.',
381
230
  char: 'g',
@@ -423,13 +272,9 @@ DeployCommand.flags = {
423
272
  network: core_1.Flags.string({
424
273
  summary: 'Network configuration to use from the networks config file.',
425
274
  }),
426
- // TODO: should be networksFile (with an "s"), or?
427
275
  'network-file': core_1.Flags.file({
428
276
  summary: 'Networks config file path.',
429
277
  default: 'networks.json',
430
278
  }),
431
- 'from-hosted-service': core_1.Flags.string({
432
- summary: 'Hosted service Subgraph Name to deploy to studio.',
433
- }),
434
279
  };
435
280
  exports.default = DeployCommand;
@@ -8,10 +8,7 @@ export default class InitCommand extends Command {
8
8
  static flags: {
9
9
  help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
10
10
  protocol: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
- product: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
- studio: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
11
  node: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
14
- 'allow-simple-name': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
12
  'from-contract': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
16
13
  'from-example': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
17
14
  'contract-name': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
@@ -88,14 +88,10 @@ const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum-gravatar';
88
88
  class InitCommand extends core_1.Command {
89
89
  async run() {
90
90
  const { args: { subgraphName, directory }, flags, } = await this.parse(InitCommand);
91
- const { protocol, product, studio, node: nodeFlag, 'allow-simple-name': allowSimpleNameFlag, 'from-contract': fromContract, 'contract-name': contractName, 'from-example': fromExample, 'index-events': indexEvents, 'skip-install': skipInstall, 'skip-git': skipGit, network, abi: abiPath, 'start-block': startBlock, spkg: spkgPath, } = flags;
91
+ const { protocol, node: nodeFlag, 'from-contract': fromContract, 'contract-name': contractName, 'from-example': fromExample, 'index-events': indexEvents, 'skip-install': skipInstall, 'skip-git': skipGit, network, abi: abiPath, 'start-block': startBlock, spkg: spkgPath, } = flags;
92
92
  initDebugger('Flags: %O', flags);
93
- let { node, allowSimpleName } = (0, node_1.chooseNodeUrl)({
94
- product,
95
- // if we are loading example, we want to ensure we are using studio
96
- studio: studio || fromExample !== undefined,
93
+ let { node } = (0, node_1.chooseNodeUrl)({
97
94
  node: nodeFlag,
98
- allowSimpleName: allowSimpleNameFlag,
99
95
  });
100
96
  if (fromContract && fromExample) {
101
97
  this.error('Only one of "--from-example" and "--from-contract" can be used at a time.', {
@@ -128,7 +124,6 @@ class InitCommand extends core_1.Command {
128
124
  if (fromExample && subgraphName && directory) {
129
125
  await initSubgraphFromExample.bind(this)({
130
126
  fromExample,
131
- allowSimpleName,
132
127
  directory,
133
128
  subgraphName,
134
129
  skipInstall,
@@ -174,7 +169,6 @@ class InitCommand extends core_1.Command {
174
169
  await initSubgraphFromContract.bind(this)({
175
170
  protocolInstance,
176
171
  abi,
177
- allowSimpleName,
178
172
  directory,
179
173
  contract: fromContract,
180
174
  indexEvents,
@@ -192,7 +186,6 @@ class InitCommand extends core_1.Command {
192
186
  }
193
187
  if (fromExample) {
194
188
  const answers = await processFromExampleInitForm.bind(this)({
195
- allowSimpleName,
196
189
  subgraphName,
197
190
  directory,
198
191
  });
@@ -201,7 +194,6 @@ class InitCommand extends core_1.Command {
201
194
  return;
202
195
  }
203
196
  await initSubgraphFromExample.bind(this)({
204
- allowSimpleName,
205
197
  fromExample,
206
198
  subgraphName: answers.subgraphName,
207
199
  directory: answers.directory,
@@ -213,12 +205,8 @@ class InitCommand extends core_1.Command {
213
205
  // Otherwise, take the user through the interactive form
214
206
  const answers = await processInitForm.bind(this)({
215
207
  protocol: protocol,
216
- product,
217
- studio,
218
- node,
219
208
  abi,
220
209
  abiPath,
221
- allowSimpleName,
222
210
  directory,
223
211
  contract: fromContract,
224
212
  indexEvents,
@@ -233,15 +221,11 @@ class InitCommand extends core_1.Command {
233
221
  this.exit(1);
234
222
  return;
235
223
  }
236
- ({ node, allowSimpleName } = (0, node_1.chooseNodeUrl)({
237
- product: answers.product,
238
- studio: answers.studio,
224
+ ({ node, } = (0, node_1.chooseNodeUrl)({
239
225
  node,
240
- allowSimpleName,
241
226
  }));
242
227
  await initSubgraphFromContract.bind(this)({
243
228
  protocolInstance: answers.protocolInstance,
244
- allowSimpleName,
245
229
  subgraphName: answers.subgraphName,
246
230
  directory: answers.directory,
247
231
  abi: answers.abi,
@@ -272,31 +256,10 @@ InitCommand.flags = {
272
256
  protocol: core_1.Flags.string({
273
257
  options: protocolChoices,
274
258
  }),
275
- product: core_1.Flags.string({
276
- summary: 'Selects the product for which to initialize.',
277
- options: ['subgraph-studio', 'hosted-service'],
278
- deprecated: {
279
- message: 'In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/',
280
- },
281
- }),
282
- studio: core_1.Flags.boolean({
283
- summary: 'Shortcut for "--product subgraph-studio".',
284
- exclusive: ['product'],
285
- deprecated: {
286
- message: 'In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/',
287
- },
288
- }),
289
259
  node: core_1.Flags.string({
290
260
  summary: 'Graph node for which to initialize.',
291
261
  char: 'g',
292
262
  }),
293
- 'allow-simple-name': core_1.Flags.boolean({
294
- description: 'Use a subgraph name without a prefix.',
295
- default: false,
296
- deprecated: {
297
- message: 'In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/',
298
- },
299
- }),
300
263
  'from-contract': core_1.Flags.string({
301
264
  description: 'Creates a scaffold based on an existing contract.',
302
265
  exclusive: ['from-example'],
@@ -351,31 +314,14 @@ InitCommand.flags = {
351
314
  }),
352
315
  };
353
316
  exports.default = InitCommand;
354
- async function processFromExampleInitForm({ directory: initDirectory, subgraphName: initSubgraphName, allowSimpleName: initAllowSimpleName, }) {
317
+ async function processFromExampleInitForm({ directory: initDirectory, subgraphName: initSubgraphName, }) {
355
318
  try {
356
319
  const { subgraphName } = await gluegun_1.prompt.ask([
357
320
  {
358
321
  type: 'input',
359
322
  name: 'subgraphName',
360
- // TODO: is defaulting to studio ok?
361
323
  message: () => 'Subgraph slug',
362
324
  initial: initSubgraphName,
363
- validate: name => {
364
- try {
365
- (0, subgraph_1.validateSubgraphName)(name, {
366
- allowSimpleName: initAllowSimpleName,
367
- });
368
- return true;
369
- }
370
- catch (e) {
371
- return `${e.message}
372
-
373
- Examples:
374
-
375
- $ graph init ${os_1.default.userInfo().username}/${name}
376
- $ graph init ${name} --allow-simple-name`;
377
- }
378
- },
379
325
  },
380
326
  ]);
381
327
  const { directory } = await gluegun_1.prompt.ask([
@@ -417,7 +363,7 @@ async function retryWithPrompt(func) {
417
363
  }
418
364
  return undefined;
419
365
  }
420
- 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, spkgPath: initSpkgPath, }) {
366
+ async function processInitForm({ protocol: initProtocol, abi: initAbi, abiPath: initAbiPath, directory: initDirectory, contract: initContract, indexEvents: initIndexEvents, fromExample: initFromExample, network: initNetwork, subgraphName: initSubgraphName, contractName: initContractName, startBlock: initStartBlock, spkgPath: initSpkgPath, }) {
421
367
  let abiFromEtherscan = undefined;
422
368
  try {
423
369
  const { protocol } = await gluegun_1.prompt.ask({
@@ -438,57 +384,12 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
438
384
  const protocolInstance = new protocols_1.default(protocol);
439
385
  const isSubstreams = protocol === 'substreams';
440
386
  initDebugger.extend('processInitForm')('isSubstreams: %O', isSubstreams);
441
- const { product } = await gluegun_1.prompt.ask([
442
- {
443
- type: 'select',
444
- name: 'product',
445
- message: 'Product for which to initialize',
446
- choices: ['subgraph-studio', 'hosted-service'],
447
- skip: protocol === 'arweave' ||
448
- protocol === 'cosmos' ||
449
- protocol === 'near' ||
450
- initProduct === 'subgraph-studio' ||
451
- initProduct === 'hosted-service' ||
452
- initStudio !== undefined ||
453
- initNode !== undefined,
454
- result: value => {
455
- if (initProduct)
456
- return initProduct;
457
- if (initStudio)
458
- return 'subgraph-studio';
459
- // For now we only support NEAR subgraphs in the Hosted Service
460
- if (protocol === 'near') {
461
- return 'hosted-service';
462
- }
463
- if (value == 'subgraph-studio') {
464
- initAllowSimpleName = true;
465
- }
466
- return value;
467
- },
468
- },
469
- ]);
470
387
  const { subgraphName } = await gluegun_1.prompt.ask([
471
388
  {
472
389
  type: 'input',
473
390
  name: 'subgraphName',
474
- message: () => (product == 'subgraph-studio' ? 'Subgraph slug' : 'Subgraph name'),
391
+ message: 'Subgraph slug',
475
392
  initial: initSubgraphName,
476
- validate: name => {
477
- try {
478
- (0, subgraph_1.validateSubgraphName)(name, {
479
- allowSimpleName: initAllowSimpleName,
480
- });
481
- return true;
482
- }
483
- catch (e) {
484
- return `${e.message}
485
-
486
- Examples:
487
-
488
- $ graph init ${os_1.default.userInfo().username}/${name}
489
- $ graph init ${name} --allow-simple-name`;
490
- }
491
- },
492
393
  },
493
394
  ]);
494
395
  const { directory } = await gluegun_1.prompt.ask([
@@ -502,7 +403,7 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
502
403
  : true,
503
404
  },
504
405
  ]);
505
- let choices = (await AVAILABLE_NETWORKS())?.[product === 'subgraph-studio' ? 'studio' : 'hostedService'];
406
+ let choices = (await AVAILABLE_NETWORKS())?.['studio'];
506
407
  if (!choices) {
507
408
  this.error('Unable to fetch available networks from API. Please report this issue. As a workaround you can pass `--network` flag from the available networks: https://thegraph.com/docs/en/developing/supported-networks', { exit: 1 });
508
409
  }
@@ -690,10 +591,8 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
690
591
  protocolInstance,
691
592
  subgraphName,
692
593
  directory,
693
- studio: product === 'subgraph-studio',
694
594
  startBlock,
695
595
  fromExample: !!initFromExample,
696
- product,
697
596
  network,
698
597
  contractName,
699
598
  contract,
@@ -720,21 +619,6 @@ const loadAbiFromFile = (ABI, filename) => {
720
619
  return ABI.load('Contract', filename);
721
620
  }
722
621
  };
723
- function revalidateSubgraphName(subgraphName, { allowSimpleName }) {
724
- // Fail if the subgraph name is invalid
725
- try {
726
- (0, subgraph_1.validateSubgraphName)(subgraphName, { allowSimpleName });
727
- return true;
728
- }
729
- catch (e) {
730
- this.error(`${e.message}
731
-
732
- Examples:
733
-
734
- $ graph init ${os_1.default.userInfo().username}/${subgraphName}
735
- $ graph init ${subgraphName} --allow-simple-name`);
736
- }
737
- }
738
622
  // Inspired from: https://github.com/graphprotocol/graph-tooling/issues/1450#issuecomment-1713992618
739
623
  async function isInRepo() {
740
624
  try {
@@ -800,12 +684,7 @@ Subgraph ${subgraphName} created in ${relativeDir}
800
684
 
801
685
  Make sure to visit the documentation on https://thegraph.com/docs/ for further information.`);
802
686
  }
803
- async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphName, directory, skipInstall, skipGit, }, { commands, }) {
804
- // Fail if the subgraph name is invalid
805
- if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
806
- process.exitCode = 1;
807
- return;
808
- }
687
+ async function initSubgraphFromExample({ fromExample, subgraphName, directory, skipInstall, skipGit, }, { commands, }) {
809
688
  // Fail if the output directory already exists
810
689
  if (gluegun_1.filesystem.exists(directory)) {
811
690
  this.error(`Directory or file "${directory}" already exists`, { exit: 1 });
@@ -898,13 +777,8 @@ async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphN
898
777
  }
899
778
  printNextSteps.bind(this)({ subgraphName, directory }, { commands });
900
779
  }
901
- async function initSubgraphFromContract({ protocolInstance, allowSimpleName, subgraphName, directory, abi, network, contract, indexEvents, contractName, node, startBlock, spkgPath, skipInstall, skipGit, }, { commands, addContract, }) {
780
+ async function initSubgraphFromContract({ protocolInstance, subgraphName, directory, abi, network, contract, indexEvents, contractName, node, startBlock, spkgPath, skipInstall, skipGit, }, { commands, addContract, }) {
902
781
  const isSubstreams = protocolInstance.name === 'substreams';
903
- // Fail if the subgraph name is invalid
904
- if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
905
- this.exit(1);
906
- return;
907
- }
908
782
  // Fail if the output directory already exists
909
783
  if (gluegun_1.filesystem.exists(directory)) {
910
784
  this.error(`Directory or file "${directory}" already exists`, { exit: 1 });
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.73.0",
2
+ "version": "0.74.0-alpha-20240608081136-69147a6",
3
3
  "commands": {
4
4
  "add": {
5
5
  "id": "add",
@@ -77,37 +77,9 @@
77
77
  "char": "h",
78
78
  "description": "Show CLI help.",
79
79
  "allowNo": false
80
- },
81
- "product": {
82
- "name": "product",
83
- "type": "option",
84
- "summary": "Select a product for which to authenticate.",
85
- "multiple": false,
86
- "options": [
87
- "subgraph-studio",
88
- "hosted-service"
89
- ],
90
- "deprecated": {
91
- "message": "In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/"
92
- }
93
- },
94
- "studio": {
95
- "name": "studio",
96
- "type": "boolean",
97
- "summary": "Shortcut for \"--product subgraph-studio\".",
98
- "allowNo": false,
99
- "exclusive": [
100
- "product"
101
- ],
102
- "deprecated": {
103
- "message": "In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/"
104
- }
105
80
  }
106
81
  },
107
82
  "args": {
108
- "node": {
109
- "name": "node"
110
- },
111
83
  "deploy-key": {
112
84
  "name": "deploy-key"
113
85
  }
@@ -345,25 +317,6 @@
345
317
  "description": "Show CLI help.",
346
318
  "allowNo": false
347
319
  },
348
- "product": {
349
- "name": "product",
350
- "type": "option",
351
- "summary": "Select a product for which to authenticate.",
352
- "multiple": false,
353
- "options": [
354
- "subgraph-studio",
355
- "hosted-service"
356
- ]
357
- },
358
- "studio": {
359
- "name": "studio",
360
- "type": "boolean",
361
- "summary": "Shortcut for \"--product subgraph-studio\".",
362
- "allowNo": false,
363
- "exclusive": [
364
- "product"
365
- ]
366
- },
367
320
  "node": {
368
321
  "name": "node",
369
322
  "type": "option",
@@ -463,12 +416,6 @@
463
416
  "summary": "Networks config file path.",
464
417
  "multiple": false,
465
418
  "default": "networks.json"
466
- },
467
- "from-hosted-service": {
468
- "name": "from-hosted-service",
469
- "type": "option",
470
- "summary": "Hosted service Subgraph Name to deploy to studio.",
471
- "multiple": false
472
419
  }
473
420
  },
474
421
  "args": {
@@ -509,31 +456,6 @@
509
456
  "substreams"
510
457
  ]
511
458
  },
512
- "product": {
513
- "name": "product",
514
- "type": "option",
515
- "summary": "Selects the product for which to initialize.",
516
- "multiple": false,
517
- "options": [
518
- "subgraph-studio",
519
- "hosted-service"
520
- ],
521
- "deprecated": {
522
- "message": "In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/"
523
- }
524
- },
525
- "studio": {
526
- "name": "studio",
527
- "type": "boolean",
528
- "summary": "Shortcut for \"--product subgraph-studio\".",
529
- "allowNo": false,
530
- "exclusive": [
531
- "product"
532
- ],
533
- "deprecated": {
534
- "message": "In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/"
535
- }
536
- },
537
459
  "node": {
538
460
  "name": "node",
539
461
  "type": "option",
@@ -541,15 +463,6 @@
541
463
  "summary": "Graph node for which to initialize.",
542
464
  "multiple": false
543
465
  },
544
- "allow-simple-name": {
545
- "name": "allow-simple-name",
546
- "type": "boolean",
547
- "description": "Use a subgraph name without a prefix.",
548
- "allowNo": false,
549
- "deprecated": {
550
- "message": "In next major version, this flag will be removed. By default we will deploy to the Graph Studio. Learn more about Sunrise of Decentralized Data https://thegraph.com/blog/unveiling-updated-sunrise-decentralized-data/"
551
- }
552
- },
553
466
  "from-contract": {
554
467
  "name": "from-contract",
555
468
  "type": "option",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.73.0",
3
+ "version": "0.74.0-alpha-20240608081136-69147a6",
4
4
  "description": "CLI for building for and deploying to The Graph",
5
5
  "license": "(Apache-2.0 OR MIT)",
6
6
  "engines": {