@graphprotocol/graph-cli 0.40.0 → 0.40.1-alpha-20230216174117-760a195
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 +10 -0
- package/dist/bin.js +31 -3
- package/dist/command-helpers/network.js +16 -13
- package/dist/command-helpers/network.test.js +2 -2
- package/dist/command-helpers/spinner.js +4 -27
- package/dist/commands/add.js +48 -67
- package/dist/commands/auth.js +40 -102
- package/dist/commands/build.js +51 -68
- package/dist/commands/codegen.js +39 -61
- package/dist/commands/create.js +31 -55
- package/dist/commands/deploy.js +112 -174
- package/dist/commands/init.js +519 -512
- package/dist/commands/local.js +93 -103
- package/dist/commands/remove.js +32 -56
- package/dist/commands/test.js +81 -88
- package/dist/index.js +5 -0
- package/oclif.manifest.json +724 -0
- package/package.json +10 -3
- package/dist/cli.js +0 -26
- package/dist/command-helpers/gluegun.js +0 -48
package/dist/commands/deploy.js
CHANGED
|
@@ -28,11 +28,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const path_1 = __importDefault(require("path"));
|
|
30
30
|
const url_1 = require("url");
|
|
31
|
-
const
|
|
31
|
+
const core_1 = require("@oclif/core");
|
|
32
32
|
const auth_1 = require("../command-helpers/auth");
|
|
33
33
|
const compiler_1 = require("../command-helpers/compiler");
|
|
34
34
|
const DataSourcesExtractor = __importStar(require("../command-helpers/data-sources"));
|
|
35
|
-
const gluegun_1 = require("../command-helpers/gluegun");
|
|
36
35
|
const ipfs_1 = require("../command-helpers/ipfs");
|
|
37
36
|
const jsonrpc_1 = require("../command-helpers/jsonrpc");
|
|
38
37
|
const network_1 = require("../command-helpers/network");
|
|
@@ -40,100 +39,15 @@ const node_1 = require("../command-helpers/node");
|
|
|
40
39
|
const studio_1 = require("../command-helpers/studio");
|
|
41
40
|
const version_1 = require("../command-helpers/version");
|
|
42
41
|
const protocols_1 = __importDefault(require("../protocols"));
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
--deploy-key <key> User deploy key
|
|
53
|
-
-l --version-label <label> Version label used for the deployment
|
|
54
|
-
-h, --help Show usage information
|
|
55
|
-
-i, --ipfs <node> Upload build results to an IPFS node (default: ${ipfs_1.DEFAULT_IPFS_URL})
|
|
56
|
-
-hdr, --headers <map> Add custom headers that will be used by the IPFS HTTP client (default: {})
|
|
57
|
-
--debug-fork ID of a remote subgraph whose store will be GraphQL queried
|
|
58
|
-
-o, --output-dir <path> Output directory for build results (default: build/)
|
|
59
|
-
--skip-migrations Skip subgraph migrations (default: false)
|
|
60
|
-
-w, --watch Regenerate types when subgraph files change (default: false)
|
|
61
|
-
--network <name> Network configuration to use from the networks config file
|
|
62
|
-
--network-file <path> Networks config file path (default: "./networks.json")
|
|
63
|
-
`;
|
|
64
|
-
const processForm = async (toolbox, { product, studio, node, versionLabel }) => {
|
|
65
|
-
const questions = [
|
|
66
|
-
{
|
|
67
|
-
type: 'select',
|
|
68
|
-
name: 'product',
|
|
69
|
-
message: 'Product for which to deploy',
|
|
70
|
-
choices: ['subgraph-studio', 'hosted-service'],
|
|
71
|
-
skip: product === 'subgraph-studio' ||
|
|
72
|
-
product === 'hosted-service' ||
|
|
73
|
-
studio !== undefined ||
|
|
74
|
-
node !== undefined,
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
type: 'input',
|
|
78
|
-
name: 'versionLabel',
|
|
79
|
-
message: 'Version Label (e.g. v0.0.1)',
|
|
80
|
-
skip: versionLabel !== undefined,
|
|
81
|
-
},
|
|
82
|
-
];
|
|
83
|
-
try {
|
|
84
|
-
const answers = await toolbox.prompt.ask(questions);
|
|
85
|
-
return answers;
|
|
86
|
-
}
|
|
87
|
-
catch (e) {
|
|
88
|
-
return undefined;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
exports.default = {
|
|
92
|
-
description: 'Deploys the subgraph to a Graph node',
|
|
93
|
-
run: async (toolbox) => {
|
|
94
|
-
// Obtain tools
|
|
95
|
-
const { filesystem, print } = toolbox;
|
|
96
|
-
// Parse CLI parameters
|
|
97
|
-
let { product, studio, deployKey, accessToken, versionLabel, l, g, h, i, help, ipfs, headers, hdr, node, o, outputDir, skipMigrations, w, watch, debugFork, network, networkFile, } = toolbox.parameters.options;
|
|
98
|
-
// Support both long and short option variants
|
|
99
|
-
help || (help = h);
|
|
100
|
-
ipfs = ipfs || i || ipfs_1.DEFAULT_IPFS_URL;
|
|
101
|
-
headers = headers || hdr || '{}';
|
|
102
|
-
node || (node = g);
|
|
103
|
-
outputDir || (outputDir = o);
|
|
104
|
-
watch || (watch = w);
|
|
105
|
-
versionLabel || (versionLabel = l);
|
|
106
|
-
try {
|
|
107
|
-
headers = JSON.parse(headers);
|
|
108
|
-
}
|
|
109
|
-
catch (e) {
|
|
110
|
-
print.error('Please make sure headers is a valid JSON value');
|
|
111
|
-
process.exitCode = 1;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
let subgraphName, manifest;
|
|
115
|
-
try {
|
|
116
|
-
[subgraphName, manifest] = (0, gluegun_1.fixParameters)(toolbox.parameters, {
|
|
117
|
-
h,
|
|
118
|
-
help,
|
|
119
|
-
w,
|
|
120
|
-
watch,
|
|
121
|
-
studio,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
catch (e) {
|
|
125
|
-
print.error(e.message);
|
|
126
|
-
process.exitCode = 1;
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
// Fall back to default values for options / parameters
|
|
130
|
-
outputDir = outputDir && outputDir !== '' ? outputDir : filesystem.path('build');
|
|
131
|
-
manifest =
|
|
132
|
-
manifest !== undefined && manifest !== '' ? manifest : filesystem.resolve('subgraph.yaml');
|
|
133
|
-
networkFile =
|
|
134
|
-
networkFile !== undefined && networkFile !== ''
|
|
135
|
-
? networkFile
|
|
136
|
-
: filesystem.resolve('networks.json');
|
|
42
|
+
const headersFlag = core_1.Flags.custom({
|
|
43
|
+
summary: 'Add custom headers that will be used by the IPFS HTTP client.',
|
|
44
|
+
aliases: ['hdr'],
|
|
45
|
+
parse: val => JSON.parse(val),
|
|
46
|
+
default: {},
|
|
47
|
+
});
|
|
48
|
+
class DeployCommand extends core_1.Command {
|
|
49
|
+
async run() {
|
|
50
|
+
const { args: { 'subgraph-name': subgraphName, 'subgraph-manifest': manifest }, flags: { product, 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, }, } = await this.parse(DeployCommand);
|
|
137
51
|
try {
|
|
138
52
|
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest);
|
|
139
53
|
for (const { network } of dataSourcesAndTemplates) {
|
|
@@ -141,53 +55,19 @@ exports.default = {
|
|
|
141
55
|
}
|
|
142
56
|
}
|
|
143
57
|
catch (e) {
|
|
144
|
-
|
|
145
|
-
process.exitCode = 1;
|
|
146
|
-
return;
|
|
58
|
+
this.error(e, { exit: 1 });
|
|
147
59
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
product,
|
|
157
|
-
studio,
|
|
158
|
-
node,
|
|
159
|
-
versionLabel: 'skip', // determine label requirement later
|
|
160
|
-
});
|
|
161
|
-
if (inputs === undefined) {
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
product = inputs.product;
|
|
165
|
-
({ node } = (0, node_1.chooseNodeUrl)({
|
|
166
|
-
product,
|
|
167
|
-
studio,
|
|
168
|
-
node,
|
|
169
|
-
}));
|
|
170
|
-
}
|
|
171
|
-
// Validate the subgraph name
|
|
172
|
-
if (!subgraphName) {
|
|
173
|
-
print.error(`No subgraph ${product == 'subgraph-studio' || studio ? 'slug' : 'name'} provided`);
|
|
174
|
-
print.info(HELP);
|
|
175
|
-
process.exitCode = 1;
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
// Validate node
|
|
60
|
+
const { node } = (0, node_1.chooseNodeUrl)({
|
|
61
|
+
product,
|
|
62
|
+
studio,
|
|
63
|
+
node: nodeFlag ||
|
|
64
|
+
(await core_1.ux.prompt('Which product to deploy for?', {
|
|
65
|
+
required: true,
|
|
66
|
+
})),
|
|
67
|
+
});
|
|
179
68
|
if (!node) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
process.exitCode = 1;
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
// Validate IPFS
|
|
186
|
-
if (!ipfs) {
|
|
187
|
-
print.error(`No IPFS node provided`);
|
|
188
|
-
print.info(HELP);
|
|
189
|
-
process.exitCode = 1;
|
|
190
|
-
return;
|
|
69
|
+
// shouldn't happen, but we do the check to satisfy TS
|
|
70
|
+
this.error('No Graph node provided');
|
|
191
71
|
}
|
|
192
72
|
let protocol;
|
|
193
73
|
try {
|
|
@@ -203,13 +83,11 @@ exports.default = {
|
|
|
203
83
|
protocol = protocols_1.default.fromDataSources(dataSourcesAndTemplates);
|
|
204
84
|
}
|
|
205
85
|
catch (e) {
|
|
206
|
-
|
|
207
|
-
process.exitCode = 1;
|
|
208
|
-
return;
|
|
86
|
+
this.error(e, { exit: 1 });
|
|
209
87
|
}
|
|
210
88
|
if (network) {
|
|
211
89
|
const identifierName = protocol.getContract().identifierName();
|
|
212
|
-
await (0, network_1.updateSubgraphNetwork)(
|
|
90
|
+
await (0, network_1.updateSubgraphNetwork)(manifest, network, networkFile, identifierName);
|
|
213
91
|
}
|
|
214
92
|
const isStudio = node.match(/studio/);
|
|
215
93
|
const isHostedService = node.match(/thegraph.com/) && !isStudio;
|
|
@@ -219,35 +97,30 @@ exports.default = {
|
|
|
219
97
|
outputDir,
|
|
220
98
|
outputFormat: 'wasm',
|
|
221
99
|
skipMigrations,
|
|
222
|
-
blockIpfsMethods: isStudio,
|
|
100
|
+
blockIpfsMethods: isStudio || undefined,
|
|
223
101
|
protocol,
|
|
224
102
|
});
|
|
225
103
|
// Exit with an error code if the compiler couldn't be created
|
|
226
104
|
if (!compiler) {
|
|
227
|
-
|
|
105
|
+
this.exit(1);
|
|
228
106
|
return;
|
|
229
107
|
}
|
|
230
108
|
// Ask for label if not on hosted service
|
|
109
|
+
let versionLabel = versionLabelFlag;
|
|
231
110
|
if (!versionLabel && !isHostedService) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
studio,
|
|
235
|
-
node,
|
|
236
|
-
versionLabel,
|
|
111
|
+
versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
|
|
112
|
+
required: true,
|
|
237
113
|
});
|
|
238
|
-
if (inputs === undefined) {
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
versionLabel = inputs.versionLabel;
|
|
242
114
|
}
|
|
243
115
|
const requestUrl = new url_1.URL(node);
|
|
244
116
|
const client = (0, jsonrpc_1.createJsonRpcClient)(requestUrl);
|
|
245
117
|
// Exit with an error code if the client couldn't be created
|
|
246
118
|
if (!client) {
|
|
247
|
-
|
|
119
|
+
this.exit(1);
|
|
248
120
|
return;
|
|
249
121
|
}
|
|
250
122
|
// Use the deploy key, if one is set
|
|
123
|
+
let deployKey = deployKeyFlag;
|
|
251
124
|
if (!deployKey && accessToken) {
|
|
252
125
|
deployKey = accessToken; // backwards compatibility
|
|
253
126
|
}
|
|
@@ -256,9 +129,10 @@ exports.default = {
|
|
|
256
129
|
// @ts-expect-error options property seems to exist
|
|
257
130
|
client.options.headers = { Authorization: 'Bearer ' + deployKey };
|
|
258
131
|
}
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias -- request needs it
|
|
133
|
+
const self = this;
|
|
259
134
|
const deploySubgraph = async (ipfsHash) => {
|
|
260
|
-
|
|
261
|
-
// `Failed to deploy to Graph node ${requestUrl}`,
|
|
135
|
+
core_1.ux.action.start(`Deploying to Graph node ${requestUrl}`);
|
|
262
136
|
client.request('subgraph_deploy', {
|
|
263
137
|
name: subgraphName,
|
|
264
138
|
ipfs_hash: ipfsHash,
|
|
@@ -272,27 +146,25 @@ exports.default = {
|
|
|
272
146
|
// @ts-expect-error TODO: why are the arguments not typed?
|
|
273
147
|
res) => {
|
|
274
148
|
if (jsonRpcError) {
|
|
275
|
-
|
|
149
|
+
let errorMessage = `Failed to deploy to Graph node ${requestUrl}: ${jsonRpcError.message}`;
|
|
276
150
|
// Provide helpful advice when the subgraph has not been created yet
|
|
277
151
|
if (jsonRpcError.message.match(/subgraph name not found/)) {
|
|
278
152
|
if (isHostedService) {
|
|
279
|
-
|
|
280
|
-
|
|
153
|
+
errorMessage +=
|
|
154
|
+
'\nYou may need to create it at https://thegraph.com/explorer/dashboard.';
|
|
281
155
|
}
|
|
282
156
|
else {
|
|
283
|
-
|
|
157
|
+
errorMessage += `
|
|
284
158
|
Make sure to create the subgraph first by running the following command:
|
|
285
|
-
$ graph create --node ${node} ${subgraphName}
|
|
159
|
+
$ graph create --node ${node} ${subgraphName}`;
|
|
286
160
|
}
|
|
287
161
|
}
|
|
288
|
-
|
|
162
|
+
self.error(errorMessage, { exit: 1 });
|
|
289
163
|
}
|
|
290
164
|
else if (requestError) {
|
|
291
|
-
|
|
292
|
-
process.exitCode = 1;
|
|
165
|
+
self.error(`HTTP error deploying the subgraph ${requestError.code}`, { exit: 1 });
|
|
293
166
|
}
|
|
294
167
|
else {
|
|
295
|
-
spinner.stop();
|
|
296
168
|
const base = requestUrl.protocol + '//' + requestUrl.hostname;
|
|
297
169
|
let playground = res.playground;
|
|
298
170
|
let queries = res.queries;
|
|
@@ -304,14 +176,13 @@ $ graph create --node ${node} ${subgraphName}`);
|
|
|
304
176
|
queries = base + queries;
|
|
305
177
|
}
|
|
306
178
|
if (isHostedService) {
|
|
307
|
-
|
|
179
|
+
core_1.ux.action.stop(`Deployed to https://thegraph.com/explorer/subgraph/${subgraphName}`);
|
|
308
180
|
}
|
|
309
181
|
else {
|
|
310
|
-
|
|
182
|
+
core_1.ux.action.stop(`Deployed to ${String(playground)}`);
|
|
311
183
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
print.info(``);
|
|
184
|
+
self.log('Subgraph endpoints:');
|
|
185
|
+
self.log(`Queries (HTTP):\n${queries}`);
|
|
315
186
|
}
|
|
316
187
|
});
|
|
317
188
|
};
|
|
@@ -331,5 +202,72 @@ $ graph create --node ${node} ${subgraphName}`);
|
|
|
331
202
|
}
|
|
332
203
|
await deploySubgraph(result);
|
|
333
204
|
}
|
|
334
|
-
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
exports.default = DeployCommand;
|
|
208
|
+
DeployCommand.description = 'Deploys a subgraph to a Graph node.';
|
|
209
|
+
DeployCommand.args = {
|
|
210
|
+
'subgraph-name': core_1.Args.string({
|
|
211
|
+
required: true,
|
|
212
|
+
}),
|
|
213
|
+
'subgraph-manifest': core_1.Args.string({
|
|
214
|
+
default: 'subgraph.yaml',
|
|
215
|
+
}),
|
|
216
|
+
};
|
|
217
|
+
DeployCommand.flags = {
|
|
218
|
+
product: core_1.Flags.string({
|
|
219
|
+
summary: 'Select a product for which to authenticate.',
|
|
220
|
+
options: ['subgraph-studio', 'hosted-service'],
|
|
221
|
+
}),
|
|
222
|
+
studio: core_1.Flags.boolean({
|
|
223
|
+
summary: 'Shortcut for "--product subgraph-studio".',
|
|
224
|
+
exclusive: ['product'],
|
|
225
|
+
}),
|
|
226
|
+
node: core_1.Flags.string({
|
|
227
|
+
summary: 'Graph node for which to initialize.',
|
|
228
|
+
char: 'g',
|
|
229
|
+
}),
|
|
230
|
+
'deploy-key': core_1.Flags.string({
|
|
231
|
+
summary: 'User deploy key.',
|
|
232
|
+
required: true,
|
|
233
|
+
exclusive: ['access-token'],
|
|
234
|
+
}),
|
|
235
|
+
'access-token': core_1.Flags.string({
|
|
236
|
+
deprecated: true,
|
|
237
|
+
summary: 'Graph access key. DEPRECATED: Use "--deploy-key" instead.',
|
|
238
|
+
exclusive: ['deploy-key'],
|
|
239
|
+
}),
|
|
240
|
+
'version-label': core_1.Flags.string({
|
|
241
|
+
summary: 'Version label used for the deployment.',
|
|
242
|
+
char: 'l',
|
|
243
|
+
}),
|
|
244
|
+
ipfs: core_1.Flags.string({
|
|
245
|
+
summary: 'Upload build results to an IPFS node.',
|
|
246
|
+
char: 'i',
|
|
247
|
+
default: ipfs_1.DEFAULT_IPFS_URL,
|
|
248
|
+
}),
|
|
249
|
+
headers: headersFlag(),
|
|
250
|
+
'debug-fork': core_1.Flags.string({
|
|
251
|
+
summary: 'ID of a remote subgraph whose store will be GraphQL queried.',
|
|
252
|
+
}),
|
|
253
|
+
'output-dir': core_1.Flags.directory({
|
|
254
|
+
summary: 'Output directory for build results.',
|
|
255
|
+
char: 'o',
|
|
256
|
+
default: 'build/',
|
|
257
|
+
}),
|
|
258
|
+
'skip-migrations': core_1.Flags.boolean({
|
|
259
|
+
summary: 'Skip subgraph migrations.',
|
|
260
|
+
}),
|
|
261
|
+
watch: core_1.Flags.boolean({
|
|
262
|
+
summary: 'Regenerate types when subgraph files change.',
|
|
263
|
+
char: 'w',
|
|
264
|
+
}),
|
|
265
|
+
network: core_1.Flags.string({
|
|
266
|
+
summary: 'Network configuration to use from the networks config file.',
|
|
267
|
+
}),
|
|
268
|
+
// TODO: should be networksFile (with an "s"), or?
|
|
269
|
+
'network-file': core_1.Flags.file({
|
|
270
|
+
summary: 'Networks config file path.',
|
|
271
|
+
default: 'networks.json',
|
|
272
|
+
}),
|
|
335
273
|
};
|