@graphprotocol/graph-cli 0.37.4 → 0.37.5
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 +8 -0
- package/dist/bin.js +6 -0
- package/dist/cli.js +26 -0
- package/dist/codegen/schema.js +244 -0
- package/dist/codegen/schema.test.js +455 -0
- package/dist/codegen/template.js +66 -0
- package/dist/codegen/types/conversions.js +335 -0
- package/dist/codegen/types/index.js +71 -0
- package/dist/codegen/types/index.test.js +563 -0
- package/dist/codegen/typescript.js +200 -0
- package/dist/codegen/util.js +40 -0
- package/dist/codegen/util.test.js +93 -0
- package/dist/command-helpers/abi.js +76 -0
- package/dist/command-helpers/auth.js +76 -0
- package/dist/command-helpers/compiler.js +66 -0
- package/dist/command-helpers/data-sources.js +29 -0
- package/dist/command-helpers/fs.js +9 -0
- package/dist/command-helpers/gluegun.js +48 -0
- package/dist/command-helpers/ipfs.js +5 -0
- package/dist/command-helpers/jsonrpc.js +27 -0
- package/dist/command-helpers/network.js +90 -0
- package/dist/command-helpers/network.test.js +86 -0
- package/dist/command-helpers/node.js +40 -0
- package/dist/command-helpers/scaffold.js +110 -0
- package/dist/command-helpers/spinner.js +80 -0
- package/dist/command-helpers/studio.js +14 -0
- package/dist/command-helpers/studio.test.js +41 -0
- package/dist/command-helpers/subgraph.js +22 -0
- package/dist/command-helpers/version.js +66 -0
- package/dist/command-helpers/version.test.js +186 -0
- package/dist/commands/add.js +187 -0
- package/dist/commands/auth.js +122 -0
- package/dist/commands/build.js +136 -0
- package/dist/commands/codegen.js +128 -0
- package/dist/commands/create.js +94 -0
- package/dist/commands/deploy.js +335 -0
- package/dist/commands/init.js +800 -0
- package/dist/commands/local.js +380 -0
- package/dist/commands/remove.js +95 -0
- package/dist/commands/test.js +293 -0
- package/dist/compiler/asc.js +83 -0
- package/dist/compiler/index.js +466 -0
- package/dist/debug.js +16 -0
- package/dist/migrations/mapping_api_version_0_0_1.js +83 -0
- package/dist/migrations/mapping_api_version_0_0_2.js +83 -0
- package/dist/migrations/mapping_api_version_0_0_3.js +83 -0
- package/dist/migrations/mapping_api_version_0_0_4.js +85 -0
- package/dist/migrations/mapping_api_version_0_0_5.js +85 -0
- package/dist/migrations/spec_version_0_0_2.js +45 -0
- package/dist/migrations/spec_version_0_0_3.js +50 -0
- package/dist/migrations/util/load-manifest.js +16 -0
- package/dist/migrations/util/versions.js +28 -0
- package/dist/migrations.js +54 -0
- package/dist/protocols/arweave/manifest.graphql +57 -0
- package/dist/protocols/arweave/scaffold/manifest.js +18 -0
- package/dist/protocols/arweave/scaffold/mapping.js +52 -0
- package/dist/protocols/arweave/subgraph.js +23 -0
- package/dist/protocols/contract.js +2 -0
- package/dist/protocols/cosmos/manifest.graphql +76 -0
- package/dist/protocols/cosmos/scaffold/manifest.js +15 -0
- package/dist/protocols/cosmos/scaffold/mapping.js +38 -0
- package/dist/protocols/cosmos/subgraph.js +28 -0
- package/dist/protocols/ethereum/abi.js +138 -0
- package/dist/protocols/ethereum/codegen/abi.js +474 -0
- package/dist/protocols/ethereum/codegen/abi.test.js +325 -0
- package/dist/protocols/ethereum/codegen/template.js +52 -0
- package/dist/protocols/ethereum/contract.js +22 -0
- package/dist/protocols/ethereum/manifest.graphql +94 -0
- package/dist/protocols/ethereum/scaffold/manifest.js +32 -0
- package/dist/protocols/ethereum/scaffold/mapping.js +65 -0
- package/dist/protocols/ethereum/subgraph.js +172 -0
- package/dist/protocols/ethereum/type-generator.js +123 -0
- package/dist/protocols/index.js +266 -0
- package/dist/protocols/ipfs/codegen/file_template.js +53 -0
- package/dist/protocols/near/contract.js +41 -0
- package/dist/protocols/near/manifest.graphql +64 -0
- package/dist/protocols/near/scaffold/manifest.js +16 -0
- package/dist/protocols/near/scaffold/mapping.js +38 -0
- package/dist/protocols/near/subgraph.js +23 -0
- package/dist/protocols/subgraph.js +2 -0
- package/dist/protocols/substreams/manifest.graphql +45 -0
- package/dist/protocols/substreams/scaffold/manifest.js +12 -0
- package/dist/protocols/substreams/subgraph.js +23 -0
- package/dist/scaffold/cosmos.test.js +82 -0
- package/dist/scaffold/ethereum.test.js +496 -0
- package/dist/scaffold/index.js +133 -0
- package/dist/scaffold/mapping.js +57 -0
- package/dist/scaffold/near.test.js +85 -0
- package/dist/scaffold/schema.js +86 -0
- package/dist/scaffold/tests.js +179 -0
- package/dist/schema.js +54 -0
- package/dist/subgraph.js +243 -0
- package/dist/type-generator.js +225 -0
- package/dist/validation/contract.js +44 -0
- package/dist/validation/index.js +10 -0
- package/dist/validation/manifest.js +266 -0
- package/dist/validation/schema.js +768 -0
- package/dist/validation/schema.test.js +35 -0
- package/dist/watcher.js +79 -0
- package/package.json +1 -1
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
30
|
+
const path_1 = __importDefault(require("path"));
|
|
31
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
32
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
33
|
+
const toolbox = __importStar(require("gluegun"));
|
|
34
|
+
const immutable_1 = __importDefault(require("immutable"));
|
|
35
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
36
|
+
const spinner_1 = require("../command-helpers/spinner");
|
|
37
|
+
const debug_1 = __importDefault(require("../debug"));
|
|
38
|
+
const migrations_1 = require("../migrations");
|
|
39
|
+
const subgraph_1 = __importDefault(require("../subgraph"));
|
|
40
|
+
const watcher_1 = __importDefault(require("../watcher"));
|
|
41
|
+
const asc = __importStar(require("./asc"));
|
|
42
|
+
const compilerDebug = (0, debug_1.default)('graph-cli:compiler');
|
|
43
|
+
class Compiler {
|
|
44
|
+
options;
|
|
45
|
+
ipfs;
|
|
46
|
+
sourceDir;
|
|
47
|
+
blockIpfsMethods;
|
|
48
|
+
libsDirs;
|
|
49
|
+
globalsFile;
|
|
50
|
+
protocol;
|
|
51
|
+
ABI;
|
|
52
|
+
constructor(options) {
|
|
53
|
+
this.options = options;
|
|
54
|
+
this.options = options;
|
|
55
|
+
this.ipfs = options.ipfs;
|
|
56
|
+
this.sourceDir = path_1.default.dirname(options.subgraphManifest);
|
|
57
|
+
this.blockIpfsMethods = options.blockIpfsMethods;
|
|
58
|
+
this.libsDirs = [];
|
|
59
|
+
if (options.protocol.name !== 'substreams') {
|
|
60
|
+
for (let dir = path_1.default.resolve(this.sourceDir);
|
|
61
|
+
// Terminate after the root dir or when we have found node_modules
|
|
62
|
+
dir !== undefined;
|
|
63
|
+
// Continue with the parent directory, terminate after the root dir
|
|
64
|
+
dir = path_1.default.dirname(dir) === dir ? undefined : path_1.default.dirname(dir)) {
|
|
65
|
+
if (fs_extra_1.default.existsSync(path_1.default.join(dir, 'node_modules'))) {
|
|
66
|
+
this.libsDirs.push(path_1.default.join(dir, 'node_modules'));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (this.libsDirs.length === 0) {
|
|
70
|
+
throw Error(`could not locate \`node_modules\` in parent directories of subgraph manifest`);
|
|
71
|
+
}
|
|
72
|
+
const globalsFile = path_1.default.join('@graphprotocol', 'graph-ts', 'global', 'global.ts');
|
|
73
|
+
const globalsLib = this.libsDirs.find(item => {
|
|
74
|
+
return fs_extra_1.default.existsSync(path_1.default.join(item, globalsFile));
|
|
75
|
+
});
|
|
76
|
+
if (!globalsLib) {
|
|
77
|
+
throw Error('Could not locate `@graphprotocol/graph-ts` package in parent directories of subgraph manifest.');
|
|
78
|
+
}
|
|
79
|
+
this.globalsFile = path_1.default.join(globalsLib, globalsFile);
|
|
80
|
+
}
|
|
81
|
+
// @ts-expect-error assigned or not, we dont care
|
|
82
|
+
if (!this.globalsFile) {
|
|
83
|
+
throw new Error('Globals file is missing.');
|
|
84
|
+
}
|
|
85
|
+
this.protocol = this.options.protocol;
|
|
86
|
+
this.ABI = this.protocol.getABI();
|
|
87
|
+
process.on('uncaughtException', e => {
|
|
88
|
+
toolbox.print.error(`UNCAUGHT EXCEPTION: ${e}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
subgraphDir(parent, subgraph) {
|
|
92
|
+
return path_1.default.join(parent, subgraph.get('name'));
|
|
93
|
+
}
|
|
94
|
+
displayPath(p) {
|
|
95
|
+
return path_1.default.relative(process.cwd(), p);
|
|
96
|
+
}
|
|
97
|
+
cacheKeyForFile(filename) {
|
|
98
|
+
const hash = crypto_1.default.createHash('sha1');
|
|
99
|
+
hash.update(fs_extra_1.default.readFileSync(filename));
|
|
100
|
+
return hash.digest('hex');
|
|
101
|
+
}
|
|
102
|
+
async compile() {
|
|
103
|
+
try {
|
|
104
|
+
if (!this.options.skipMigrations) {
|
|
105
|
+
await (0, migrations_1.applyMigrations)({
|
|
106
|
+
sourceDir: this.sourceDir,
|
|
107
|
+
manifestFile: this.options.subgraphManifest,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const subgraph = await this.loadSubgraph();
|
|
111
|
+
const compiledSubgraph = await this.compileSubgraph(subgraph);
|
|
112
|
+
const localSubgraph = await this.writeSubgraphToOutputDirectory(this.options.protocol, compiledSubgraph);
|
|
113
|
+
if (this.ipfs !== undefined) {
|
|
114
|
+
const ipfsHash = await this.uploadSubgraphToIPFS(localSubgraph);
|
|
115
|
+
this.completed(ipfsHash);
|
|
116
|
+
return ipfsHash;
|
|
117
|
+
}
|
|
118
|
+
this.completed(path_1.default.join(this.options.outputDir, 'subgraph.yaml'));
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
toolbox.print.error(e);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
completed(ipfsHashOrPath) {
|
|
127
|
+
toolbox.print.info('');
|
|
128
|
+
toolbox.print.success(`Build completed: ${chalk_1.default.blue(ipfsHashOrPath)}`);
|
|
129
|
+
toolbox.print.info('');
|
|
130
|
+
}
|
|
131
|
+
async loadSubgraph({ quiet } = { quiet: false }) {
|
|
132
|
+
const subgraphLoadOptions = { protocol: this.protocol, skipValidation: false };
|
|
133
|
+
if (quiet) {
|
|
134
|
+
return (await subgraph_1.default.load(this.options.subgraphManifest, subgraphLoadOptions)).result;
|
|
135
|
+
}
|
|
136
|
+
const manifestPath = this.displayPath(this.options.subgraphManifest);
|
|
137
|
+
return await (0, spinner_1.withSpinner)(`Load subgraph from ${manifestPath}`, `Failed to load subgraph from ${manifestPath}`, `Warnings loading subgraph from ${manifestPath}`, async () => {
|
|
138
|
+
return subgraph_1.default.load(this.options.subgraphManifest, subgraphLoadOptions);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async getFilesToWatch() {
|
|
142
|
+
try {
|
|
143
|
+
const files = [];
|
|
144
|
+
const subgraph = await this.loadSubgraph({ quiet: true });
|
|
145
|
+
// Add the subgraph manifest file
|
|
146
|
+
files.push(this.options.subgraphManifest);
|
|
147
|
+
// Add all file paths specified in manifest
|
|
148
|
+
files.push(path_1.default.resolve(subgraph.getIn(['schema', 'file'])));
|
|
149
|
+
subgraph.get('dataSources').map((dataSource) => {
|
|
150
|
+
files.push(dataSource.getIn(['mapping', 'file']));
|
|
151
|
+
// Only watch ABI related files if the target protocol has support/need for them.
|
|
152
|
+
if (this.protocol.hasABIs()) {
|
|
153
|
+
dataSource.getIn(['mapping', 'abis']).map((abi) => {
|
|
154
|
+
files.push(abi.get('file'));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// Make paths absolute
|
|
159
|
+
return files.map(file => path_1.default.resolve(file));
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
throw Error(`Failed to load subgraph: ${e.message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async watchAndCompile(onCompiled) {
|
|
166
|
+
const compiler = this;
|
|
167
|
+
let spinner;
|
|
168
|
+
// Create watcher and recompile once and then on every change to a watched file
|
|
169
|
+
const watcher = new watcher_1.default({
|
|
170
|
+
onReady: () => (spinner = toolbox.print.spin('Watching subgraph files')),
|
|
171
|
+
onTrigger: async (changedFile) => {
|
|
172
|
+
if (changedFile !== undefined) {
|
|
173
|
+
spinner.info(`File change detected: ${this.displayPath(changedFile)}\n`);
|
|
174
|
+
}
|
|
175
|
+
const ipfsHash = await compiler.compile();
|
|
176
|
+
onCompiled?.(ipfsHash);
|
|
177
|
+
spinner.start();
|
|
178
|
+
},
|
|
179
|
+
onCollectFiles: async () => await compiler.getFilesToWatch(),
|
|
180
|
+
onError: error => {
|
|
181
|
+
spinner.stop();
|
|
182
|
+
toolbox.print.error(`${error.message}\n`);
|
|
183
|
+
spinner.start();
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
// Catch keyboard interrupt: close watcher and exit process
|
|
187
|
+
process.on('SIGINT', () => {
|
|
188
|
+
watcher.close();
|
|
189
|
+
process.exit();
|
|
190
|
+
});
|
|
191
|
+
try {
|
|
192
|
+
await watcher.watch();
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
toolbox.print.error(String(e.message));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
_writeSubgraphFile(maybeRelativeFile, data, sourceDir, targetDir, spinner) {
|
|
199
|
+
const absoluteSourceFile = path_1.default.resolve(sourceDir, maybeRelativeFile);
|
|
200
|
+
const relativeSourceFile = path_1.default.relative(sourceDir, absoluteSourceFile);
|
|
201
|
+
const targetFile = path_1.default.join(targetDir, relativeSourceFile);
|
|
202
|
+
(0, spinner_1.step)(spinner, 'Write subgraph file', this.displayPath(targetFile));
|
|
203
|
+
fs_extra_1.default.mkdirsSync(path_1.default.dirname(targetFile));
|
|
204
|
+
fs_extra_1.default.writeFileSync(targetFile, data);
|
|
205
|
+
return targetFile;
|
|
206
|
+
}
|
|
207
|
+
async compileSubgraph(subgraph) {
|
|
208
|
+
return await (0, spinner_1.withSpinner)(`Compile subgraph`, `Failed to compile subgraph`, `Warnings while compiling subgraph`, async (spinner) => {
|
|
209
|
+
// Cache compiled files so identical input files are only compiled once
|
|
210
|
+
const compiledFiles = new Map();
|
|
211
|
+
await asc.ready();
|
|
212
|
+
subgraph = subgraph.update('dataSources', (dataSources) => dataSources.map((dataSource) => dataSource.updateIn(['mapping', 'file'], (mappingPath) => this._compileDataSourceMapping(this.protocol, dataSource, mappingPath, compiledFiles, spinner))));
|
|
213
|
+
subgraph = subgraph.update('templates', (templates) => templates === undefined
|
|
214
|
+
? templates
|
|
215
|
+
: templates.map((template) => template.updateIn(['mapping', 'file'], (mappingPath) => this._compileTemplateMapping(template, mappingPath, compiledFiles, spinner))));
|
|
216
|
+
return subgraph;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
_compileDataSourceMapping(protocol, dataSource, mappingPath, compiledFiles, spinner) {
|
|
220
|
+
if (protocol.name == 'substreams') {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const dataSourceName = dataSource.getIn(['name']);
|
|
225
|
+
const baseDir = this.sourceDir;
|
|
226
|
+
const absoluteMappingPath = path_1.default.resolve(baseDir, mappingPath);
|
|
227
|
+
const inputFile = path_1.default.relative(baseDir, absoluteMappingPath);
|
|
228
|
+
this._validateMappingContent(absoluteMappingPath);
|
|
229
|
+
// If the file has already been compiled elsewhere, just use that output
|
|
230
|
+
// file and return early
|
|
231
|
+
const inputCacheKey = this.cacheKeyForFile(absoluteMappingPath);
|
|
232
|
+
const alreadyCompiled = compiledFiles.has(inputCacheKey);
|
|
233
|
+
if (alreadyCompiled) {
|
|
234
|
+
const outFile = compiledFiles.get(inputCacheKey);
|
|
235
|
+
(0, spinner_1.step)(spinner, 'Compile data source:', `${dataSourceName} => ${this.displayPath(outFile)} (already compiled)`);
|
|
236
|
+
return outFile;
|
|
237
|
+
}
|
|
238
|
+
const outFile = path_1.default.resolve(this.subgraphDir(this.options.outputDir, dataSource), this.options.outputFormat == 'wasm' ? `${dataSourceName}.wasm` : `${dataSourceName}.wast`);
|
|
239
|
+
(0, spinner_1.step)(spinner, 'Compile data source:', `${dataSourceName} => ${this.displayPath(outFile)}`);
|
|
240
|
+
const outputFile = path_1.default.relative(baseDir, outFile);
|
|
241
|
+
// Create output directory
|
|
242
|
+
fs_extra_1.default.mkdirsSync(path_1.default.dirname(outFile));
|
|
243
|
+
const libs = this.libsDirs.join(',');
|
|
244
|
+
const global = path_1.default.relative(baseDir, this.globalsFile);
|
|
245
|
+
asc.compile({
|
|
246
|
+
inputFile,
|
|
247
|
+
global,
|
|
248
|
+
baseDir,
|
|
249
|
+
libs,
|
|
250
|
+
outputFile,
|
|
251
|
+
});
|
|
252
|
+
// Remember the output file to avoid compiling the same file again
|
|
253
|
+
compiledFiles.set(inputCacheKey, outFile);
|
|
254
|
+
return outFile;
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
throw Error(`Failed to compile data source mapping: ${e.message}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
_compileTemplateMapping(template, mappingPath, compiledFiles, spinner) {
|
|
261
|
+
try {
|
|
262
|
+
const templateName = template.get('name');
|
|
263
|
+
const baseDir = this.sourceDir;
|
|
264
|
+
const absoluteMappingPath = path_1.default.resolve(baseDir, mappingPath);
|
|
265
|
+
const inputFile = path_1.default.relative(baseDir, absoluteMappingPath);
|
|
266
|
+
this._validateMappingContent(absoluteMappingPath);
|
|
267
|
+
// If the file has already been compiled elsewhere, just use that output
|
|
268
|
+
// file and return early
|
|
269
|
+
const inputCacheKey = this.cacheKeyForFile(absoluteMappingPath);
|
|
270
|
+
const alreadyCompiled = compiledFiles.has(inputCacheKey);
|
|
271
|
+
if (alreadyCompiled) {
|
|
272
|
+
const outFile = compiledFiles.get(inputCacheKey);
|
|
273
|
+
(0, spinner_1.step)(spinner, 'Compile data source template:', `${templateName} => ${this.displayPath(outFile)} (already compiled)`);
|
|
274
|
+
return outFile;
|
|
275
|
+
}
|
|
276
|
+
const outFile = path_1.default.resolve(this.options.outputDir, 'templates', templateName, this.options.outputFormat == 'wasm' ? `${templateName}.wasm` : `${templateName}.wast`);
|
|
277
|
+
(0, spinner_1.step)(spinner, 'Compile data source template:', `${templateName} => ${this.displayPath(outFile)}`);
|
|
278
|
+
const outputFile = path_1.default.relative(baseDir, outFile);
|
|
279
|
+
// Create output directory
|
|
280
|
+
fs_extra_1.default.mkdirsSync(path_1.default.dirname(outFile));
|
|
281
|
+
const libs = this.libsDirs.join(',');
|
|
282
|
+
const global = path_1.default.relative(baseDir, this.globalsFile);
|
|
283
|
+
asc.compile({
|
|
284
|
+
inputFile,
|
|
285
|
+
global,
|
|
286
|
+
baseDir,
|
|
287
|
+
libs,
|
|
288
|
+
outputFile,
|
|
289
|
+
});
|
|
290
|
+
// Remember the output file to avoid compiling the same file again
|
|
291
|
+
compiledFiles.set(inputCacheKey, outFile);
|
|
292
|
+
return outFile;
|
|
293
|
+
}
|
|
294
|
+
catch (e) {
|
|
295
|
+
throw Error(`Failed to compile data source template: ${e.message}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
_validateMappingContent(filePath) {
|
|
299
|
+
const data = fs_extra_1.default.readFileSync(filePath);
|
|
300
|
+
if (this.blockIpfsMethods && (data.includes('ipfs.cat') || data.includes('ipfs.map'))) {
|
|
301
|
+
throw Error(`
|
|
302
|
+
Subgraph Studio does not support mappings with ipfs methods.
|
|
303
|
+
Please remove all instances of ipfs.cat and ipfs.map from
|
|
304
|
+
${filePath}
|
|
305
|
+
`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
async writeSubgraphToOutputDirectory(protocol, subgraph) {
|
|
309
|
+
const displayDir = `${this.displayPath(this.options.outputDir)}${toolbox.filesystem.separator}`;
|
|
310
|
+
return await (0, spinner_1.withSpinner)(`Write compiled subgraph to ${displayDir}`, `Failed to write compiled subgraph to ${displayDir}`, `Warnings while writing compiled subgraph to ${displayDir}`, async (spinner) => {
|
|
311
|
+
// Copy schema and update its path
|
|
312
|
+
subgraph = subgraph.updateIn(['schema', 'file'], schemaFile => {
|
|
313
|
+
const schemaFilePath = path_1.default.resolve(this.sourceDir, schemaFile);
|
|
314
|
+
const schemaFileName = path_1.default.basename(schemaFile);
|
|
315
|
+
const targetFile = path_1.default.resolve(this.options.outputDir, schemaFileName);
|
|
316
|
+
(0, spinner_1.step)(spinner, 'Copy schema file', this.displayPath(targetFile));
|
|
317
|
+
fs_extra_1.default.copyFileSync(schemaFilePath, targetFile);
|
|
318
|
+
return path_1.default.relative(this.options.outputDir, targetFile);
|
|
319
|
+
});
|
|
320
|
+
// Copy data source files and update their paths
|
|
321
|
+
subgraph = subgraph.update('dataSources', (dataSources) => dataSources.map(dataSource => {
|
|
322
|
+
let updatedDataSource = dataSource;
|
|
323
|
+
if (this.protocol.hasABIs()) {
|
|
324
|
+
updatedDataSource = updatedDataSource
|
|
325
|
+
// Write data source ABIs to the output directory
|
|
326
|
+
.updateIn(['mapping', 'abis'], (abis) => abis.map((abi) => abi.update('file', (abiFile) => {
|
|
327
|
+
abiFile = path_1.default.resolve(this.sourceDir, abiFile);
|
|
328
|
+
const abiData = this.ABI.load(abi.get('name'), abiFile);
|
|
329
|
+
return path_1.default.relative(this.options.outputDir, this._writeSubgraphFile(abiFile, JSON.stringify(abiData.data.toJS(), null, 2), this.sourceDir, this.subgraphDir(this.options.outputDir, dataSource), spinner));
|
|
330
|
+
})));
|
|
331
|
+
}
|
|
332
|
+
if (protocol.name == 'substreams') {
|
|
333
|
+
updatedDataSource = updatedDataSource
|
|
334
|
+
// Write data source ABIs to the output directory
|
|
335
|
+
.updateIn(['source', 'package'], (substreamsPackage) => substreamsPackage.update('file', (packageFile) => {
|
|
336
|
+
packageFile = path_1.default.resolve(this.sourceDir, packageFile);
|
|
337
|
+
const packageContent = fs_extra_1.default.readFileSync(packageFile);
|
|
338
|
+
return path_1.default.relative(this.options.outputDir, this._writeSubgraphFile(packageFile, packageContent, this.sourceDir, this.subgraphDir(this.options.outputDir, dataSource), spinner));
|
|
339
|
+
}));
|
|
340
|
+
return updatedDataSource;
|
|
341
|
+
}
|
|
342
|
+
// The mapping file is already being written to the output
|
|
343
|
+
// directory by the AssemblyScript compiler
|
|
344
|
+
return updatedDataSource.updateIn(['mapping', 'file'], (mappingFile) => path_1.default.relative(this.options.outputDir, path_1.default.resolve(this.sourceDir, mappingFile)));
|
|
345
|
+
}));
|
|
346
|
+
// Copy template files and update their paths
|
|
347
|
+
subgraph = subgraph.update('templates', templates => templates === undefined
|
|
348
|
+
? templates
|
|
349
|
+
: templates.map((template) => {
|
|
350
|
+
let updatedTemplate = template;
|
|
351
|
+
if (this.protocol.hasABIs()) {
|
|
352
|
+
updatedTemplate = updatedTemplate
|
|
353
|
+
// Write template ABIs to the output directory
|
|
354
|
+
.updateIn(['mapping', 'abis'], (abis) => abis.map(abi => abi.update('file', (abiFile) => {
|
|
355
|
+
abiFile = path_1.default.resolve(this.sourceDir, abiFile);
|
|
356
|
+
const abiData = this.ABI.load(abi.get('name'), abiFile);
|
|
357
|
+
return path_1.default.relative(this.options.outputDir, this._writeSubgraphFile(abiFile, JSON.stringify(abiData.data.toJS(), null, 2), this.sourceDir, this.subgraphDir(this.options.outputDir, template), spinner));
|
|
358
|
+
})));
|
|
359
|
+
}
|
|
360
|
+
// The mapping file is already being written to the output
|
|
361
|
+
// directory by the AssemblyScript compiler
|
|
362
|
+
return updatedTemplate.updateIn(['mapping', 'file'], (mappingFile) => path_1.default.relative(this.options.outputDir, path_1.default.resolve(this.sourceDir, mappingFile)));
|
|
363
|
+
}));
|
|
364
|
+
// Write the subgraph manifest itself
|
|
365
|
+
const outputFilename = path_1.default.join(this.options.outputDir, 'subgraph.yaml');
|
|
366
|
+
(0, spinner_1.step)(spinner, 'Write subgraph manifest', this.displayPath(outputFilename));
|
|
367
|
+
await subgraph_1.default.write(subgraph, outputFilename);
|
|
368
|
+
return subgraph;
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async uploadSubgraphToIPFS(subgraph) {
|
|
372
|
+
return (0, spinner_1.withSpinner)(`Upload subgraph to IPFS`, `Failed to upload subgraph to IPFS`, `Warnings while uploading subgraph to IPFS`, async (spinner) => {
|
|
373
|
+
// Cache uploaded IPFS files so identical files are only uploaded once
|
|
374
|
+
const uploadedFiles = new Map();
|
|
375
|
+
// Collect all source (path -> hash) updates to apply them later
|
|
376
|
+
const updates = [];
|
|
377
|
+
// Upload the schema to IPFS
|
|
378
|
+
updates.push({
|
|
379
|
+
keyPath: ['schema', 'file'],
|
|
380
|
+
value: await this._uploadFileToIPFS(subgraph.getIn(['schema', 'file']), uploadedFiles, spinner),
|
|
381
|
+
});
|
|
382
|
+
if (this.protocol.hasABIs()) {
|
|
383
|
+
for (const [i, dataSource] of subgraph.get('dataSources').entries()) {
|
|
384
|
+
for (const [j, abi] of dataSource.getIn(['mapping', 'abis']).entries()) {
|
|
385
|
+
updates.push({
|
|
386
|
+
keyPath: ['dataSources', i, 'mapping', 'abis', j, 'file'],
|
|
387
|
+
value: await this._uploadFileToIPFS(abi.get('file'), uploadedFiles, spinner),
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Upload all mappings
|
|
393
|
+
if (this.protocol.name !== 'substreams') {
|
|
394
|
+
for (const [i, dataSource] of subgraph.get('dataSources').entries()) {
|
|
395
|
+
updates.push({
|
|
396
|
+
keyPath: ['dataSources', i, 'mapping', 'file'],
|
|
397
|
+
value: await this._uploadFileToIPFS(dataSource.getIn(['mapping', 'file']), uploadedFiles, spinner),
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
for (const [i, dataSource] of subgraph.get('dataSources').entries()) {
|
|
403
|
+
updates.push({
|
|
404
|
+
keyPath: ['dataSources', i, 'source', 'package', 'file'],
|
|
405
|
+
value: await this._uploadFileToIPFS(dataSource.getIn(['source', 'package', 'file']), uploadedFiles, spinner),
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
for (const [i, template] of subgraph.get('templates', immutable_1.default.List()).entries()) {
|
|
410
|
+
if (this.protocol.hasABIs()) {
|
|
411
|
+
for (const [j, abi] of template.getIn(['mapping', 'abis']).entries()) {
|
|
412
|
+
updates.push({
|
|
413
|
+
keyPath: ['templates', i, 'mapping', 'abis', j, 'file'],
|
|
414
|
+
value: await this._uploadFileToIPFS(abi.get('file'), uploadedFiles, spinner),
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
updates.push({
|
|
419
|
+
keyPath: ['templates', i, 'mapping', 'file'],
|
|
420
|
+
value: await this._uploadFileToIPFS(template.getIn(['mapping', 'file']), uploadedFiles, spinner),
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
// Apply all updates to the subgraph
|
|
424
|
+
for (const update of updates) {
|
|
425
|
+
subgraph = subgraph.setIn(update.keyPath, update.value);
|
|
426
|
+
}
|
|
427
|
+
// Upload the subgraph itself
|
|
428
|
+
return await this._uploadSubgraphDefinitionToIPFS(subgraph);
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
async _uploadFileToIPFS(maybeRelativeFile, uploadedFiles, spinner) {
|
|
432
|
+
compilerDebug('Resolving IPFS file "%s" from output dir "%s"', maybeRelativeFile, this.options.outputDir);
|
|
433
|
+
const absoluteFile = path_1.default.resolve(this.options.outputDir, maybeRelativeFile);
|
|
434
|
+
(0, spinner_1.step)(spinner, 'Add file to IPFS', this.displayPath(absoluteFile));
|
|
435
|
+
const uploadCacheKey = this.cacheKeyForFile(absoluteFile);
|
|
436
|
+
const alreadyUploaded = uploadedFiles.has(uploadCacheKey);
|
|
437
|
+
if (!alreadyUploaded) {
|
|
438
|
+
// @ts-expect-error Buffer.from with Buffer data can indeed accept utf-8
|
|
439
|
+
const content = Buffer.from(await fs_extra_1.default.readFile(absoluteFile), 'utf-8');
|
|
440
|
+
const hash = await this._uploadToIPFS({
|
|
441
|
+
path: path_1.default.relative(this.options.outputDir, absoluteFile),
|
|
442
|
+
content,
|
|
443
|
+
});
|
|
444
|
+
uploadedFiles.set(uploadCacheKey, hash);
|
|
445
|
+
}
|
|
446
|
+
const hash = uploadedFiles.get(uploadCacheKey);
|
|
447
|
+
(0, spinner_1.step)(spinner, ' ..', `${hash}${alreadyUploaded ? ' (already uploaded)' : ''}`);
|
|
448
|
+
return immutable_1.default.fromJS({ '/': `/ipfs/${hash}` });
|
|
449
|
+
}
|
|
450
|
+
async _uploadSubgraphDefinitionToIPFS(subgraph) {
|
|
451
|
+
const str = js_yaml_1.default.safeDump(subgraph.toJS(), { noRefs: true, sortKeys: true });
|
|
452
|
+
const file = { path: 'subgraph.yaml', content: Buffer.from(str, 'utf-8') };
|
|
453
|
+
return await this._uploadToIPFS(file);
|
|
454
|
+
}
|
|
455
|
+
async _uploadToIPFS(file) {
|
|
456
|
+
try {
|
|
457
|
+
const hash = (await this.ipfs.add([file]))[0].hash;
|
|
458
|
+
await this.ipfs.pin.add(hash);
|
|
459
|
+
return hash;
|
|
460
|
+
}
|
|
461
|
+
catch (e) {
|
|
462
|
+
throw Error(`Failed to upload file to IPFS: ${e.message}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
exports.default = Compiler;
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const debug_1 = __importDefault(require("debug"));
|
|
7
|
+
debug_1.default.formatters.L = immutableList => {
|
|
8
|
+
return JSON.stringify(immutableList);
|
|
9
|
+
};
|
|
10
|
+
debug_1.default.formatters.M = immutableMap => {
|
|
11
|
+
if (immutableMap.toMap != null) {
|
|
12
|
+
return JSON.stringify(immutableMap.toMap());
|
|
13
|
+
}
|
|
14
|
+
return immutableMap;
|
|
15
|
+
};
|
|
16
|
+
exports.default = debug_1.default;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
+
if (mod && mod.__esModule) return mod;
|
|
21
|
+
var result = {};
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
+
__setModuleDefault(result, mod);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const toolbox = __importStar(require("gluegun"));
|
|
31
|
+
const semver_1 = __importDefault(require("semver"));
|
|
32
|
+
const load_manifest_1 = require("./util/load-manifest");
|
|
33
|
+
const versions_1 = require("./util/versions");
|
|
34
|
+
// If any of the manifest apiVersions are 0.0.1, replace them with 0.0.2
|
|
35
|
+
exports.default = {
|
|
36
|
+
name: 'Bump mapping apiVersion from 0.0.1 to 0.0.2',
|
|
37
|
+
predicate: async ({ sourceDir, manifestFile }) => {
|
|
38
|
+
// Obtain the graph-ts version, if possible
|
|
39
|
+
let graphTsVersion;
|
|
40
|
+
try {
|
|
41
|
+
graphTsVersion = await (0, versions_1.getGraphTsVersion)(sourceDir);
|
|
42
|
+
}
|
|
43
|
+
catch (_) {
|
|
44
|
+
// If we cannot obtain the version, return a hint that the graph-ts
|
|
45
|
+
// hasn't been installed yet
|
|
46
|
+
return 'graph-ts dependency not installed yet';
|
|
47
|
+
}
|
|
48
|
+
const manifest = await (0, load_manifest_1.loadManifest)(manifestFile);
|
|
49
|
+
return (
|
|
50
|
+
// Only migrate if the graph-ts version is > 0.5.1...
|
|
51
|
+
semver_1.default.gt(graphTsVersion, '0.5.1') &&
|
|
52
|
+
// ...and we have a manifest with mapping > apiVersion = 0.0.1
|
|
53
|
+
manifest &&
|
|
54
|
+
typeof manifest === 'object' &&
|
|
55
|
+
Array.isArray(manifest.dataSources) &&
|
|
56
|
+
(manifest.dataSources.reduce((hasOldMappings, dataSource) => hasOldMappings ||
|
|
57
|
+
(typeof dataSource === 'object' &&
|
|
58
|
+
dataSource.mapping &&
|
|
59
|
+
typeof dataSource.mapping === 'object' &&
|
|
60
|
+
dataSource.mapping.apiVersion === '0.0.1'), false) ||
|
|
61
|
+
(Array.isArray(manifest.templates) &&
|
|
62
|
+
manifest.templates.reduce((hasOldMappings, template) => hasOldMappings ||
|
|
63
|
+
(typeof template === 'object' &&
|
|
64
|
+
template.mapping &&
|
|
65
|
+
typeof template.mapping === 'object' &&
|
|
66
|
+
template.mapping.apiVersion === '0.0.1'), false))));
|
|
67
|
+
},
|
|
68
|
+
apply: async ({ manifestFile }) => {
|
|
69
|
+
// Make sure we catch all variants; we could load the manifest
|
|
70
|
+
// and replace the values in the data structures here; unfortunately
|
|
71
|
+
// writing that back to the file messes with the formatting more than
|
|
72
|
+
// we'd like; that's why for now, we use a simple patching approach
|
|
73
|
+
await toolbox.patching.replace(manifestFile,
|
|
74
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
75
|
+
new RegExp('apiVersion: 0.0.1', 'g'), 'apiVersion: 0.0.2');
|
|
76
|
+
await toolbox.patching.replace(manifestFile,
|
|
77
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
78
|
+
new RegExp("apiVersion: '0.0.1'", 'g'), "apiVersion: '0.0.2'");
|
|
79
|
+
await toolbox.patching.replace(manifestFile,
|
|
80
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
81
|
+
new RegExp('apiVersion: "0.0.1"', 'g'), 'apiVersion: "0.0.2"');
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
+
if (mod && mod.__esModule) return mod;
|
|
21
|
+
var result = {};
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
+
__setModuleDefault(result, mod);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
27
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const toolbox = __importStar(require("gluegun"));
|
|
31
|
+
const semver_1 = __importDefault(require("semver"));
|
|
32
|
+
const load_manifest_1 = require("./util/load-manifest");
|
|
33
|
+
const versions_1 = require("./util/versions");
|
|
34
|
+
// If any of the manifest apiVersions are 0.0.2, replace them with 0.0.3
|
|
35
|
+
exports.default = {
|
|
36
|
+
name: 'Bump mapping apiVersion from 0.0.2 to 0.0.3',
|
|
37
|
+
predicate: async ({ sourceDir, manifestFile }) => {
|
|
38
|
+
// Obtain the graph-ts version, if possible
|
|
39
|
+
let graphTsVersion;
|
|
40
|
+
try {
|
|
41
|
+
graphTsVersion = await (0, versions_1.getGraphTsVersion)(sourceDir);
|
|
42
|
+
}
|
|
43
|
+
catch (_) {
|
|
44
|
+
// If we cannot obtain the version, return a hint that the graph-ts
|
|
45
|
+
// hasn't been installed yet
|
|
46
|
+
return 'graph-ts dependency not installed yet';
|
|
47
|
+
}
|
|
48
|
+
const manifest = await (0, load_manifest_1.loadManifest)(manifestFile);
|
|
49
|
+
return (
|
|
50
|
+
// Only migrate if the graph-ts version is > 0.12.0...
|
|
51
|
+
semver_1.default.gt(graphTsVersion, '0.12.0') &&
|
|
52
|
+
// ...and we have a manifest with mapping > apiVersion = 0.0.2
|
|
53
|
+
manifest &&
|
|
54
|
+
typeof manifest === 'object' &&
|
|
55
|
+
Array.isArray(manifest.dataSources) &&
|
|
56
|
+
(manifest.dataSources.reduce((hasOldMappings, dataSource) => hasOldMappings ||
|
|
57
|
+
(typeof dataSource === 'object' &&
|
|
58
|
+
dataSource.mapping &&
|
|
59
|
+
typeof dataSource.mapping === 'object' &&
|
|
60
|
+
dataSource.mapping.apiVersion === '0.0.2'), false) ||
|
|
61
|
+
(Array.isArray(manifest.templates) &&
|
|
62
|
+
manifest.templates.reduce((hasOldMappings, template) => hasOldMappings ||
|
|
63
|
+
(typeof template === 'object' &&
|
|
64
|
+
template.mapping &&
|
|
65
|
+
typeof template.mapping === 'object' &&
|
|
66
|
+
template.mapping.apiVersion === '0.0.2'), false))));
|
|
67
|
+
},
|
|
68
|
+
apply: async ({ manifestFile }) => {
|
|
69
|
+
// Make sure we catch all variants; we could load the manifest
|
|
70
|
+
// and replace the values in the data structures here; unfortunately
|
|
71
|
+
// writing that back to the file messes with the formatting more than
|
|
72
|
+
// we'd like; that's why for now, we use a simple patching approach
|
|
73
|
+
await toolbox.patching.replace(manifestFile,
|
|
74
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
75
|
+
new RegExp('apiVersion: 0.0.2', 'g'), 'apiVersion: 0.0.3');
|
|
76
|
+
await toolbox.patching.replace(manifestFile,
|
|
77
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
78
|
+
new RegExp("apiVersion: '0.0.2'", 'g'), "apiVersion: '0.0.3'");
|
|
79
|
+
await toolbox.patching.replace(manifestFile,
|
|
80
|
+
// @ts-expect-error toolbox patching seems to accept RegExp
|
|
81
|
+
new RegExp('apiVersion: "0.0.2"', 'g'), 'apiVersion: "0.0.3"');
|
|
82
|
+
},
|
|
83
|
+
};
|