@graphprotocol/graph-cli 0.51.0-alpha-20230530203813-7e94f46 → 0.51.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 +12 -2
- package/dist/codegen/schema.d.ts +7 -0
- package/dist/codegen/schema.js +96 -0
- package/dist/codegen/schema.test.js +2 -7
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.js +38 -0
- package/dist/type-generator.js +1 -0
- package/oclif.manifest.json +34 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
# @graphprotocol/graph-cli
|
|
2
2
|
|
|
3
|
-
## 0.51.0
|
|
3
|
+
## 0.51.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
+
- [#1340](https://github.com/graphprotocol/graph-tooling/pull/1340)
|
|
8
|
+
[`2375877`](https://github.com/graphprotocol/graph-tooling/commit/23758774b33b5b7c6934f57a3e137870205ca6f0)
|
|
9
|
+
Thanks [@incrypto32](https://github.com/incrypto32)! - Add support for codegen for derived field
|
|
10
|
+
loaders, This adds getters for derived fields defined in the schema for entities.
|
|
11
|
+
|
|
12
|
+
- [#1363](https://github.com/graphprotocol/graph-tooling/pull/1363)
|
|
13
|
+
[`f928262`](https://github.com/graphprotocol/graph-tooling/commit/f9282626d7e906cfdc0fc826bdbc92ff2c907e97)
|
|
14
|
+
Thanks [@saihaj](https://github.com/saihaj)! - add `graph clean` command to delete generated
|
|
15
|
+
artifacts
|
|
16
|
+
|
|
7
17
|
- [#1296](https://github.com/graphprotocol/graph-tooling/pull/1296)
|
|
8
|
-
[`
|
|
18
|
+
[`dab4ca1`](https://github.com/graphprotocol/graph-tooling/commit/dab4ca1f5df7dcd0928bbaa20304f41d23b20ced)
|
|
9
19
|
Thanks [@dotansimha](https://github.com/dotansimha)! - Added support for handling GraphQL `Int8`
|
|
10
20
|
scalar as `i64` (AssemblyScript)
|
|
11
21
|
|
package/dist/codegen/schema.d.ts
CHANGED
|
@@ -21,13 +21,20 @@ export default class SchemaCodeGenerator {
|
|
|
21
21
|
constructor(schema: Schema);
|
|
22
22
|
generateModuleImports(): tsCodegen.ModuleImports[];
|
|
23
23
|
generateTypes(): Array<tsCodegen.Class>;
|
|
24
|
+
generateDerivedLoaders(): any[];
|
|
24
25
|
_isEntityTypeDefinition(def: DefinitionNode): def is ObjectTypeDefinitionNode;
|
|
26
|
+
_isDerivedField(field: FieldDefinitionNode | undefined): boolean;
|
|
25
27
|
_isInterfaceDefinition(def: DefinitionNode): def is InterfaceTypeDefinitionNode;
|
|
26
28
|
_generateEntityType(def: ObjectTypeDefinitionNode): tsCodegen.Class;
|
|
29
|
+
_generateDerivedLoader(typeName: string): any;
|
|
30
|
+
_getTypeNameForField(gqlType: TypeNode): string;
|
|
27
31
|
_generateConstructor(_entityName: string, fields: readonly FieldDefinitionNode[] | undefined): tsCodegen.Method;
|
|
28
32
|
_generateStoreMethods(entityName: string, idField: IdField): Array<tsCodegen.Method | tsCodegen.StaticMethod>;
|
|
29
33
|
_generateEntityFieldMethods(entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode): Array<tsCodegen.Method>;
|
|
30
34
|
_generateEntityFieldGetter(_entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode): tsCodegen.Method;
|
|
35
|
+
_generateDerivedFieldGetter(entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode): tsCodegen.Method;
|
|
36
|
+
_returnTypeForDervied(gqlType: TypeNode): tsCodegen.NamedType;
|
|
37
|
+
_generatedEntityDerivedFieldGetter(_entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode): tsCodegen.Method;
|
|
31
38
|
_generateEntityFieldSetter(_entityDef: ObjectTypeDefinitionNode, fieldDef: FieldDefinitionNode): tsCodegen.Method | null;
|
|
32
39
|
_resolveFieldType(gqlType: NamedTypeNode): string;
|
|
33
40
|
/** Return the type that values for this field must have. For scalar
|
package/dist/codegen/schema.js
CHANGED
|
@@ -22,7 +22,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
/* eslint-disable unicorn/no-array-for-each */
|
|
30
|
+
const debug_1 = __importDefault(require("debug"));
|
|
26
31
|
const typesCodegen = __importStar(require("./types"));
|
|
27
32
|
const tsCodegen = __importStar(require("./typescript"));
|
|
28
33
|
class IdField {
|
|
@@ -98,10 +103,23 @@ class SchemaCodeGenerator {
|
|
|
98
103
|
})
|
|
99
104
|
.filter(Boolean);
|
|
100
105
|
}
|
|
106
|
+
generateDerivedLoaders() {
|
|
107
|
+
const fields = this.schema.ast.definitions.filter(def => this._isEntityTypeDefinition(def))
|
|
108
|
+
.flatMap((def) => def.fields)
|
|
109
|
+
.filter(def => this._isDerivedField(def))
|
|
110
|
+
.filter(def => def?.type !== undefined).map(def => this._getTypeNameForField(def.type));
|
|
111
|
+
return [...new Set(fields)].map(typeName => {
|
|
112
|
+
return this._generateDerivedLoader(typeName);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
101
115
|
_isEntityTypeDefinition(def) {
|
|
102
116
|
return (def.kind === 'ObjectTypeDefinition' &&
|
|
103
117
|
def.directives?.find(directive => directive.name.value === 'entity') !== undefined);
|
|
104
118
|
}
|
|
119
|
+
_isDerivedField(field) {
|
|
120
|
+
return (field?.directives?.find((directive) => directive.name.value === 'derivedFrom') !==
|
|
121
|
+
undefined);
|
|
122
|
+
}
|
|
105
123
|
_isInterfaceDefinition(def) {
|
|
106
124
|
return def.kind === 'InterfaceTypeDefinition';
|
|
107
125
|
}
|
|
@@ -120,6 +138,42 @@ class SchemaCodeGenerator {
|
|
|
120
138
|
.forEach((method) => klass.addMethod(method));
|
|
121
139
|
return klass;
|
|
122
140
|
}
|
|
141
|
+
_generateDerivedLoader(typeName) {
|
|
142
|
+
// <field>Loader
|
|
143
|
+
const klass = tsCodegen.klass(`${typeName}Loader`, { export: true, extends: 'Entity' });
|
|
144
|
+
klass.addMember(tsCodegen.klassMember('_entity', 'string'));
|
|
145
|
+
klass.addMember(tsCodegen.klassMember('_field', 'string'));
|
|
146
|
+
klass.addMember(tsCodegen.klassMember('_id', 'string'));
|
|
147
|
+
// Generate and add a constructor
|
|
148
|
+
klass.addMethod(tsCodegen.method('constructor', [
|
|
149
|
+
tsCodegen.param('entity', 'string'),
|
|
150
|
+
tsCodegen.param('id', 'string'),
|
|
151
|
+
tsCodegen.param('field', 'string'),
|
|
152
|
+
], undefined, `
|
|
153
|
+
super();
|
|
154
|
+
this._entity = entity;
|
|
155
|
+
this._id = id;
|
|
156
|
+
this._field = field;
|
|
157
|
+
`));
|
|
158
|
+
// Generate load() method for the Loader
|
|
159
|
+
klass.addMethod(tsCodegen.method('load', [], `${typeName}[]`, `
|
|
160
|
+
let value = store.loadRelated(this._entity, this._id, this._field);
|
|
161
|
+
return changetype<${typeName}[]>(value);
|
|
162
|
+
`));
|
|
163
|
+
return klass;
|
|
164
|
+
}
|
|
165
|
+
_getTypeNameForField(gqlType) {
|
|
166
|
+
if (gqlType.kind === 'NonNullType') {
|
|
167
|
+
return this._getTypeNameForField(gqlType.type);
|
|
168
|
+
}
|
|
169
|
+
if (gqlType.kind === 'ListType') {
|
|
170
|
+
return this._getTypeNameForField(gqlType.type);
|
|
171
|
+
}
|
|
172
|
+
if (gqlType.kind === 'NamedType') {
|
|
173
|
+
return gqlType.name.value;
|
|
174
|
+
}
|
|
175
|
+
throw new Error(`Unknown type kind: ${gqlType}`);
|
|
176
|
+
}
|
|
123
177
|
_generateConstructor(_entityName, fields) {
|
|
124
178
|
const idField = IdField.fromFields(fields);
|
|
125
179
|
return tsCodegen.method('constructor', [tsCodegen.param('id', idField.tsNamedType())], undefined, `
|
|
@@ -156,6 +210,12 @@ class SchemaCodeGenerator {
|
|
|
156
210
|
.filter(Boolean);
|
|
157
211
|
}
|
|
158
212
|
_generateEntityFieldGetter(_entityDef, fieldDef) {
|
|
213
|
+
const isDerivedField = this._isDerivedField(fieldDef);
|
|
214
|
+
const codegenDebug = (0, debug_1.default)('codegen');
|
|
215
|
+
if (isDerivedField) {
|
|
216
|
+
codegenDebug(`Generating derived field getter for ${fieldDef.name.value}`);
|
|
217
|
+
return this._generateDerivedFieldGetter(_entityDef, fieldDef);
|
|
218
|
+
}
|
|
159
219
|
const name = fieldDef.name.value;
|
|
160
220
|
const gqlType = fieldDef.type;
|
|
161
221
|
const fieldValueType = this._valueTypeFromGraphQl(gqlType);
|
|
@@ -179,6 +239,42 @@ class SchemaCodeGenerator {
|
|
|
179
239
|
${isNullable ? getNullable : getNonNullable}
|
|
180
240
|
`);
|
|
181
241
|
}
|
|
242
|
+
_generateDerivedFieldGetter(entityDef, fieldDef) {
|
|
243
|
+
const entityName = entityDef.name.value;
|
|
244
|
+
const name = fieldDef.name.value;
|
|
245
|
+
const gqlType = fieldDef.type;
|
|
246
|
+
const returnType = this._returnTypeForDervied(gqlType);
|
|
247
|
+
return tsCodegen.method(`get ${name}`, [], returnType, `
|
|
248
|
+
return new ${returnType}('${entityName}', this.get('id')!.toString(), '${name}')
|
|
249
|
+
`);
|
|
250
|
+
}
|
|
251
|
+
_returnTypeForDervied(gqlType) {
|
|
252
|
+
if (gqlType.kind === 'NonNullType') {
|
|
253
|
+
return this._returnTypeForDervied(gqlType.type);
|
|
254
|
+
}
|
|
255
|
+
if (gqlType.kind === 'ListType') {
|
|
256
|
+
return this._returnTypeForDervied(gqlType.type);
|
|
257
|
+
}
|
|
258
|
+
const type = tsCodegen.namedType(gqlType.name.value + 'Loader');
|
|
259
|
+
return type;
|
|
260
|
+
}
|
|
261
|
+
_generatedEntityDerivedFieldGetter(_entityDef, fieldDef) {
|
|
262
|
+
const name = fieldDef.name.value;
|
|
263
|
+
const gqlType = fieldDef.type;
|
|
264
|
+
const fieldValueType = this._valueTypeFromGraphQl(gqlType);
|
|
265
|
+
const returnType = this._typeFromGraphQl(gqlType);
|
|
266
|
+
const isNullable = returnType instanceof tsCodegen.NullableType;
|
|
267
|
+
const getNonNullable = `return ${typesCodegen.valueToAsc('value!', fieldValueType)}`;
|
|
268
|
+
const getNullable = `if (!value || value.kind == ValueKind.NULL) {
|
|
269
|
+
return null
|
|
270
|
+
} else {
|
|
271
|
+
return ${typesCodegen.valueToAsc('value', fieldValueType)}
|
|
272
|
+
}`;
|
|
273
|
+
return tsCodegen.method(`get ${name}`, [], returnType, `
|
|
274
|
+
let value = this.get('${name}')
|
|
275
|
+
${isNullable ? getNullable : getNonNullable}
|
|
276
|
+
`);
|
|
277
|
+
}
|
|
182
278
|
_generateEntityFieldSetter(_entityDef, fieldDef) {
|
|
183
279
|
const name = fieldDef.name.value;
|
|
184
280
|
const isDerivedField = !!fieldDef.directives?.find(directive => directive.name.value === 'derivedFrom');
|
|
@@ -299,14 +299,9 @@ describe('Schema code generator', () => {
|
|
|
299
299
|
{
|
|
300
300
|
name: 'get wallets',
|
|
301
301
|
params: [],
|
|
302
|
-
returnType: new typescript_1.
|
|
302
|
+
returnType: new typescript_1.NamedType('WalletLoader'),
|
|
303
303
|
body: `
|
|
304
|
-
|
|
305
|
-
if (!value || value.kind == ValueKind.NULL) {
|
|
306
|
-
return null
|
|
307
|
-
} else {
|
|
308
|
-
return value.toStringArray()
|
|
309
|
-
}
|
|
304
|
+
return new WalletLoader("Account", this.get('id')!.toString(), "wallets")
|
|
310
305
|
`,
|
|
311
306
|
},
|
|
312
307
|
],
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class CleanCommand extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
6
|
+
'codegen-dir': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
7
|
+
'build-dir': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const gluegun_1 = require("gluegun");
|
|
5
|
+
class CleanCommand extends core_1.Command {
|
|
6
|
+
async run() {
|
|
7
|
+
const { flags: { 'codegen-dir': codegenDir, 'build-dir': buildDir }, } = await this.parse(CleanCommand);
|
|
8
|
+
const spinner = gluegun_1.print.spin(`Cleaning cache and generated files`);
|
|
9
|
+
spinner.start();
|
|
10
|
+
try {
|
|
11
|
+
await gluegun_1.filesystem.removeAsync(codegenDir);
|
|
12
|
+
await gluegun_1.filesystem.removeAsync(buildDir);
|
|
13
|
+
spinner.succeed();
|
|
14
|
+
gluegun_1.print.success('Cache and generated files cleaned');
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
spinner.fail('Failed to clean cache and generated files');
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
spinner.stop();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
CleanCommand.description = 'Clean the cache and generated files.';
|
|
25
|
+
CleanCommand.flags = {
|
|
26
|
+
help: core_1.Flags.help({
|
|
27
|
+
char: 'h',
|
|
28
|
+
}),
|
|
29
|
+
'codegen-dir': core_1.Flags.directory({
|
|
30
|
+
summary: 'Directory where the "graph codegen" code is stored.',
|
|
31
|
+
default: 'generated/',
|
|
32
|
+
}),
|
|
33
|
+
'build-dir': core_1.Flags.directory({
|
|
34
|
+
summary: 'Directory where the "graph build" code is stored.',
|
|
35
|
+
default: 'build/',
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
exports.default = CleanCommand;
|
package/dist/type-generator.js
CHANGED
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.51.0
|
|
2
|
+
"version": "0.51.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"add": {
|
|
5
5
|
"id": "add",
|
|
@@ -184,6 +184,39 @@
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
|
+
"clean": {
|
|
188
|
+
"id": "clean",
|
|
189
|
+
"description": "Clean the cache and generated files.",
|
|
190
|
+
"strict": true,
|
|
191
|
+
"pluginName": "@graphprotocol/graph-cli",
|
|
192
|
+
"pluginAlias": "@graphprotocol/graph-cli",
|
|
193
|
+
"pluginType": "core",
|
|
194
|
+
"aliases": [],
|
|
195
|
+
"flags": {
|
|
196
|
+
"help": {
|
|
197
|
+
"name": "help",
|
|
198
|
+
"type": "boolean",
|
|
199
|
+
"char": "h",
|
|
200
|
+
"description": "Show CLI help.",
|
|
201
|
+
"allowNo": false
|
|
202
|
+
},
|
|
203
|
+
"codegen-dir": {
|
|
204
|
+
"name": "codegen-dir",
|
|
205
|
+
"type": "option",
|
|
206
|
+
"summary": "Directory where the \"graph codegen\" code is stored.",
|
|
207
|
+
"multiple": false,
|
|
208
|
+
"default": "generated/"
|
|
209
|
+
},
|
|
210
|
+
"build-dir": {
|
|
211
|
+
"name": "build-dir",
|
|
212
|
+
"type": "option",
|
|
213
|
+
"summary": "Directory where the \"graph build\" code is stored.",
|
|
214
|
+
"multiple": false,
|
|
215
|
+
"default": "build/"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"args": {}
|
|
219
|
+
},
|
|
187
220
|
"codegen": {
|
|
188
221
|
"id": "codegen",
|
|
189
222
|
"description": "Generates AssemblyScript types for a subgraph.",
|