@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.
- package/CHANGELOG.md +7 -0
- package/babel.config.js +3 -0
- package/dist/bin.js +6 -0
- package/dist/cli.js +32 -0
- package/dist/codegen/schema.js +250 -0
- package/dist/codegen/schema.test.js +458 -0
- package/dist/codegen/template.js +65 -0
- package/dist/codegen/types/conversions.js +359 -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 +46 -0
- package/dist/codegen/util.test.js +93 -0
- package/dist/command-helpers/abi.js +78 -0
- package/dist/command-helpers/auth.js +77 -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 +49 -0
- package/dist/command-helpers/ipfs.js +5 -0
- package/dist/command-helpers/jsonrpc.js +29 -0
- package/dist/command-helpers/network.js +93 -0
- package/dist/command-helpers/network.test.js +86 -0
- package/dist/command-helpers/node.js +40 -0
- package/dist/command-helpers/scaffold.js +112 -0
- package/dist/command-helpers/spinner.js +84 -0
- package/dist/command-helpers/studio.js +13 -0
- package/dist/command-helpers/studio.test.js +41 -0
- package/dist/command-helpers/subgraph.js +24 -0
- package/dist/command-helpers/version.js +74 -0
- package/dist/command-helpers/version.test.js +179 -0
- package/dist/commands/add.js +190 -0
- package/dist/commands/auth.js +127 -0
- package/dist/commands/build.js +140 -0
- package/dist/commands/codegen.js +135 -0
- package/dist/commands/create.js +86 -0
- package/dist/commands/deploy.js +334 -0
- package/dist/commands/init.js +788 -0
- package/dist/commands/local.js +387 -0
- package/dist/commands/remove.js +86 -0
- package/dist/commands/test.js +295 -0
- package/dist/compiler/asc.js +83 -0
- package/dist/compiler/index.js +474 -0
- package/dist/debug.js +16 -0
- package/dist/migrations/mapping_api_version_0_0_1.js +78 -0
- package/dist/migrations/mapping_api_version_0_0_2.js +76 -0
- package/dist/migrations/mapping_api_version_0_0_3.js +78 -0
- package/dist/migrations/mapping_api_version_0_0_4.js +80 -0
- package/dist/migrations/mapping_api_version_0_0_5.js +80 -0
- package/dist/migrations/spec_version_0_0_2.js +49 -0
- package/dist/migrations/spec_version_0_0_3.js +54 -0
- package/dist/migrations/util/load-manifest.js +18 -0
- package/dist/migrations/util/versions.js +29 -0
- package/dist/migrations.js +56 -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/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 +25 -0
- package/dist/protocols/ethereum/abi.js +140 -0
- package/dist/protocols/ethereum/codegen/abi.js +451 -0
- package/dist/protocols/ethereum/codegen/abi.test.js +328 -0
- package/dist/protocols/ethereum/codegen/template.js +50 -0
- package/dist/protocols/ethereum/contract.js +20 -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 +171 -0
- package/dist/protocols/ethereum/type-generator.js +125 -0
- package/dist/protocols/index.js +268 -0
- package/dist/protocols/ipfs/codegen/file_template.js +50 -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 +20 -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 +83 -0
- package/dist/scaffold/ethereum.test.js +505 -0
- package/dist/scaffold/index.js +128 -0
- package/dist/scaffold/mapping.js +61 -0
- package/dist/scaffold/near.test.js +86 -0
- package/dist/scaffold/schema.js +83 -0
- package/dist/scaffold/tests.js +175 -0
- package/dist/schema.js +54 -0
- package/dist/subgraph.js +249 -0
- package/dist/type-generator.js +224 -0
- package/dist/validation/contract.js +46 -0
- package/dist/validation/index.js +8 -0
- package/dist/validation/manifest.js +271 -0
- package/dist/validation/schema.js +796 -0
- package/dist/validation/schema.test.js +35 -0
- package/dist/watcher.js +79 -0
- package/jest.config.js +1 -1
- package/package.json +16 -9
- package/{bin/graph → src/bin.ts} +2 -1
- package/src/cli.ts +36 -0
- package/src/codegen/schema.js +23 -22
- package/src/codegen/schema.test.js +33 -27
- package/src/codegen/{template.js → template.ts} +8 -6
- package/src/codegen/types/conversions.ts +382 -0
- package/src/codegen/types/index.js +4 -7
- package/src/codegen/types/index.test.js +10 -4
- package/src/codegen/{typescript.js → typescript.ts} +44 -26
- package/src/codegen/util.js +1 -1
- package/src/codegen/util.test.js +5 -2
- package/src/command-helpers/abi.js +46 -30
- package/src/command-helpers/auth.js +6 -9
- package/src/command-helpers/compiler.js +4 -6
- package/src/command-helpers/data-sources.js +8 -11
- package/src/command-helpers/fs.ts +5 -0
- package/src/command-helpers/gluegun.js +2 -4
- package/src/command-helpers/ipfs.ts +3 -0
- package/src/command-helpers/{jsonrpc.js → jsonrpc.ts} +11 -16
- package/src/command-helpers/network.js +58 -44
- package/src/command-helpers/network.test.js +23 -19
- package/src/command-helpers/node.js +3 -7
- package/src/command-helpers/scaffold.js +34 -25
- package/src/command-helpers/{spinner.js → spinner.ts} +10 -10
- package/src/command-helpers/studio.test.js +61 -30
- package/src/command-helpers/studio.ts +20 -0
- package/src/command-helpers/{subgraph.js → subgraph.ts} +6 -6
- package/src/command-helpers/version.js +11 -16
- package/src/command-helpers/version.test.js +111 -82
- package/src/commands/add.js +49 -35
- package/src/commands/auth.js +13 -25
- package/src/commands/build.js +9 -9
- package/src/commands/codegen.js +12 -12
- package/src/commands/create.js +22 -22
- package/src/commands/deploy.js +39 -34
- package/src/commands/init.js +21 -24
- package/src/commands/local.js +15 -14
- package/src/commands/remove.js +22 -22
- package/src/commands/test.js +86 -70
- package/src/compiler/{asc.js → asc.ts} +29 -16
- package/src/compiler/index.js +18 -18
- package/src/{debug.js → debug.ts} +2 -2
- package/src/migrations/mapping_api_version_0_0_1.js +7 -7
- package/src/migrations/mapping_api_version_0_0_2.js +5 -5
- package/src/migrations/mapping_api_version_0_0_3.js +7 -7
- package/src/migrations/mapping_api_version_0_0_4.js +7 -7
- package/src/migrations/mapping_api_version_0_0_5.js +7 -7
- package/src/migrations/spec_version_0_0_2.js +5 -5
- package/src/migrations/spec_version_0_0_3.js +5 -5
- package/src/migrations/util/load-manifest.js +6 -9
- package/src/migrations/util/versions.js +5 -10
- package/src/{migrations.js → migrations.ts} +14 -15
- package/src/protocols/arweave/scaffold/manifest.js +1 -4
- package/src/protocols/arweave/scaffold/mapping.js +1 -3
- package/src/protocols/arweave/subgraph.ts +22 -0
- package/src/protocols/cosmos/scaffold/manifest.js +1 -4
- package/src/protocols/cosmos/scaffold/mapping.js +1 -3
- package/src/protocols/cosmos/subgraph.js +2 -2
- package/src/protocols/ethereum/abi.js +7 -13
- package/src/protocols/ethereum/codegen/abi.js +219 -222
- package/src/protocols/ethereum/codegen/abi.test.js +6 -6
- package/src/protocols/ethereum/codegen/template.js +3 -5
- package/src/protocols/ethereum/contract.js +3 -2
- package/src/protocols/ethereum/scaffold/manifest.js +4 -7
- package/src/protocols/ethereum/scaffold/mapping.js +4 -11
- package/src/protocols/ethereum/subgraph.js +21 -20
- package/src/protocols/ethereum/type-generator.js +24 -30
- package/src/protocols/{index.js → index.ts} +65 -46
- package/src/protocols/ipfs/codegen/file_template.js +2 -2
- package/src/protocols/near/{contract.js → contract.ts} +16 -12
- package/src/protocols/near/scaffold/manifest.js +2 -5
- package/src/protocols/near/scaffold/mapping.js +1 -3
- package/src/protocols/near/subgraph.js +3 -6
- package/src/protocols/subgraph.ts +12 -0
- package/src/protocols/substreams/scaffold/{manifest.js → manifest.ts} +2 -7
- package/src/protocols/substreams/subgraph.ts +22 -0
- package/src/scaffold/cosmos.test.js +3 -3
- package/src/scaffold/ethereum.test.js +4 -4
- package/src/scaffold/index.js +7 -7
- package/src/scaffold/mapping.js +3 -3
- package/src/scaffold/near.test.js +3 -3
- package/src/scaffold/schema.js +4 -4
- package/src/scaffold/tests.js +72 -58
- package/src/schema.ts +26 -0
- package/src/{subgraph.js → subgraph.ts} +80 -60
- package/src/type-generator.js +20 -20
- package/src/validation/contract.js +2 -6
- package/src/validation/index.js +1 -1
- package/src/validation/manifest.js +24 -22
- package/src/validation/schema.test.js +1 -1
- package/src/validation/{schema.js → schema.ts} +268 -221
- package/src/{watcher.js → watcher.ts} +23 -12
- package/tests/cli/globalSetup.js +2 -2
- package/tests/cli/globalTeardown.js +2 -2
- package/tests/cli/init.test.js +2 -2
- package/tests/cli/util.js +7 -13
- package/tsconfig.json +18 -0
- package/src/cli.js +0 -38
- package/src/codegen/types/conversions.js +0 -329
- package/src/command-helpers/fs.js +0 -8
- package/src/command-helpers/ipfs.js +0 -6
- package/src/command-helpers/studio.js +0 -15
- package/src/protocols/arweave/subgraph.js +0 -20
- package/src/protocols/substreams/subgraph.js +0 -17
- package/src/schema.js +0 -23
|
@@ -0,0 +1,224 @@
|
|
|
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 immutable_1 = __importDefault(require("immutable"));
|
|
31
|
+
const path_1 = __importDefault(require("path"));
|
|
32
|
+
const prettier_1 = __importDefault(require("prettier"));
|
|
33
|
+
const graphql = __importStar(require("graphql/language"));
|
|
34
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
35
|
+
const toolbox = __importStar(require("gluegun/toolbox"));
|
|
36
|
+
const schema_1 = __importDefault(require("./schema"));
|
|
37
|
+
const subgraph_1 = __importDefault(require("./subgraph"));
|
|
38
|
+
const template_1 = __importDefault(require("./codegen/template"));
|
|
39
|
+
const watcher_1 = __importDefault(require("./watcher"));
|
|
40
|
+
const spinner_1 = require("./command-helpers/spinner");
|
|
41
|
+
const migrations_1 = require("./migrations");
|
|
42
|
+
const typescript_1 = require("./codegen/typescript");
|
|
43
|
+
const fs_1 = require("./command-helpers/fs");
|
|
44
|
+
const Index_bs_js_1 = __importDefault(require("@float-capital/float-subgraph-uncrashable/src/Index.bs.js"));
|
|
45
|
+
class TypeGenerator {
|
|
46
|
+
constructor(options) {
|
|
47
|
+
this.options = options || {};
|
|
48
|
+
this.sourceDir =
|
|
49
|
+
this.options.sourceDir ||
|
|
50
|
+
(this.options.subgraphManifest && path_1.default.dirname(this.options.subgraphManifest));
|
|
51
|
+
this.protocol = this.options.protocol;
|
|
52
|
+
this.protocolTypeGenerator = this.protocol.getTypeGenerator({
|
|
53
|
+
sourceDir: this.sourceDir,
|
|
54
|
+
outputDir: this.options.outputDir,
|
|
55
|
+
});
|
|
56
|
+
process.on('uncaughtException', function (e) {
|
|
57
|
+
toolbox.print.error(`UNCAUGHT EXCEPTION: ${e}`);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async generateTypes() {
|
|
61
|
+
try {
|
|
62
|
+
if (!this.options.skipMigrations && this.options.subgraphManifest) {
|
|
63
|
+
await (0, migrations_1.applyMigrations)({
|
|
64
|
+
sourceDir: this.sourceDir,
|
|
65
|
+
manifestFile: this.options.subgraphManifest,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
let subgraph = await this.loadSubgraph();
|
|
69
|
+
// Not all protocols support/have ABIs.
|
|
70
|
+
if (this.protocol.hasABIs()) {
|
|
71
|
+
const abis = await this.protocolTypeGenerator.loadABIs(subgraph);
|
|
72
|
+
await this.protocolTypeGenerator.generateTypesForABIs(abis);
|
|
73
|
+
}
|
|
74
|
+
await this.generateTypesForDataSourceTemplates(subgraph);
|
|
75
|
+
// Not all protocols support/have ABIs.
|
|
76
|
+
if (this.protocol.hasABIs()) {
|
|
77
|
+
const templateAbis = await this.protocolTypeGenerator.loadDataSourceTemplateABIs(subgraph);
|
|
78
|
+
await this.protocolTypeGenerator.generateTypesForDataSourceTemplateABIs(templateAbis);
|
|
79
|
+
}
|
|
80
|
+
let schema = await this.loadSchema(subgraph);
|
|
81
|
+
await this.generateTypesForSchema(schema);
|
|
82
|
+
toolbox.print.success('\nTypes generated successfully\n');
|
|
83
|
+
if (this.options.uncrashable && this.options.uncrashableConfig) {
|
|
84
|
+
await this.generateUncrashableEntities(schema);
|
|
85
|
+
toolbox.print.success('\nUncrashable Helpers generated successfully\n');
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async generateUncrashableEntities(graphSchema) {
|
|
94
|
+
let ast = graphql.parse(graphSchema.document);
|
|
95
|
+
let entityDefinitions = ast['definitions'];
|
|
96
|
+
return await (0, spinner_1.withSpinner)(`Generate Uncrashable Entity Helpers`, `Failed to generate Uncrashable Entity Helpers`, `Warnings while generating Uncrashable Entity Helpers`, async (spinner) => {
|
|
97
|
+
Index_bs_js_1.default.run(entityDefinitions, this.options.uncrashableConfig, this.options.outputDir);
|
|
98
|
+
let outputFile = path_1.default.join(this.options.outputDir, 'UncrashableEntityHelpers.ts');
|
|
99
|
+
(0, spinner_1.step)(spinner, 'Save uncrashable entities to', (0, fs_1.displayPath)(outputFile));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async loadSubgraph({ quiet } = { quiet: false }) {
|
|
103
|
+
const subgraphLoadOptions = { protocol: this.protocol, skipValidation: false };
|
|
104
|
+
if (quiet) {
|
|
105
|
+
return this.options.subgraph
|
|
106
|
+
? this.options.subgraph
|
|
107
|
+
: subgraph_1.default.load(this.options.subgraphManifest, subgraphLoadOptions).result;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const manifestPath = (0, fs_1.displayPath)(this.options.subgraphManifest);
|
|
111
|
+
return await (0, spinner_1.withSpinner)(`Load subgraph from ${manifestPath}`, `Failed to load subgraph from ${manifestPath}`, `Warnings while loading subgraph from ${manifestPath}`, async (spinner) => {
|
|
112
|
+
return this.options.subgraph
|
|
113
|
+
? this.options.subgraph
|
|
114
|
+
: subgraph_1.default.load(this.options.subgraphManifest, subgraphLoadOptions);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async loadSchema(subgraph) {
|
|
119
|
+
let maybeRelativePath = subgraph.getIn(['schema', 'file']);
|
|
120
|
+
let absolutePath = path_1.default.resolve(this.sourceDir, maybeRelativePath);
|
|
121
|
+
return await (0, spinner_1.withSpinner)(`Load GraphQL schema from ${(0, fs_1.displayPath)(absolutePath)}`, `Failed to load GraphQL schema from ${(0, fs_1.displayPath)(absolutePath)}`, `Warnings while loading GraphQL schema from ${(0, fs_1.displayPath)(absolutePath)}`, async (spinner) => {
|
|
122
|
+
let maybeRelativePath = subgraph.getIn(['schema', 'file']);
|
|
123
|
+
let absolutePath = path_1.default.resolve(this.sourceDir, maybeRelativePath);
|
|
124
|
+
return schema_1.default.load(absolutePath);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async generateTypesForSchema(schema) {
|
|
128
|
+
return await (0, spinner_1.withSpinner)(`Generate types for GraphQL schema`, `Failed to generate types for GraphQL schema`, `Warnings while generating types for GraphQL schema`, async (spinner) => {
|
|
129
|
+
// Generate TypeScript module from schema
|
|
130
|
+
let codeGenerator = schema.codeGenerator();
|
|
131
|
+
let code = prettier_1.default.format([
|
|
132
|
+
typescript_1.GENERATED_FILE_NOTE,
|
|
133
|
+
...codeGenerator.generateModuleImports(),
|
|
134
|
+
...codeGenerator.generateTypes(),
|
|
135
|
+
].join('\n'), {
|
|
136
|
+
parser: 'typescript',
|
|
137
|
+
});
|
|
138
|
+
let outputFile = path_1.default.join(this.options.outputDir, 'schema.ts');
|
|
139
|
+
(0, spinner_1.step)(spinner, 'Write types to', (0, fs_1.displayPath)(outputFile));
|
|
140
|
+
await fs_extra_1.default.mkdirs(path_1.default.dirname(outputFile));
|
|
141
|
+
await fs_extra_1.default.writeFile(outputFile, code);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async generateTypesForDataSourceTemplates(subgraph) {
|
|
145
|
+
return await (0, spinner_1.withSpinner)(`Generate types for data source templates`, `Failed to generate types for data source templates`, `Warnings while generating types for data source templates`, async (spinner) => {
|
|
146
|
+
// Combine the generated code for all templates
|
|
147
|
+
let codeSegments = subgraph
|
|
148
|
+
.get('templates', immutable_1.default.List())
|
|
149
|
+
.reduce((codeSegments, template) => {
|
|
150
|
+
(0, spinner_1.step)(spinner, 'Generate types for data source template', `${template.get('name')}`);
|
|
151
|
+
let codeGenerator = new template_1.default(template, this.protocol);
|
|
152
|
+
// Only generate module imports once, because they are identical for
|
|
153
|
+
// all types generated for data source templates.
|
|
154
|
+
if (codeSegments.isEmpty()) {
|
|
155
|
+
codeSegments = codeSegments.concat(codeGenerator.generateModuleImports());
|
|
156
|
+
}
|
|
157
|
+
return codeSegments.concat(codeGenerator.generateTypes());
|
|
158
|
+
}, immutable_1.default.List());
|
|
159
|
+
if (!codeSegments.isEmpty()) {
|
|
160
|
+
let code = prettier_1.default.format([typescript_1.GENERATED_FILE_NOTE, ...codeSegments].join('\n'), {
|
|
161
|
+
parser: 'typescript',
|
|
162
|
+
});
|
|
163
|
+
let outputFile = path_1.default.join(this.options.outputDir, 'templates.ts');
|
|
164
|
+
(0, spinner_1.step)(spinner, `Write types for templates to`, (0, fs_1.displayPath)(outputFile));
|
|
165
|
+
await fs_extra_1.default.mkdirs(path_1.default.dirname(outputFile));
|
|
166
|
+
await fs_extra_1.default.writeFile(outputFile, code);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async getFilesToWatch() {
|
|
171
|
+
try {
|
|
172
|
+
let files = [];
|
|
173
|
+
let subgraph = await this.loadSubgraph({ quiet: true });
|
|
174
|
+
// Add the subgraph manifest file
|
|
175
|
+
files.push(this.options.subgraphManifest);
|
|
176
|
+
// Add the GraphQL schema to the watched files
|
|
177
|
+
files.push(subgraph.getIn(['schema', 'file']));
|
|
178
|
+
// Add all file paths specified in manifest
|
|
179
|
+
subgraph.get('dataSources').map(dataSource => {
|
|
180
|
+
dataSource.getIn(['mapping', 'abis']).map(abi => {
|
|
181
|
+
files.push(abi.get('file'));
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
// Make paths absolute
|
|
185
|
+
return files.map(file => path_1.default.resolve(file));
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
throw Error(`Failed to load subgraph: ${e.message}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async watchAndGenerateTypes() {
|
|
192
|
+
let generator = this;
|
|
193
|
+
let spinner;
|
|
194
|
+
// Create watcher and generate types once and then on every change to a watched file
|
|
195
|
+
let watcher = new watcher_1.default({
|
|
196
|
+
onReady: () => (spinner = toolbox.print.spin('Watching subgraph files')),
|
|
197
|
+
onTrigger: async (changedFile) => {
|
|
198
|
+
if (changedFile !== undefined) {
|
|
199
|
+
spinner.info(`File change detected: ${(0, fs_1.displayPath)(changedFile)}\n`);
|
|
200
|
+
}
|
|
201
|
+
await generator.generateTypes();
|
|
202
|
+
spinner.start();
|
|
203
|
+
},
|
|
204
|
+
onCollectFiles: async () => await generator.getFilesToWatch(),
|
|
205
|
+
onError: error => {
|
|
206
|
+
spinner.stop();
|
|
207
|
+
toolbox.print.error(`${error}\n`);
|
|
208
|
+
spinner.start();
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
// Catch keyboard interrupt: close watcher and exit process
|
|
212
|
+
process.on('SIGINT', () => {
|
|
213
|
+
watcher.close();
|
|
214
|
+
process.exit();
|
|
215
|
+
});
|
|
216
|
+
try {
|
|
217
|
+
await watcher.watch();
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
toolbox.print.error(`${e.message}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.default = TypeGenerator;
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
exports.validateContractValues = exports.validateContract = void 0;
|
|
7
|
+
const immutable_1 = __importDefault(require("immutable"));
|
|
8
|
+
const validateContract = (value, ProtocolContract) => {
|
|
9
|
+
const contract = new ProtocolContract(value);
|
|
10
|
+
const { valid, error } = contract.validate();
|
|
11
|
+
if (!valid) {
|
|
12
|
+
return {
|
|
13
|
+
valid,
|
|
14
|
+
error: `Contract ${ProtocolContract.identifierName()} is invalid: ${value}\n${error}`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return { valid, error };
|
|
18
|
+
};
|
|
19
|
+
exports.validateContract = validateContract;
|
|
20
|
+
const validateContractValues = (manifest, protocol) => {
|
|
21
|
+
const ProtocolContract = protocol.getContract();
|
|
22
|
+
const fieldName = ProtocolContract.identifierName();
|
|
23
|
+
return manifest
|
|
24
|
+
.get('dataSources')
|
|
25
|
+
.filter(dataSource => protocol.isValidKindName(dataSource.get('kind')))
|
|
26
|
+
.reduce((errors, dataSource, dataSourceIndex) => {
|
|
27
|
+
let path = ['dataSources', dataSourceIndex, 'source', fieldName];
|
|
28
|
+
// No need to validate if the source has no contract field
|
|
29
|
+
if (!dataSource.get('source').has(fieldName)) {
|
|
30
|
+
return errors;
|
|
31
|
+
}
|
|
32
|
+
let contractValue = dataSource.getIn(['source', fieldName]);
|
|
33
|
+
const { valid, error } = validateContract(contractValue, ProtocolContract);
|
|
34
|
+
// Validate whether the contract is valid for the protocol
|
|
35
|
+
if (valid) {
|
|
36
|
+
return errors;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return errors.push(immutable_1.default.fromJS({
|
|
40
|
+
path,
|
|
41
|
+
message: error,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
}, immutable_1.default.List());
|
|
45
|
+
};
|
|
46
|
+
exports.validateContractValues = validateContractValues;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = {
|
|
4
|
+
validateSchema: require('./schema').validateSchema,
|
|
5
|
+
validateManifest: require('./manifest').validateManifest,
|
|
6
|
+
validateContractValues: require('./contract').validateContractValues,
|
|
7
|
+
validateContract: require('./contract').validateContract,
|
|
8
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
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
|
+
exports.validateManifest = void 0;
|
|
7
|
+
const immutable_1 = __importDefault(require("immutable"));
|
|
8
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const protocols_1 = __importDefault(require("../protocols"));
|
|
11
|
+
const List = immutable_1.default.List;
|
|
12
|
+
const Map = immutable_1.default.Map;
|
|
13
|
+
/**
|
|
14
|
+
* Returns a user-friendly type name for a value.
|
|
15
|
+
*/
|
|
16
|
+
const typeName = value => List.isList(value) ? 'list' : Map.isMap(value) ? 'map' : typeof value;
|
|
17
|
+
/**
|
|
18
|
+
* Converts an immutable or plain JavaScript value to a YAML string.
|
|
19
|
+
*/
|
|
20
|
+
const toYAML = x => js_yaml_1.default
|
|
21
|
+
.safeDump(typeName(x) === 'list' || typeName(x) === 'map' ? x.toJS() : x, {
|
|
22
|
+
indent: 2,
|
|
23
|
+
})
|
|
24
|
+
.trim();
|
|
25
|
+
/**
|
|
26
|
+
* Looks up the type of a field in a GraphQL object type.
|
|
27
|
+
*/
|
|
28
|
+
const getFieldType = (type, fieldName) => {
|
|
29
|
+
let fieldDef = type
|
|
30
|
+
.get('fields')
|
|
31
|
+
.find(field => field.getIn(['name', 'value']) === fieldName);
|
|
32
|
+
return fieldDef !== undefined ? fieldDef.get('type') : undefined;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Resolves a type in the GraphQL schema.
|
|
36
|
+
*/
|
|
37
|
+
const resolveType = (schema, type) => type.has('type')
|
|
38
|
+
? resolveType(schema, type.get('type'))
|
|
39
|
+
: type.get('kind') === 'NamedType'
|
|
40
|
+
? schema
|
|
41
|
+
.get('definitions')
|
|
42
|
+
.find(def => def.getIn(['name', 'value']) === type.getIn(['name', 'value']))
|
|
43
|
+
: 'resolveType: unimplemented';
|
|
44
|
+
/**
|
|
45
|
+
* A map of supported validators.
|
|
46
|
+
*/
|
|
47
|
+
const validators = immutable_1.default.fromJS({
|
|
48
|
+
ScalarTypeDefinition: (value, ctx) => validators.get(ctx.getIn(['type', 'name', 'value']))(value, ctx),
|
|
49
|
+
UnionTypeDefinition: (value, ctx) => {
|
|
50
|
+
const unionVariants = ctx.getIn(['type', 'types']);
|
|
51
|
+
let errors = List();
|
|
52
|
+
for (const variantType of unionVariants) {
|
|
53
|
+
const variantErrors = validateValue(value, ctx.set('type', variantType));
|
|
54
|
+
// No errors found, union variant matched, early return
|
|
55
|
+
if (variantErrors.isEmpty()) {
|
|
56
|
+
return List();
|
|
57
|
+
}
|
|
58
|
+
errors = errors.push(variantErrors);
|
|
59
|
+
}
|
|
60
|
+
// Return errors from variant that matched the most
|
|
61
|
+
return List(errors.minBy(variantErrors => variantErrors.count()));
|
|
62
|
+
},
|
|
63
|
+
NamedType: (value, ctx) => validateValue(value, ctx.update('type', type => resolveType(ctx.get('schema'), type))),
|
|
64
|
+
NonNullType: (value, ctx) => value !== null && value !== undefined
|
|
65
|
+
? validateValue(value, ctx.update('type', type => type.get('type')))
|
|
66
|
+
: immutable_1.default.fromJS([
|
|
67
|
+
{
|
|
68
|
+
path: ctx.get('path'),
|
|
69
|
+
message: `No value provided`,
|
|
70
|
+
},
|
|
71
|
+
]),
|
|
72
|
+
ListType: (value, ctx) => List.isList(value)
|
|
73
|
+
? value.reduce((errors, value, i) => errors.concat(validateValue(value, ctx
|
|
74
|
+
.update('path', path => path.push(i))
|
|
75
|
+
.update('type', type => type.get('type')))), List())
|
|
76
|
+
: immutable_1.default.fromJS([
|
|
77
|
+
{
|
|
78
|
+
path: ctx.get('path'),
|
|
79
|
+
message: `Expected list, found ${typeName(value)}:\n${toYAML(value)}`,
|
|
80
|
+
},
|
|
81
|
+
]),
|
|
82
|
+
ObjectTypeDefinition: (value, ctx) => {
|
|
83
|
+
return Map.isMap(value)
|
|
84
|
+
? ctx
|
|
85
|
+
.getIn(['type', 'fields'])
|
|
86
|
+
.map(fieldDef => fieldDef.getIn(['name', 'value']))
|
|
87
|
+
.concat(value.keySeq())
|
|
88
|
+
.toSet()
|
|
89
|
+
.reduce((errors, key) => getFieldType(ctx.get('type'), key)
|
|
90
|
+
? errors.concat(validateValue(value.get(key), ctx
|
|
91
|
+
.update('path', path => path.push(key))
|
|
92
|
+
.set('type', getFieldType(ctx.get('type'), key))))
|
|
93
|
+
: errors.push(key == 'templates' && ctx.get('protocol').hasTemplates()
|
|
94
|
+
? immutable_1.default.fromJS({
|
|
95
|
+
path: ctx.get('path'),
|
|
96
|
+
message: `The way to declare data source templates has changed, ` +
|
|
97
|
+
`please move the templates from inside data sources to ` +
|
|
98
|
+
`a \`templates:\` field at the top level of the manifest.`,
|
|
99
|
+
})
|
|
100
|
+
: immutable_1.default.fromJS({
|
|
101
|
+
path: ctx.get('path'),
|
|
102
|
+
message: `Unexpected key in map: ${key}`,
|
|
103
|
+
})), List())
|
|
104
|
+
: immutable_1.default.fromJS([
|
|
105
|
+
{
|
|
106
|
+
path: ctx.get('path'),
|
|
107
|
+
message: `Expected map, found ${typeName(value)}:\n${toYAML(value)}`,
|
|
108
|
+
},
|
|
109
|
+
]);
|
|
110
|
+
},
|
|
111
|
+
EnumTypeDefinition: (value, ctx) => {
|
|
112
|
+
const enumValues = ctx.getIn(['type', 'values']).map(v => {
|
|
113
|
+
return v.getIn(['name', 'value']);
|
|
114
|
+
});
|
|
115
|
+
const allowedValues = enumValues.toArray().join(', ');
|
|
116
|
+
return enumValues.includes(value)
|
|
117
|
+
? List()
|
|
118
|
+
: immutable_1.default.fromJS([
|
|
119
|
+
{
|
|
120
|
+
path: ctx.get('path'),
|
|
121
|
+
message: `Unexpected enum value: ${value}, allowed values: ${allowedValues}`,
|
|
122
|
+
},
|
|
123
|
+
]);
|
|
124
|
+
},
|
|
125
|
+
String: (value, ctx) => typeof value === 'string'
|
|
126
|
+
? List()
|
|
127
|
+
: immutable_1.default.fromJS([
|
|
128
|
+
{
|
|
129
|
+
path: ctx.get('path'),
|
|
130
|
+
message: `Expected string, found ${typeName(value)}:\n${toYAML(value)}`,
|
|
131
|
+
},
|
|
132
|
+
]),
|
|
133
|
+
BigInt: (value, ctx) => typeof value === 'number'
|
|
134
|
+
? List()
|
|
135
|
+
: immutable_1.default.fromJS([
|
|
136
|
+
{
|
|
137
|
+
path: ctx.get('path'),
|
|
138
|
+
message: `Expected BigInt, found ${typeName(value)}:\n${toYAML(value)}`,
|
|
139
|
+
},
|
|
140
|
+
]),
|
|
141
|
+
File: (value, ctx) => typeof value === 'string'
|
|
142
|
+
? require('fs').existsSync(ctx.get('resolveFile')(value))
|
|
143
|
+
? List()
|
|
144
|
+
: immutable_1.default.fromJS([
|
|
145
|
+
{
|
|
146
|
+
path: ctx.get('path'),
|
|
147
|
+
message: `File does not exist: ${path_1.default.relative(process.cwd(), value)}`,
|
|
148
|
+
},
|
|
149
|
+
])
|
|
150
|
+
: immutable_1.default.fromJS([
|
|
151
|
+
{
|
|
152
|
+
path: ctx.get('path'),
|
|
153
|
+
message: `Expected filename, found ${typeName(value)}:\n${value}`,
|
|
154
|
+
},
|
|
155
|
+
]),
|
|
156
|
+
Boolean: (value, ctx) => typeof value === 'boolean'
|
|
157
|
+
? List()
|
|
158
|
+
: immutable_1.default.fromJS([
|
|
159
|
+
{
|
|
160
|
+
path: ctx.get('path'),
|
|
161
|
+
message: `Expected true or false, found ${typeName(value)}:\n${toYAML(value)}`,
|
|
162
|
+
},
|
|
163
|
+
]),
|
|
164
|
+
});
|
|
165
|
+
const validateValue = (value, ctx) => {
|
|
166
|
+
let kind = ctx.getIn(['type', 'kind']);
|
|
167
|
+
let validator = validators.get(kind);
|
|
168
|
+
if (validator !== undefined) {
|
|
169
|
+
// If the type is nullable, accept undefined and null; if the nullable
|
|
170
|
+
// type is wrapped in a `NonNullType`, the validator for that `NonNullType`
|
|
171
|
+
// will catch the missing/unset value
|
|
172
|
+
if (kind !== 'NonNullType' && (value === undefined || value === null)) {
|
|
173
|
+
return List();
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
return validator(value, ctx);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
return immutable_1.default.fromJS([
|
|
181
|
+
{
|
|
182
|
+
path: ctx.get('path'),
|
|
183
|
+
message: `No validator for unsupported schema type: ${kind}`,
|
|
184
|
+
},
|
|
185
|
+
]);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
// Transforms list of data sources like this:
|
|
189
|
+
// [
|
|
190
|
+
// { name: 'contract0', kind: 'ethereum/contract', network: 'mainnet' },
|
|
191
|
+
// { name: 'contract1', kind: 'ethereum', network: 'mainnet' },
|
|
192
|
+
// { name: 'contract2', kind: 'ethereum/contract', network: 'gnosis' },
|
|
193
|
+
// { name: 'contract3', kind: 'near', network: 'near-mainnet' },
|
|
194
|
+
// ]
|
|
195
|
+
//
|
|
196
|
+
// Into Immutable JS structure like this (protocol kind is normalized):
|
|
197
|
+
// {
|
|
198
|
+
// ethereum: {
|
|
199
|
+
// mainnet: ['contract0', 'contract1'],
|
|
200
|
+
// gnosis: ['contract2'],
|
|
201
|
+
// },
|
|
202
|
+
// near: {
|
|
203
|
+
// 'near-mainnet': ['contract3'],
|
|
204
|
+
// },
|
|
205
|
+
// }
|
|
206
|
+
const dataSourceListToMap = dataSources => dataSources.reduce((protocolKinds, dataSource) => protocolKinds.update(protocols_1.default.normalizeName(dataSource.kind), networks => (networks || immutable_1.default.OrderedMap()).update(dataSource.network, dataSourceNames => (dataSourceNames || immutable_1.default.OrderedSet()).add(dataSource.name))), immutable_1.default.OrderedMap());
|
|
207
|
+
const validateDataSourceProtocolAndNetworks = value => {
|
|
208
|
+
const dataSources = [...value.dataSources, ...(value.templates || [])];
|
|
209
|
+
const protocolNetworkMap = dataSourceListToMap(dataSources);
|
|
210
|
+
if (protocolNetworkMap.size > 1) {
|
|
211
|
+
return immutable_1.default.fromJS([
|
|
212
|
+
{
|
|
213
|
+
path: [],
|
|
214
|
+
message: `Conflicting protocol kinds used in data sources and templates:
|
|
215
|
+
${protocolNetworkMap
|
|
216
|
+
.map((dataSourceNames, protocolKind) => ` ${protocolKind === undefined
|
|
217
|
+
? 'Data sources and templates having no protocol kind set'
|
|
218
|
+
: `Data sources and templates using '${protocolKind}'`}:\n${dataSourceNames
|
|
219
|
+
.valueSeq()
|
|
220
|
+
.flatten()
|
|
221
|
+
.map(ds => ` - ${ds}`)
|
|
222
|
+
.join('\n')}`)
|
|
223
|
+
.join('\n')}
|
|
224
|
+
Recommendation: Make all data sources and templates use the same protocol kind.`,
|
|
225
|
+
},
|
|
226
|
+
]);
|
|
227
|
+
}
|
|
228
|
+
const networks = protocolNetworkMap.first();
|
|
229
|
+
if (networks.size > 1) {
|
|
230
|
+
return immutable_1.default.fromJS([
|
|
231
|
+
{
|
|
232
|
+
path: [],
|
|
233
|
+
message: `Conflicting networks used in data sources and templates:
|
|
234
|
+
${networks
|
|
235
|
+
.map((dataSources, network) => ` ${network === undefined
|
|
236
|
+
? 'Data sources and templates having no network set'
|
|
237
|
+
: `Data sources and templates using '${network}'`}:\n${dataSources.map(ds => ` - ${ds}`).join('\n')}`)
|
|
238
|
+
.join('\n')}
|
|
239
|
+
Recommendation: Make all data sources and templates use the same network name.`,
|
|
240
|
+
},
|
|
241
|
+
]);
|
|
242
|
+
}
|
|
243
|
+
return List();
|
|
244
|
+
};
|
|
245
|
+
const validateManifest = (value, type, schema, protocol, { resolveFile }) => {
|
|
246
|
+
// Validate manifest using the GraphQL schema that defines its structure
|
|
247
|
+
let errors = value !== null && value !== undefined
|
|
248
|
+
? validateValue(immutable_1.default.fromJS(value), immutable_1.default.fromJS({
|
|
249
|
+
schema: schema,
|
|
250
|
+
type: type,
|
|
251
|
+
path: [],
|
|
252
|
+
errors: [],
|
|
253
|
+
resolveFile,
|
|
254
|
+
protocol,
|
|
255
|
+
}))
|
|
256
|
+
: immutable_1.default.fromJS([
|
|
257
|
+
{
|
|
258
|
+
path: [],
|
|
259
|
+
message: `Expected non-empty value, found ${typeName(value)}:\n ${value}`,
|
|
260
|
+
},
|
|
261
|
+
]);
|
|
262
|
+
// Fail early because a broken manifest prevents us from performing
|
|
263
|
+
// additional validation steps
|
|
264
|
+
if (!errors.isEmpty()) {
|
|
265
|
+
return errors;
|
|
266
|
+
}
|
|
267
|
+
// Validate that all data sources are for the same `network` and `protocol` (kind)
|
|
268
|
+
// (this includes _no_ network/protocol at all)
|
|
269
|
+
return validateDataSourceProtocolAndNetworks(value);
|
|
270
|
+
};
|
|
271
|
+
exports.validateManifest = validateManifest;
|