@graphprotocol/graph-cli 0.87.0 → 0.88.0-alpha-20241025141646-fd1fcd9

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.88.0-alpha-20241025141646-fd1fcd9
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.87.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 ||
@@ -33,9 +18,6 @@ class AuthCommand extends core_1.Command {
33
18
  if (deployKey.length > 200) {
34
19
  this.error('✖ Deploy key must not exceed 200 characters', { exit: 1 });
35
20
  }
36
- if (product === 'hosted-service' || node?.match(/api.thegraph.com/)) {
37
- this.error('✖ The hosted service is deprecated', { exit: 1 });
38
- }
39
21
  try {
40
22
  await (0, auth_1.saveDeployKey)(node, deployKey);
41
23
  gluegun_1.print.success(`Deploy key set for ${node}`);
@@ -47,26 +29,11 @@ class AuthCommand extends core_1.Command {
47
29
  }
48
30
  AuthCommand.description = 'Sets the deploy key to use when deploying to a Graph node.';
49
31
  AuthCommand.args = {
50
- node: core_1.Args.string(),
51
32
  'deploy-key': core_1.Args.string(),
52
33
  };
53
34
  AuthCommand.flags = {
54
35
  help: core_1.Flags.help({
55
36
  char: 'h',
56
37
  }),
57
- product: core_1.Flags.string({
58
- summary: 'Select a product for which to authenticate.',
59
- options: ['subgraph-studio', 'hosted-service'],
60
- deprecated: {
61
- 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/',
62
- },
63
- }),
64
- studio: core_1.Flags.boolean({
65
- summary: 'Shortcut for "--product subgraph-studio".',
66
- exclusive: ['product'],
67
- deprecated: {
68
- 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/',
69
- },
70
- }),
71
38
  };
72
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,149 +48,21 @@ 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
- if (product === 'hosted-service') {
181
- this.error('✖ The hosted service is deprecated', { exit: 1 });
182
- }
183
59
  const { node } = (0, node_1.chooseNodeUrl)({
184
- product,
185
- studio,
186
60
  node: nodeFlag,
187
61
  });
188
62
  if (!node) {
189
63
  // shouldn't happen, but we do the check to satisfy TS
190
64
  this.error('No Graph node provided');
191
65
  }
192
- const isStudio = node.match(/studio/);
193
- const isHostedService = node.match(/thegraph.com/) && !isStudio;
194
66
  const requestUrl = new url_1.URL(node);
195
67
  const client = (0, jsonrpc_1.createJsonRpcClient)(requestUrl);
196
68
  // Exit with an error code if the client couldn't be created
@@ -213,11 +85,9 @@ class DeployCommand extends core_1.Command {
213
85
  }
214
86
  // Ask for label if not on hosted service
215
87
  let versionLabel = versionLabelFlag;
216
- if (!versionLabel && !isHostedService) {
217
- versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
218
- required: true,
219
- });
220
- }
88
+ versionLabel || (versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
89
+ required: true,
90
+ }));
221
91
  const deploySubgraph = async (ipfsHash) => {
222
92
  const spinner = gluegun_1.print.spin(`Deploying to Graph node ${requestUrl}`);
223
93
  client.request('subgraph_deploy', {
@@ -238,18 +108,6 @@ class DeployCommand extends core_1.Command {
238
108
  const message = jsonRpcError?.message || jsonRpcError?.code?.toString();
239
109
  deployDebugger('message: %O', message);
240
110
  let errorMessage = `Failed to deploy to Graph node ${requestUrl}: ${message}`;
241
- // Provide helpful advice when the subgraph has not been created yet
242
- if (message?.match(/subgraph name not found/)) {
243
- if (isHostedService) {
244
- errorMessage +=
245
- '\nYou may need to create it at https://thegraph.com/explorer/dashboard.';
246
- }
247
- else {
248
- errorMessage += `
249
- Make sure to create the subgraph first by running the following command:
250
- $ graph create --node ${node} ${subgraphName}`;
251
- }
252
- }
253
111
  if (message?.match(/auth failure/)) {
254
112
  errorMessage += '\nYou may need to authenticate first.';
255
113
  }
@@ -272,12 +130,7 @@ class DeployCommand extends core_1.Command {
272
130
  if (queries.charAt(0) === ':') {
273
131
  queries = base + queries;
274
132
  }
275
- if (isHostedService) {
276
- gluegun_1.print.success(`Deployed to https://thegraph.com/explorer/subgraph/${subgraphName}`);
277
- }
278
- else {
279
- gluegun_1.print.success(`Deployed to ${playground}`);
280
- }
133
+ gluegun_1.print.success(`Deployed to ${playground}`);
281
134
  gluegun_1.print.info('\nSubgraph endpoints:');
282
135
  gluegun_1.print.info(`Queries (HTTP): ${queries}`);
283
136
  gluegun_1.print.info(``);
@@ -371,14 +224,6 @@ DeployCommand.flags = {
371
224
  help: core_1.Flags.help({
372
225
  char: 'h',
373
226
  }),
374
- product: core_1.Flags.string({
375
- summary: 'Select a product for which to authenticate.',
376
- options: productOptions,
377
- }),
378
- studio: core_1.Flags.boolean({
379
- summary: 'Shortcut for "--product subgraph-studio".',
380
- exclusive: ['product'],
381
- }),
382
227
  node: core_1.Flags.string({
383
228
  summary: 'Graph node for which to initialize.',
384
229
  char: 'g',
@@ -426,13 +271,9 @@ DeployCommand.flags = {
426
271
  network: core_1.Flags.string({
427
272
  summary: 'Network configuration to use from the networks config file.',
428
273
  }),
429
- // TODO: should be networksFile (with an "s"), or?
430
274
  'network-file': core_1.Flags.file({
431
275
  summary: 'Networks config file path.',
432
276
  default: 'networks.json',
433
277
  }),
434
- 'from-hosted-service': core_1.Flags.string({
435
- summary: 'Hosted service Subgraph Name to deploy to studio.',
436
- }),
437
278
  };
438
279
  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,17 +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
- if (product === 'hosted-service') {
94
- this.error('✖ The hosted service is deprecated', { exit: 1 });
95
- }
96
- let { node, allowSimpleName } = (0, node_1.chooseNodeUrl)({
97
- product,
98
- // if we are loading example, we want to ensure we are using studio
99
- studio: studio || fromExample !== undefined,
93
+ let { node } = (0, node_1.chooseNodeUrl)({
100
94
  node: nodeFlag,
101
- allowSimpleName: allowSimpleNameFlag,
102
95
  });
103
96
  if (fromContract && fromExample) {
104
97
  this.error('Only one of "--from-example" and "--from-contract" can be used at a time.', {
@@ -131,7 +124,6 @@ class InitCommand extends core_1.Command {
131
124
  if (fromExample && subgraphName && directory) {
132
125
  await initSubgraphFromExample.bind(this)({
133
126
  fromExample,
134
- allowSimpleName,
135
127
  directory,
136
128
  subgraphName,
137
129
  skipInstall,
@@ -177,7 +169,6 @@ class InitCommand extends core_1.Command {
177
169
  await initSubgraphFromContract.bind(this)({
178
170
  protocolInstance,
179
171
  abi,
180
- allowSimpleName,
181
172
  directory,
182
173
  contract: fromContract,
183
174
  indexEvents,
@@ -195,7 +186,6 @@ class InitCommand extends core_1.Command {
195
186
  }
196
187
  if (fromExample) {
197
188
  const answers = await processFromExampleInitForm.bind(this)({
198
- allowSimpleName,
199
189
  subgraphName,
200
190
  directory,
201
191
  });
@@ -204,7 +194,6 @@ class InitCommand extends core_1.Command {
204
194
  return;
205
195
  }
206
196
  await initSubgraphFromExample.bind(this)({
207
- allowSimpleName,
208
197
  fromExample,
209
198
  subgraphName: answers.subgraphName,
210
199
  directory: answers.directory,
@@ -216,12 +205,8 @@ class InitCommand extends core_1.Command {
216
205
  // Otherwise, take the user through the interactive form
217
206
  const answers = await processInitForm.bind(this)({
218
207
  protocol: protocol,
219
- product,
220
- studio,
221
- node,
222
208
  abi,
223
209
  abiPath,
224
- allowSimpleName,
225
210
  directory,
226
211
  contract: fromContract,
227
212
  indexEvents,
@@ -236,15 +221,11 @@ class InitCommand extends core_1.Command {
236
221
  this.exit(1);
237
222
  return;
238
223
  }
239
- ({ node, allowSimpleName } = (0, node_1.chooseNodeUrl)({
240
- product: answers.product,
241
- studio: answers.studio,
224
+ ({ node } = (0, node_1.chooseNodeUrl)({
242
225
  node,
243
- allowSimpleName,
244
226
  }));
245
227
  await initSubgraphFromContract.bind(this)({
246
228
  protocolInstance: answers.protocolInstance,
247
- allowSimpleName,
248
229
  subgraphName: answers.subgraphName,
249
230
  directory: answers.directory,
250
231
  abi: answers.abi,
@@ -275,31 +256,10 @@ InitCommand.flags = {
275
256
  protocol: core_1.Flags.string({
276
257
  options: protocolChoices,
277
258
  }),
278
- product: core_1.Flags.string({
279
- summary: 'Selects the product for which to initialize.',
280
- options: ['subgraph-studio', 'hosted-service'],
281
- deprecated: {
282
- 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/',
283
- },
284
- }),
285
- studio: core_1.Flags.boolean({
286
- summary: 'Shortcut for "--product subgraph-studio".',
287
- exclusive: ['product'],
288
- deprecated: {
289
- 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/',
290
- },
291
- }),
292
259
  node: core_1.Flags.string({
293
260
  summary: 'Graph node for which to initialize.',
294
261
  char: 'g',
295
262
  }),
296
- 'allow-simple-name': core_1.Flags.boolean({
297
- description: 'Use a subgraph name without a prefix.',
298
- default: false,
299
- deprecated: {
300
- 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/',
301
- },
302
- }),
303
263
  'from-contract': core_1.Flags.string({
304
264
  description: 'Creates a scaffold based on an existing contract.',
305
265
  exclusive: ['from-example'],
@@ -354,31 +314,14 @@ InitCommand.flags = {
354
314
  }),
355
315
  };
356
316
  exports.default = InitCommand;
357
- async function processFromExampleInitForm({ directory: initDirectory, subgraphName: initSubgraphName, allowSimpleName: initAllowSimpleName, }) {
317
+ async function processFromExampleInitForm({ directory: initDirectory, subgraphName: initSubgraphName, }) {
358
318
  try {
359
319
  const { subgraphName } = await gluegun_1.prompt.ask([
360
320
  {
361
321
  type: 'input',
362
322
  name: 'subgraphName',
363
- // TODO: is defaulting to studio ok?
364
323
  message: () => 'Subgraph slug',
365
324
  initial: initSubgraphName,
366
- validate: name => {
367
- try {
368
- (0, subgraph_1.validateSubgraphName)(name, {
369
- allowSimpleName: initAllowSimpleName,
370
- });
371
- return true;
372
- }
373
- catch (e) {
374
- return `${e.message}
375
-
376
- Examples:
377
-
378
- $ graph init ${os_1.default.userInfo().username}/${name}
379
- $ graph init ${name} --allow-simple-name`;
380
- }
381
- },
382
325
  },
383
326
  ]);
384
327
  const { directory } = await gluegun_1.prompt.ask([
@@ -420,7 +363,7 @@ async function retryWithPrompt(func) {
420
363
  }
421
364
  return undefined;
422
365
  }
423
- 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, }) {
424
367
  let abiFromEtherscan = undefined;
425
368
  try {
426
369
  const { protocol } = await gluegun_1.prompt.ask({
@@ -441,60 +384,12 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
441
384
  const protocolInstance = new protocols_1.default(protocol);
442
385
  const isSubstreams = protocol === 'substreams';
443
386
  initDebugger.extend('processInitForm')('isSubstreams: %O', isSubstreams);
444
- const { product } = await gluegun_1.prompt.ask([
445
- {
446
- type: 'select',
447
- name: 'product',
448
- message: 'Product for which to initialize',
449
- choices: ['subgraph-studio', 'hosted-service'],
450
- skip: protocol === 'arweave' ||
451
- protocol === 'cosmos' ||
452
- protocol === 'near' ||
453
- initProduct === 'subgraph-studio' ||
454
- initProduct === 'hosted-service' ||
455
- initStudio !== undefined ||
456
- initNode !== undefined,
457
- result: value => {
458
- if (initProduct)
459
- return initProduct;
460
- if (initStudio)
461
- return 'subgraph-studio';
462
- // For now we only support NEAR subgraphs in the Hosted Service
463
- if (protocol === 'near') {
464
- return 'hosted-service';
465
- }
466
- if (value == 'subgraph-studio') {
467
- initAllowSimpleName = true;
468
- }
469
- return value;
470
- },
471
- },
472
- ]);
473
- if (product == 'hosted-service') {
474
- this.error('✖ The hosted service is deprecated', { exit: 1 });
475
- }
476
387
  const { subgraphName } = await gluegun_1.prompt.ask([
477
388
  {
478
389
  type: 'input',
479
390
  name: 'subgraphName',
480
- message: () => (product == 'subgraph-studio' ? 'Subgraph slug' : 'Subgraph name'),
391
+ message: 'Subgraph slug',
481
392
  initial: initSubgraphName,
482
- validate: name => {
483
- try {
484
- (0, subgraph_1.validateSubgraphName)(name, {
485
- allowSimpleName: initAllowSimpleName,
486
- });
487
- return true;
488
- }
489
- catch (e) {
490
- return `${e.message}
491
-
492
- Examples:
493
-
494
- $ graph init ${os_1.default.userInfo().username}/${name}
495
- $ graph init ${name} --allow-simple-name`;
496
- }
497
- },
498
393
  },
499
394
  ]);
500
395
  const { directory } = await gluegun_1.prompt.ask([
@@ -508,7 +403,7 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
508
403
  : true,
509
404
  },
510
405
  ]);
511
- let choices = (await AVAILABLE_NETWORKS())?.[product === 'subgraph-studio' ? 'studio' : 'hostedService'];
406
+ let choices = (await AVAILABLE_NETWORKS())?.['studio'];
512
407
  if (!choices) {
513
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 });
514
409
  }
@@ -696,10 +591,8 @@ async function processInitForm({ protocol: initProtocol, product: initProduct, s
696
591
  protocolInstance,
697
592
  subgraphName,
698
593
  directory,
699
- studio: product === 'subgraph-studio',
700
594
  startBlock,
701
595
  fromExample: !!initFromExample,
702
- product,
703
596
  network,
704
597
  contractName,
705
598
  contract,
@@ -726,21 +619,6 @@ const loadAbiFromFile = (ABI, filename) => {
726
619
  return ABI.load('Contract', filename);
727
620
  }
728
621
  };
729
- function revalidateSubgraphName(subgraphName, { allowSimpleName }) {
730
- // Fail if the subgraph name is invalid
731
- try {
732
- (0, subgraph_1.validateSubgraphName)(subgraphName, { allowSimpleName });
733
- return true;
734
- }
735
- catch (e) {
736
- this.error(`${e.message}
737
-
738
- Examples:
739
-
740
- $ graph init ${os_1.default.userInfo().username}/${subgraphName}
741
- $ graph init ${subgraphName} --allow-simple-name`);
742
- }
743
- }
744
622
  // Inspired from: https://github.com/graphprotocol/graph-tooling/issues/1450#issuecomment-1713992618
745
623
  async function isInRepo() {
746
624
  try {
@@ -806,12 +684,7 @@ Subgraph ${subgraphName} created in ${relativeDir}
806
684
 
807
685
  Make sure to visit the documentation on https://thegraph.com/docs/ for further information.`);
808
686
  }
809
- async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphName, directory, skipInstall, skipGit, }, { commands, }) {
810
- // Fail if the subgraph name is invalid
811
- if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
812
- process.exitCode = 1;
813
- return;
814
- }
687
+ async function initSubgraphFromExample({ fromExample, subgraphName, directory, skipInstall, skipGit, }, { commands, }) {
815
688
  // Fail if the output directory already exists
816
689
  if (gluegun_1.filesystem.exists(directory)) {
817
690
  this.error(`Directory or file "${directory}" already exists`, { exit: 1 });
@@ -904,13 +777,8 @@ async function initSubgraphFromExample({ fromExample, allowSimpleName, subgraphN
904
777
  }
905
778
  printNextSteps.bind(this)({ subgraphName, directory }, { commands });
906
779
  }
907
- 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, }) {
908
781
  const isSubstreams = protocolInstance.name === 'substreams';
909
- // Fail if the subgraph name is invalid
910
- if (!revalidateSubgraphName.bind(this)(subgraphName, { allowSimpleName })) {
911
- this.exit(1);
912
- return;
913
- }
914
782
  // Fail if the output directory already exists
915
783
  if (gluegun_1.filesystem.exists(directory)) {
916
784
  this.error(`Directory or file "${directory}" already exists`, { exit: 1 });
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.87.0",
2
+ "version": "0.88.0-alpha-20241025141646-fd1fcd9",
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.87.0",
3
+ "version": "0.88.0-alpha-20241025141646-fd1fcd9",
4
4
  "description": "CLI for building for and deploying to The Graph",
5
5
  "license": "(Apache-2.0 OR MIT)",
6
6
  "engines": {