@graphprotocol/graph-cli 0.25.3 → 0.28.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.
Files changed (37) hide show
  1. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/ethereum.ts +1 -1
  2. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/tendermint.ts +554 -0
  3. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/common/collections.ts +52 -2
  4. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/common/numbers.ts +11 -0
  5. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/common/value.ts +47 -0
  6. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/global/global.ts +150 -1
  7. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/index.ts +2 -0
  8. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/package.json +2 -1
  9. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/test/test.js +2 -0
  10. package/examples/basic-event-handlers/package.json +5 -5
  11. package/examples/basic-event-handlers/yarn.lock +12 -12
  12. package/examples/example-subgraph/package.json +1 -1
  13. package/examples/example-subgraph/yarn.lock +4 -4
  14. package/package.json +27 -24
  15. package/src/codegen/schema.js +104 -25
  16. package/src/codegen/schema.test.js +3 -7
  17. package/src/commands/deploy.js +3 -1
  18. package/src/commands/init.js +2 -0
  19. package/src/commands/test.js +82 -59
  20. package/src/protocols/ethereum/codegen/abi.js +72 -2
  21. package/src/protocols/ethereum/manifest.graphql +92 -0
  22. package/src/protocols/index.js +41 -7
  23. package/src/protocols/near/manifest.graphql +57 -0
  24. package/src/protocols/tendermint/contract.js +12 -0
  25. package/src/protocols/tendermint/manifest.graphql +64 -0
  26. package/src/protocols/tendermint/subgraph.js +20 -0
  27. package/src/scaffold/index.js +1 -1
  28. package/src/subgraph.js +18 -13
  29. package/src/validation/manifest.js +29 -8
  30. package/src/validation/schema.js +120 -119
  31. package/tests/cli/validation/example-values-found.stderr +2 -2
  32. package/tests/cli/validation/invalid-manifest/subgraph.yaml +2 -1
  33. package/tests/cli/validation/invalid-manifest-cannot-infer-protocol/subgraph.yaml +12 -0
  34. package/tests/cli/validation/invalid-manifest-cannot-infer-protocol.stderr +5 -0
  35. package/tests/cli/validation/invalid-manifest.stderr +0 -3
  36. package/tests/cli/validation.test.js +8 -0
  37. package/manifest-schema.graphql +0 -122
@@ -16,6 +16,17 @@ export enum ValueKind {
16
16
  BIGINT = 7,
17
17
  }
18
18
 
