@graphprotocol/graph-cli 0.37.2 → 0.37.3-alpha-20230110163550-d64bef6

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