@graphprotocol/graph-cli 0.49.0-alpha-20230505152117-ef48fdf → 0.49.0-alpha-20230508062634-72ffd3d

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @graphprotocol/graph-cli
2
2
 
3
- ## 0.49.0-alpha-20230505152117-ef48fdf
3
+ ## 0.49.0-alpha-20230508062634-72ffd3d
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -9,29 +9,16 @@
9
9
  Thanks [@saihaj](https://github.com/saihaj)! - do not generate types, instead show a message to
10
10
  user to use substreams CLI for codegen.
11
11
 
12
+ - [#1340](https://github.com/graphprotocol/graph-tooling/pull/1340)
13
+ [`72ffd3d`](https://github.com/graphprotocol/graph-tooling/commit/72ffd3def132ccf4d50a18e0e6fd1b377da6cd48)
14
+ Thanks [@incrypto32](https://github.com/incrypto32)! - Add support for codegen for derived field
15
+ loaders, This adds getters for derived fields defined in the schema for entities.
16
+
12
17
  - [#1306](https://github.com/graphprotocol/graph-tooling/pull/1306)
13
18
  [`f5e4b58`](https://github.com/graphprotocol/graph-tooling/commit/f5e4b58989edc5f3bb8211f1b912449e77832de8)
14
19
  Thanks [@saihaj](https://github.com/saihaj)! - Add loadInBlock function for entities as part of
15
20
  codegen
16
21
 
17
- - [#1339](https://github.com/graphprotocol/graph-tooling/pull/1339)
18
- [`214cd71`](https://github.com/graphprotocol/graph-tooling/commit/214cd7153aabd427b52c87f5f3643212cb615913)
19
- Thanks [@saihaj](https://github.com/saihaj)! - allow deploy optimism and optimism-goerli on studio
20
-
21
- ### Patch Changes
22
-
23
- - [#1328](https://github.com/graphprotocol/graph-tooling/pull/1328)
24
- [`4963215`](https://github.com/graphprotocol/graph-tooling/commit/4963215564797393424c563ea0b51aabbfd8e33e)
25
- Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
26
-
27
- - Updated dependency [`@oclif/core@2.8.4` ↗︎](https://www.npmjs.com/package/@oclif/core/v/2.8.4)
28
- (from `2.8.2`, in `dependencies`)
29
-
30
- - [#1331](https://github.com/graphprotocol/graph-tooling/pull/1331)
31
- [`b2c8dec`](https://github.com/graphprotocol/graph-tooling/commit/b2c8decb7806d25df6ca4e07f6dfdf7941516435)
32
- Thanks [@saihaj](https://github.com/saihaj)! - only allow mainnet for substreams in network
33
- selection for init
34
-
35
22
  ## 0.48.0
36
23
 
37
24
  ### Minor Changes
@@ -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: any): 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: any, fieldDef: FieldDefinitionNode): tsCodegen.Method;
36
+ _returnTypeForDervied(gqlType: any): any;
37
+ _generatedEntityDerivedFieldGetter(_entityDef: any, 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
@@ -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');
@@ -276,14 +276,9 @@ describe('Schema code generator', () => {
276
276
  {
277
277
  name: 'get wallets',
278
278
  params: [],
279
- returnType: new typescript_1.NullableType(new typescript_1.ArrayType(new typescript_1.NamedType('string'))),
279
+ returnType: new typescript_1.NamedType('WalletLoader'),
280
280
  body: `
281
- let value = this.get('wallets')
282
- if (!value || value.kind == ValueKind.NULL) {
283
- return null
284
- } else {
285
- return value.toStringArray()
286
- }
281
+ return new WalletLoader("Account", this.get('id')!.toString(), "wallets")
287
282
  `,
288
283
  },
289
284
  ],
@@ -1,4 +1,4 @@
1
- export declare const allowedStudioNetworks: readonly ["mainnet", "rinkeby", "goerli", "gnosis", "chapel", "optimism-goerli", "clover", "fantom", "matic", "fantom-testnet", "arbitrum-goerli", "fuji", "celo-alfajores", "mumbai", "aurora-testnet", "near-testnet", "optimism", "optimism-goerli", "theta-testnet-001", "osmo-test-4", "base-testnet", "celo", "arbitrum-one", "avalanche", "zksync-era", "sepolia", "polygon-zkevm-testnet", "polygon-zkevm"];
1
+ export declare const allowedStudioNetworks: readonly ["mainnet", "rinkeby", "goerli", "gnosis", "chapel", "optimism-goerli", "clover", "fantom", "matic", "fantom-testnet", "arbitrum-goerli", "fuji", "celo-alfajores", "mumbai", "aurora-testnet", "near-testnet", "theta-testnet-001", "osmo-test-4", "base-testnet", "celo", "arbitrum-one", "avalanche", "zksync-era", "sepolia", "polygon-zkevm-testnet", "polygon-zkevm"];
2
2
  export declare const validateStudioNetwork: ({ studio, product, network, }: {
3
3
  studio?: string | boolean | undefined;
4
4
  product?: string | undefined;
@@ -18,8 +18,6 @@ exports.allowedStudioNetworks = [
18
18
  'mumbai',
19
19
  'aurora-testnet',
20
20
  'near-testnet',
21
- 'optimism',
22
- 'optimism-goerli',
23
21
  'theta-testnet-001',
24
22
  'osmo-test-4',
25
23
  'base-testnet',
@@ -88,7 +88,7 @@ class Protocol {
88
88
  });
89
89
  }
90
90
  static availableNetworks() {
91
- return immutable_1.default.fromJS({
91
+ let networks = immutable_1.default.fromJS({
92
92
  arweave: ['arweave-mainnet'],
93
93
  ethereum: [
94
94
  'mainnet',
@@ -135,6 +135,13 @@ class Protocol {
135
135
  ],
136
136
  substreams: ['mainnet'],
137
137
  });
138
+ const allNetworks = [];
139
+ // eslint-disable-next-line unicorn/no-array-for-each
140
+ networks.forEach(value => {
141
+ allNetworks.push(...value);
142
+ });
143
+ networks = networks.set('substreams', immutable_1.default.List(allNetworks));
144
+ return networks;
138
145
  }
139
146
  static normalizeName(name) {
140
147
  return Protocol.availableProtocols().findKey(possibleNames => {
@@ -130,6 +130,7 @@ class TypeGenerator {
130
130
  typescript_1.GENERATED_FILE_NOTE,
131
131
  ...codeGenerator.generateModuleImports(),
132
132
  ...codeGenerator.generateTypes(),
133
+ ...codeGenerator.generateDerivedLoaders(),
133
134
  ].join('\n'), {
134
135
  parser: 'typescript',
135
136
  });
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.49.0-alpha-20230505152117-ef48fdf",
2
+ "version": "0.49.0-alpha-20230508062634-72ffd3d",
3
3
  "commands": {
4
4
  "add": {
5
5
  "id": "add",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.49.0-alpha-20230505152117-ef48fdf",
3
+ "version": "0.49.0-alpha-20230508062634-72ffd3d",
4
4
  "description": "CLI for building for and deploying to The Graph",
5
5
  "license": "(Apache-2.0 OR MIT)",
6
6
  "engines": {
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "dependencies": {
22
22
  "@float-capital/float-subgraph-uncrashable": "^0.0.0-alpha.4",
23
- "@oclif/core": "2.8.4",
23
+ "@oclif/core": "2.8.2",
24
24
  "@whatwg-node/fetch": "^0.8.4",
25
25
  "assemblyscript": "0.19.23",
26
26
  "binary-install-raw": "0.0.13",