@graphprotocol/graph-cli 0.37.3-alpha-20230112170916-36bdc67 → 0.37.3-alpha-20230112190020-19838fd
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 +1 -1
- package/dist/command-helpers/gluegun.js +2 -3
- package/dist/command-helpers/jsonrpc.js +2 -2
- package/dist/commands/add.js +13 -13
- package/dist/commands/auth.js +2 -2
- package/dist/commands/create.js +7 -2
- package/dist/commands/test.js +18 -14
- package/jest.config.js +3 -3
- package/package.json +4 -4
- package/src/command-helpers/gluegun.ts +10 -5
- package/src/command-helpers/jsonrpc.ts +1 -3
- package/src/command-helpers/node.ts +2 -2
- package/src/commands/{add.js → add.ts} +37 -18
- package/src/commands/{auth.js → auth.ts} +20 -7
- package/src/commands/binary-install-raw.d.ts +1 -0
- package/src/commands/{create.js → create.ts} +27 -18
- package/src/commands/{test.js → test.ts} +77 -31
- package/src/subgraph.ts +1 -1
- package/tests/cli/{globalSetup.js → globalSetup.ts} +0 -0
- package/tests/cli/{globalTeardown.js → globalTeardown.ts} +0 -0
- package/tests/cli/{init.test.js → init.test.ts} +0 -0
- package/tests/cli/spawn-command.d.ts +6 -0
- package/tests/cli/{util.js → util.ts} +33 -15
- package/tests/cli/{validation.test.js → validation.test.ts} +0 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fixParameters = void 0;
|
|
4
2
|
// Workaround for https://github.com/infinitered/gluegun/pull/464.
|
|
5
3
|
//
|
|
6
4
|
// There is currently no way in Gluegun to define command-line options
|
|
@@ -26,7 +24,8 @@ exports.fixParameters = void 0;
|
|
|
26
24
|
// The `fixParameters` function checks if any of the provided boolean
|
|
27
25
|
// options has a string value; if so, it pushes it to the front of the
|
|
28
26
|
// parameters array and returns the result of that.
|
|
29
|
-
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.fixParameters = void 0;
|
|
30
29
|
const fixParameters = (parameters, booleanOptions) => {
|
|
31
30
|
let unexpectedStringOptions = Object.keys(booleanOptions)
|
|
32
31
|
.filter(key => typeof booleanOptions[key] === 'string')
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.createJsonRpcClient = void 0;
|
|
7
7
|
const jayson_1 = __importDefault(require("jayson"));
|
|
8
8
|
const gluegun_1 = require("gluegun");
|
|
9
|
-
|
|
9
|
+
function createJsonRpcClient(url) {
|
|
10
10
|
const params = {
|
|
11
11
|
host: url.hostname,
|
|
12
12
|
port: url.port,
|
|
@@ -25,5 +25,5 @@ const createJsonRpcClient = (url) => {
|
|
|
25
25
|
gluegun_1.print.error('The Graph Node URL must be of the following format: http(s)://host[:port]/[path]');
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
exports.createJsonRpcClient = createJsonRpcClient;
|
package/dist/commands/add.js
CHANGED
|
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const chalk_1 = __importDefault(require("chalk"));
|
|
30
|
-
const toolbox = __importStar(require("gluegun
|
|
30
|
+
const toolbox = __importStar(require("gluegun"));
|
|
31
31
|
const immutable_1 = __importDefault(require("immutable"));
|
|
32
32
|
const spinner_1 = require("../command-helpers/spinner");
|
|
33
33
|
const subgraph_1 = __importDefault(require("../subgraph"));
|
|
@@ -55,7 +55,7 @@ exports.default = {
|
|
|
55
55
|
// Obtain tools
|
|
56
56
|
let { print, system } = toolbox;
|
|
57
57
|
// Read CLI parameters
|
|
58
|
-
let { abi, contractName, h, help, mergeEntities, networkFile } = toolbox.parameters.options;
|
|
58
|
+
let { abi, contractName, h, help, mergeEntities, networkFile, } = toolbox.parameters.options;
|
|
59
59
|
contractName = contractName || 'Contract';
|
|
60
60
|
try {
|
|
61
61
|
(0, gluegun_1.fixParameters)(toolbox.parameters, {
|
|
@@ -69,8 +69,8 @@ exports.default = {
|
|
|
69
69
|
process.exitCode = 1;
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
let address = toolbox.parameters.first || toolbox.parameters.array[0];
|
|
73
|
-
let manifestPath = toolbox.parameters.second || toolbox.parameters.array[1] || './subgraph.yaml';
|
|
72
|
+
let address = toolbox.parameters.first || toolbox.parameters.array?.[0];
|
|
73
|
+
let manifestPath = toolbox.parameters.second || toolbox.parameters.array?.[1] || './subgraph.yaml';
|
|
74
74
|
// Show help text if requested
|
|
75
75
|
if (help || h) {
|
|
76
76
|
print.info(HELP);
|
|
@@ -85,7 +85,7 @@ exports.default = {
|
|
|
85
85
|
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifestPath);
|
|
86
86
|
let protocol = protocols_1.default.fromDataSources(dataSourcesAndTemplates);
|
|
87
87
|
let manifest = await subgraph_1.default.load(manifestPath, { protocol });
|
|
88
|
-
let network = manifest.result.
|
|
88
|
+
let network = manifest.result.getIn(['dataSources', 0, 'network']);
|
|
89
89
|
let result = manifest.result.asMutable();
|
|
90
90
|
let entities = getEntities(manifest);
|
|
91
91
|
let contractNames = getContractNames(manifest);
|
|
@@ -130,30 +130,30 @@ exports.default = {
|
|
|
130
130
|
const networksFile = networkFile || './networks.json';
|
|
131
131
|
await (0, network_1.updateNetworksFile)(toolbox, network, contractName, address, networksFile);
|
|
132
132
|
// Detect Yarn and/or NPM
|
|
133
|
-
let yarn =
|
|
134
|
-
let npm =
|
|
133
|
+
let yarn = system.which('yarn');
|
|
134
|
+
let npm = system.which('npm');
|
|
135
135
|
if (!yarn && !npm) {
|
|
136
136
|
print.error(`Neither Yarn nor NPM were found on your system. Please install one of them.`);
|
|
137
137
|
process.exitCode = 1;
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
|
-
await (0, spinner_1.withSpinner)('Running codegen', 'Failed to run codegen', 'Warning during codegen', async (
|
|
140
|
+
await (0, spinner_1.withSpinner)('Running codegen', 'Failed to run codegen', 'Warning during codegen', async () => {
|
|
141
141
|
await system.run(yarn ? 'yarn codegen' : 'npm run codegen');
|
|
142
142
|
});
|
|
143
143
|
},
|
|
144
144
|
};
|
|
145
|
-
const getEntities = manifest => {
|
|
145
|
+
const getEntities = (manifest) => {
|
|
146
146
|
let dataSources = manifest.result.get('dataSources', immutable_1.default.List());
|
|
147
147
|
let templates = manifest.result.get('templates', immutable_1.default.List());
|
|
148
148
|
return dataSources
|
|
149
149
|
.concat(templates)
|
|
150
|
-
.map(dataSource => dataSource.getIn(['mapping', 'entities']))
|
|
150
|
+
.map((dataSource) => dataSource.getIn(['mapping', 'entities']))
|
|
151
151
|
.flatten();
|
|
152
152
|
};
|
|
153
|
-
const getContractNames = manifest => {
|
|
153
|
+
const getContractNames = (manifest) => {
|
|
154
154
|
let dataSources = manifest.result.get('dataSources', immutable_1.default.List());
|
|
155
155
|
let templates = manifest.result.get('templates', immutable_1.default.List());
|
|
156
|
-
return dataSources.concat(templates).map(dataSource => dataSource.get('name'));
|
|
156
|
+
return dataSources.concat(templates).map((dataSource) => dataSource.get('name'));
|
|
157
157
|
};
|
|
158
158
|
const updateEventNamesOnCollision = (ethabi, entities, contractName, mergeEntities) => {
|
|
159
159
|
let abiData = ethabi.data;
|
|
@@ -168,7 +168,7 @@ const updateEventNamesOnCollision = (ethabi, entities, contractName, mergeEntiti
|
|
|
168
168
|
print.error(`Contract name ('${contractName}')
|
|
169
169
|
+ event name ('${dataRow.get('name')}') entity already exists.`);
|
|
170
170
|
process.exitCode = 1;
|
|
171
|
-
|
|
171
|
+
break;
|
|
172
172
|
}
|
|
173
173
|
if (mergeEntities) {
|
|
174
174
|
collisionEntities.push(dataRow.get('name'));
|
package/dist/commands/auth.js
CHANGED
|
@@ -48,9 +48,9 @@ exports.default = {
|
|
|
48
48
|
description: 'Sets the deploy key to use when deploying to a Graph node',
|
|
49
49
|
run: async (toolbox) => {
|
|
50
50
|
// Obtain tools
|
|
51
|
-
|
|
51
|
+
const { print } = toolbox;
|
|
52
52
|
// Read CLI parameters
|
|
53
|
-
|
|
53
|
+
const { product, studio, h, help } = toolbox.parameters.options;
|
|
54
54
|
// Show help text if requested
|
|
55
55
|
if (help || h) {
|
|
56
56
|
print.info(HELP);
|
package/dist/commands/create.js
CHANGED
|
@@ -21,7 +21,7 @@ exports.default = {
|
|
|
21
21
|
description: 'Registers a subgraph name',
|
|
22
22
|
run: async (toolbox) => {
|
|
23
23
|
// Obtain tools
|
|
24
|
-
|
|
24
|
+
const { print } = toolbox;
|
|
25
25
|
// Read CLI parameters
|
|
26
26
|
let { accessToken, g, h, help, node } = toolbox.parameters.options;
|
|
27
27
|
let subgraphName = toolbox.parameters.first;
|
|
@@ -65,10 +65,15 @@ exports.default = {
|
|
|
65
65
|
// Use the access token, if one is set
|
|
66
66
|
accessToken = await (0, auth_1.identifyDeployKey)(node, accessToken);
|
|
67
67
|
if (accessToken !== undefined && accessToken !== null) {
|
|
68
|
+
// @ts-expect-error options property seems to exist
|
|
68
69
|
client.options.headers = { Authorization: `Bearer ${accessToken}` };
|
|
69
70
|
}
|
|
70
71
|
let spinner = print.spin(`Creating subgraph in Graph node: ${requestUrl}`);
|
|
71
|
-
client.request('subgraph_create', { name: subgraphName }, function (
|
|
72
|
+
client.request('subgraph_create', { name: subgraphName }, function (
|
|
73
|
+
// @ts-expect-error TODO: why are the arguments not typed?
|
|
74
|
+
requestError,
|
|
75
|
+
// @ts-expect-error TODO: why are the arguments not typed?
|
|
76
|
+
jsonRpcError) {
|
|
72
77
|
if (jsonRpcError) {
|
|
73
78
|
spinner.fail(`Error creating the subgraph: ${jsonRpcError.message}`);
|
|
74
79
|
process.exitCode = 1;
|
package/dist/commands/test.js
CHANGED
|
@@ -29,8 +29,12 @@ exports.default = {
|
|
|
29
29
|
description: 'Runs rust binary for subgraph testing',
|
|
30
30
|
run: async (toolbox) => {
|
|
31
31
|
// Read CLI parameters
|
|
32
|
-
let { c, coverage, d, docker, f, force, h, help, l, logs, r, recompile, v, version } = toolbox.parameters.options;
|
|
33
|
-
|
|
32
|
+
let { c, coverage, d, docker, f, force, h, help, l, logs, r, recompile, v, version, } = toolbox.parameters.options;
|
|
33
|
+
const testsFolder = './tests';
|
|
34
|
+
let opts = {
|
|
35
|
+
testsFolder,
|
|
36
|
+
cachePath: path_1.default.join(testsFolder, '.latest.json'),
|
|
37
|
+
};
|
|
34
38
|
// Support both long and short option variants
|
|
35
39
|
opts.coverage = coverage || c;
|
|
36
40
|
opts.docker = docker || d;
|
|
@@ -39,7 +43,6 @@ exports.default = {
|
|
|
39
43
|
opts.logs = logs || l;
|
|
40
44
|
opts.recompile = recompile || r;
|
|
41
45
|
opts.version = version || v;
|
|
42
|
-
opts.testsFolder = './tests';
|
|
43
46
|
// Fix if a boolean flag (e.g -c, --coverage) has an argument
|
|
44
47
|
try {
|
|
45
48
|
(0, gluegun_2.fixParameters)(toolbox.parameters, {
|
|
@@ -62,7 +65,7 @@ exports.default = {
|
|
|
62
65
|
process.exitCode = 1;
|
|
63
66
|
return;
|
|
64
67
|
}
|
|
65
|
-
let datasource = toolbox.parameters.first || toolbox.parameters.array[0];
|
|
68
|
+
let datasource = toolbox.parameters.first || toolbox.parameters.array?.[0];
|
|
66
69
|
// Show help text if requested
|
|
67
70
|
if (opts.help) {
|
|
68
71
|
gluegun_1.print.info(HELP);
|
|
@@ -85,7 +88,6 @@ exports.default = {
|
|
|
85
88
|
process.exit(1);
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
|
-
opts.cachePath = path_1.default.join(opts.testsFolder, '.latest.json');
|
|
89
91
|
setVersionFromCache(opts);
|
|
90
92
|
// Fetch the latest version tag if version is not specified with -v/--version or if the version is not cached
|
|
91
93
|
if (opts.force || (!opts.version && !opts.latestVersion)) {
|
|
@@ -127,7 +129,8 @@ async function runBinary(datasource, opts) {
|
|
|
127
129
|
let latestVersion = opts.latestVersion;
|
|
128
130
|
let recompileOpt = opts.recompile;
|
|
129
131
|
const platform = await getPlatform(logsOpt);
|
|
130
|
-
const url = `https://github.com/LimeChain/matchstick/releases/download/${versionOpt ||
|
|
132
|
+
const url = `https://github.com/LimeChain/matchstick/releases/download/${versionOpt ||
|
|
133
|
+
latestVersion}/${platform}`;
|
|
131
134
|
if (logsOpt) {
|
|
132
135
|
gluegun_1.print.info(`Download link: ${url}`);
|
|
133
136
|
}
|
|
@@ -150,9 +153,10 @@ async function getPlatform(logsOpt) {
|
|
|
150
153
|
const linuxInfo = type === 'Linux' ? await getLinuxInfo() : {};
|
|
151
154
|
const linuxDistro = linuxInfo.name;
|
|
152
155
|
const release = linuxInfo.version || os_1.default.release();
|
|
153
|
-
const majorVersion = parseInt(linuxInfo.version, 10) || semver_1.default.major(release);
|
|
156
|
+
const majorVersion = parseInt(linuxInfo.version || '', 10) || semver_1.default.major(release);
|
|
154
157
|
if (logsOpt) {
|
|
155
|
-
gluegun_1.print.info(`OS type: ${linuxDistro ||
|
|
158
|
+
gluegun_1.print.info(`OS type: ${linuxDistro ||
|
|
159
|
+
type}\nOS arch: ${arch}\nOS release: ${release}\nOS major version: ${majorVersion}\nCPU model: ${cpuCore.model}`);
|
|
156
160
|
}
|
|
157
161
|
if (arch === 'x64' || isAppleSilicon) {
|
|
158
162
|
if (type === 'Darwin') {
|
|
@@ -206,9 +210,9 @@ async function runDocker(datasource, opts) {
|
|
|
206
210
|
let recompileOpt = opts.recompile;
|
|
207
211
|
// Remove binary-install-raw binaries, because docker has permission issues
|
|
208
212
|
// when building the docker images
|
|
209
|
-
|
|
213
|
+
gluegun_1.filesystem.remove('./node_modules/binary-install-raw/bin');
|
|
210
214
|
// Get current working directory
|
|
211
|
-
let current_folder =
|
|
215
|
+
let current_folder = gluegun_1.filesystem.cwd();
|
|
212
216
|
// Declate dockerfilePath with default location
|
|
213
217
|
let dockerfilePath = path_1.default.join(opts.testsFolder || 'tests', '.docker/Dockerfile');
|
|
214
218
|
// Check if the Dockerfil already exists
|
|
@@ -219,7 +223,7 @@ async function runDocker(datasource, opts) {
|
|
|
219
223
|
await dockerfile(dockerfilePath, versionOpt, latestVersion);
|
|
220
224
|
}
|
|
221
225
|
// Run a command to check if matchstick image already exists
|
|
222
|
-
(0, child_process_1.exec)('docker images -q matchstick', (
|
|
226
|
+
(0, child_process_1.exec)('docker images -q matchstick', (_error, stdout, _stderr) => {
|
|
223
227
|
// Collect all(if any) flags and options that have to be passed to the matchstick binary
|
|
224
228
|
let testArgs = '';
|
|
225
229
|
if (coverageOpt)
|
|
@@ -247,7 +251,7 @@ async function runDocker(datasource, opts) {
|
|
|
247
251
|
// Use spawn() and {stdio: 'inherit'} so we can see the logs in real time.
|
|
248
252
|
if (!dockerfileExists || stdout === '' || versionOpt || forceOpt) {
|
|
249
253
|
if (stdout !== '') {
|
|
250
|
-
(0, child_process_1.exec)('docker image rm matchstick', (
|
|
254
|
+
(0, child_process_1.exec)('docker image rm matchstick', (_error, stdout, _stderr) => {
|
|
251
255
|
gluegun_1.print.info(chalk_1.default.bold(`Removing matchstick image\n${stdout}`));
|
|
252
256
|
});
|
|
253
257
|
}
|
|
@@ -283,9 +287,9 @@ async function dockerfile(dockerfilePath, versionOpt, latestVersion) {
|
|
|
283
287
|
}
|
|
284
288
|
});
|
|
285
289
|
// Write the Dockerfile
|
|
286
|
-
|
|
290
|
+
gluegun_1.filesystem.write(dockerfilePath, content);
|
|
287
291
|
// Replaces the version placeholders
|
|
288
|
-
await gluegun_1.patching.replace(dockerfilePath, '<MATCHSTICK_VERSION>', versionOpt || latestVersion);
|
|
292
|
+
await gluegun_1.patching.replace(dockerfilePath, '<MATCHSTICK_VERSION>', versionOpt || latestVersion || 'unknown');
|
|
289
293
|
}
|
|
290
294
|
catch (error) {
|
|
291
295
|
spinner.fail(`A problem occurred while generating the Dockerfile. Please attend to the errors below:\n ${error.message}`);
|
package/jest.config.js
CHANGED
|
@@ -49,10 +49,10 @@ module.exports = {
|
|
|
49
49
|
// forceCoverageMatch: [],
|
|
50
50
|
|
|
51
51
|
// A path to a module which exports an async function that is triggered once before all test suites
|
|
52
|
-
globalSetup: './tests/cli/globalSetup',
|
|
52
|
+
globalSetup: './tests/cli/globalSetup.ts',
|
|
53
53
|
|
|
54
54
|
// A path to a module which exports an async function that is triggered once after all test suites
|
|
55
|
-
globalTeardown: './tests/cli/globalTeardown',
|
|
55
|
+
globalTeardown: './tests/cli/globalTeardown.ts',
|
|
56
56
|
|
|
57
57
|
// A set of global variables that need to be available in all test environments
|
|
58
58
|
// globals: {},
|
|
@@ -136,7 +136,7 @@ module.exports = {
|
|
|
136
136
|
testMatch: ['**/?(*.)+(spec|test).(t|j)s?(x)'],
|
|
137
137
|
|
|
138
138
|
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
|
|
139
|
-
testPathIgnorePatterns: ['/src/commands/test.
|
|
139
|
+
testPathIgnorePatterns: ['/src/commands/test.ts', '/node_modules/', '/dist/'],
|
|
140
140
|
|
|
141
141
|
// The regexp pattern Jest uses to detect test files
|
|
142
142
|
// testRegex: "",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphprotocol/graph-cli",
|
|
3
|
-
"version": "0.37.3-alpha-
|
|
3
|
+
"version": "0.37.3-alpha-20230112190020-19838fd",
|
|
4
4
|
"license": "(Apache-2.0 OR MIT)",
|
|
5
5
|
"description": "CLI for building for and deploying to The Graph",
|
|
6
6
|
"main": "dist/cli.js",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"test": "jest --verbose",
|
|
58
|
-
"test:init": "jest tests/cli/init.test.
|
|
59
|
-
"test:validation": "jest tests/cli/validation.test.
|
|
58
|
+
"test:init": "jest tests/cli/init.test.ts --verbose",
|
|
59
|
+
"test:validation": "jest tests/cli/validation.test.ts --verbose",
|
|
60
60
|
"type-check": "tsc --noEmit",
|
|
61
|
-
"build": "tsc
|
|
61
|
+
"build": "tsc -b tsconfig.build.json && copyfiles -u 1 src/**/*.graphql dist/ && chmod +x ./dist/bin.js"
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -23,8 +23,13 @@
|
|
|
23
23
|
// The `fixParameters` function checks if any of the provided boolean
|
|
24
24
|
// options has a string value; if so, it pushes it to the front of the
|
|
25
25
|
// parameters array and returns the result of that.
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
|
|
27
|
+
import { GluegunParameters } from 'gluegun'
|
|
28
|
+
|
|
29
|
+
export const fixParameters = (
|
|
30
|
+
parameters: GluegunParameters,
|
|
31
|
+
booleanOptions: Record<string, string>,
|
|
32
|
+
) => {
|
|
28
33
|
let unexpectedStringOptions = Object.keys(booleanOptions)
|
|
29
34
|
.filter(key => typeof booleanOptions[key] === 'string')
|
|
30
35
|
.map(key => ({ key, value: booleanOptions[key] }))
|
|
@@ -39,9 +44,9 @@ export const fixParameters = (parameters: any, booleanOptions: any) => {
|
|
|
39
44
|
)
|
|
40
45
|
} else if (unexpectedStringOptions.length == 1) {
|
|
41
46
|
let params = parameters.array
|
|
42
|
-
params
|
|
43
|
-
return params
|
|
47
|
+
params!.unshift(unexpectedStringOptions[0].value)
|
|
48
|
+
return params!
|
|
44
49
|
} else {
|
|
45
|
-
return parameters.array
|
|
50
|
+
return parameters.array!
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import jayson from 'jayson'
|
|
2
2
|
import { print } from 'gluegun'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
export function createJsonRpcClient(url: URL): jayson.Client | null {
|
|
5
5
|
const params = {
|
|
6
6
|
host: url.hostname,
|
|
7
7
|
port: url.port,
|
|
@@ -24,5 +24,3 @@ const createJsonRpcClient = (url: URL) => {
|
|
|
24
24
|
return null
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
export { createJsonRpcClient }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk'
|
|
2
|
-
import * as toolbox from 'gluegun
|
|
2
|
+
import * as toolbox from 'gluegun'
|
|
3
3
|
import immutable from 'immutable'
|
|
4
4
|
import { withSpinner } from '../command-helpers/spinner'
|
|
5
5
|
import Subgraph from '../subgraph'
|
|
@@ -29,15 +29,29 @@ ${chalk.dim('Options:')}
|
|
|
29
29
|
-h, --help Show usage information
|
|
30
30
|
`
|
|
31
31
|
|
|
32
|
+
export interface AddOptions {
|
|
33
|
+
abi?: string
|
|
34
|
+
contractName?: string
|
|
35
|
+
mergeEntities?: boolean
|
|
36
|
+
networkFile?: string
|
|
37
|
+
help?: boolean
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
export default {
|
|
33
41
|
description: 'Adds a new datasource to a subgraph',
|
|
34
|
-
run: async toolbox => {
|
|
42
|
+
run: async (toolbox: toolbox.GluegunToolbox) => {
|
|
35
43
|
// Obtain tools
|
|
36
44
|
let { print, system } = toolbox
|
|
37
45
|
|
|
38
46
|
// Read CLI parameters
|
|
39
|
-
let {
|
|
40
|
-
|
|
47
|
+
let {
|
|
48
|
+
abi,
|
|
49
|
+
contractName,
|
|
50
|
+
h,
|
|
51
|
+
help,
|
|
52
|
+
mergeEntities,
|
|
53
|
+
networkFile,
|
|
54
|
+
} = toolbox.parameters.options
|
|
41
55
|
|
|
42
56
|
contractName = contractName || 'Contract'
|
|
43
57
|
|
|
@@ -53,9 +67,9 @@ export default {
|
|
|
53
67
|
return
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
let address = toolbox.parameters.first || toolbox.parameters.array[0]
|
|
70
|
+
let address = toolbox.parameters.first || toolbox.parameters.array?.[0]
|
|
57
71
|
let manifestPath =
|
|
58
|
-
toolbox.parameters.second || toolbox.parameters.array[1] || './subgraph.yaml'
|
|
72
|
+
toolbox.parameters.second || toolbox.parameters.array?.[1] || './subgraph.yaml'
|
|
59
73
|
|
|
60
74
|
// Show help text if requested
|
|
61
75
|
if (help || h) {
|
|
@@ -73,7 +87,7 @@ export default {
|
|
|
73
87
|
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifestPath)
|
|
74
88
|
let protocol = Protocol.fromDataSources(dataSourcesAndTemplates)
|
|
75
89
|
let manifest = await Subgraph.load(manifestPath, { protocol })
|
|
76
|
-
let network = manifest.result.
|
|
90
|
+
let network = manifest.result.getIn(['dataSources', 0, 'network']) as any
|
|
77
91
|
let result = manifest.result.asMutable()
|
|
78
92
|
|
|
79
93
|
let entities = getEntities(manifest)
|
|
@@ -109,7 +123,7 @@ export default {
|
|
|
109
123
|
await writeSchema(
|
|
110
124
|
ethabi,
|
|
111
125
|
protocol,
|
|
112
|
-
result.getIn(['schema', 'file']),
|
|
126
|
+
result.getIn(['schema', 'file']) as any,
|
|
113
127
|
collisionEntities,
|
|
114
128
|
)
|
|
115
129
|
await writeMapping(ethabi, protocol, contractName, collisionEntities)
|
|
@@ -127,7 +141,7 @@ export default {
|
|
|
127
141
|
// Handle the collisions edge case by copying another data source yaml data
|
|
128
142
|
if (mergeEntities && onlyCollisions) {
|
|
129
143
|
let firstDataSource = dataSources.get(0)
|
|
130
|
-
let source = dataSource.get('source')
|
|
144
|
+
let source = dataSource.get('source') as any
|
|
131
145
|
let mapping = firstDataSource.get('mapping').asMutable()
|
|
132
146
|
|
|
133
147
|
// Save the address of the new data source
|
|
@@ -146,8 +160,8 @@ export default {
|
|
|
146
160
|
await updateNetworksFile(toolbox, network, contractName, address, networksFile)
|
|
147
161
|
|
|
148
162
|
// Detect Yarn and/or NPM
|
|
149
|
-
let yarn =
|
|
150
|
-
let npm =
|
|
163
|
+
let yarn = system.which('yarn')
|
|
164
|
+
let npm = system.which('npm')
|
|
151
165
|
if (!yarn && !npm) {
|
|
152
166
|
print.error(
|
|
153
167
|
`Neither Yarn nor NPM were found on your system. Please install one of them.`,
|
|
@@ -160,31 +174,36 @@ export default {
|
|
|
160
174
|
'Running codegen',
|
|
161
175
|
'Failed to run codegen',
|
|
162
176
|
'Warning during codegen',
|
|
163
|
-
async
|
|
177
|
+
async () => {
|
|
164
178
|
await system.run(yarn ? 'yarn codegen' : 'npm run codegen')
|
|
165
179
|
},
|
|
166
180
|
)
|
|
167
181
|
},
|
|
168
182
|
}
|
|
169
183
|
|
|
170
|
-
const getEntities = manifest => {
|
|
184
|
+
const getEntities = (manifest: any) => {
|
|
171
185
|
let dataSources = manifest.result.get('dataSources', immutable.List())
|
|
172
186
|
let templates = manifest.result.get('templates', immutable.List())
|
|
173
187
|
|
|
174
188
|
return dataSources
|
|
175
189
|
.concat(templates)
|
|
176
|
-
.map(dataSource => dataSource.getIn(['mapping', 'entities']))
|
|
190
|
+
.map((dataSource: any) => dataSource.getIn(['mapping', 'entities']))
|
|
177
191
|
.flatten()
|
|
178
192
|
}
|
|
179
193
|
|
|
180
|
-
const getContractNames = manifest => {
|
|
194
|
+
const getContractNames = (manifest: any) => {
|
|
181
195
|
let dataSources = manifest.result.get('dataSources', immutable.List())
|
|
182
196
|
let templates = manifest.result.get('templates', immutable.List())
|
|
183
197
|
|
|
184
|
-
return dataSources.concat(templates).map(dataSource => dataSource.get('name'))
|
|
198
|
+
return dataSources.concat(templates).map((dataSource: any) => dataSource.get('name'))
|
|
185
199
|
}
|
|
186
200
|
|
|
187
|
-
const updateEventNamesOnCollision = (
|
|
201
|
+
const updateEventNamesOnCollision = (
|
|
202
|
+
ethabi: any,
|
|
203
|
+
entities: any,
|
|
204
|
+
contractName: string,
|
|
205
|
+
mergeEntities: boolean,
|
|
206
|
+
) => {
|
|
188
207
|
let abiData = ethabi.data
|
|
189
208
|
let { print } = toolbox
|
|
190
209
|
let collisionEntities = []
|
|
@@ -199,7 +218,7 @@ const updateEventNamesOnCollision = (ethabi, entities, contractName, mergeEntiti
|
|
|
199
218
|
print.error(`Contract name ('${contractName}')
|
|
200
219
|
+ event name ('${dataRow.get('name')}') entity already exists.`)
|
|
201
220
|
process.exitCode = 1
|
|
202
|
-
|
|
221
|
+
break
|
|
203
222
|
}
|
|
204
223
|
|
|
205
224
|
if (mergeEntities) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk'
|
|
2
|
+
import { GluegunToolbox } from 'gluegun'
|
|
2
3
|
import { saveDeployKey } from '../command-helpers/auth'
|
|
3
4
|
import { chooseNodeUrl } from '../command-helpers/node'
|
|
4
5
|
import { fixParameters } from '../command-helpers/gluegun'
|
|
@@ -16,7 +17,19 @@ ${chalk.dim('Options:')}
|
|
|
16
17
|
-h, --help Show usage information
|
|
17
18
|
`
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
export interface AuthOptions {
|
|
21
|
+
product?: 'subgraph-studio' | 'hosted-service'
|
|
22
|
+
studio?: string
|
|
23
|
+
help?: boolean
|
|
24
|
+
// not a cli arg
|
|
25
|
+
node?: string
|
|
26
|
+
deployKey?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const processForm = async (
|
|
30
|
+
toolbox: GluegunToolbox,
|
|
31
|
+
{ product, studio, node, deployKey }: AuthOptions,
|
|
32
|
+
) => {
|
|
20
33
|
const questions = [
|
|
21
34
|
{
|
|
22
35
|
type: 'select',
|
|
@@ -47,12 +60,12 @@ const processForm = async (toolbox, { product, studio, node, deployKey }) => {
|
|
|
47
60
|
|
|
48
61
|
export default {
|
|
49
62
|
description: 'Sets the deploy key to use when deploying to a Graph node',
|
|
50
|
-
run: async toolbox => {
|
|
63
|
+
run: async (toolbox: GluegunToolbox) => {
|
|
51
64
|
// Obtain tools
|
|
52
|
-
|
|
65
|
+
const { print } = toolbox
|
|
53
66
|
|
|
54
67
|
// Read CLI parameters
|
|
55
|
-
|
|
68
|
+
const { product, studio, h, help } = toolbox.parameters.options
|
|
56
69
|
|
|
57
70
|
// Show help text if requested
|
|
58
71
|
if (help || h) {
|
|
@@ -60,7 +73,7 @@ export default {
|
|
|
60
73
|
return
|
|
61
74
|
}
|
|
62
75
|
|
|
63
|
-
let firstParam, secondParam
|
|
76
|
+
let firstParam: string, secondParam: string
|
|
64
77
|
try {
|
|
65
78
|
;[firstParam, secondParam] = fixParameters(toolbox.parameters, {
|
|
66
79
|
h,
|
|
@@ -74,7 +87,7 @@ export default {
|
|
|
74
87
|
}
|
|
75
88
|
|
|
76
89
|
// if user specifies --product or --studio then deployKey is the first parameter
|
|
77
|
-
let node
|
|
90
|
+
let node: string | undefined
|
|
78
91
|
let deployKey
|
|
79
92
|
if (product || studio) {
|
|
80
93
|
;({ node } = chooseNodeUrl({ product, studio, node }))
|
|
@@ -119,7 +132,7 @@ export default {
|
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
try {
|
|
122
|
-
await saveDeployKey(node
|
|
135
|
+
await saveDeployKey(node!, deployKey)
|
|
123
136
|
print.success(`Deploy key set for ${node}`)
|
|
124
137
|
} catch (e) {
|
|
125
138
|
print.error(e)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'binary-install-raw'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { URL } from 'url'
|
|
2
2
|
import chalk from 'chalk'
|
|
3
|
+
import * as toolbox from 'gluegun'
|
|
3
4
|
import { validateNodeUrl } from '../command-helpers/node'
|
|
4
5
|
import { identifyDeployKey as identifyAccessToken } from '../command-helpers/auth'
|
|
5
6
|
import { createJsonRpcClient } from '../command-helpers/jsonrpc'
|
|
@@ -14,11 +15,17 @@ ${chalk.dim('Options:')}
|
|
|
14
15
|
-g, --node <url> Graph node to create the subgraph in
|
|
15
16
|
`
|
|
16
17
|
|
|
18
|
+
export interface AddOptions {
|
|
19
|
+
accessToken?: string
|
|
20
|
+
help?: boolean
|
|
21
|
+
node?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
export default {
|
|
18
25
|
description: 'Registers a subgraph name',
|
|
19
|
-
run: async toolbox => {
|
|
26
|
+
run: async (toolbox: toolbox.GluegunToolbox) => {
|
|
20
27
|
// Obtain tools
|
|
21
|
-
|
|
28
|
+
const { print } = toolbox
|
|
22
29
|
|
|
23
30
|
// Read CLI parameters
|
|
24
31
|
let { accessToken, g, h, help, node } = toolbox.parameters.options
|
|
@@ -69,25 +76,27 @@ export default {
|
|
|
69
76
|
// Use the access token, if one is set
|
|
70
77
|
accessToken = await identifyAccessToken(node, accessToken)
|
|
71
78
|
if (accessToken !== undefined && accessToken !== null) {
|
|
79
|
+
// @ts-expect-error options property seems to exist
|
|
72
80
|
client.options.headers = { Authorization: `Bearer ${accessToken}` }
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
let spinner = print.spin(`Creating subgraph in Graph node: ${requestUrl}`)
|
|
76
|
-
client.request(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
client.request('subgraph_create', { name: subgraphName }, function(
|
|
85
|
+
// @ts-expect-error TODO: why are the arguments not typed?
|
|
86
|
+
requestError,
|
|
87
|
+
// @ts-expect-error TODO: why are the arguments not typed?
|
|
88
|
+
jsonRpcError,
|
|
89
|
+
) {
|
|
90
|
+
if (jsonRpcError) {
|
|
91
|
+
spinner.fail(`Error creating the subgraph: ${jsonRpcError.message}`)
|
|
92
|
+
process.exitCode = 1
|
|
93
|
+
} else if (requestError) {
|
|
94
|
+
spinner.fail(`HTTP error creating the subgraph: ${requestError.code}`)
|
|
95
|
+
process.exitCode = 1
|
|
96
|
+
} else {
|
|
97
|
+
spinner.stop()
|
|
98
|
+
print.success(`Created subgraph: ${subgraphName}`)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
92
101
|
},
|
|
93
102
|
}
|
|
@@ -2,7 +2,7 @@ import { Binary } from 'binary-install-raw'
|
|
|
2
2
|
import os from 'os'
|
|
3
3
|
import chalk from 'chalk'
|
|
4
4
|
import fetch from 'node-fetch'
|
|
5
|
-
import { filesystem, patching, print, system } from 'gluegun'
|
|
5
|
+
import { filesystem, GluegunToolbox, patching, print, system } from 'gluegun'
|
|
6
6
|
import { fixParameters } from '../command-helpers/gluegun'
|
|
7
7
|
import path from 'path'
|
|
8
8
|
import semver from 'semver'
|
|
@@ -22,14 +22,46 @@ ${chalk.dim('Options:')}
|
|
|
22
22
|
-v, --version <tag> Choose the version of the rust binary that you want to be downloaded/used
|
|
23
23
|
`
|
|
24
24
|
|
|
25
|
+
export interface TestOptions {
|
|
26
|
+
coverage?: boolean
|
|
27
|
+
docker?: boolean
|
|
28
|
+
force?: boolean
|
|
29
|
+
help?: boolean
|
|
30
|
+
logs?: boolean
|
|
31
|
+
recompile?: boolean
|
|
32
|
+
version?: string
|
|
33
|
+
// not a cli arg
|
|
34
|
+
testsFolder: string
|
|
35
|
+
cachePath: string
|
|
36
|
+
latestVersion?: string
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
export default {
|
|
26
40
|
description: 'Runs rust binary for subgraph testing',
|
|
27
|
-
run: async toolbox => {
|
|
41
|
+
run: async (toolbox: GluegunToolbox) => {
|
|
28
42
|
// Read CLI parameters
|
|
29
|
-
let {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
let {
|
|
44
|
+
c,
|
|
45
|
+
coverage,
|
|
46
|
+
d,
|
|
47
|
+
docker,
|
|
48
|
+
f,
|
|
49
|
+
force,
|
|
50
|
+
h,
|
|
51
|
+
help,
|
|
52
|
+
l,
|
|
53
|
+
logs,
|
|
54
|
+
r,
|
|
55
|
+
recompile,
|
|
56
|
+
v,
|
|
57
|
+
version,
|
|
58
|
+
} = toolbox.parameters.options
|
|
59
|
+
|
|
60
|
+
const testsFolder = './tests'
|
|
61
|
+
let opts: TestOptions = {
|
|
62
|
+
testsFolder,
|
|
63
|
+
cachePath: path.join(testsFolder, '.latest.json'),
|
|
64
|
+
}
|
|
33
65
|
// Support both long and short option variants
|
|
34
66
|
opts.coverage = coverage || c
|
|
35
67
|
opts.docker = docker || d
|
|
@@ -38,7 +70,6 @@ export default {
|
|
|
38
70
|
opts.logs = logs || l
|
|
39
71
|
opts.recompile = recompile || r
|
|
40
72
|
opts.version = version || v
|
|
41
|
-
opts.testsFolder = './tests'
|
|
42
73
|
// Fix if a boolean flag (e.g -c, --coverage) has an argument
|
|
43
74
|
try {
|
|
44
75
|
fixParameters(toolbox.parameters, {
|
|
@@ -61,7 +92,7 @@ export default {
|
|
|
61
92
|
return
|
|
62
93
|
}
|
|
63
94
|
|
|
64
|
-
let datasource = toolbox.parameters.first || toolbox.parameters.array[0]
|
|
95
|
+
let datasource = toolbox.parameters.first || toolbox.parameters.array?.[0]
|
|
65
96
|
// Show help text if requested
|
|
66
97
|
if (opts.help) {
|
|
67
98
|
print.info(HELP)
|
|
@@ -72,7 +103,7 @@ export default {
|
|
|
72
103
|
if (filesystem.exists('matchstick.yaml')) {
|
|
73
104
|
try {
|
|
74
105
|
// Load the config
|
|
75
|
-
let config = await yaml.load(filesystem.read('matchstick.yaml', 'utf8'))
|
|
106
|
+
let config = await yaml.load(filesystem.read('matchstick.yaml', 'utf8')!)
|
|
76
107
|
|
|
77
108
|
// Check if matchstick.yaml and testsFolder not null
|
|
78
109
|
if (config && config.testsFolder) {
|
|
@@ -88,7 +119,6 @@ export default {
|
|
|
88
119
|
}
|
|
89
120
|
}
|
|
90
121
|
|
|
91
|
-
opts.cachePath = path.join(opts.testsFolder, '.latest.json')
|
|
92
122
|
setVersionFromCache(opts)
|
|
93
123
|
|
|
94
124
|
// Fetch the latest version tag if version is not specified with -v/--version or if the version is not cached
|
|
@@ -116,7 +146,7 @@ export default {
|
|
|
116
146
|
},
|
|
117
147
|
}
|
|
118
148
|
|
|
119
|
-
async function setVersionFromCache(opts) {
|
|
149
|
+
async function setVersionFromCache(opts: TestOptions) {
|
|
120
150
|
if (filesystem.exists(opts.cachePath) == 'file') {
|
|
121
151
|
let cached = filesystem.read(opts.cachePath, 'json')
|
|
122
152
|
// Get the cache age in days
|
|
@@ -128,7 +158,7 @@ async function setVersionFromCache(opts) {
|
|
|
128
158
|
}
|
|
129
159
|
}
|
|
130
160
|
|
|
131
|
-
async function runBinary(datasource, opts) {
|
|
161
|
+
async function runBinary(datasource: string | undefined, opts: TestOptions) {
|
|
132
162
|
let coverageOpt = opts.coverage
|
|
133
163
|
let forceOpt = opts.force
|
|
134
164
|
let logsOpt = opts.logs
|
|
@@ -138,9 +168,8 @@ async function runBinary(datasource, opts) {
|
|
|
138
168
|
|
|
139
169
|
const platform = await getPlatform(logsOpt)
|
|
140
170
|
|
|
141
|
-
const url = `https://github.com/LimeChain/matchstick/releases/download/${
|
|
142
|
-
|
|
143
|
-
}/${platform}`
|
|
171
|
+
const url = `https://github.com/LimeChain/matchstick/releases/download/${versionOpt ||
|
|
172
|
+
latestVersion}/${platform}`
|
|
144
173
|
|
|
145
174
|
if (logsOpt) {
|
|
146
175
|
print.info(`Download link: ${url}`)
|
|
@@ -156,7 +185,7 @@ async function runBinary(datasource, opts) {
|
|
|
156
185
|
args.length > 0 ? binary.run(...args) : binary.run()
|
|
157
186
|
}
|
|
158
187
|
|
|
159
|
-
async function getPlatform(logsOpt) {
|
|
188
|
+
async function getPlatform(logsOpt: boolean | undefined) {
|
|
160
189
|
const type = os.type()
|
|
161
190
|
const arch = os.arch()
|
|
162
191
|
const cpuCore = os.cpus()[0]
|
|
@@ -164,13 +193,12 @@ async function getPlatform(logsOpt) {
|
|
|
164
193
|
const linuxInfo = type === 'Linux' ? await getLinuxInfo() : {}
|
|
165
194
|
const linuxDistro = linuxInfo.name
|
|
166
195
|
const release = linuxInfo.version || os.release()
|
|
167
|
-
const majorVersion = parseInt(linuxInfo.version, 10) || semver.major(release)
|
|
196
|
+
const majorVersion = parseInt(linuxInfo.version || '', 10) || semver.major(release)
|
|
168
197
|
|
|
169
198
|
if (logsOpt) {
|
|
170
199
|
print.info(
|
|
171
|
-
`OS type: ${
|
|
172
|
-
|
|
173
|
-
}\nOS arch: ${arch}\nOS release: ${release}\nOS major version: ${majorVersion}\nCPU model: ${
|
|
200
|
+
`OS type: ${linuxDistro ||
|
|
201
|
+
type}\nOS arch: ${arch}\nOS release: ${release}\nOS major version: ${majorVersion}\nCPU model: ${
|
|
174
202
|
cpuCore.model
|
|
175
203
|
}`,
|
|
176
204
|
)
|
|
@@ -199,7 +227,21 @@ async function getPlatform(logsOpt) {
|
|
|
199
227
|
throw new Error(`Unsupported platform: ${type} ${arch} ${majorVersion}`)
|
|
200
228
|
}
|
|
201
229
|
|
|
202
|
-
|
|
230
|
+
/**
|
|
231
|
+
* The result of running `cat /etc/*-release | grep -E '(^VERSION|^NAME)='`
|
|
232
|
+
*
|
|
233
|
+
* May look like this:
|
|
234
|
+
* ```sh
|
|
235
|
+
* NAME="Ubuntu"
|
|
236
|
+
* VERSION="16.04.7 LTS (Xenial Xerus)"
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
interface LinuxInfo {
|
|
240
|
+
name?: string
|
|
241
|
+
version?: string
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function getLinuxInfo(): Promise<LinuxInfo> {
|
|
203
245
|
try {
|
|
204
246
|
let result = await system.run("cat /etc/*-release | grep -E '(^VERSION|^NAME)='", {
|
|
205
247
|
trim: true,
|
|
@@ -208,10 +250,10 @@ async function getLinuxInfo() {
|
|
|
208
250
|
.replace(/['"]+/g, '')
|
|
209
251
|
.split('\n')
|
|
210
252
|
.map(p => p.split('='))
|
|
211
|
-
let linuxInfo = {}
|
|
253
|
+
let linuxInfo: LinuxInfo = {}
|
|
212
254
|
|
|
213
255
|
infoArray.forEach(val => {
|
|
214
|
-
linuxInfo[val[0].toLowerCase()] = val[1]
|
|
256
|
+
linuxInfo[val[0].toLowerCase() as keyof LinuxInfo] = val[1]
|
|
215
257
|
})
|
|
216
258
|
|
|
217
259
|
return linuxInfo
|
|
@@ -221,7 +263,7 @@ async function getLinuxInfo() {
|
|
|
221
263
|
}
|
|
222
264
|
}
|
|
223
265
|
|
|
224
|
-
async function runDocker(datasource, opts) {
|
|
266
|
+
async function runDocker(datasource: string | undefined, opts: TestOptions) {
|
|
225
267
|
let coverageOpt = opts.coverage
|
|
226
268
|
let forceOpt = opts.force
|
|
227
269
|
let versionOpt = opts.version
|
|
@@ -230,10 +272,10 @@ async function runDocker(datasource, opts) {
|
|
|
230
272
|
|
|
231
273
|
// Remove binary-install-raw binaries, because docker has permission issues
|
|
232
274
|
// when building the docker images
|
|
233
|
-
|
|
275
|
+
filesystem.remove('./node_modules/binary-install-raw/bin')
|
|
234
276
|
|
|
235
277
|
// Get current working directory
|
|
236
|
-
let current_folder =
|
|
278
|
+
let current_folder = filesystem.cwd()
|
|
237
279
|
|
|
238
280
|
// Declate dockerfilePath with default location
|
|
239
281
|
let dockerfilePath = path.join(opts.testsFolder || 'tests', '.docker/Dockerfile')
|
|
@@ -248,7 +290,7 @@ async function runDocker(datasource, opts) {
|
|
|
248
290
|
}
|
|
249
291
|
|
|
250
292
|
// Run a command to check if matchstick image already exists
|
|
251
|
-
exec('docker images -q matchstick', (
|
|
293
|
+
exec('docker images -q matchstick', (_error, stdout, _stderr) => {
|
|
252
294
|
// Collect all(if any) flags and options that have to be passed to the matchstick binary
|
|
253
295
|
let testArgs = ''
|
|
254
296
|
if (coverageOpt) testArgs = testArgs + ' -c'
|
|
@@ -277,7 +319,7 @@ async function runDocker(datasource, opts) {
|
|
|
277
319
|
// Use spawn() and {stdio: 'inherit'} so we can see the logs in real time.
|
|
278
320
|
if (!dockerfileExists || stdout === '' || versionOpt || forceOpt) {
|
|
279
321
|
if (stdout !== '') {
|
|
280
|
-
exec('docker image rm matchstick', (
|
|
322
|
+
exec('docker image rm matchstick', (_error, stdout, _stderr) => {
|
|
281
323
|
print.info(chalk.bold(`Removing matchstick image\n${stdout}`))
|
|
282
324
|
})
|
|
283
325
|
}
|
|
@@ -300,7 +342,11 @@ async function runDocker(datasource, opts) {
|
|
|
300
342
|
|
|
301
343
|
// Downloads Dockerfile template from the demo-subgraph repo
|
|
302
344
|
// Replaces the placeholders with their respective values
|
|
303
|
-
async function dockerfile(
|
|
345
|
+
async function dockerfile(
|
|
346
|
+
dockerfilePath: string,
|
|
347
|
+
versionOpt: string | undefined,
|
|
348
|
+
latestVersion: string | undefined,
|
|
349
|
+
) {
|
|
304
350
|
let spinner = print.spin('Generating Dockerfile...')
|
|
305
351
|
|
|
306
352
|
try {
|
|
@@ -318,13 +364,13 @@ async function dockerfile(dockerfilePath, versionOpt, latestVersion) {
|
|
|
318
364
|
})
|
|
319
365
|
|
|
320
366
|
// Write the Dockerfile
|
|
321
|
-
|
|
367
|
+
filesystem.write(dockerfilePath, content)
|
|
322
368
|
|
|
323
369
|
// Replaces the version placeholders
|
|
324
370
|
await patching.replace(
|
|
325
371
|
dockerfilePath,
|
|
326
372
|
'<MATCHSTICK_VERSION>',
|
|
327
|
-
versionOpt || latestVersion,
|
|
373
|
+
versionOpt || latestVersion || 'unknown',
|
|
328
374
|
)
|
|
329
375
|
} catch (error) {
|
|
330
376
|
spinner.fail(
|
package/src/subgraph.ts
CHANGED
|
@@ -275,7 +275,7 @@ More than one template named '${name}', template names must be unique.`,
|
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
let manifest = immutable.fromJS(data)
|
|
278
|
+
let manifest = immutable.fromJS(data) as immutable.Map<any, any>
|
|
279
279
|
|
|
280
280
|
// Validate the schema
|
|
281
281
|
Subgraph.validateSchema(manifest, { resolveFile })
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare module 'spawn-command' {
|
|
2
|
+
import { spawn, SpawnOptions, ChildProcessByStdio, StdioPipe } from 'child_process'
|
|
3
|
+
type SpawnResult = ChildProcessByStdio<Writable, Readable, Readable>
|
|
4
|
+
export { SpawnOptions, SpawnResult }
|
|
5
|
+
export default function spawn(command: string, options: SpawnOptions): SpawnResult
|
|
6
|
+
}
|
|
@@ -6,20 +6,30 @@ import stripAnsi from 'strip-ansi'
|
|
|
6
6
|
// Deletes folder if:
|
|
7
7
|
// - flag is true
|
|
8
8
|
// - folder exists
|
|
9
|
-
const deleteDir = (dir, flag) => {
|
|
9
|
+
const deleteDir = (dir: string, flag: boolean) => {
|
|
10
10
|
if (flag && fs.existsSync(dir)) {
|
|
11
11
|
fs.removeSync(dir)
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const resolvePath = p => path.join(__dirname, p)
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const resolvePath = (p: string) => path.join(__dirname, p)
|
|
16
|
+
|
|
17
|
+
export function cliTest(
|
|
18
|
+
title: string,
|
|
19
|
+
args: string[],
|
|
20
|
+
testPath: string,
|
|
21
|
+
options: {
|
|
22
|
+
cwd?: string
|
|
23
|
+
deleteDir?: boolean
|
|
24
|
+
exitCode?: number
|
|
25
|
+
timeout?: number
|
|
26
|
+
} = {},
|
|
27
|
+
) {
|
|
18
28
|
test(
|
|
19
29
|
title,
|
|
20
30
|
async () => {
|
|
21
31
|
try {
|
|
22
|
-
deleteDir(resolvePath(`./${testPath}`), options.deleteDir)
|
|
32
|
+
deleteDir(resolvePath(`./${testPath}`), !!options.deleteDir)
|
|
23
33
|
|
|
24
34
|
// Use the provided cwd if desired
|
|
25
35
|
let cwd = options.cwd ? options.cwd : resolvePath(`./${testPath}`)
|
|
@@ -62,14 +72,24 @@ const cliTest = (title, args, testPath, options = {}) => {
|
|
|
62
72
|
expect(stripAnsi(stdout)).toBe(expectedStdout)
|
|
63
73
|
}
|
|
64
74
|
} finally {
|
|
65
|
-
deleteDir(resolvePath(`./${testPath}`), options.deleteDir)
|
|
75
|
+
deleteDir(resolvePath(`./${testPath}`), !!options.deleteDir)
|
|
66
76
|
}
|
|
67
77
|
},
|
|
68
78
|
options.timeout || undefined,
|
|
69
79
|
)
|
|
70
80
|
}
|
|
71
81
|
|
|
72
|
-
|
|
82
|
+
function runCommand(
|
|
83
|
+
command: string,
|
|
84
|
+
args: string[] = [],
|
|
85
|
+
cwd = process.cwd(),
|
|
86
|
+
): Promise<
|
|
87
|
+
[
|
|
88
|
+
number | null, // exitCode
|
|
89
|
+
string, // stdout
|
|
90
|
+
string, // stderr
|
|
91
|
+
]
|
|
92
|
+
> {
|
|
73
93
|
// Make sure to set an absolute working directory
|
|
74
94
|
cwd = cwd[0] !== '/' ? path.resolve(__dirname, cwd) : cwd
|
|
75
95
|
|
|
@@ -82,11 +102,11 @@ const runCommand = async (command, args = [], cwd = process.cwd()) => {
|
|
|
82
102
|
reject(error)
|
|
83
103
|
})
|
|
84
104
|
|
|
85
|
-
child.stdout.on('data', data => {
|
|
105
|
+
child.stdout.on('data', (data: Buffer) => {
|
|
86
106
|
stdout += data.toString()
|
|
87
107
|
})
|
|
88
108
|
|
|
89
|
-
child.stderr.on('data', data => {
|
|
109
|
+
child.stderr.on('data', (data: Buffer) => {
|
|
90
110
|
stderr += data.toString()
|
|
91
111
|
})
|
|
92
112
|
|
|
@@ -96,15 +116,13 @@ const runCommand = async (command, args = [], cwd = process.cwd()) => {
|
|
|
96
116
|
})
|
|
97
117
|
}
|
|
98
118
|
|
|
99
|
-
|
|
119
|
+
export function runGraphCli(args: string[], cwd: string) {
|
|
100
120
|
// Resolve the path to graph.js
|
|
101
121
|
let graphCli = path.join(__dirname, '..', '..', 'dist', 'bin.js')
|
|
102
122
|
|
|
103
|
-
return
|
|
123
|
+
return runCommand(graphCli, args, cwd)
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
const npmLinkCli = () => runCommand('npm', ['link'])
|
|
107
|
-
|
|
108
|
-
const npmUnlinkCli = () => runCommand('npm', ['unlink'])
|
|
126
|
+
export const npmLinkCli = () => runCommand('npm', ['link'])
|
|
109
127
|
|
|
110
|
-
export
|
|
128
|
+
export const npmUnlinkCli = () => runCommand('npm', ['unlink'])
|
|
File without changes
|