@graphprotocol/graph-cli 0.50.0-alpha-20230523132328-eb6bf7e → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/dist/codegen/types/conversions.js +1 -0
- package/dist/command-helpers/data-sources.d.ts +1 -0
- package/dist/command-helpers/data-sources.js +12 -1
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.js +85 -53
- package/oclif.manifest.json +8 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# @graphprotocol/graph-cli
|
|
2
2
|
|
|
3
|
-
## 0.50.0
|
|
3
|
+
## 0.50.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
+
- [#1353](https://github.com/graphprotocol/graph-tooling/pull/1353)
|
|
8
|
+
[`125c687`](https://github.com/graphprotocol/graph-tooling/commit/125c6874e9d2fb67bf9f0211e9f9f306bc6fe55c)
|
|
9
|
+
Thanks [@saihaj](https://github.com/saihaj)! - Add a new `--ipfs-hash` flag to `graph deploy`
|
|
10
|
+
allowing to deploy a subgraph that is already compiled and uploaded to IPFS.
|
|
11
|
+
|
|
7
12
|
- [#1335](https://github.com/graphprotocol/graph-tooling/pull/1335)
|
|
8
13
|
[`7343f50`](https://github.com/graphprotocol/graph-tooling/commit/7343f50c0e2b767de04909e6020b88fea97ae3cd)
|
|
9
14
|
Thanks [@saihaj](https://github.com/saihaj)! - For substreams generate the directory tree as
|
|
@@ -48,6 +53,10 @@
|
|
|
48
53
|
- Updated dependency [`gluegun@5.1.2` ↗︎](https://www.npmjs.com/package/gluegun/v/5.1.2) (from
|
|
49
54
|
`https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep`, in `dependencies`)
|
|
50
55
|
|
|
56
|
+
- [#1351](https://github.com/graphprotocol/graph-tooling/pull/1351)
|
|
57
|
+
[`c7cf89c`](https://github.com/graphprotocol/graph-tooling/commit/c7cf89c2b7b60b39bd89473d8440ece2acdcb9a3)
|
|
58
|
+
Thanks [@saihaj](https://github.com/saihaj)! - return tuple arrays as a Bytes array in GraphQL
|
|
59
|
+
|
|
51
60
|
- [#1329](https://github.com/graphprotocol/graph-tooling/pull/1329)
|
|
52
61
|
[`308cb8a`](https://github.com/graphprotocol/graph-tooling/commit/308cb8af3fb2cabbad08f409d77481994a95865c)
|
|
53
62
|
Thanks [@saihaj](https://github.com/saihaj)! - Point to new examples repo instead of old
|
|
@@ -295,6 +295,7 @@ const ASSEMBLYSCRIPT_TO_VALUE = [
|
|
|
295
295
|
],
|
|
296
296
|
['Array<Array<string>>', /\[\[.*\]\]/, (code) => `Value.fromStringMatrix(${code})`],
|
|
297
297
|
['Array<Array<string | null>>', null, (code) => `Value.fromStringMatrix(${code})`],
|
|
298
|
+
['Array<ethereum.Tuple>', '[Bytes]', (code) => `Value.fromArray(${code})`],
|
|
298
299
|
// Arrays
|
|
299
300
|
['Array<Address>', '[Bytes]', (code) => `Value.fromBytesArray(${code})`],
|
|
300
301
|
['Array<Bytes>', '[Bytes]', (code) => `Value.fromBytesArray(${code})`],
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import immutable from 'immutable';
|
|
2
2
|
import Protocol from '../protocols';
|
|
3
3
|
export declare const fromFilePath: (manifestPath: string) => Promise<any>;
|
|
4
|
+
export declare function fromManifestString(manifest: string): any;
|
|
4
5
|
export declare const fromManifest: (manifest: immutable.Map<any, any>, protocol: Protocol) => any;
|
|
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fromManifest = exports.fromFilePath = void 0;
|
|
6
|
+
exports.fromManifest = exports.fromManifestString = exports.fromFilePath = void 0;
|
|
7
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
7
8
|
const immutable_1 = __importDefault(require("immutable"));
|
|
8
9
|
const load_manifest_1 = require("../migrations/util/load-manifest");
|
|
9
10
|
// Loads manifest from file path and returns all:
|
|
@@ -15,6 +16,16 @@ const fromFilePath = async (manifestPath) => {
|
|
|
15
16
|
return dataSources.concat(templates);
|
|
16
17
|
};
|
|
17
18
|
exports.fromFilePath = fromFilePath;
|
|
19
|
+
// Loads manifest from file path and returns all:
|
|
20
|
+
// - data sources
|
|
21
|
+
// - templates
|
|
22
|
+
// In a single list.
|
|
23
|
+
function fromManifestString(manifest) {
|
|
24
|
+
// TODO: can we make it typesafe?
|
|
25
|
+
const { dataSources = [], templates = [] } = (js_yaml_1.default.safeLoad(manifest) || {});
|
|
26
|
+
return dataSources.concat(templates);
|
|
27
|
+
}
|
|
28
|
+
exports.fromManifestString = fromManifestString;
|
|
18
29
|
const extractDataSourceByType = (manifest, dataSourceType, protocol) => manifest
|
|
19
30
|
.get(dataSourceType, immutable_1.default.List())
|
|
20
31
|
.reduce((dataSources, dataSource, dataSourceIndex) => protocol.isValidKindName(dataSource.get('kind'))
|
|
@@ -14,6 +14,7 @@ export default class DeployCommand extends Command {
|
|
|
14
14
|
'access-token': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
15
15
|
'version-label': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
16
16
|
ipfs: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
17
|
+
'ipfs-hash': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
17
18
|
headers: import("@oclif/core/lib/interfaces").OptionFlag<Record<string, string> | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
18
19
|
'debug-fork': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
19
20
|
'output-dir': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
package/dist/commands/deploy.js
CHANGED
|
@@ -40,6 +40,7 @@ const node_1 = require("../command-helpers/node");
|
|
|
40
40
|
const studio_1 = require("../command-helpers/studio");
|
|
41
41
|
const version_1 = require("../command-helpers/version");
|
|
42
42
|
const protocols_1 = __importDefault(require("../protocols"));
|
|
43
|
+
const ipfs_http_client_1 = require("ipfs-http-client");
|
|
43
44
|
const headersFlag = core_1.Flags.custom({
|
|
44
45
|
summary: 'Add custom headers that will be used by the IPFS HTTP client.',
|
|
45
46
|
aliases: ['hdr'],
|
|
@@ -49,7 +50,7 @@ const headersFlag = core_1.Flags.custom({
|
|
|
49
50
|
const productOptions = ['subgraph-studio', 'hosted-service'];
|
|
50
51
|
class DeployCommand extends core_1.Command {
|
|
51
52
|
async run() {
|
|
52
|
-
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, }, } = await this.parse(DeployCommand);
|
|
53
|
+
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, }, } = await this.parse(DeployCommand);
|
|
53
54
|
const subgraphName = subgraphNameArg ||
|
|
54
55
|
(await core_1.ux.prompt('What is the subgraph name?', {
|
|
55
56
|
required: true,
|
|
@@ -71,15 +72,6 @@ class DeployCommand extends core_1.Command {
|
|
|
71
72
|
},
|
|
72
73
|
])
|
|
73
74
|
.then(({ product }) => product));
|
|
74
|
-
try {
|
|
75
|
-
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest);
|
|
76
|
-
for (const { network } of dataSourcesAndTemplates) {
|
|
77
|
-
(0, studio_1.validateStudioNetwork)({ studio, product, network });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
this.error(e, { exit: 1 });
|
|
82
|
-
}
|
|
83
75
|
const { node } = (0, node_1.chooseNodeUrl)({
|
|
84
76
|
product,
|
|
85
77
|
studio,
|
|
@@ -89,49 +81,8 @@ class DeployCommand extends core_1.Command {
|
|
|
89
81
|
// shouldn't happen, but we do the check to satisfy TS
|
|
90
82
|
this.error('No Graph node provided');
|
|
91
83
|
}
|
|
92
|
-
let protocol;
|
|
93
|
-
try {
|
|
94
|
-
// Checks to make sure deploy doesn't run against
|
|
95
|
-
// older subgraphs (both apiVersion and graph-ts version).
|
|
96
|
-
//
|
|
97
|
-
// We don't want the deploy to run without these conditions
|
|
98
|
-
// because that would mean the CLI would try to compile code
|
|
99
|
-
// using the wrong AssemblyScript compiler.
|
|
100
|
-
await (0, version_1.assertManifestApiVersion)(manifest, '0.0.5');
|
|
101
|
-
await (0, version_1.assertGraphTsVersion)(path_1.default.dirname(manifest), '0.25.0');
|
|
102
|
-
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest);
|
|
103
|
-
protocol = protocols_1.default.fromDataSources(dataSourcesAndTemplates);
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
this.error(e, { exit: 1 });
|
|
107
|
-
}
|
|
108
|
-
if (network) {
|
|
109
|
-
const identifierName = protocol.getContract().identifierName();
|
|
110
|
-
await (0, network_1.updateSubgraphNetwork)(manifest, network, networkFile, identifierName);
|
|
111
|
-
}
|
|
112
84
|
const isStudio = node.match(/studio/);
|
|
113
85
|
const isHostedService = node.match(/thegraph.com/) && !isStudio;
|
|
114
|
-
const compiler = (0, compiler_1.createCompiler)(manifest, {
|
|
115
|
-
ipfs,
|
|
116
|
-
headers,
|
|
117
|
-
outputDir,
|
|
118
|
-
outputFormat: 'wasm',
|
|
119
|
-
skipMigrations,
|
|
120
|
-
blockIpfsMethods: isStudio || undefined,
|
|
121
|
-
protocol,
|
|
122
|
-
});
|
|
123
|
-
// Exit with an error code if the compiler couldn't be created
|
|
124
|
-
if (!compiler) {
|
|
125
|
-
this.exit(1);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
// Ask for label if not on hosted service
|
|
129
|
-
let versionLabel = versionLabelFlag;
|
|
130
|
-
if (!versionLabel && !isHostedService) {
|
|
131
|
-
versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
|
|
132
|
-
required: true,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
86
|
const requestUrl = new url_1.URL(node);
|
|
136
87
|
const client = (0, jsonrpc_1.createJsonRpcClient)(requestUrl);
|
|
137
88
|
// Exit with an error code if the client couldn't be created
|
|
@@ -149,6 +100,13 @@ class DeployCommand extends core_1.Command {
|
|
|
149
100
|
// @ts-expect-error options property seems to exist
|
|
150
101
|
client.options.headers = { Authorization: 'Bearer ' + deployKey };
|
|
151
102
|
}
|
|
103
|
+
// Ask for label if not on hosted service
|
|
104
|
+
let versionLabel = versionLabelFlag;
|
|
105
|
+
if (!versionLabel && !isHostedService) {
|
|
106
|
+
versionLabel = await core_1.ux.prompt('Which version label to use? (e.g. "v0.0.1")', {
|
|
107
|
+
required: true,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
152
110
|
// eslint-disable-next-line @typescript-eslint/no-this-alias -- request needs it
|
|
153
111
|
const self = this;
|
|
154
112
|
const deploySubgraph = async (ipfsHash) => {
|
|
@@ -175,8 +133,8 @@ class DeployCommand extends core_1.Command {
|
|
|
175
133
|
}
|
|
176
134
|
else {
|
|
177
135
|
errorMessage += `
|
|
178
|
-
Make sure to create the subgraph first by running the following command:
|
|
179
|
-
$ graph create --node ${node} ${subgraphName}`;
|
|
136
|
+
Make sure to create the subgraph first by running the following command:
|
|
137
|
+
$ graph create --node ${node} ${subgraphName}`;
|
|
180
138
|
}
|
|
181
139
|
}
|
|
182
140
|
self.error(errorMessage, { exit: 1 });
|
|
@@ -206,9 +164,79 @@ $ graph create --node ${node} ${subgraphName}`;
|
|
|
206
164
|
gluegun_1.print.info('\nSubgraph endpoints:');
|
|
207
165
|
gluegun_1.print.info(`Queries (HTTP): ${queries}`);
|
|
208
166
|
gluegun_1.print.info(``);
|
|
167
|
+
process.exit(0);
|
|
209
168
|
}
|
|
210
169
|
});
|
|
211
170
|
};
|
|
171
|
+
// we are provided the IPFS hash, so we deploy directly
|
|
172
|
+
if (ipfsHash) {
|
|
173
|
+
// Connect to the IPFS node (if a node address was provided)
|
|
174
|
+
const ipfsClient = (0, ipfs_http_client_1.create)({ url: (0, compiler_1.appendApiVersionForGraph)(ipfs.toString()), headers });
|
|
175
|
+
// Fetch the manifest from IPFS
|
|
176
|
+
const manifestBuffer = ipfsClient.cat(ipfsHash);
|
|
177
|
+
let manifestFile = '';
|
|
178
|
+
for await (const chunk of manifestBuffer) {
|
|
179
|
+
manifestFile += chunk.toString();
|
|
180
|
+
}
|
|
181
|
+
if (!manifestFile) {
|
|
182
|
+
this.error(`Could not find subgraph manifest at IPFS hash ${ipfsHash}`, { exit: 1 });
|
|
183
|
+
}
|
|
184
|
+
await ipfsClient.pin.add(ipfsHash);
|
|
185
|
+
try {
|
|
186
|
+
const dataSourcesAndTemplates = DataSourcesExtractor.fromManifestString(manifestFile);
|
|
187
|
+
for (const { network } of dataSourcesAndTemplates) {
|
|
188
|
+
(0, studio_1.validateStudioNetwork)({ studio, product, network });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
this.error(e, { exit: 1 });
|
|
193
|
+
}
|
|
194
|
+
await deploySubgraph(ipfsHash);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest);
|
|
199
|
+
for (const { network } of dataSourcesAndTemplates) {
|
|
200
|
+
(0, studio_1.validateStudioNetwork)({ studio, product, network });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
this.error(e, { exit: 1 });
|
|
205
|
+
}
|
|
206
|
+
let protocol;
|
|
207
|
+
try {
|
|
208
|
+
// Checks to make sure deploy doesn't run against
|
|
209
|
+
// older subgraphs (both apiVersion and graph-ts version).
|
|
210
|
+
//
|
|
211
|
+
// We don't want the deploy to run without these conditions
|
|
212
|
+
// because that would mean the CLI would try to compile code
|
|
213
|
+
// using the wrong AssemblyScript compiler.
|
|
214
|
+
await (0, version_1.assertManifestApiVersion)(manifest, '0.0.5');
|
|
215
|
+
await (0, version_1.assertGraphTsVersion)(path_1.default.dirname(manifest), '0.25.0');
|
|
216
|
+
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest);
|
|
217
|
+
protocol = protocols_1.default.fromDataSources(dataSourcesAndTemplates);
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
this.error(e, { exit: 1 });
|
|
221
|
+
}
|
|
222
|
+
if (network) {
|
|
223
|
+
const identifierName = protocol.getContract().identifierName();
|
|
224
|
+
await (0, network_1.updateSubgraphNetwork)(manifest, network, networkFile, identifierName);
|
|
225
|
+
}
|
|
226
|
+
const compiler = (0, compiler_1.createCompiler)(manifest, {
|
|
227
|
+
ipfs,
|
|
228
|
+
headers,
|
|
229
|
+
outputDir,
|
|
230
|
+
outputFormat: 'wasm',
|
|
231
|
+
skipMigrations,
|
|
232
|
+
blockIpfsMethods: isStudio || undefined,
|
|
233
|
+
protocol,
|
|
234
|
+
});
|
|
235
|
+
// Exit with an error code if the compiler couldn't be created
|
|
236
|
+
if (!compiler) {
|
|
237
|
+
this.exit(1);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
212
240
|
if (watch) {
|
|
213
241
|
await compiler.watchAndCompile(async (ipfsHash) => {
|
|
214
242
|
if (ipfsHash !== undefined) {
|
|
@@ -268,6 +296,10 @@ DeployCommand.flags = {
|
|
|
268
296
|
char: 'i',
|
|
269
297
|
default: ipfs_1.DEFAULT_IPFS_URL,
|
|
270
298
|
}),
|
|
299
|
+
'ipfs-hash': core_1.Flags.string({
|
|
300
|
+
summary: 'IPFS hash of the subgraph manifest to deploy.',
|
|
301
|
+
required: false,
|
|
302
|
+
}),
|
|
271
303
|
headers: headersFlag(),
|
|
272
304
|
'debug-fork': core_1.Flags.string({
|
|
273
305
|
summary: 'ID of a remote subgraph whose store will be GraphQL queried.',
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.50.0
|
|
2
|
+
"version": "0.50.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"add": {
|
|
5
5
|
"id": "add",
|
|
@@ -362,6 +362,13 @@
|
|
|
362
362
|
"multiple": false,
|
|
363
363
|
"default": "https://api.thegraph.com/ipfs/api/v0"
|
|
364
364
|
},
|
|
365
|
+
"ipfs-hash": {
|
|
366
|
+
"name": "ipfs-hash",
|
|
367
|
+
"type": "option",
|
|
368
|
+
"summary": "IPFS hash of the subgraph manifest to deploy.",
|
|
369
|
+
"required": false,
|
|
370
|
+
"multiple": false
|
|
371
|
+
},
|
|
365
372
|
"headers": {
|
|
366
373
|
"name": "headers",
|
|
367
374
|
"type": "option",
|