@graphprotocol/graph-cli 0.57.0-alpha-20230904080157-a384f00 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -9
- package/dist/codegen/schema.d.ts +1 -1
- package/dist/command-helpers/abi.js +1 -1
- package/dist/command-helpers/data-sources.js +1 -1
- package/dist/command-helpers/scaffold.d.ts +10 -10
- package/dist/command-helpers/scaffold.js +6 -2
- package/dist/commands/add.js +2 -2
- package/dist/commands/auth.js +1 -1
- package/dist/commands/build.js +1 -1
- package/dist/commands/clean.js +1 -1
- package/dist/commands/create.js +1 -1
- package/dist/commands/deploy.js +2 -2
- package/dist/commands/init.js +1 -1
- package/dist/commands/local.js +1 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/test.js +2 -2
- package/dist/debug.js +6 -0
- package/dist/protocols/arweave/manifest.graphql +0 -2
- package/dist/protocols/cosmos/manifest.graphql +0 -2
- package/dist/protocols/ethereum/manifest.graphql +0 -2
- package/dist/protocols/near/manifest.graphql +0 -2
- package/dist/scaffold/index.d.ts +19 -19
- package/dist/scaffold/schema.js +6 -2
- package/dist/scaffold/tests.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/subgraph.js +28 -4
- package/dist/type-generator.js +2 -2
- package/dist/validation/manifest.js +0 -14
- package/dist/validation/schema.js +152 -70
- package/oclif.manifest.json +1 -1
- package/package.json +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,54 @@
|
|
|
1
1
|
# @graphprotocol/graph-cli
|
|
2
2
|
|
|
3
|
-
## 0.57.0
|
|
3
|
+
## 0.57.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
- [#
|
|
8
|
-
[`
|
|
9
|
-
Thanks [@
|
|
10
|
-
|
|
7
|
+
- [#1439](https://github.com/graphprotocol/graph-tooling/pull/1439)
|
|
8
|
+
[`b583097`](https://github.com/graphprotocol/graph-tooling/commit/b583097f464a478151068d96d668334602bed3ba)
|
|
9
|
+
Thanks [@saihaj](https://github.com/saihaj)! - Enable autocomplete for CLI commands. To configure
|
|
10
|
+
run
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
graph autocomplete
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
and follow the steps in the prompt.
|
|
17
|
+
|
|
18
|
+
- [#1441](https://github.com/graphprotocol/graph-tooling/pull/1441)
|
|
19
|
+
[`2e656e9`](https://github.com/graphprotocol/graph-tooling/commit/2e656e9cdaaea6d87866adaa142da597fcd7ce65)
|
|
20
|
+
Thanks [@saihaj](https://github.com/saihaj)! - show suggestions when an invalid command is entered
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- [#1439](https://github.com/graphprotocol/graph-tooling/pull/1439)
|
|
25
|
+
[`b583097`](https://github.com/graphprotocol/graph-tooling/commit/b583097f464a478151068d96d668334602bed3ba)
|
|
26
|
+
Thanks [@saihaj](https://github.com/saihaj)! - dependencies updates:
|
|
27
|
+
|
|
28
|
+
- Added dependency
|
|
29
|
+
[`@oclif/plugin-autocomplete@^2.3.6` ↗︎](https://www.npmjs.com/package/@oclif/plugin-autocomplete/v/2.3.6)
|
|
30
|
+
(to `dependencies`)
|
|
31
|
+
|
|
32
|
+
- [#1441](https://github.com/graphprotocol/graph-tooling/pull/1441)
|
|
33
|
+
[`2e656e9`](https://github.com/graphprotocol/graph-tooling/commit/2e656e9cdaaea6d87866adaa142da597fcd7ce65)
|
|
34
|
+
Thanks [@saihaj](https://github.com/saihaj)! - dependencies updates:
|
|
35
|
+
|
|
36
|
+
- Added dependency
|
|
37
|
+
[`@oclif/plugin-not-found@^2.4.0` ↗︎](https://www.npmjs.com/package/@oclif/plugin-not-found/v/2.4.0)
|
|
38
|
+
(to `dependencies`)
|
|
39
|
+
|
|
40
|
+
- [#1435](https://github.com/graphprotocol/graph-tooling/pull/1435)
|
|
41
|
+
[`f05b47c`](https://github.com/graphprotocol/graph-tooling/commit/f05b47cf64912d0c66255c9f0076f1696a708ff2)
|
|
42
|
+
Thanks [@saihaj](https://github.com/saihaj)! - update prettier
|
|
43
|
+
|
|
44
|
+
- [#1433](https://github.com/graphprotocol/graph-tooling/pull/1433)
|
|
45
|
+
[`4492e4f`](https://github.com/graphprotocol/graph-tooling/commit/4492e4fdefb48407ef89df82eeef4d92bb0747e9)
|
|
46
|
+
Thanks [@saihaj](https://github.com/saihaj)! - when generating nested tuples make sure they are
|
|
47
|
+
non-nullable
|
|
48
|
+
|
|
49
|
+
- [#1433](https://github.com/graphprotocol/graph-tooling/pull/1433)
|
|
50
|
+
[`4492e4f`](https://github.com/graphprotocol/graph-tooling/commit/4492e4fdefb48407ef89df82eeef4d92bb0747e9)
|
|
51
|
+
Thanks [@saihaj](https://github.com/saihaj)! - 2D arrays are valid entities
|
|
11
52
|
|
|
12
53
|
## 0.56.0
|
|
13
54
|
|
|
@@ -637,8 +678,8 @@
|
|
|
637
678
|
[`044cd92`](https://github.com/graphprotocol/graph-tooling/commit/044cd92d0ceb9628c7f7fbe3627a09b867710247)
|
|
638
679
|
Thanks [@enisdenjo](https://github.com/enisdenjo)! - dependencies updates:
|
|
639
680
|
|
|
640
|
-
- Added dependency [`@oclif/core@2.0.7` ↗︎](https://www.npmjs.com/package/@oclif/core/v/2.0.7)
|
|
641
|
-
`dependencies`)
|
|
681
|
+
- Added dependency [`@oclif/core@2.0.7` ↗︎](https://www.npmjs.com/package/@oclif/core/v/2.0.7)
|
|
682
|
+
(to `dependencies`)
|
|
642
683
|
|
|
643
684
|
- [#1074](https://github.com/graphprotocol/graph-tooling/pull/1074)
|
|
644
685
|
[`e84d1e8`](https://github.com/graphprotocol/graph-tooling/commit/e84d1e873d9b2a8967c5fe2a85fce48b2caeb75f)
|
|
@@ -734,8 +775,8 @@
|
|
|
734
775
|
[`4c5e452`](https://github.com/graphprotocol/graph-cli/commit/4c5e452cbc2eceb75db29019fb3b4c769c9618f4)
|
|
735
776
|
Thanks [@saihaj](https://github.com/saihaj)! - dependencies updates:
|
|
736
777
|
|
|
737
|
-
- Updated dependency [`immutable@4.2.1` ↗︎](https://www.npmjs.com/package/immutable/v/4.2.1)
|
|
738
|
-
`3.8.2`, in `dependencies`)
|
|
778
|
+
- Updated dependency [`immutable@4.2.1` ↗︎](https://www.npmjs.com/package/immutable/v/4.2.1)
|
|
779
|
+
(from `3.8.2`, in `dependencies`)
|
|
739
780
|
|
|
740
781
|
- [`d42f199`](https://github.com/graphprotocol/graph-cli/commit/d42f199502df7bac79e8cafc667d5c712f5a3599)
|
|
741
782
|
Thanks [@darienmh](https://github.com/darienmh)! - fix `chapel` network etherscan URL
|
package/dist/codegen/schema.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { DefinitionNode, FieldDefinitionNode, InterfaceTypeDefinitionNode, NamedTypeNode, ObjectTypeDefinitionNode, TypeNode } from 'graphql/language';
|
|
1
2
|
import Schema from '../schema';
|
|
2
3
|
import * as tsCodegen from './typescript';
|
|
3
|
-
import type { DefinitionNode, FieldDefinitionNode, InterfaceTypeDefinitionNode, NamedTypeNode, ObjectTypeDefinitionNode, TypeNode } from 'graphql/language';
|
|
4
4
|
declare class IdField {
|
|
5
5
|
static BYTES: symbol;
|
|
6
6
|
static STRING: symbol;
|
|
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.loadAbiFromBlockScout = exports.getStartBlockForContract = exports.fetchTransactionByHashFromRPC = exports.fetchContractCreationHashWithRetry = exports.fetchDeployContractTransactionFromEtherscan = exports.loadStartBlockForContract = exports.loadAbiFromEtherscan = void 0;
|
|
7
|
-
const fetch_1 = require("@whatwg-node/fetch");
|
|
8
7
|
const immutable_1 = __importDefault(require("immutable"));
|
|
8
|
+
const fetch_1 = require("@whatwg-node/fetch");
|
|
9
9
|
const spinner_1 = require("./spinner");
|
|
10
10
|
const loadAbiFromEtherscan = async (ABICtor, network, address) => await (0, spinner_1.withSpinner)(`Fetching ABI from Etherscan`, `Failed to fetch ABI from Etherscan`, `Warnings while fetching ABI from Etherscan`, async () => {
|
|
11
11
|
const scanApiUrl = getEtherscanLikeAPIUrl(network);
|
|
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.fromManifest = exports.fromManifestString = exports.fromFilePath = void 0;
|
|
7
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
8
7
|
const immutable_1 = __importDefault(require("immutable"));
|
|
8
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
9
9
|
const load_manifest_1 = require("../migrations/util/load-manifest");
|
|
10
10
|
// Loads manifest from file path and returns all:
|
|
11
11
|
// - data sources
|
|
@@ -15,26 +15,26 @@ export declare const generateScaffold: ({ protocolInstance, abi, contract, netwo
|
|
|
15
15
|
node?: string | undefined;
|
|
16
16
|
spkgPath?: string | undefined;
|
|
17
17
|
}, spinner: Spinner) => Promise<{
|
|
18
|
-
'subgraph.yaml': string
|
|
19
|
-
'schema.graphql': string
|
|
20
|
-
'package.json': string
|
|
18
|
+
'subgraph.yaml': Promise<string>;
|
|
19
|
+
'schema.graphql': Promise<string>;
|
|
20
|
+
'package.json': Promise<string>;
|
|
21
21
|
'tsconfig.json'?: undefined;
|
|
22
22
|
src?: undefined;
|
|
23
23
|
abis?: undefined;
|
|
24
24
|
tests?: undefined;
|
|
25
25
|
} | {
|
|
26
|
-
'package.json': string
|
|
27
|
-
'subgraph.yaml': string
|
|
28
|
-
'schema.graphql': string
|
|
29
|
-
'tsconfig.json': string
|
|
26
|
+
'package.json': Promise<string>;
|
|
27
|
+
'subgraph.yaml': Promise<string>;
|
|
28
|
+
'schema.graphql': Promise<string>;
|
|
29
|
+
'tsconfig.json': Promise<string>;
|
|
30
30
|
src: {
|
|
31
|
-
[x: string]: string
|
|
31
|
+
[x: string]: Promise<string>;
|
|
32
32
|
} | undefined;
|
|
33
33
|
abis: {
|
|
34
|
-
[x: string]: string
|
|
34
|
+
[x: string]: Promise<string>;
|
|
35
35
|
} | undefined;
|
|
36
36
|
tests: {
|
|
37
|
-
[x: string]: string
|
|
37
|
+
[x: string]: Promise<string>;
|
|
38
38
|
} | undefined;
|
|
39
39
|
}>;
|
|
40
40
|
export declare const writeScaffold: (scaffold: any, directory: string, spinner: Spinner) => Promise<void>;
|
|
@@ -17,9 +17,13 @@ const tests_1 = require("../scaffold/tests");
|
|
|
17
17
|
const spinner_1 = require("./spinner");
|
|
18
18
|
const generateDataSource = async (protocol, contractName, network, contractAddress, abi, startBlock) => {
|
|
19
19
|
const protocolManifest = protocol.getManifestScaffold();
|
|
20
|
-
return immutable_1.Map.of('kind', protocol.name, 'name', contractName, 'network', network, 'source', yaml_1.default.parse(prettier_1.default.format(protocolManifest.source({
|
|
20
|
+
return immutable_1.Map.of('kind', protocol.name, 'name', contractName, 'network', network, 'source', yaml_1.default.parse(await prettier_1.default.format(protocolManifest.source({
|
|
21
|
+
contract: contractAddress,
|
|
22
|
+
contractName,
|
|
23
|
+
startBlock,
|
|
24
|
+
}), {
|
|
21
25
|
parser: 'yaml',
|
|
22
|
-
})), 'mapping', yaml_1.default.parse(prettier_1.default.format(protocolManifest.mapping({ abi, contractName }), {
|
|
26
|
+
})), 'mapping', yaml_1.default.parse(await prettier_1.default.format(protocolManifest.mapping({ abi, contractName }), {
|
|
23
27
|
parser: 'yaml',
|
|
24
28
|
}))).asMutable();
|
|
25
29
|
};
|
package/dist/commands/add.js
CHANGED
|
@@ -26,10 +26,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const core_1 = require("@oclif/core");
|
|
30
|
-
const errors_1 = require("@oclif/core/lib/errors");
|
|
31
29
|
const gluegun_1 = require("gluegun");
|
|
32
30
|
const immutable_1 = __importDefault(require("immutable"));
|
|
31
|
+
const core_1 = require("@oclif/core");
|
|
32
|
+
const errors_1 = require("@oclif/core/lib/errors");
|
|
33
33
|
const abi_1 = require("../command-helpers/abi");
|
|
34
34
|
const DataSourcesExtractor = __importStar(require("../command-helpers/data-sources"));
|
|
35
35
|
const network_1 = require("../command-helpers/network");
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@oclif/core");
|
|
4
3
|
const gluegun_1 = require("gluegun");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
5
|
const auth_1 = require("../command-helpers/auth");
|
|
6
6
|
const node_1 = require("../command-helpers/node");
|
|
7
7
|
class AuthCommand extends core_1.Command {
|
package/dist/commands/build.js
CHANGED
|
@@ -26,8 +26,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const core_1 = require("@oclif/core");
|
|
30
29
|
const gluegun_1 = require("gluegun");
|
|
30
|
+
const core_1 = require("@oclif/core");
|
|
31
31
|
const compiler_1 = require("../command-helpers/compiler");
|
|
32
32
|
const DataSourcesExtractor = __importStar(require("../command-helpers/data-sources"));
|
|
33
33
|
const network_1 = require("../command-helpers/network");
|
package/dist/commands/clean.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@oclif/core");
|
|
4
3
|
const gluegun_1 = require("gluegun");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
5
|
class CleanCommand extends core_1.Command {
|
|
6
6
|
async run() {
|
|
7
7
|
const { flags: { 'codegen-dir': codegenDir, 'build-dir': buildDir }, } = await this.parse(CleanCommand);
|
package/dist/commands/create.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const url_1 = require("url");
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
4
|
const gluegun_1 = require("gluegun");
|
|
5
|
+
const core_1 = require("@oclif/core");
|
|
6
6
|
const auth_1 = require("../command-helpers/auth");
|
|
7
7
|
const jsonrpc_1 = require("../command-helpers/jsonrpc");
|
|
8
8
|
const node_1 = require("../command-helpers/node");
|
package/dist/commands/deploy.js
CHANGED
|
@@ -28,8 +28,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const path_1 = __importDefault(require("path"));
|
|
30
30
|
const url_1 = require("url");
|
|
31
|
-
const core_1 = require("@oclif/core");
|
|
32
31
|
const gluegun_1 = require("gluegun");
|
|
32
|
+
const ipfs_http_client_1 = require("ipfs-http-client");
|
|
33
|
+
const core_1 = require("@oclif/core");
|
|
33
34
|
const auth_1 = require("../command-helpers/auth");
|
|
34
35
|
const compiler_1 = require("../command-helpers/compiler");
|
|
35
36
|
const DataSourcesExtractor = __importStar(require("../command-helpers/data-sources"));
|
|
@@ -40,7 +41,6 @@ const node_1 = require("../command-helpers/node");
|
|
|
40
41
|
const studio_1 = require("../command-helpers/studio");
|
|
41
42
|
const version_1 = require("../command-helpers/version");
|
|
42
43
|
const protocols_1 = __importDefault(require("../protocols"));
|
|
43
|
-
const ipfs_http_client_1 = require("ipfs-http-client");
|
|
44
44
|
const headersFlag = core_1.Flags.custom({
|
|
45
45
|
summary: 'Add custom headers that will be used by the IPFS HTTP client.',
|
|
46
46
|
aliases: ['hdr'],
|
package/dist/commands/init.js
CHANGED
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const fs_1 = __importDefault(require("fs"));
|
|
7
7
|
const os_1 = __importDefault(require("os"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const core_1 = require("@oclif/core");
|
|
10
9
|
const gluegun_1 = require("gluegun");
|
|
10
|
+
const core_1 = require("@oclif/core");
|
|
11
11
|
const abi_1 = require("../command-helpers/abi");
|
|
12
12
|
const network_1 = require("../command-helpers/network");
|
|
13
13
|
const node_1 = require("../command-helpers/node");
|
package/dist/commands/local.js
CHANGED
|
@@ -7,11 +7,11 @@ const child_process_1 = require("child_process");
|
|
|
7
7
|
const http_1 = __importDefault(require("http"));
|
|
8
8
|
const net_1 = __importDefault(require("net"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const core_1 = require("@oclif/core");
|
|
11
10
|
const docker_compose_1 = __importDefault(require("docker-compose"));
|
|
12
11
|
const gluegun_1 = require("gluegun");
|
|
13
12
|
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
|
14
13
|
const tmp_promise_1 = __importDefault(require("tmp-promise"));
|
|
14
|
+
const core_1 = require("@oclif/core");
|
|
15
15
|
const spinner_1 = require("../command-helpers/spinner");
|
|
16
16
|
// Clean up temporary files even when an uncaught exception occurs
|
|
17
17
|
tmp_promise_1.default.setGracefulCleanup();
|
package/dist/commands/remove.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const url_1 = require("url");
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
4
|
const gluegun_1 = require("gluegun");
|
|
5
|
+
const core_1 = require("@oclif/core");
|
|
6
6
|
const auth_1 = require("../command-helpers/auth");
|
|
7
7
|
const jsonrpc_1 = require("../command-helpers/jsonrpc");
|
|
8
8
|
const node_1 = require("../command-helpers/node");
|
package/dist/commands/test.js
CHANGED
|
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const child_process_1 = require("child_process");
|
|
7
7
|
const os_1 = __importDefault(require("os"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const core_1 = require("@oclif/core");
|
|
10
|
-
const fetch_1 = require("@whatwg-node/fetch");
|
|
11
9
|
const binary_install_raw_1 = require("binary-install-raw");
|
|
12
10
|
const gluegun_1 = require("gluegun");
|
|
13
11
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
14
12
|
const semver_1 = __importDefault(require("semver"));
|
|
13
|
+
const core_1 = require("@oclif/core");
|
|
14
|
+
const fetch_1 = require("@whatwg-node/fetch");
|
|
15
15
|
class TestCommand extends core_1.Command {
|
|
16
16
|
async run() {
|
|
17
17
|
const { args: { datasource }, flags: { coverage, docker, force, logs, recompile, version }, } = await this.parse(TestCommand);
|
package/dist/debug.js
CHANGED
|
@@ -11,6 +11,12 @@ debug_1.default.formatters.M = immutableMap => {
|
|
|
11
11
|
if (immutableMap.toMap != null) {
|
|
12
12
|
return JSON.stringify(immutableMap.toMap());
|
|
13
13
|
}
|
|
14
|
+
if (typeof immutableMap.toJS === 'function') {
|
|
15
|
+
return JSON.stringify(immutableMap.toJS());
|
|
16
|
+
}
|
|
17
|
+
if (typeof immutableMap === 'object') {
|
|
18
|
+
return JSON.stringify(immutableMap);
|
|
19
|
+
}
|
|
14
20
|
return immutableMap;
|
|
15
21
|
};
|
|
16
22
|
exports.default = debug_1.default;
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
scalar String
|
|
8
8
|
scalar File
|
|
9
9
|
scalar BigInt
|
|
10
|
-
scalar JSON
|
|
11
10
|
|
|
12
11
|
type SubgraphManifest {
|
|
13
12
|
specVersion: String!
|
|
@@ -26,7 +25,6 @@ type DataSource {
|
|
|
26
25
|
kind: String!
|
|
27
26
|
name: String!
|
|
28
27
|
network: String
|
|
29
|
-
context: JSON
|
|
30
28
|
source: ContractSource!
|
|
31
29
|
mapping: ContractMapping!
|
|
32
30
|
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
scalar String
|
|
8
8
|
scalar File
|
|
9
9
|
scalar BigInt
|
|
10
|
-
scalar JSON
|
|
11
10
|
|
|
12
11
|
type SubgraphManifest {
|
|
13
12
|
specVersion: String!
|
|
@@ -27,7 +26,6 @@ type DataSource {
|
|
|
27
26
|
kind: String!
|
|
28
27
|
name: String!
|
|
29
28
|
network: String
|
|
30
|
-
context: JSON
|
|
31
29
|
source: ContractSource!
|
|
32
30
|
mapping: ContractMapping!
|
|
33
31
|
}
|
|
@@ -8,7 +8,6 @@ scalar String
|
|
|
8
8
|
scalar File
|
|
9
9
|
scalar BigInt
|
|
10
10
|
scalar Boolean
|
|
11
|
-
scalar JSON
|
|
12
11
|
|
|
13
12
|
type SubgraphManifest {
|
|
14
13
|
specVersion: String!
|
|
@@ -29,7 +28,6 @@ type DataSource {
|
|
|
29
28
|
kind: String!
|
|
30
29
|
name: String!
|
|
31
30
|
network: String
|
|
32
|
-
context: JSON
|
|
33
31
|
source: ContractSource!
|
|
34
32
|
mapping: ContractMapping!
|
|
35
33
|
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
scalar String
|
|
8
8
|
scalar File
|
|
9
9
|
scalar BigInt
|
|
10
|
-
scalar JSON
|
|
11
10
|
|
|
12
11
|
type SubgraphManifest {
|
|
13
12
|
specVersion: String!
|
|
@@ -27,7 +26,6 @@ type DataSource {
|
|
|
27
26
|
kind: String!
|
|
28
27
|
name: String!
|
|
29
28
|
network: String
|
|
30
|
-
context: JSON
|
|
31
29
|
source: ContractSource!
|
|
32
30
|
mapping: ContractMapping!
|
|
33
31
|
}
|
package/dist/scaffold/index.d.ts
CHANGED
|
@@ -24,42 +24,42 @@ export default class Scaffold {
|
|
|
24
24
|
startBlock?: string;
|
|
25
25
|
spkgPath?: string;
|
|
26
26
|
constructor(options: ScaffoldOptions);
|
|
27
|
-
generatePackageJson(): string
|
|
28
|
-
generatePackageJsonForSubstreams(): string
|
|
29
|
-
generateManifest(): string
|
|
30
|
-
generateSchema(): string
|
|
31
|
-
generateTsConfig(): string
|
|
27
|
+
generatePackageJson(): Promise<string>;
|
|
28
|
+
generatePackageJsonForSubstreams(): Promise<string>;
|
|
29
|
+
generateManifest(): Promise<string>;
|
|
30
|
+
generateSchema(): Promise<string>;
|
|
31
|
+
generateTsConfig(): Promise<string>;
|
|
32
32
|
generateMappings(): {
|
|
33
|
-
[x: string]: string
|
|
33
|
+
[x: string]: Promise<string>;
|
|
34
34
|
} | undefined;
|
|
35
|
-
generateMapping(): string
|
|
35
|
+
generateMapping(): Promise<string>;
|
|
36
36
|
generateABIs(): {
|
|
37
|
-
[x: string]: string
|
|
37
|
+
[x: string]: Promise<string>;
|
|
38
38
|
} | undefined;
|
|
39
39
|
generateTests(): {
|
|
40
|
-
[x: string]: string
|
|
40
|
+
[x: string]: Promise<string>;
|
|
41
41
|
} | undefined;
|
|
42
42
|
generate(): {
|
|
43
|
-
'subgraph.yaml': string
|
|
44
|
-
'schema.graphql': string
|
|
45
|
-
'package.json': string
|
|
43
|
+
'subgraph.yaml': Promise<string>;
|
|
44
|
+
'schema.graphql': Promise<string>;
|
|
45
|
+
'package.json': Promise<string>;
|
|
46
46
|
'tsconfig.json'?: undefined;
|
|
47
47
|
src?: undefined;
|
|
48
48
|
abis?: undefined;
|
|
49
49
|
tests?: undefined;
|
|
50
50
|
} | {
|
|
51
|
-
'package.json': string
|
|
52
|
-
'subgraph.yaml': string
|
|
53
|
-
'schema.graphql': string
|
|
54
|
-
'tsconfig.json': string
|
|
51
|
+
'package.json': Promise<string>;
|
|
52
|
+
'subgraph.yaml': Promise<string>;
|
|
53
|
+
'schema.graphql': Promise<string>;
|
|
54
|
+
'tsconfig.json': Promise<string>;
|
|
55
55
|
src: {
|
|
56
|
-
[x: string]: string
|
|
56
|
+
[x: string]: Promise<string>;
|
|
57
57
|
} | undefined;
|
|
58
58
|
abis: {
|
|
59
|
-
[x: string]: string
|
|
59
|
+
[x: string]: Promise<string>;
|
|
60
60
|
} | undefined;
|
|
61
61
|
tests: {
|
|
62
|
-
[x: string]: string
|
|
62
|
+
[x: string]: Promise<string>;
|
|
63
63
|
} | undefined;
|
|
64
64
|
};
|
|
65
65
|
}
|
package/dist/scaffold/schema.js
CHANGED
|
@@ -46,14 +46,18 @@ const protocolTypeToGraphQL = (protocol, name) => {
|
|
|
46
46
|
// TODO: this is a hack to make array type non-nullable
|
|
47
47
|
// We should refactor the way we convert the Values from ASC to GraphQL
|
|
48
48
|
// For arrays we always want non-nullable children
|
|
49
|
-
return convertedType.endsWith(']') ? convertedType.replace(
|
|
49
|
+
return convertedType.endsWith(']') ? convertedType.replace(/\]/g, '!]') : convertedType;
|
|
50
50
|
};
|
|
51
51
|
exports.protocolTypeToGraphQL = protocolTypeToGraphQL;
|
|
52
52
|
const generateField = ({ name, type, protocolName, }) => `${name}: ${(0, exports.protocolTypeToGraphQL)(protocolName, type)}! # ${type}`;
|
|
53
53
|
exports.generateField = generateField;
|
|
54
54
|
const generateEventFields = ({ index, input, protocolName, }) => input.type == 'tuple'
|
|
55
55
|
? util
|
|
56
|
-
.unrollTuple({
|
|
56
|
+
.unrollTuple({
|
|
57
|
+
value: input,
|
|
58
|
+
path: [input.name || `param${index}`],
|
|
59
|
+
index,
|
|
60
|
+
})
|
|
57
61
|
.map(({ path, type }) => (0, exports.generateField)({ name: path.join('_'), type, protocolName }))
|
|
58
62
|
: [
|
|
59
63
|
(0, exports.generateField)({
|
package/dist/scaffold/tests.d.ts
CHANGED
package/dist/schema.d.ts
CHANGED
package/dist/subgraph.js
CHANGED
|
@@ -49,8 +49,9 @@ const buildCombinedWarning = (filename, warnings) => warnings.size > 0
|
|
|
49
49
|
: null;
|
|
50
50
|
class Subgraph {
|
|
51
51
|
static async validate(data, protocol, { resolveFile }) {
|
|
52
|
-
subgraphDebug(
|
|
52
|
+
subgraphDebug.extend('validate')('Validating Subgraph with protocol %M', protocol);
|
|
53
53
|
if (protocol.name == null) {
|
|
54
|
+
subgraphDebug.extend('validate')('Protocol has no name, skipping validation');
|
|
54
55
|
return immutable_1.default.fromJS([
|
|
55
56
|
{
|
|
56
57
|
path: [],
|
|
@@ -66,13 +67,18 @@ class Subgraph {
|
|
|
66
67
|
return definition.name.value === 'SubgraphManifest';
|
|
67
68
|
});
|
|
68
69
|
// Validate the subgraph manifest using this schema
|
|
69
|
-
return validation.validateManifest(data, rootType, schema, protocol, {
|
|
70
|
+
return validation.validateManifest(data, rootType, schema, protocol, {
|
|
71
|
+
resolveFile,
|
|
72
|
+
});
|
|
70
73
|
}
|
|
71
74
|
static validateSchema(manifest, { resolveFile }) {
|
|
75
|
+
subgraphDebug.extend('validate')('Validating schema in manifest');
|
|
72
76
|
const filename = resolveFile(manifest.getIn(['schema', 'file']));
|
|
77
|
+
subgraphDebug.extend('validate')('Loaded schema from %s', filename);
|
|
73
78
|
const validationErrors = validation.validateSchema(filename);
|
|
74
79
|
let errors;
|
|
75
80
|
if (validationErrors.size > 0) {
|
|
81
|
+
subgraphDebug.extend('validate')('Schema validation failed for %s', filename);
|
|
76
82
|
errors = validationErrors.groupBy(error => error.get('entity')).sort();
|
|
77
83
|
const msg = errors.reduce((msg, errors, entity) => {
|
|
78
84
|
errors = errors.groupBy((error) => error.get('directive'));
|
|
@@ -94,6 +100,7 @@ class Subgraph {
|
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
102
|
static validateRepository(manifest) {
|
|
103
|
+
subgraphDebug.extend('validate')('Validating repository in manifest');
|
|
97
104
|
const repository = manifest.get('repository');
|
|
98
105
|
return /^https:\/\/github\.com\/graphprotocol\/graph-tooling?$/.test(repository) ||
|
|
99
106
|
// For legacy reasons, we should error on example subgraphs
|
|
@@ -107,6 +114,7 @@ Please replace it with a link to your subgraph source code.`,
|
|
|
107
114
|
: immutable_1.default.List();
|
|
108
115
|
}
|
|
109
116
|
static validateDescription(manifest) {
|
|
117
|
+
subgraphDebug.extend('validate')('Validating description in manifest');
|
|
110
118
|
// TODO: Maybe implement this in the future for each protocol example description
|
|
111
119
|
return manifest.get('description', '').startsWith('Gravatar for ')
|
|
112
120
|
? immutable_1.default.List().push(immutable_1.default.fromJS({
|
|
@@ -118,6 +126,7 @@ Please update it to tell users more about your subgraph.`,
|
|
|
118
126
|
: immutable_1.default.List();
|
|
119
127
|
}
|
|
120
128
|
static validateHandlers(manifest, protocol, protocolSubgraph) {
|
|
129
|
+
subgraphDebug.extend('validate')('Validating handlers for protocol %s', protocol?.name);
|
|
121
130
|
return manifest
|
|
122
131
|
.get('dataSources')
|
|
123
132
|
.filter((dataSource) => protocol.isValidKindName(dataSource.get('kind')))
|
|
@@ -125,7 +134,7 @@ Please update it to tell users more about your subgraph.`,
|
|
|
125
134
|
const path = ['dataSources', dataSourceIndex, 'mapping'];
|
|
126
135
|
const mapping = dataSource.get('mapping');
|
|
127
136
|
const handlerTypes = protocolSubgraph.handlerTypes();
|
|
128
|
-
subgraphDebug('Validating dataSource "%s" handlers with %d handlers types defined for protocol', dataSource.get('name'), handlerTypes.size);
|
|
137
|
+
subgraphDebug.extend('validate')('Validating dataSource "%s" handlers with %d handlers types defined for protocol', dataSource.get('name'), handlerTypes.size);
|
|
129
138
|
if (handlerTypes.size == 0) {
|
|
130
139
|
return errors;
|
|
131
140
|
}
|
|
@@ -144,13 +153,16 @@ At least one such handler must be defined.`,
|
|
|
144
153
|
}, immutable_1.default.List());
|
|
145
154
|
}
|
|
146
155
|
static validateContractValues(manifest, protocol) {
|
|
156
|
+
subgraphDebug.extend('validate')('Validating contract values for protocol %s', protocol?.name);
|
|
147
157
|
if (!protocol.hasContract()) {
|
|
158
|
+
subgraphDebug.extend('validate')('Protocol has no contract, skipping validation');
|
|
148
159
|
return immutable_1.default.List();
|
|
149
160
|
}
|
|
150
161
|
return validation.validateContractValues(manifest, protocol);
|
|
151
162
|
}
|
|
152
163
|
// Validate that data source names are unique, so they don't overwrite each other.
|
|
153
164
|
static validateUniqueDataSourceNames(manifest) {
|
|
165
|
+
subgraphDebug.extend('validate')('Validating that data source names are unique');
|
|
154
166
|
const names = [];
|
|
155
167
|
return manifest
|
|
156
168
|
.get('dataSources')
|
|
@@ -158,6 +170,7 @@ At least one such handler must be defined.`,
|
|
|
158
170
|
const path = ['dataSources', dataSourceIndex, 'name'];
|
|
159
171
|
const name = dataSource.get('name');
|
|
160
172
|
if (names.includes(name)) {
|
|
173
|
+
subgraphDebug.extend('validate')("Found duplicate data source name '%s', adding error");
|
|
161
174
|
errors = errors.push(immutable_1.default.fromJS({
|
|
162
175
|
path,
|
|
163
176
|
message: `\
|
|
@@ -169,6 +182,7 @@ More than one data source named '${name}', data source names must be unique.`,
|
|
|
169
182
|
}, immutable_1.default.List());
|
|
170
183
|
}
|
|
171
184
|
static validateUniqueTemplateNames(manifest) {
|
|
185
|
+
subgraphDebug.extend('validate')('Validating that template names are unique');
|
|
172
186
|
const names = [];
|
|
173
187
|
return manifest
|
|
174
188
|
.get('templates', immutable_1.default.List())
|
|
@@ -176,6 +190,7 @@ More than one data source named '${name}', data source names must be unique.`,
|
|
|
176
190
|
const path = ['templates', templateIndex, 'name'];
|
|
177
191
|
const name = template.get('name');
|
|
178
192
|
if (names.includes(name)) {
|
|
193
|
+
subgraphDebug.extend('validate')("Found duplicate template name '%s', adding error");
|
|
179
194
|
errors = errors.push(immutable_1.default.fromJS({
|
|
180
195
|
path,
|
|
181
196
|
message: `\
|
|
@@ -202,21 +217,30 @@ More than one template named '${name}', template names must be unique.`,
|
|
|
202
217
|
data = require(path_1.default.resolve(filename));
|
|
203
218
|
}
|
|
204
219
|
else {
|
|
220
|
+
subgraphDebug('Loading manifest from %s', filename);
|
|
205
221
|
const raw_data = await fs_extra_1.default.readFile(filename, 'utf-8');
|
|
222
|
+
subgraphDebug('Checking for file data sources in %s', filename);
|
|
206
223
|
has_file_data_sources = raw_data.includes('kind: file');
|
|
224
|
+
subgraphDebug('Parsing manifest from %s', filename);
|
|
207
225
|
data = yaml_1.default.parse(raw_data);
|
|
208
226
|
}
|
|
209
227
|
// Helper to resolve files relative to the subgraph manifest
|
|
210
228
|
const resolveFile = maybeRelativeFile => path_1.default.resolve(path_1.default.dirname(filename), maybeRelativeFile);
|
|
211
229
|
// TODO: Validation for file data sources
|
|
212
230
|
if (!has_file_data_sources) {
|
|
213
|
-
|
|
231
|
+
subgraphDebug('Validating manifest from %s', filename);
|
|
232
|
+
const manifestErrors = await Subgraph.validate(data, protocol, {
|
|
233
|
+
resolveFile,
|
|
234
|
+
});
|
|
214
235
|
if (manifestErrors.size > 0) {
|
|
236
|
+
subgraphDebug('Manifest validation failed for %s', filename);
|
|
215
237
|
throwCombinedError(filename, manifestErrors);
|
|
216
238
|
}
|
|
217
239
|
}
|
|
218
240
|
const manifest = immutable_1.default.fromJS(data);
|
|
241
|
+
subgraphDebug.extend('manifest')('Loaded: %M', manifest);
|
|
219
242
|
// Validate the schema
|
|
243
|
+
subgraphDebug.extend('manifest')('Validating schema');
|
|
220
244
|
Subgraph.validateSchema(manifest, { resolveFile });
|
|
221
245
|
// Perform other validations
|
|
222
246
|
const protocolSubgraph = protocol.getSubgraph({
|
package/dist/type-generator.js
CHANGED
|
@@ -27,13 +27,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const path_1 = __importDefault(require("path"));
|
|
30
|
-
// @ts-expect-error TODO: type out if necessary
|
|
31
|
-
const Index_bs_js_1 = __importDefault(require("@float-capital/float-subgraph-uncrashable/src/Index.bs.js"));
|
|
32
30
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
33
31
|
const toolbox = __importStar(require("gluegun"));
|
|
34
32
|
const graphql = __importStar(require("graphql/language"));
|
|
35
33
|
const immutable_1 = __importDefault(require("immutable"));
|
|
36
34
|
const prettier_1 = __importDefault(require("prettier"));
|
|
35
|
+
// @ts-expect-error TODO: type out if necessary
|
|
36
|
+
const Index_bs_js_1 = __importDefault(require("@float-capital/float-subgraph-uncrashable/src/Index.bs.js"));
|
|
37
37
|
const template_1 = __importDefault(require("./codegen/template"));
|
|
38
38
|
const typescript_1 = require("./codegen/typescript");
|
|
39
39
|
const fs_1 = require("./command-helpers/fs");
|
|
@@ -154,20 +154,6 @@ const validators = immutable_1.default.fromJS({
|
|
|
154
154
|
message: `Expected filename, found ${typeName(value)}:\n${value}`,
|
|
155
155
|
},
|
|
156
156
|
]),
|
|
157
|
-
JSON: (value, ctx) => {
|
|
158
|
-
try {
|
|
159
|
-
JSON.parse(JSON.stringify(value));
|
|
160
|
-
return List();
|
|
161
|
-
}
|
|
162
|
-
catch (e) {
|
|
163
|
-
return immutable_1.default.fromJS([
|
|
164
|
-
{
|
|
165
|
-
path: ctx.get('path'),
|
|
166
|
-
message: `Invalid JSON value: ${e.message}`,
|
|
167
|
-
},
|
|
168
|
-
]);
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
157
|
Boolean: (value, ctx) => typeof value === 'boolean'
|
|
172
158
|
? List()
|
|
173
159
|
: immutable_1.default.fromJS([
|
|
@@ -30,6 +30,8 @@ exports.validateSchema = exports.typeSuggestion = void 0;
|
|
|
30
30
|
const fs_1 = __importDefault(require("fs"));
|
|
31
31
|
const graphql = __importStar(require("graphql/language"));
|
|
32
32
|
const immutable_1 = __importDefault(require("immutable"));
|
|
33
|
+
const debug_1 = __importDefault(require("../debug"));
|
|
34
|
+
const validateDebugger = (0, debug_1.default)('graph-cli:validation');
|
|
33
35
|
const List = immutable_1.default.List;
|
|
34
36
|
const Set = immutable_1.default.Set;
|
|
35
37
|
// Builtin scalar types
|
|
@@ -101,18 +103,23 @@ const parseSchema = (doc) => {
|
|
|
101
103
|
throw new Error(`Invalid GraphQL schema: ${e}`);
|
|
102
104
|
}
|
|
103
105
|
};
|
|
104
|
-
const validateEntityDirective = (def) =>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
const validateEntityDirective = (def) => {
|
|
107
|
+
validateDebugger('Validating entity directive for %s', def?.name?.value);
|
|
108
|
+
return def.directives.find((directive) => directive.name.value === 'entity')
|
|
109
|
+
? List()
|
|
110
|
+
: immutable_1.default.fromJS([
|
|
111
|
+
{
|
|
112
|
+
loc: def.loc,
|
|
113
|
+
entity: def.name.value,
|
|
114
|
+
message: `Defined without @entity directive`,
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
};
|
|
113
118
|
const validateEntityID = (def) => {
|
|
119
|
+
validateDebugger('Validating entity ID for %s', def?.name?.value);
|
|
114
120
|
const idField = def.fields.find((field) => field.name.value === 'id');
|
|
115
121
|
if (idField === undefined) {
|
|
122
|
+
validateDebugger('Entity %s has no id field', def?.name?.value);
|
|
116
123
|
return immutable_1.default.fromJS([
|
|
117
124
|
{
|
|
118
125
|
loc: def.loc,
|
|
@@ -126,8 +133,10 @@ const validateEntityID = (def) => {
|
|
|
126
133
|
(idField.type.type.name.value === 'ID' ||
|
|
127
134
|
idField.type.type.name.value === 'Bytes' ||
|
|
128
135
|
idField.type.type.name.value === 'String')) {
|
|
136
|
+
validateDebugger('Entity %s has valid id field', def?.name?.value);
|
|
129
137
|
return List();
|
|
130
138
|
}
|
|
139
|
+
validateDebugger('Entity %s has invalid id field', def?.name?.value);
|
|
131
140
|
return immutable_1.default.fromJS([
|
|
132
141
|
{
|
|
133
142
|
loc: idField.loc,
|
|
@@ -136,52 +145,80 @@ const validateEntityID = (def) => {
|
|
|
136
145
|
},
|
|
137
146
|
]);
|
|
138
147
|
};
|
|
139
|
-
const validateListFieldType = (def, field) =>
|
|
140
|
-
field
|
|
141
|
-
field.type.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
loc: field.loc,
|
|
145
|
-
entity: def.name.value,
|
|
146
|
-
message: `\
|
|
147
|
-
Field '${field.name.value}':
|
|
148
|
-
Field has type [${field.type.type.name.value}]! but
|
|
149
|
-
must have type [${field.type.type.name.value}!]!
|
|
150
|
-
|
|
151
|
-
Reason: Lists with null elements are not supported.`,
|
|
152
|
-
},
|
|
153
|
-
])
|
|
154
|
-
: field.type.kind === 'ListType' && field.type.type.kind !== 'NonNullType'
|
|
148
|
+
const validateListFieldType = (def, field) => {
|
|
149
|
+
validateDebugger('Validating list field type for %s', def?.name?.value);
|
|
150
|
+
return field.type.kind === 'NonNullType' &&
|
|
151
|
+
field.type.kind === 'ListType' &&
|
|
152
|
+
field.type.type.kind !== 'NonNullType'
|
|
155
153
|
? immutable_1.default.fromJS([
|
|
156
154
|
{
|
|
157
155
|
loc: field.loc,
|
|
158
156
|
entity: def.name.value,
|
|
159
157
|
message: `\
|
|
160
158
|
Field '${field.name.value}':
|
|
161
|
-
Field has type [${field.type.type.name.value}] but
|
|
162
|
-
must have type [${field.type.type.name.value}!]
|
|
159
|
+
Field has type [${field.type.type.name.value}]! but
|
|
160
|
+
must have type [${field.type.type.name.value}!]!
|
|
163
161
|
|
|
164
162
|
Reason: Lists with null elements are not supported.`,
|
|
165
163
|
},
|
|
166
164
|
])
|
|
167
|
-
:
|
|
165
|
+
: field.type.kind === 'ListType' && field.type.type.kind !== 'NonNullType'
|
|
166
|
+
? immutable_1.default.fromJS([
|
|
167
|
+
{
|
|
168
|
+
loc: field.loc,
|
|
169
|
+
entity: def.name.value,
|
|
170
|
+
message: `\
|
|
171
|
+
Field '${field.name.value}':
|
|
172
|
+
Field has type [${field.type.type.name.value}] but
|
|
173
|
+
must have type [${field.type.type.name.value}!]
|
|
174
|
+
|
|
175
|
+
Reason: Lists with null elements are not supported.`,
|
|
176
|
+
},
|
|
177
|
+
])
|
|
178
|
+
: List();
|
|
179
|
+
};
|
|
168
180
|
const unwrapType = (type) => {
|
|
169
|
-
|
|
170
|
-
const
|
|
181
|
+
validateDebugger.extend('definition')('Unwrapping type %M', type);
|
|
182
|
+
const innerTypeFromList = (listType) => {
|
|
183
|
+
validateDebugger.extend('unwrapType').extend('definition')('Unwrapping list type %M', listType);
|
|
184
|
+
if (listType.type.kind === 'NonNullType') {
|
|
185
|
+
validateDebugger.extend('unwrapType').extend('innerTypeFromList')('Returning non-null list type');
|
|
186
|
+
return innerTypeFromNonNull(listType.type);
|
|
187
|
+
}
|
|
188
|
+
validateDebugger.extend('unwrapType').extend('innerTypeFromList')('Returning list type');
|
|
189
|
+
return unwrapType(listType.type);
|
|
190
|
+
};
|
|
191
|
+
const innerTypeFromNonNull = (nonNullType) => {
|
|
192
|
+
validateDebugger.extend('unwrapType').extend('definition')('Unwrapping non-null type %M', nonNullType);
|
|
193
|
+
if (nonNullType.type.kind === 'ListType') {
|
|
194
|
+
validateDebugger.extend('unwrapType').extend('innerTypeFromNonNull')('Returning non-null list type');
|
|
195
|
+
return innerTypeFromList(nonNullType.type);
|
|
196
|
+
}
|
|
197
|
+
validateDebugger.extend('unwrapType').extend('innerTypeFromNonNull')('Returning non-null type');
|
|
198
|
+
return unwrapType(nonNullType.type);
|
|
199
|
+
};
|
|
171
200
|
// Obtain the inner-most type from the field
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
if (type.kind === 'NonNullType') {
|
|
202
|
+
validateDebugger('Returning inner type from non-null type');
|
|
203
|
+
return innerTypeFromNonNull(type);
|
|
204
|
+
}
|
|
205
|
+
if (type.kind === 'ListType') {
|
|
206
|
+
validateDebugger('Returning inner type from list type');
|
|
207
|
+
return innerTypeFromList(type);
|
|
208
|
+
}
|
|
209
|
+
validateDebugger('Returning inner type');
|
|
210
|
+
return type;
|
|
211
|
+
};
|
|
212
|
+
const gatherLocalTypes = (defs) => {
|
|
213
|
+
validateDebugger('Gathering local types');
|
|
214
|
+
return defs
|
|
215
|
+
.filter(def => def.kind === 'ObjectTypeDefinition' ||
|
|
216
|
+
def.kind === 'EnumTypeDefinition' ||
|
|
217
|
+
def.kind === 'InterfaceTypeDefinition')
|
|
218
|
+
.map(def =>
|
|
219
|
+
// @ts-expect-error TODO: name field does not exist on definition, really?
|
|
220
|
+
def.name.value);
|
|
221
|
+
};
|
|
185
222
|
const gatherImportedTypes = (defs) => defs
|
|
186
223
|
.filter(def => def.kind === 'ObjectTypeDefinition' &&
|
|
187
224
|
def.name.value == RESERVED_TYPE &&
|
|
@@ -206,19 +243,28 @@ def.directives
|
|
|
206
243
|
}
|
|
207
244
|
return flattened;
|
|
208
245
|
}, [])), []);
|
|
209
|
-
const entityTypeByName = (defs, name) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
246
|
+
const entityTypeByName = (defs, name) => {
|
|
247
|
+
validateDebugger('Looking up entity type %s', name);
|
|
248
|
+
return defs
|
|
249
|
+
.filter(def => def.kind === 'InterfaceTypeDefinition' ||
|
|
250
|
+
(def.kind === 'ObjectTypeDefinition' &&
|
|
251
|
+
def.directives.find((directive) => directive.name.value === 'entity')))
|
|
252
|
+
.find(def => def.name.value === name);
|
|
253
|
+
};
|
|
254
|
+
const fieldTargetEntityName = (field) => {
|
|
255
|
+
validateDebugger('Looking up field target entity name for %s', field?.name?.value);
|
|
256
|
+
return unwrapType(field.type).name.value;
|
|
257
|
+
};
|
|
215
258
|
const fieldTargetEntity = (defs, field) => entityTypeByName(defs, fieldTargetEntityName(field));
|
|
216
259
|
const validateInnerFieldType = (defs, def, field) => {
|
|
260
|
+
validateDebugger('Validating inner field type for %s', def?.name?.value);
|
|
217
261
|
const innerType = unwrapType(field.type);
|
|
218
262
|
// Get the name of the type
|
|
219
263
|
const typeName = innerType.name.value;
|
|
264
|
+
validateDebugger('Inner field type name: %s', typeName);
|
|
220
265
|
// Look up a possible suggestion for the type to catch common mistakes
|
|
221
266
|
const suggestion = (0, exports.typeSuggestion)(typeName);
|
|
267
|
+
validateDebugger('Inner field type suggestion: %s', suggestion);
|
|
222
268
|
// Collect all types that we can use here: built-ins + entities + enums + interfaces
|
|
223
269
|
const availableTypes = List.of(...BUILTIN_SCALAR_TYPES, ...gatherLocalTypes(defs), ...gatherImportedTypes(defs));
|
|
224
270
|
// Check whether the type name is available, otherwise return an error
|
|
@@ -292,6 +338,7 @@ does not exist on type '${targetEntity.name.value}'`,
|
|
|
292
338
|
]);
|
|
293
339
|
}
|
|
294
340
|
const backrefTypeName = unwrapType(derivedFromField.type);
|
|
341
|
+
validateDebugger.extend('definition')('Backref type name: %M', backrefTypeName);
|
|
295
342
|
const backRefEntity = entityTypeByName(defs, backrefTypeName.name.value);
|
|
296
343
|
// The field we are deriving from must either have type 'def' or one of the
|
|
297
344
|
// interface types that 'def' is implementing
|
|
@@ -682,6 +729,7 @@ const validateImportDirectiveArgumentFrom = (def, directive, argument) => {
|
|
|
682
729
|
}, List());
|
|
683
730
|
};
|
|
684
731
|
const validateImportDirectiveFields = (def, directive) => {
|
|
732
|
+
validateDebugger('Validating import directive fields: %s', def?.name?.value);
|
|
685
733
|
return directive.arguments.reduce((errors, argument) => {
|
|
686
734
|
return errors.concat(['types', 'from'].includes(argument.name.value)
|
|
687
735
|
? List([])
|
|
@@ -695,6 +743,7 @@ const validateImportDirectiveFields = (def, directive) => {
|
|
|
695
743
|
}, List([]));
|
|
696
744
|
};
|
|
697
745
|
const validateImportDirectiveTypes = (def, directive) => {
|
|
746
|
+
validateDebugger('Validating import directive types: %s', def?.name?.value);
|
|
698
747
|
const types = directive.arguments.find((argument) => argument.name.value == 'types');
|
|
699
748
|
return types
|
|
700
749
|
? validateImportDirectiveArgumentTypes(def, directive, types)
|
|
@@ -707,6 +756,7 @@ const validateImportDirectiveTypes = (def, directive) => {
|
|
|
707
756
|
]);
|
|
708
757
|
};
|
|
709
758
|
const validateImportDirectiveFrom = (def, directive) => {
|
|
759
|
+
validateDebugger('Validating import directive from: %s', def?.name?.value);
|
|
710
760
|
const from = directive.arguments.find((argument) => argument.name.value == 'from');
|
|
711
761
|
return from
|
|
712
762
|
? validateImportDirectiveArgumentFrom(def, directive, from)
|
|
@@ -718,13 +768,19 @@ const validateImportDirectiveFrom = (def, directive) => {
|
|
|
718
768
|
}),
|
|
719
769
|
]);
|
|
720
770
|
};
|
|
721
|
-
const validateImportDirective = (def, directive) =>
|
|
771
|
+
const validateImportDirective = (def, directive) => {
|
|
772
|
+
validateDebugger('Validating import directive: %s', def?.name?.value);
|
|
773
|
+
return List.of(...validateImportDirectiveFields(def, directive), ...validateImportDirectiveTypes(def, directive), ...validateImportDirectiveFrom(def, directive));
|
|
774
|
+
};
|
|
722
775
|
const validateFulltext = (def, directive) => List.of(...validateFulltextFields(def, directive), ...validateFulltextName(def, directive), ...validateFulltextLanguage(def, directive), ...validateFulltextAlgorithm(def, directive), ...validateFulltextInclude(def, directive));
|
|
723
776
|
const validateSubgraphSchemaDirective = (def, directive) => {
|
|
777
|
+
validateDebugger('Validating subgraph schema directive: %s', def?.name?.value);
|
|
724
778
|
if (directive.name.value == 'import') {
|
|
779
|
+
validateDebugger('Validating import directive: %s', def?.name?.value);
|
|
725
780
|
return validateImportDirective(def, directive);
|
|
726
781
|
}
|
|
727
782
|
if (directive.name.value == 'fulltext') {
|
|
783
|
+
validateDebugger('Validating fulltext directive: %s', def?.name?.value);
|
|
728
784
|
return validateFulltext(def, directive);
|
|
729
785
|
}
|
|
730
786
|
return List([
|
|
@@ -735,32 +791,52 @@ const validateSubgraphSchemaDirective = (def, directive) => {
|
|
|
735
791
|
}),
|
|
736
792
|
]);
|
|
737
793
|
};
|
|
738
|
-
const validateSubgraphSchemaDirectives = (def) =>
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
794
|
+
const validateSubgraphSchemaDirectives = (def) => {
|
|
795
|
+
validateDebugger('Validating subgraph schema directives: %s', def?.name?.value);
|
|
796
|
+
return def.directives.reduce((errors, directive) => errors.concat(validateSubgraphSchemaDirective(def, directive)), List());
|
|
797
|
+
};
|
|
798
|
+
const validateTypeHasNoFields = (def) => {
|
|
799
|
+
validateDebugger('Validating type has no fields: %s', def?.name?.value);
|
|
800
|
+
return def.fields.length
|
|
801
|
+
? List([
|
|
802
|
+
immutable_1.default.fromJS({
|
|
803
|
+
loc: def.name.loc,
|
|
804
|
+
entity: def.name.value,
|
|
805
|
+
message: `${def.name.value} type is not allowed any fields by convention`,
|
|
806
|
+
}),
|
|
807
|
+
])
|
|
808
|
+
: List();
|
|
809
|
+
};
|
|
748
810
|
const validateAtLeastOneExtensionField = (_def) => List();
|
|
749
811
|
const typeDefinitionValidators = {
|
|
750
|
-
ObjectTypeDefinition: (defs, def) =>
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
812
|
+
ObjectTypeDefinition: (defs, def) => {
|
|
813
|
+
validateDebugger('Validating object type definition: %s', def?.name?.value);
|
|
814
|
+
return def.name && def.name.value == RESERVED_TYPE
|
|
815
|
+
? List.of(...validateSubgraphSchemaDirectives(def), ...validateTypeHasNoFields(def))
|
|
816
|
+
: List.of(...validateEntityDirective(def), ...validateEntityID(def), ...validateEntityFields(defs, def), ...validateNoImportDirective(def), ...validateNoFulltext(def));
|
|
817
|
+
},
|
|
818
|
+
ObjectTypeExtension: (_defs, def) => {
|
|
819
|
+
validateDebugger('Validating object type extension: %s', def?.name?.value);
|
|
820
|
+
return validateAtLeastOneExtensionField(def);
|
|
821
|
+
},
|
|
822
|
+
};
|
|
823
|
+
const validateTypeDefinition = (defs, def) => {
|
|
824
|
+
validateDebugger.extend('definition')('Validating type definition: %M', def);
|
|
825
|
+
return typeDefinitionValidators[def.kind] === undefined
|
|
826
|
+
? List()
|
|
827
|
+
: typeDefinitionValidators[def.kind](defs, def);
|
|
828
|
+
};
|
|
829
|
+
const validateTypeDefinitions = (defs) => {
|
|
830
|
+
validateDebugger('Validating type definitions');
|
|
831
|
+
return defs.reduce((errors, def) => errors.concat(validateTypeDefinition(defs, def)), List());
|
|
832
|
+
};
|
|
759
833
|
const validateNamingCollisionsInTypes = (types) => {
|
|
834
|
+
validateDebugger('Validating naming collisions in types');
|
|
760
835
|
let seen = Set();
|
|
761
836
|
let conflicting = Set();
|
|
762
837
|
return types.reduce((errors, type) => {
|
|
763
838
|
if (seen.has(type) && !conflicting.has(type)) {
|
|
839
|
+
validateDebugger('Found naming collision');
|
|
764
840
|
errors = errors.push(immutable_1.default.fromJS({
|
|
765
841
|
loc: { start: 1, end: 1 },
|
|
766
842
|
entity: type,
|
|
@@ -774,10 +850,16 @@ const validateNamingCollisionsInTypes = (types) => {
|
|
|
774
850
|
return errors;
|
|
775
851
|
}, List());
|
|
776
852
|
};
|
|
777
|
-
const validateNamingCollisions = (local, imported) =>
|
|
853
|
+
const validateNamingCollisions = (local, imported) => {
|
|
854
|
+
validateDebugger('Validating naming collisions');
|
|
855
|
+
return validateNamingCollisionsInTypes(local.concat(imported));
|
|
856
|
+
};
|
|
778
857
|
const validateSchema = (filename) => {
|
|
858
|
+
validateDebugger('Validating schema: %s', filename);
|
|
779
859
|
const doc = loadSchema(filename);
|
|
860
|
+
validateDebugger('Loaded schema: %s', filename);
|
|
780
861
|
const schema = parseSchema(doc);
|
|
862
|
+
validateDebugger.extend('schema')('Parsed schema: %M', schema);
|
|
781
863
|
return List.of(...validateTypeDefinitions(schema.definitions), ...validateNamingCollisions(gatherLocalTypes(schema.definitions), gatherImportedTypes(schema.definitions)));
|
|
782
864
|
};
|
|
783
865
|
exports.validateSchema = validateSchema;
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphprotocol/graph-cli",
|
|
3
|
-
"version": "0.57.0
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"description": "CLI for building for and deploying to The Graph",
|
|
5
5
|
"license": "(Apache-2.0 OR MIT)",
|
|
6
6
|
"engines": {
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4",
|
|
23
23
|
"@oclif/core": "2.8.6",
|
|
24
|
+
"@oclif/plugin-autocomplete": "^2.3.6",
|
|
25
|
+
"@oclif/plugin-not-found": "^2.4.0",
|
|
24
26
|
"@whatwg-node/fetch": "^0.8.4",
|
|
25
27
|
"assemblyscript": "0.19.23",
|
|
26
28
|
"binary-install-raw": "0.0.13",
|
|
@@ -72,6 +74,10 @@
|
|
|
72
74
|
],
|
|
73
75
|
"additionalVersionFlags": [
|
|
74
76
|
"-v"
|
|
77
|
+
],
|
|
78
|
+
"plugins": [
|
|
79
|
+
"@oclif/plugin-not-found",
|
|
80
|
+
"@oclif/plugin-autocomplete"
|
|
75
81
|
]
|
|
76
82
|
},
|
|
77
83
|
"scripts": {
|