19
+ const VALUE_KIND_NAMES = [
20
+ 'String',
21
+ 'Int',
22
+ 'BigDecimal',
23
+ 'bool',
24
+ 'Array',
25
+ 'null',
26
+ 'Bytes',
27
+ 'BigInt',
28
+ ]
29
+
19
30
  /**
20
31
  * Pointer type for Value data.
21
32
  *
@@ -129,6 +140,42 @@ export class Value {
129
140
  return output
130
141
  }
131
142
 
143
+ /** Return a string that indicates the kind of value `this` contains for
144
+ * logging and error messages */
145
+ displayKind(): string {
146
+ if (this.kind >= VALUE_KIND_NAMES.length) {
147
+ return `Unknown (${this.kind})`
148
+ } else {
149
+ return VALUE_KIND_NAMES[this.kind]
150
+ }
151
+ }
152
+
153
+ /** Return a string representation of the value of `this` for logging and
154
+ * error messages */
155
+ displayData(): string {
156
+ switch (this.kind) {
157
+ case ValueKind.STRING:
158
+ return this.toString()
159
+ case ValueKind.INT:
160
+ return this.toI32().toString()
161
+ case ValueKind.BIGDECIMAL:
162
+ return this.toBigDecimal().toString()
163
+ case ValueKind.BOOL:
164
+ return this.toBoolean().toString()
165
+ case ValueKind.ARRAY:
166
+ let arr = this.toArray()
167
+ return '[' + arr.map<string>((elt) => elt.displayData()).join(', ') + ']'
168
+ case ValueKind.NULL:
169
+ return 'null'
170
+ case ValueKind.BYTES:
171
+ return this.toBytes().toHexString()
172
+ case ValueKind.BIGINT:
173
+ return this.toBigInt().toString()
174
+ default:
175
+ return `Unknown data (kind = ${this.kind})`
176
+ }
177
+ }
178
+
132
179
  static fromBooleanArray(input: Array<boolean>): Value {
133
180
  let output = new Array<Value>(input.length)
134
181
  for (let i: i32 = 0; i < input.length; i++) {
@@ -1,8 +1,16 @@
1
1
  import { BigDecimal } from '../common/numbers'
2
- import { TypedMapEntry, Entity, TypedMap, Result, Wrapped } from '../common/collections'
2
+ import {
3
+ Bytes,
4
+ TypedMapEntry,
5
+ Entity,
6
+ TypedMap,
7
+ Result,
8
+ Wrapped,
9
+ } from '../common/collections'
3
10
  import { JSONValue, Value } from '../common/value'
4
11
  import { ethereum } from '../chain/ethereum'
5
12
  import { near } from '../chain/near'
13
+ import { tendermint } from '../chain/tendermint'
6
14
 
7
15
  export enum TypeId {
8
16
  String = 0,
@@ -92,6 +100,53 @@ export enum TypeId {
92
100
  NearChunkHeader = 84,
93
101
  NearBlock = 85,
94
102
  NearReceiptWithOutcome = 86,
103
+ TendermintArrayEventTx = 87,
104
+ TendermintArrayEvent = 88,
105
+ TendermintArrayCommitSig = 89,
106
+ TendermintArrayBytes = 90,
107
+ TendermintArrayEvidence = 91,
108
+ TendermintArrayEventAttribute = 92,
109
+ TendermintBlockIDFlagEnum = 93,
110
+ TendermintSignedMsgTypeEnum = 94,
111
+ TendermintEventList = 95,
112
+ TendermintEventBlock = 96,
113
+ TendermintResponseBeginBlock = 97,
114
+ TendermintResponseEndBlock = 98,
115
+ TendermintValidatorUpdate = 99,
116
+ TendermintArrayValidatorUpdate = 100,
117
+ TendermintConsensusParams = 101,
118
+ TendermintBlockParams = 102,
119
+ TendermintEvidenceParams = 103,
120
+ TendermintValidatorParams = 104,
121
+ TendermintVersionParams = 105,
122
+ TendermintBlock = 106,
123
+ TendermintCommit = 107,
124
+ TendermintCommitSig = 108,
125
+ TendermintHeader = 109,
126
+ TendermintConsensus = 110,
127
+ TendermintBlockID = 111,
128
+ TendermintPartSetHeader = 112,
129
+ TendermintData = 113,
130
+ TendermintEvidence = 114,
131
+ TendermintDuplicateVoteEvidence = 115,
132
+ TendermintEventTx = 116,
133
+ TendermintEventVote = 117,
134
+ TendermintLightClientAttackEvidence = 118,
135
+ TendermintLightBlock = 119,
136
+ TendermintValidatorSet = 120,
137
+ TendermintSignedHeader = 121,
138
+ TendermintEvidenceList = 122,
139
+ TendermintValidator = 123,
140
+ TendermintArrayValidator = 124,
141
+ TendermintPublicKey = 125,
142
+ TendermintTxResult = 126,
143
+ TendermintResponseDeliverTx = 127,
144
+ TendermintEvent = 128,
145
+ TendermintEventAttribute = 129,
146
+ TendermintEventValidatorSetUpdates = 130,
147
+ TendermintDuration = 131,
148
+ TendermintTimestamp = 132,
149
+ TendermintEventData = 133,
95
150
  }
96
151
 
97
152
  export function id_of_type(typeId: TypeId): usize {
@@ -271,6 +326,100 @@ export function id_of_type(typeId: TypeId): usize {
271
326
  return idof<near.Block>()
272
327
  case TypeId.NearReceiptWithOutcome:
273
328
  return idof<near.ReceiptWithOutcome>()
329
+ case TypeId.TendermintArrayEventTx:
330
+ return idof<Array<tendermint.EventTx>>()
331
+ case TypeId.TendermintArrayEvent:
332
+ return idof<Array<tendermint.Event>>()
333
+ case TypeId.TendermintArrayCommitSig:
334
+ return idof<Array<tendermint.CommitSig>>()
335
+ case TypeId.TendermintArrayBytes:
336
+ return idof<Array<Bytes>>()
337
+ case TypeId.TendermintArrayEvidence:
338
+ return idof<Array<tendermint.Evidence>>()
339
+ case TypeId.TendermintArrayEventAttribute:
340
+ return idof<Array<tendermint.EventAttribute>>()
341
+ case TypeId.TendermintBlockIDFlagEnum:
342
+ return idof<Array<tendermint.BlockIDFlag>>()
343
+ case TypeId.TendermintSignedMsgTypeEnum:
344
+ return idof<Array<tendermint.SignedMsgType>>()
345
+ case TypeId.TendermintEventList:
346
+ return idof<tendermint.EventList>()
347
+ case TypeId.TendermintEventBlock:
348
+ return idof<tendermint.EventBlock>()
349
+ case TypeId.TendermintResponseBeginBlock:
350
+ return idof<tendermint.ResponseBeginBlock>()
351
+ case TypeId.TendermintResponseEndBlock:
352
+ return idof<tendermint.ResponseEndBlock>()
353
+ case TypeId.TendermintValidatorUpdate:
354
+ return idof<tendermint.ValidatorUpdate>()
355
+ case TypeId.TendermintArrayValidatorUpdate:
356
+ return idof<Array<tendermint.ValidatorUpdate>>()
357
+ case TypeId.TendermintConsensusParams:
358
+ return idof<tendermint.ConsensusParams>()
359
+ case TypeId.TendermintBlockParams:
360
+ return idof<tendermint.BlockParams>()
361
+ case TypeId.TendermintEvidenceParams:
362
+ return idof<tendermint.EvidenceParams>()
363
+ case TypeId.TendermintValidatorParams:
364
+ return idof<tendermint.ValidatorParams>()
365
+ case TypeId.TendermintVersionParams:
366
+ return idof<tendermint.VersionParams>()
367
+ case TypeId.TendermintBlock:
368
+ return idof<tendermint.Block>()
369
+ case TypeId.TendermintCommit:
370
+ return idof<tendermint.Commit>()
371
+ case TypeId.TendermintCommitSig:
372
+ return idof<tendermint.CommitSig>()
373
+ case TypeId.TendermintHeader:
374
+ return idof<tendermint.Header>()
375
+ case TypeId.TendermintConsensus:
376
+ return idof<tendermint.Consensus>()
377
+ case TypeId.TendermintBlockID:
378
+ return idof<tendermint.BlockID>()
379
+ case TypeId.TendermintPartSetHeader:
380
+ return idof<tendermint.PartSetHeader>()
381
+ case TypeId.TendermintData:
382
+ return idof<tendermint.Data>()
383
+ case TypeId.TendermintEvidence:
384
+ return idof<tendermint.Evidence>()
385
+ case TypeId.TendermintDuplicateVoteEvidence:
386
+ return idof<tendermint.DuplicateVoteEvidence>()
387
+ case TypeId.TendermintEventTx:
388
+ return idof<tendermint.EventTx>()
389
+ case TypeId.TendermintEventVote:
390
+ return idof<tendermint.EventVote>()
391
+ case TypeId.TendermintLightClientAttackEvidence:
392
+ return idof<tendermint.LightClientAttackEvidence>()
393
+ case TypeId.TendermintLightBlock:
394
+ return idof<tendermint.LightBlock>()
395
+ case TypeId.TendermintValidatorSet:
396
+ return idof<tendermint.ValidatorSet>()
397
+ case TypeId.TendermintSignedHeader:
398
+ return idof<tendermint.SignedHeader>()
399
+ case TypeId.TendermintEvidenceList:
400
+ return idof<tendermint.EvidenceList>()
401
+ case TypeId.TendermintValidator:
402
+ return idof<tendermint.Validator>()
403
+ case TypeId.TendermintArrayValidator:
404
+ return idof<Array<tendermint.Validator>>()
405
+ case TypeId.TendermintPublicKey:
406
+ return idof<tendermint.PublicKey>()
407
+ case TypeId.TendermintTxResult:
408
+ return idof<tendermint.TxResult>()
409
+ case TypeId.TendermintResponseDeliverTx:
410
+ return idof<tendermint.ResponseDeliverTx>()
411
+ case TypeId.TendermintEvent:
412
+ return idof<tendermint.Event>()
413
+ case TypeId.TendermintEventAttribute:
414
+ return idof<tendermint.EventAttribute>()
415
+ case TypeId.TendermintEventValidatorSetUpdates:
416
+ return idof<tendermint.EventValidatorSetUpdates>()
417
+ case TypeId.TendermintDuration:
418
+ return idof<tendermint.Duration>()
419
+ case TypeId.TendermintTimestamp:
420
+ return idof<tendermint.Timestamp>()
421
+ case TypeId.TendermintEventData:
422
+ return idof<tendermint.EventData>()
274
423
  default:
275
424
  return 0
276
425
  }
@@ -4,6 +4,8 @@ import './common/eager_offset'
4
4
  export * from './chain/ethereum'
5
5
  // NEAR support
6
6
  export * from './chain/near'
7
+ // Tendermint support
8
+ export * from './chain/tendermint'
7
9
  // Regular re-exports
8
10
  export * from './common/numbers'
9
11
  export * from './common/collections'
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-ts",
3
3
  "description": "TypeScript/AssemblyScript library for writing subgraph mappings for The Graph",
4
- "version": "0.24.0",
4
+ "version": "0.26.0",
5
5
  "module": "index.ts",
6
6
  "types": "index.ts",
7
7
  "main": "index.ts",
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "scripts": {
15
15
  "lint": "prettier -c **/*.{js,ts}",
16
+ "format": "prettier --write -c **/*.{js,ts}",
16
17
  "build": "asc --explicitStart --exportRuntime --runtime stub index.ts helper-functions.ts --lib graph-ts -b index.wasm",
17
18
  "test": "node test/test.js"
18
19
  }
@@ -31,6 +31,7 @@ async function main() {
31
31
  fs.copyFileSync('common/value.ts', 'test/temp_lib/common/value.ts')
32
32
  fs.copyFileSync('chain/ethereum.ts', 'test/temp_lib/chain/ethereum.ts')
33
33
  fs.copyFileSync('chain/near.ts', 'test/temp_lib/chain/near.ts')
34
+ fs.copyFileSync('chain/tendermint.ts', 'test/temp_lib/chain/tendermint.ts')
34
35
  fs.copyFileSync('index.ts', 'test/temp_lib/index.ts')
35
36
 
36
37
  try {
@@ -63,6 +64,7 @@ async function main() {
63
64
  fs.rmdirSync('test/temp_lib/common')
64
65
  fs.unlinkSync('test/temp_lib/chain/ethereum.ts')
65
66
  fs.unlinkSync('test/temp_lib/chain/near.ts')
67
+ fs.unlinkSync('test/temp_lib/chain/tendermint.ts')
66
68
  fs.rmdirSync('test/temp_lib/chain')
67
69
  fs.unlinkSync('test/temp_lib/index.ts')
68
70
  fs.rmdirSync('test/temp_lib')
@@ -9,14 +9,14 @@
9
9
  "deploy-test": "../../bin/graph deploy test/basic-event-handlers --version-label v0.0.1 --ipfs http://localhost:15001 --node http://127.0.0.1:18020"
10
10
  },
11
11
  "devDependencies": {
12
- "@graphprotocol/graph-ts": "0.24.1",
12
+ "@graphprotocol/graph-ts": "0.26.0",
13
13
  "apollo-fetch": "^0.7.0"
14
14
  },
15
15
  "dependencies": {
16
- "babel-polyfill": "^6.26.0",
17
- "babel-register": "^6.26.0",
18
- "truffle": "^5.0.4",
19
- "truffle-hdwallet-provider": "^1.0.4"
16
+ "babel-polyfill": "6.26.0",
17
+ "babel-register": "6.26.0",
18
+ "truffle": "5.0.12",
19
+ "truffle-hdwallet-provider": "1.0.6"
20
20
  },
21
21
  "resolutions": {
22
22
  "assemblyscript": "0.19.10"
@@ -2,10 +2,10 @@
2
2
  # yarn lockfile v1
3
3
 
4
4
 
5
- "@graphprotocol/graph-ts@0.24.1":
6
- version "0.24.1"
7
- resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.24.1.tgz#50961b52b5383f9c5cf5e6e23fa039f24e729ddf"
8
- integrity sha512-2vU4m5ZPQIqMlMce/z5vmOtGHRlRmcRhMfemS3NIwxCSxSBGVnX2zb7QBTzzdQKGwsAZdbz6V0okkOtvohELfQ==
5
+ "@graphprotocol/graph-ts@0.26.0":
6
+ version "0.26.0"
7
+ resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.26.0.tgz#576f995531eebaca4374901aeaff499219e382e8"
8
+ integrity sha512-GW/emOJl+35MXgmIxTnUK7dJtPCaB9u5aAwoLVqJ8swogC794O92UrXMVrAJsherUriu+yI9bLMGmNPOIi60jw==
9
9
  dependencies:
10
10
  assemblyscript "0.19.10"
11
11
 
@@ -112,18 +112,18 @@ babel-messages@^6.23.0:
112
112
  dependencies:
113
113
  babel-runtime "^6.22.0"
114
114
 
115
- babel-polyfill@^6.26.0:
115
+ babel-polyfill@6.26.0:
116
116
  version "6.26.0"
117
- resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
117
+ resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
118
118
  integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
119
119
  dependencies:
120
120
  babel-runtime "^6.26.0"
121
121
  core-js "^2.5.0"
122
122
  regenerator-runtime "^0.10.5"
123
123
 
124
- babel-register@^6.26.0:
124
+ babel-register@6.26.0, babel-register@^6.26.0:
125
125
  version "6.26.0"
126
- resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
126
+ resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
127
127
  integrity sha1-btAhFz4vy0htestFxgCahW9kcHE=
128
128
  dependencies:
129
129
  babel-core "^6.26.0"
@@ -920,18 +920,18 @@ trim-right@^1.0.1:
920
920
  resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
921
921
  integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
922
922
 
923
- truffle-hdwallet-provider@^1.0.4:
923
+ truffle-hdwallet-provider@1.0.6:
924
924
  version "1.0.6"
925
- resolved "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-1.0.6.tgz#7cda437c9a25bda6bbc5f4ed018e932254ecc867"
925
+ resolved "https://registry.yarnpkg.com/truffle-hdwallet-provider/-/truffle-hdwallet-provider-1.0.6.tgz#7cda437c9a25bda6bbc5f4ed018e932254ecc867"
926
926
  integrity sha512-cYTG0t9XouLLEBLMjkfHe3s2JO9wrFFVeXEgpW5Ay+8S56isf3LkrAUh0ws9bcYCJ0l7jho9xkaNnakeDqq//Q==
927
927
  dependencies:
928
928
  any-promise "^1.3.0"
929
929
  bindings "^1.3.1"
930
930
  websocket "^1.0.28"
931
931
 
932
- truffle@^5.0.4:
932
+ truffle@5.0.12:
933
933
  version "5.0.12"
934
- resolved "https://registry.npmjs.org/truffle/-/truffle-5.0.12.tgz#05ab7d2561a3ee4fd5e026dcc4b91b8f3c6e3795"
934
+ resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.0.12.tgz#05ab7d2561a3ee4fd5e026dcc4b91b8f3c6e3795"
935
935
  integrity sha512-dqnDmtTGNcnL29PHQwPE/CVmFFeGLuTFeb4TS3VY/vbASefu118IKXcadOWzkCPPwktv/njwylHSPhwoS00F2A==
936
936
  dependencies:
937
937
  app-module-path "^2.2.0"
@@ -7,7 +7,7 @@
7
7
  "build-wast": "../../bin/graph build -t wast subgraph.yaml"
8
8
  },
9
9
  "devDependencies": {
10
- "@graphprotocol/graph-ts": "0.24.1"
10
+ "@graphprotocol/graph-ts": "0.26.0"
11
11
  },
12
12
  "resolutions": {
13
13
  "assemblyscript": "0.19.10"
@@ -2,10 +2,10 @@
2
2
  # yarn lockfile v1
3
3
 
4
4
 
5
- "@graphprotocol/graph-ts@0.24.1":
6
- version "0.24.1"
7
- resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.24.1.tgz#50961b52b5383f9c5cf5e6e23fa039f24e729ddf"
8
- integrity sha512-2vU4m5ZPQIqMlMce/z5vmOtGHRlRmcRhMfemS3NIwxCSxSBGVnX2zb7QBTzzdQKGwsAZdbz6V0okkOtvohELfQ==
5
+ "@graphprotocol/graph-ts@0.26.0":
6
+ version "0.26.0"
7
+ resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.26.0.tgz#576f995531eebaca4374901aeaff499219e382e8"
8
+ integrity sha512-GW/emOJl+35MXgmIxTnUK7dJtPCaB9u5aAwoLVqJ8swogC794O92UrXMVrAJsherUriu+yI9bLMGmNPOIi60jw==
9
9
  dependencies:
10
10
  assemblyscript "0.19.10"
11
11
 
package/package.json CHANGED
@@ -1,41 +1,44 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.25.3",
3
+ "version": "0.28.0",
4
+ "license": "(Apache-2.0 OR MIT)",
4
5
  "description": "CLI for building for and deploying to The Graph",
5
6
  "dependencies": {
6
7
  "assemblyscript": "0.19.10",
7
8
  "binary-install-raw": "0.0.13",
8
- "chalk": "^3.0.0",
9
- "chokidar": "^3.0.2",
10
- "debug": "^4.1.1",
11
- "docker-compose": "^0.23.2",
12
- "dockerode": "^2.5.8",
13
- "fs-extra": "^9.0.0",
14
- "glob": "^7.1.2",
9
+ "chalk": "3.0.0",
10
+ "chokidar": "3.5.1",
11
+ "debug": "4.1.1",
12
+ "docker-compose": "0.23.4",
13
+ "dockerode": "2.5.8",
14
+ "fs-extra": "9.0.0",
15
+ "glob": "7.1.6",
15
16
  "gluegun": "https://github.com/edgeandnode/gluegun#v4.3.1-pin-colors-dep",
16
- "graphql": "^15.5.0",
17
- "immutable": "^3.8.2",
18
- "ipfs-http-client": "^34.0.0",
19
- "jayson": "^3.0.2",
20
- "js-yaml": "^3.13.1",
21
- "node-fetch": "^2.3.0",
22
- "pkginfo": "^0.4.1",
23
- "prettier": "^1.13.5",
24
- "request": "^2.88.0",
17
+ "graphql": "15.5.0",
18
+ "immutable": "3.8.2",
19
+ "ipfs-http-client": "34.0.0",
20
+ "jayson": "3.2.0",
21
+ "js-yaml": "3.13.1",
22
+ "node-fetch": "2.6.0",
23
+ "pkginfo": "0.4.1",
24
+ "prettier": "1.19.1",
25
+ "request": "2.88.2",
25
26
  "semver": "7.3.5",
26
- "tmp-promise": "^3.0.2",
27
+ "sync-request": "6.1.0",
28
+ "tmp-promise": "3.0.2",
29
+ "web3-eth-abi": "1.7.0",
27
30
  "which": "2.0.2",
28
- "yaml": "^1.5.1"
31
+ "yaml": "1.9.2"
29
32
  },
30
33
  "bin": {
31
34
  "graph": "bin/graph"
32
35
  },
33
36
  "devDependencies": {
34
- "eslint": "^6.0.1",
35
- "jest": "^26.0.0",
36
- "spawn-command": "^0.0.2-1",
37
- "strip-ansi": "^6.0.0",
38
- "tern": "^0.24.0"
37
+ "eslint": "6.8.0",
38
+ "jest": "26.0.0",
39
+ "spawn-command": "0.0.2-1",
40
+ "strip-ansi": "6.0.0",
41
+ "tern": "0.24.3"
39
42
  },
40
43
  "scripts": {
41
44
  "test": "jest --verbose",
@@ -5,6 +5,53 @@ const typesCodegen = require('./types')
5
5
 
6
6
  const List = immutable.List
7
7
 
8
+ class IdField {
9
+ static BYTES = Symbol("Bytes")
10
+ static STRING = Symbol("String")
11
+
12
+ constructor(idField) {
13
+ const typeName = idField.getIn(['type', 'type', 'name', 'value'])
14
+ this.kind = typeName === "Bytes" ? IdField.BYTES : IdField.STRING
15
+ }
16
+
17
+ typeName() {
18
+ return this.kind === IdField.BYTES ? "Bytes" : "string"
19
+ }
20
+
21
+ gqlTypeName() {
22
+ return this.kind === IdField.BYTES ? "Bytes" : "String"
23
+ }
24
+
25
+ tsNamedType() {
26
+ return tsCodegen.namedType(this.typeName())
27
+ }
28
+
29
+ tsValueFrom() {
30
+ return this.kind === IdField.BYTES ? "Value.fromBytes(id)" : "Value.fromString(id)"
31
+ }
32
+
33
+ tsValueKind() {
34
+ return this.kind === IdField.BYTES ? "ValueKind.BYTES" : "ValueKind.STRING"
35
+ }
36
+
37
+ tsValueToString() {
38
+ return this.kind == IdField.BYTES ? "id.toBytes().toHexString()" : "id.toString()"
39
+ }
40
+
41
+ tsToString() {
42
+ return this.kind == IdField.BYTES ? "id.toHexString()" : "id"
43
+ }
44
+
45
+ static fromFields(fields) {
46
+ const idField = fields.find(field => field.getIn(['name', 'value']) === 'id')
47
+ return new IdField(idField)
48
+ }
49
+
50
+ static fromTypeDef(def) {
51
+ return IdField.fromFields(def.get("fields"))
52
+ }
53
+ }
54
+
8
55
  module.exports = class SchemaCodeGenerator {
9
56
  constructor(schema) {
10
57
  this.schema = schema
@@ -52,12 +99,14 @@ module.exports = class SchemaCodeGenerator {
52
99
  _generateEntityType(def) {
53
100
  let name = def.getIn(['name', 'value'])
54
101
  let klass = tsCodegen.klass(name, { export: true, extends: 'Entity' })
102
+ const fields = def.get('fields')
103
+ const idField = IdField.fromFields(fields)
55
104
 
56
105
  // Generate and add a constructor
57
- klass.addMethod(this._generateConstructor(name, def.get('fields')))
106
+ klass.addMethod(this._generateConstructor(name, fields))
58
107
 
59
108
  // Generate and add save() and getById() methods
60
- this._generateStoreMethods(name).forEach(method => klass.addMethod(method))
109
+ this._generateStoreMethods(name, idField).forEach(method => klass.addMethod(method))
61
110
 
62
111
  // Generate and add entity field getters and setters
63
112
  def
@@ -107,19 +156,20 @@ module.exports = class SchemaCodeGenerator {
107
156
  }
108
157
 
109
158
  _generateConstructor(entityName, fields) {
159
+ const idField = IdField.fromFields(fields)
110
160
  return tsCodegen.method(
111
161
  'constructor',
112
- [tsCodegen.param('id', tsCodegen.namedType('string'))],
162
+ [tsCodegen.param('id', idField.tsNamedType())],
113
163
  undefined,
114
164
  `
115
165
  super()
116
- this.set('id', Value.fromString(id))
166
+ this.set('id', ${idField.tsValueFrom()})
117
167
  ${this._generateDefaultFieldValues(fields)}
118
168
  `,
119
169
  )
120
170
  }
121
171
 
122
- _generateStoreMethods(entityName) {
172
+ _generateStoreMethods(entityName, idField) {
123
173
  return List.of(
124
174
  tsCodegen.method(
125
175
  'save',
@@ -127,23 +177,21 @@ module.exports = class SchemaCodeGenerator {
127
177
  tsCodegen.namedType('void'),
128
178
  `
129
179
  let id = this.get('id')
130
- assert(id != null, 'Cannot save ${entityName} entity without an ID')
180
+ assert(id != null,
181
+ 'Cannot save ${entityName} entity without an ID')
131
182
  if (id) {
132
- assert(
133
- id.kind == ValueKind.STRING,
134
- 'Cannot save ${entityName} entity with non-string ID. ' +
135
- 'Considering using .toHex() to convert the "id" to a string.'
136
- )
137
- store.set('${entityName}', id.toString(), this)
183
+ assert(id.kind == ${idField.tsValueKind()},
184
+ \`Entities of type ${entityName} must have an ID of type ${idField.gqlTypeName()} but the id '\${id.displayData()}' is of type \${id.displayKind()}\`)
185
+ store.set('${entityName}', ${idField.tsValueToString()}, this)
138
186
  }`,
139
187
  ),
140
188
 
141
189
  tsCodegen.staticMethod(
142
190
  'load',
143
- [tsCodegen.param('id', tsCodegen.namedType('string'))],
191
+ [tsCodegen.param('id', tsCodegen.namedType(idField.typeName()))],
144
192
  tsCodegen.nullableType(tsCodegen.namedType(entityName)),
145
193
  `
146
- return changetype<${entityName} | null>(store.get('${entityName}', id))
194
+ return changetype<${entityName} | null>(store.get('${entityName}', ${idField.tsToString()}))
147
195
  `,
148
196
  ),
149
197
  )
@@ -194,13 +242,12 @@ module.exports = class SchemaCodeGenerator {
194
242
  isArray &&
195
243
  paramType.inner instanceof tsCodegen.NullableType
196
244
  ) {
197
- let arrayTypeWithoutClosingBracked = fieldValueType.slice(0, -1)
198
- let suggestedType = `${arrayTypeWithoutClosingBracked}!]`
245
+ let baseType = this._baseType(gqlType)
199
246
 
200
247
  throw new Error(`
201
248
  GraphQL schema can't have List's with Nullable members.
202
- Error in '${name}' field of type '${fieldValueType}'.
203
- Suggestion: add an '!' to the member type of the List, change from '${fieldValueType}' to '${suggestedType}'`
249
+ Error in '${name}' field of type '[${baseType}]'.
250
+ Suggestion: add an '!' to the member type of the List, change from '[${baseType}]' to '[${baseType}!]'`
204
251
  )
205
252
  }
206
253
 
@@ -212,7 +259,7 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
212
259
  this.unset('${name}')
213
260
  } else {
214
261
  this.set('${name}', ${typesCodegen.valueFromAsc(
215
- `<${paramTypeString}>value`,
262
+ `<${paramTypeString}>value`,
216
263
  fieldValueType,
217
264
  )})
218
265
  }
@@ -226,12 +273,44 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
226
273
  )
227
274
  }
228
275
 
276
+ _resolveFieldType(gqlType) {
277
+ let typeName = gqlType.getIn(['name', 'value'])
278
+
279
+ // If this is a reference to another type, the field has the type of
280
+ // the referred type's id field
281
+ const typeDef = this.schema.ast.get("definitions").
282
+ find(def => this._isEntityTypeDefinition(def) && def.getIn(["name", "value"]) === typeName)
283
+ if (typeDef) {
284
+ return IdField.fromTypeDef(typeDef).typeName()
285
+ } else {
286
+ return typeName
287
+ }
288
+ }
289
+
290
+ /** Return the type that values for this field must have. For scalar
291
+ * types, that's the type from the subgraph schema. For references to
292
+ * other entity types, this is the same as the type of the id of the
293
+ * referred type, i.e., `string` or `Bytes`*/
229
294
  _valueTypeFromGraphQl(gqlType) {
230
- return gqlType.get('kind') === 'NonNullType'
231
- ? this._valueTypeFromGraphQl(gqlType.get('type'), false)
232
- : gqlType.get('kind') === 'ListType'
233
- ? '[' + this._valueTypeFromGraphQl(gqlType.get('type')) + ']'
234
- : gqlType.getIn(['name', 'value'])
295
+ if (gqlType.get('kind') === 'NonNullType') {
296
+ return this._valueTypeFromGraphQl(gqlType.get('type'), false)
297
+ } else if (gqlType.get('kind') === 'ListType') {
298
+ return '[' + this._valueTypeFromGraphQl(gqlType.get('type')) + ']'
299
+ } else {
300
+ return this._resolveFieldType(gqlType)
301
+ }
302
+ }
303
+
304
+ /** Determine the base type of `gqlType` by removing any non-null
305
+ * constraints and using the type of elements of lists */
306
+ _baseType(gqlType) {
307
+ if (gqlType.get('kind') === 'NonNullType') {
308
+ return this._baseType(gqlType.get('type'))
309
+ } else if (gqlType.get('kind') === 'ListType') {
310
+ return this._baseType(gqlType.get('type'))
311
+ } else {
312
+ return gqlType.getIn(['name', 'value'])
313
+ }
235
314
  }
236
315
 
237
316
  _typeFromGraphQl(gqlType, nullable = true, nullablePrimitive = false) {
@@ -243,7 +322,7 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
243
322
  } else {
244
323
  // NamedType
245
324
  let type = tsCodegen.namedType(
246
- typesCodegen.ascTypeForValue(gqlType.getIn(['name', 'value'])),
325
+ typesCodegen.ascTypeForValue(this._resolveFieldType(gqlType)),
247
326
  )
248
327
 
249
328
  // Will not wrap primitives into NullableType by default.