@graphprotocol/graph-cli 0.33.1 → 0.34.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 (33) hide show
  1. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/README.md +1 -1
  2. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/ethereum.ts +200 -0
  3. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/global/global.ts +28 -28
  4. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/methods.txt +18 -0
  5. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/package.json +1 -1
  6. package/examples/basic-event-handlers/node_modules/keccak/build/Makefile +342 -0
  7. package/examples/basic-event-handlers/node_modules/keccak/build/Release/.deps/Release/obj.target/keccak/src/addon.o.d.raw +69 -0
  8. package/examples/basic-event-handlers/node_modules/keccak/build/binding.Makefile +6 -0
  9. package/examples/basic-event-handlers/node_modules/keccak/build/config.gypi +27 -11
  10. package/examples/basic-event-handlers/node_modules/keccak/build/gyp-mac-tool +772 -0
  11. package/examples/basic-event-handlers/node_modules/keccak/build/keccak.target.mk +207 -0
  12. package/examples/basic-event-handlers/node_modules/websocket/build/Makefile +347 -0
  13. package/examples/basic-event-handlers/node_modules/websocket/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d.raw +67 -0
  14. package/examples/basic-event-handlers/node_modules/websocket/build/binding.Makefile +6 -0
  15. package/examples/basic-event-handlers/node_modules/websocket/build/bufferutil.target.mk +190 -0
  16. package/examples/basic-event-handlers/node_modules/websocket/build/config.gypi +23 -7
  17. package/examples/basic-event-handlers/node_modules/websocket/build/gyp-mac-tool +772 -0
  18. package/examples/basic-event-handlers/node_modules/websocket/build/validation.target.mk +190 -0
  19. package/examples/basic-event-handlers/package.json +1 -1
  20. package/examples/basic-event-handlers/yarn.lock +4 -4
  21. package/examples/example-subgraph/package.json +1 -1
  22. package/examples/example-subgraph/yarn.lock +4 -4
  23. package/package.json +1 -1
  24. package/src/codegen/types/conversions.js +100 -0
  25. package/src/codegen/types/index.test.js +347 -0
  26. package/src/codegen/util.js +6 -1
  27. package/src/command-helpers/spinner.js +6 -0
  28. package/src/commands/init.js +33 -12
  29. package/src/protocols/ethereum/abi.js +8 -0
  30. package/src/protocols/ethereum/codegen/abi.js +12 -1
  31. package/src/scaffold/index.js +1 -1
  32. package/src/subgraph.js +6 -5
  33. package/tests/cli/init.test.js +1 -0
@@ -191,6 +191,171 @@ describe('ethereum.Value -> AssemblyScript', () => {
191
191
  expect(codegen.ascTypeForEthereum('string[4]')).toBe('Array<string>')
192
192
  expect(codegen.ascTypeForEthereum('string[754]')).toBe('Array<string>')
193
193
  })
194
+
195
+ // Multi dimensional arrays
196
+
197
+ test('address[*][*] -> Array<Array<Address>>', () => {
198
+ expect(codegen.ethereumToAsc('x', 'address[][]')).toBe('x.toAddressMatrix()')
199
+ expect(codegen.ethereumToAsc('x', 'address[5][]')).toBe('x.toAddressMatrix()')
200
+ expect(codegen.ethereumToAsc('x', 'address[][4]')).toBe('x.toAddressMatrix()')
201
+ expect(codegen.ethereumToAsc('x', 'address[1][2]')).toBe('x.toAddressMatrix()')
202
+ expect(codegen.ethereumToAsc('x', 'address[123][321]')).toBe('x.toAddressMatrix()')
203
+
204
+ expect(codegen.ascTypeForEthereum('address[][]')).toBe('Array<Array<Address>>')
205
+ expect(codegen.ascTypeForEthereum('address[5][]')).toBe('Array<Array<Address>>')
206
+ expect(codegen.ascTypeForEthereum('address[][4]')).toBe('Array<Array<Address>>')
207
+ expect(codegen.ascTypeForEthereum('address[1][2]')).toBe('Array<Array<Address>>')
208
+ expect(codegen.ascTypeForEthereum('address[123][321]')).toBe('Array<Array<Address>>')
209
+ })
210
+
211
+ test('bool[*][*] -> Array<Array<boolean>>', () => {
212
+ expect(codegen.ethereumToAsc('x', 'bool[][]')).toBe('x.toBooleanMatrix()')
213
+ expect(codegen.ethereumToAsc('x', 'bool[1][]')).toBe('x.toBooleanMatrix()')
214
+ expect(codegen.ethereumToAsc('x', 'bool[][3]')).toBe('x.toBooleanMatrix()')
215
+ expect(codegen.ethereumToAsc('x', 'bool[5][2]')).toBe('x.toBooleanMatrix()')
216
+ expect(codegen.ethereumToAsc('x', 'bool[275][572]')).toBe('x.toBooleanMatrix()')
217
+
218
+ expect(codegen.ascTypeForEthereum('bool[][]')).toBe('Array<Array<boolean>>')
219
+ expect(codegen.ascTypeForEthereum('bool[1][]')).toBe('Array<Array<boolean>>')
220
+ expect(codegen.ascTypeForEthereum('bool[][3]')).toBe('Array<Array<boolean>>')
221
+ expect(codegen.ascTypeForEthereum('bool[5][2]')).toBe('Array<Array<boolean>>')
222
+ expect(codegen.ascTypeForEthereum('bool[275][572]')).toBe('Array<Array<boolean>>')
223
+ })
224
+
225
+ test('byte[*][*] -> Array<Array<Bytes>>', () => {
226
+ expect(codegen.ethereumToAsc('x', 'byte[][]')).toBe('x.toBytesMatrix()')
227
+ expect(codegen.ethereumToAsc('x', 'byte[7][]')).toBe('x.toBytesMatrix()')
228
+ expect(codegen.ethereumToAsc('x', 'byte[][8]')).toBe('x.toBytesMatrix()')
229
+ expect(codegen.ethereumToAsc('x', 'byte[553][355]')).toBe('x.toBytesMatrix()')
230
+
231
+ expect(codegen.ascTypeForEthereum('byte[][]')).toBe('Array<Array<Bytes>>')
232
+ expect(codegen.ascTypeForEthereum('byte[7][]')).toBe('Array<Array<Bytes>>')
233
+ expect(codegen.ascTypeForEthereum('byte[][8]')).toBe('Array<Array<Bytes>>')
234
+ expect(codegen.ascTypeForEthereum('byte[553][355]')).toBe('Array<Array<Bytes>>')
235
+ })
236
+
237
+ test('bytes[*][*] -> Array<Array<Bytes>>', () => {
238
+ expect(codegen.ethereumToAsc('x', 'bytes[][]')).toBe('x.toBytesMatrix()')
239
+ expect(codegen.ethereumToAsc('x', 'bytes[14][]')).toBe('x.toBytesMatrix()')
240
+ expect(codegen.ethereumToAsc('x', 'bytes[][41]')).toBe('x.toBytesMatrix()')
241
+ expect(codegen.ethereumToAsc('x', 'bytes[444][555]')).toBe('x.toBytesMatrix()')
242
+
243
+ expect(codegen.ascTypeForEthereum('bytes[][]')).toBe('Array<Array<Bytes>>')
244
+ expect(codegen.ascTypeForEthereum('bytes[14][]')).toBe('Array<Array<Bytes>>')
245
+ expect(codegen.ascTypeForEthereum('bytes[][41]')).toBe('Array<Array<Bytes>>')
246
+ expect(codegen.ascTypeForEthereum('bytes[444][555]')).toBe('Array<Array<Bytes>>')
247
+ })
248
+
249
+ test('bytes0[*][*] (invalid)', () => {
250
+ expect(() => codegen.ethereumToAsc('x', 'bytes0[][]')).toThrow()
251
+ expect(() => codegen.ethereumToAsc('x', 'bytes0[83][]')).toThrow()
252
+ expect(() => codegen.ethereumToAsc('x', 'bytes0[][83]')).toThrow()
253
+ expect(() => codegen.ethereumToAsc('x', 'bytes0[123][321]')).toThrow()
254
+
255
+ expect(() => codegen.ascTypeForEthereum('bytes0[][]')).toThrow()
256
+ expect(() => codegen.ascTypeForEthereum('bytes0[83][]')).toThrow()
257
+ expect(() => codegen.ascTypeForEthereum('bytes0[][83]')).toThrow()
258
+ expect(() => codegen.ascTypeForEthereum('bytes0[123][321]')).toThrow()
259
+ })
260
+
261
+ test('bytes1..32[*][*] -> Array<Array<Bytes>>', () => {
262
+ for (let i = 1; i <= 32; i++) {
263
+ expect(codegen.ethereumToAsc('x', `bytes${i}[][]`)).toBe('x.toBytesMatrix()')
264
+ expect(codegen.ethereumToAsc('x', `bytes${i}[7][]`)).toBe('x.toBytesMatrix()')
265
+ expect(codegen.ethereumToAsc('x', `bytes${i}[][7]`)).toBe('x.toBytesMatrix()')
266
+ expect(codegen.ethereumToAsc('x', `bytes${i}[432][234]`)).toBe('x.toBytesMatrix()')
267
+
268
+ expect(codegen.ascTypeForEthereum(`bytes${i}[][]`)).toBe('Array<Array<Bytes>>')
269
+ expect(codegen.ascTypeForEthereum(`bytes${i}[6][]`)).toBe('Array<Array<Bytes>>')
270
+ expect(codegen.ascTypeForEthereum(`bytes${i}[][7]`)).toBe('Array<Array<Bytes>>')
271
+ expect(codegen.ascTypeForEthereum(`bytes${i}[432][234]`)).toBe('Array<Array<Bytes>>')
272
+ }
273
+ })
274
+
275
+ test('bytes33[*][*] (invalid)', () => {
276
+ expect(() => codegen.ethereumToAsc('x', 'bytes33[][]')).toThrow()
277
+ expect(() => codegen.ethereumToAsc('x', 'bytes33[58][]')).toThrow()
278
+ expect(() => codegen.ethereumToAsc('x', 'bytes33[][85]')).toThrow()
279
+ expect(() => codegen.ethereumToAsc('x', 'bytes33[394][493]')).toThrow()
280
+
281
+ expect(() => codegen.ascTypeForEthereum('bytes33[][]')).toThrow()
282
+ expect(() => codegen.ascTypeForEthereum('bytes33[58][]')).toThrow()
283
+ expect(() => codegen.ascTypeForEthereum('bytes33[][85]')).toThrow()
284
+ expect(() => codegen.ascTypeForEthereum('bytes33[394][493]')).toThrow()
285
+ })
286
+
287
+ test('int8..32[*][*], uint8..24[*][*] -> Array<Array<i32>>', () => {
288
+ for (let i = 8; i <= 32; i += 8) {
289
+ expect(codegen.ethereumToAsc('x', `int${i}[][]`)).toBe('x.toI32Matrix()')
290
+ expect(codegen.ethereumToAsc('x', `int${i}[6][]`)).toBe('x.toI32Matrix()')
291
+ expect(codegen.ethereumToAsc('x', `int${i}[][6]`)).toBe('x.toI32Matrix()')
292
+ expect(codegen.ethereumToAsc('x', `int${i}[4638][8364]`)).toBe('x.toI32Matrix()')
293
+
294
+ expect(codegen.ascTypeForEthereum(`int${i}[][]`)).toBe('Array<Array<i32>>')
295
+ expect(codegen.ascTypeForEthereum(`int${i}[6][]`)).toBe('Array<Array<i32>>')
296
+ expect(codegen.ascTypeForEthereum(`int${i}[][6]`)).toBe('Array<Array<i32>>')
297
+ expect(codegen.ascTypeForEthereum(`int${i}[4638][8364]`)).toBe('Array<Array<i32>>')
298
+ }
299
+ for (let i = 8; i <= 24; i += 8) {
300
+ expect(codegen.ethereumToAsc('x', `uint${i}[][]`)).toBe('x.toI32Matrix()')
301
+ expect(codegen.ethereumToAsc('x', `uint${i}[6][]`)).toBe('x.toI32Matrix()')
302
+ expect(codegen.ethereumToAsc('x', `uint${i}[][6]`)).toBe('x.toI32Matrix()')
303
+ expect(codegen.ethereumToAsc('x', `uint${i}[593][395]`)).toBe('x.toI32Matrix()')
304
+
305
+ expect(codegen.ascTypeForEthereum(`uint${i}[][]`)).toBe('Array<Array<i32>>')
306
+ expect(codegen.ascTypeForEthereum(`uint${i}[6][]`)).toBe('Array<Array<i32>>')
307
+ expect(codegen.ascTypeForEthereum(`uint${i}[][6]`)).toBe('Array<Array<i32>>')
308
+ expect(codegen.ascTypeForEthereum(`uint${i}[593][395]`)).toBe('Array<Array<i32>>')
309
+ }
310
+ })
311
+
312
+ test('uint32[*][*] -> Array<Array<BigInt>>', () => {
313
+ expect(codegen.ethereumToAsc('x', `uint32[][]`)).toBe('x.toBigIntMatrix()')
314
+ expect(codegen.ethereumToAsc('x', `uint32[6][]`)).toBe('x.toBigIntMatrix()')
315
+ expect(codegen.ethereumToAsc('x', `uint32[][6]`)).toBe('x.toBigIntMatrix()')
316
+ expect(codegen.ethereumToAsc('x', `uint32[593][395]`)).toBe('x.toBigIntMatrix()')
317
+
318
+ expect(codegen.ascTypeForEthereum(`uint32[][]`)).toBe('Array<Array<BigInt>>')
319
+ expect(codegen.ascTypeForEthereum(`uint32[6][]`)).toBe('Array<Array<BigInt>>')
320
+ expect(codegen.ascTypeForEthereum(`uint32[][5]`)).toBe('Array<Array<BigInt>>')
321
+ expect(codegen.ascTypeForEthereum(`uint32[593][395]`)).toBe('Array<Array<BigInt>>')
322
+ })
323
+
324
+ test('(u)int40..256[*][*] -> Array<Array<BigInt>>', () => {
325
+ for (let i = 40; i <= 256; i += 8) {
326
+ expect(codegen.ethereumToAsc('x', `int${i}[][]`)).toBe('x.toBigIntMatrix()')
327
+ expect(codegen.ethereumToAsc('x', `int${i}[7][]`)).toBe('x.toBigIntMatrix()')
328
+ expect(codegen.ethereumToAsc('x', `int${i}[][7]`)).toBe('x.toBigIntMatrix()')
329
+ expect(codegen.ethereumToAsc('x', `int${i}[6833][3386]`)).toBe('x.toBigIntMatrix()')
330
+
331
+ expect(codegen.ascTypeForEthereum(`int${i}[][]`)).toBe('Array<Array<BigInt>>')
332
+ expect(codegen.ascTypeForEthereum(`int${i}[7][]`)).toBe('Array<Array<BigInt>>')
333
+ expect(codegen.ascTypeForEthereum(`int${i}[][7]`)).toBe('Array<Array<BigInt>>')
334
+ expect(codegen.ascTypeForEthereum(`int${i}[6833][3386]`)).toBe('Array<Array<BigInt>>')
335
+
336
+ expect(codegen.ethereumToAsc('x', `uint${i}[][]`)).toBe('x.toBigIntMatrix()')
337
+ expect(codegen.ethereumToAsc('x', `uint${i}[23][]`)).toBe('x.toBigIntMatrix()')
338
+ expect(codegen.ethereumToAsc('x', `uint${i}[][32]`)).toBe('x.toBigIntMatrix()')
339
+ expect(codegen.ethereumToAsc('x', `uint${i}[467][764]`)).toBe('x.toBigIntMatrix()')
340
+
341
+ expect(codegen.ascTypeForEthereum(`uint${i}[][]`)).toBe('Array<Array<BigInt>>')
342
+ expect(codegen.ascTypeForEthereum(`uint${i}[23][]`)).toBe('Array<Array<BigInt>>')
343
+ expect(codegen.ascTypeForEthereum(`uint${i}[][32]`)).toBe('Array<Array<BigInt>>')
344
+ expect(codegen.ascTypeForEthereum(`uint${i}[467][764]`)).toBe('Array<Array<BigInt>>')
345
+ }
346
+ })
347
+
348
+ test('string[*][*] -> Array<Array<string>>', () => {
349
+ expect(codegen.ethereumToAsc('x', 'string[][]')).toBe('x.toStringMatrix()')
350
+ expect(codegen.ethereumToAsc('x', 'string[4][]')).toBe('x.toStringMatrix()')
351
+ expect(codegen.ethereumToAsc('x', 'string[][3]')).toBe('x.toStringMatrix()')
352
+ expect(codegen.ethereumToAsc('x', 'string[754][457]')).toBe('x.toStringMatrix()')
353
+
354
+ expect(codegen.ascTypeForEthereum('string[][]')).toBe('Array<Array<string>>')
355
+ expect(codegen.ascTypeForEthereum('string[4][]')).toBe('Array<Array<string>>')
356
+ expect(codegen.ascTypeForEthereum('string[][3]')).toBe('Array<Array<string>>')
357
+ expect(codegen.ascTypeForEthereum('string[754][457]')).toBe('Array<Array<string>>')
358
+ })
194
359
  })
195
360
 
196
361
  describe('AssemblyScript -> ethereum.Value', () => {
@@ -409,6 +574,188 @@ describe('AssemblyScript -> ethereum.Value', () => {
409
574
  'ethereum.Value.fromStringArray(x)',
410
575
  )
411
576
  })
577
+
578
+ // Multidimensional arrays
579
+
580
+ test('Array<Array<Address>> -> address[*][*]', () => {
581
+ expect(codegen.ethereumFromAsc('x', 'address[][]')).toBe(
582
+ 'ethereum.Value.fromAddressMatrix(x)',
583
+ )
584
+ expect(codegen.ethereumFromAsc('x', 'address[1][]')).toBe(
585
+ 'ethereum.Value.fromAddressMatrix(x)',
586
+ )
587
+ expect(codegen.ethereumFromAsc('x', 'address[][2]')).toBe(
588
+ 'ethereum.Value.fromAddressMatrix(x)',
589
+ )
590
+ expect(codegen.ethereumFromAsc('x', 'address[123][321]')).toBe(
591
+ 'ethereum.Value.fromAddressMatrix(x)',
592
+ )
593
+ })
594
+
595
+ test('Array<Array<boolean>> -> bool[*][*]', () => {
596
+ expect(codegen.ethereumFromAsc('x', 'bool[][]')).toBe(
597
+ 'ethereum.Value.fromBooleanMatrix(x)',
598
+ )
599
+ expect(codegen.ethereumFromAsc('x', 'bool[5][]')).toBe(
600
+ 'ethereum.Value.fromBooleanMatrix(x)',
601
+ )
602
+ expect(codegen.ethereumFromAsc('x', 'bool[][5]')).toBe(
603
+ 'ethereum.Value.fromBooleanMatrix(x)',
604
+ )
605
+ expect(codegen.ethereumFromAsc('x', 'bool[275][572]')).toBe(
606
+ 'ethereum.Value.fromBooleanMatrix(x)',
607
+ )
608
+ })
609
+
610
+ test('Array<Array<Bytes>> -> byte[*][*]', () => {
611
+ expect(codegen.ethereumFromAsc('x', 'byte[][]')).toBe(
612
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
613
+ )
614
+ expect(codegen.ethereumFromAsc('x', 'byte[7][]')).toBe(
615
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
616
+ )
617
+ expect(codegen.ethereumFromAsc('x', 'byte[][6]')).toBe(
618
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
619
+ )
620
+ expect(codegen.ethereumFromAsc('x', 'byte[553][355]')).toBe(
621
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
622
+ )
623
+ })
624
+
625
+ test('Array<Array<Bytes>> -> bytes[*][*]', () => {
626
+ expect(codegen.ethereumFromAsc('x', 'bytes[][]')).toBe(
627
+ 'ethereum.Value.fromBytesMatrix(x)',
628
+ )
629
+ expect(codegen.ethereumFromAsc('x', 'bytes[14][]')).toBe(
630
+ 'ethereum.Value.fromBytesMatrix(x)',
631
+ )
632
+ expect(codegen.ethereumFromAsc('x', 'bytes[][41]')).toBe(
633
+ 'ethereum.Value.fromBytesMatrix(x)',
634
+ )
635
+ expect(codegen.ethereumFromAsc('x', 'bytes[444][333]')).toBe(
636
+ 'ethereum.Value.fromBytesMatrix(x)',
637
+ )
638
+ })
639
+
640
+ test('bytes0[*][*] (invalid)', () => {
641
+ expect(() => codegen.ethereumFromAsc('x', 'bytes0[][]')).toThrow()
642
+ expect(() => codegen.ethereumFromAsc('x', 'bytes0[83][]')).toThrow()
643
+ expect(() => codegen.ethereumFromAsc('x', 'bytes0[][38]')).toThrow()
644
+ expect(() => codegen.ethereumFromAsc('x', 'bytes0[123][321]')).toThrow()
645
+ })
646
+
647
+ test('Array<Array<Bytes>> -> bytes1..32[*][*]', () => {
648
+ for (let i = 1; i <= 32; i++) {
649
+ expect(codegen.ethereumFromAsc('x', `bytes${i}[][]`)).toBe(
650
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
651
+ )
652
+ expect(codegen.ethereumFromAsc('x', `bytes${i}[7][]`)).toBe(
653
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
654
+ )
655
+ expect(codegen.ethereumFromAsc('x', `bytes${i}[][7]`)).toBe(
656
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
657
+ )
658
+ expect(codegen.ethereumFromAsc('x', `bytes${i}[432][234]`)).toBe(
659
+ 'ethereum.Value.fromFixedBytesMatrix(x)',
660
+ )
661
+ }
662
+ })
663
+
664
+ test('bytes33[*][*] (invalid)', () => {
665
+ expect(() => codegen.ethereumFromAsc('x', 'bytes33[][]')).toThrow()
666
+ expect(() => codegen.ethereumFromAsc('x', 'bytes33[58][]')).toThrow()
667
+ expect(() => codegen.ethereumFromAsc('x', 'bytes33[][85]')).toThrow()
668
+ expect(() => codegen.ethereumFromAsc('x', 'bytes33[394][493]')).toThrow()
669
+ })
670
+
671
+ test('Array<Array<i32>> -> int8..32[*][*], uint8..24[*][*]', () => {
672
+ for (let i = 8; i <= 32; i += 8) {
673
+ expect(codegen.ethereumFromAsc('x', `int${i}[][]`)).toBe(
674
+ 'ethereum.Value.fromI32Matrix(x)',
675
+ )
676
+ expect(codegen.ethereumFromAsc('x', `int${i}[6][]`)).toBe(
677
+ 'ethereum.Value.fromI32Matrix(x)',
678
+ )
679
+ expect(codegen.ethereumFromAsc('x', `int${i}[][5]`)).toBe(
680
+ 'ethereum.Value.fromI32Matrix(x)',
681
+ )
682
+ expect(codegen.ethereumFromAsc('x', `int${i}[4638][8364]`)).toBe(
683
+ 'ethereum.Value.fromI32Matrix(x)',
684
+ )
685
+ }
686
+
687
+ for (let i = 8; i <= 24; i += 8) {
688
+ expect(codegen.ethereumFromAsc('x', `uint${i}[][]`)).toBe(
689
+ 'ethereum.Value.fromI32Matrix(x)',
690
+ )
691
+ expect(codegen.ethereumFromAsc('x', `uint${i}[6][]`)).toBe(
692
+ 'ethereum.Value.fromI32Matrix(x)',
693
+ )
694
+ expect(codegen.ethereumFromAsc('x', `uint${i}[][5]`)).toBe(
695
+ 'ethereum.Value.fromI32Matrix(x)',
696
+ )
697
+ expect(codegen.ethereumFromAsc('x', `uint${i}[593][395]`)).toBe(
698
+ 'ethereum.Value.fromI32Matrix(x)',
699
+ )
700
+ }
701
+ })
702
+
703
+ test('Array<Array<BigInt>> -> uint32[*][*]', () => {
704
+ expect(codegen.ethereumFromAsc('x', `uint32[][]`)).toBe(
705
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
706
+ )
707
+ expect(codegen.ethereumFromAsc('x', `uint32[6][]`)).toBe(
708
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
709
+ )
710
+ expect(codegen.ethereumFromAsc('x', `uint32[][5]`)).toBe(
711
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
712
+ )
713
+ expect(codegen.ethereumFromAsc('x', `uint32[593][395]`)).toBe(
714
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
715
+ )
716
+ })
717
+
718
+ test('Array<Array<BigInt>> -> (u)int40..256[*][*]', () => {
719
+ for (let i = 40; i <= 256; i += 8) {
720
+ expect(codegen.ethereumFromAsc('x', `int${i}[][]`)).toBe(
721
+ 'ethereum.Value.fromSignedBigIntMatrix(x)',
722
+ )
723
+ expect(codegen.ethereumFromAsc('x', `int${i}[8][]`)).toBe(
724
+ 'ethereum.Value.fromSignedBigIntMatrix(x)',
725
+ )
726
+ expect(codegen.ethereumFromAsc('x', `int${i}[][7]`)).toBe(
727
+ 'ethereum.Value.fromSignedBigIntMatrix(x)',
728
+ )
729
+ expect(codegen.ethereumFromAsc('x', `int${i}[6833][3386]`)).toBe(
730
+ 'ethereum.Value.fromSignedBigIntMatrix(x)',
731
+ )
732
+
733
+ expect(codegen.ethereumFromAsc('x', `uint${i}[][]`)).toBe(
734
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
735
+ )
736
+ expect(codegen.ethereumFromAsc('x', `uint${i}[23][]`)).toBe(
737
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
738
+ )
739
+ expect(codegen.ethereumFromAsc('x', `uint${i}[][32]`)).toBe(
740
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
741
+ )
742
+ expect(codegen.ethereumFromAsc('x', `uint${i}[467][764]`)).toBe(
743
+ 'ethereum.Value.fromUnsignedBigIntMatrix(x)',
744
+ )
745
+ }
746
+ })
747
+
748
+ test('Array<Array<String>> -> string[*][*]', () => {
749
+ expect(codegen.ethereumFromAsc('x', 'string[]')).toBe(
750
+ 'ethereum.Value.fromStringArray(x)',
751
+ )
752
+ expect(codegen.ethereumFromAsc('x', 'string[4]')).toBe(
753
+ 'ethereum.Value.fromStringArray(x)',
754
+ )
755
+ expect(codegen.ethereumFromAsc('x', 'string[754]')).toBe(
756
+ 'ethereum.Value.fromStringArray(x)',
757
+ )
758
+ })
412
759
  })
413
760
 
414
761
  describe('Value -> AssemblyScript', () => {
@@ -18,13 +18,17 @@ const isTupleType = t => {
18
18
  }
19
19
 
20
20
  const containsTupleType = t => {
21
- return isTupleType(t) || isTupleArrayType(t)
21
+ return isTupleType(t) || isTupleArrayType(t) || isTupleMatrixType(t)
22
22
  }
23
23
 
24
24
  const isTupleArrayType = t => {
25
25
  return t.match(/^tuple\[([0-9]+)?\]$/)
26
26
  }
27
27
 
28
+ const isTupleMatrixType = t => {
29
+ return t.match(/^tuple\[([0-9]+)?\]\[([0-9]+)?\]$/)
30
+ }
31
+
28
32
  const unrollTuple = ({ path, index, value }) =>
29
33
  value.components.reduce((acc, component, index) => {
30
34
  let name = component.name || `value${index}`
@@ -44,5 +48,6 @@ module.exports = {
44
48
  disambiguateNames,
45
49
  isTupleType,
46
50
  isTupleArrayType,
51
+ isTupleMatrixType,
47
52
  unrollTuple,
48
53
  }
@@ -28,8 +28,14 @@ const withSpinner = async (text, errorText, warningText, f) => {
28
28
  try {
29
29
  let result = await f(spinner)
30
30
  if (typeof result === 'object') {
31
+ let hasError = Object.keys(result).indexOf('error') >= 0
31
32
  let hasWarning = Object.keys(result).indexOf('warning') >= 0
32
33
  let hasResult = Object.keys(result).indexOf('result') >= 0
34
+
35
+ if (hasError) {
36
+ spinner.fail(`${errorText}: ${result.error}`)
37
+ return hasResult ? result.result : result
38
+ }
33
39
  if (hasWarning && hasResult) {
34
40
  if (result.warning !== null) {
35
41
  spinner.warn(`${warningText}: ${result.warning}`)
@@ -24,6 +24,8 @@ const Protocol = require('../protocols')
24
24
  const protocolChoices = Array.from(Protocol.availableProtocols().keys())
25
25
  const availableNetworks = Protocol.availableNetworks()
26
26
 
27
+ const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum/gravatar'
28
+
27
29
  const HELP = `
28
30
  ${chalk.bold('graph init')} [options] [subgraph-name] [directory]
29
31
 
@@ -40,7 +42,7 @@ ${chalk.dim('Options:')}
40
42
  ${chalk.dim('Choose mode with one of:')}
41
43
 
42
44
  --from-contract <contract> Creates a scaffold based on an existing contract
43
- --from-example Creates a scaffold based on an example subgraph
45
+ --from-example [example] Creates a scaffold based on an example subgraph
44
46
 
45
47
  ${chalk.dim('Options for --from-contract:')}
46
48
 
@@ -106,7 +108,7 @@ const processInitForm = async (
106
108
  message: 'Product for which to initialize',
107
109
  choices: ['subgraph-studio', 'hosted-service'],
108
110
  skip: () =>
109
- protocol === 'near' ||
111
+ protocol === 'arweave' || protocol === 'cosmos' || protocol === 'near' ||
110
112
  product === 'subgraph-studio' ||
111
113
  product === 'hosted-service' ||
112
114
  studio !== undefined || node !== undefined,
@@ -280,9 +282,6 @@ const loadAbiFromFile = async (ABI, filename) => {
280
282
 
281
283
  module.exports = {
282
284
  description: 'Creates a new subgraph with basic scaffolding',
283
- options: {
284
- boolean: ['from-example'],
285
- },
286
285
  run: async toolbox => {
287
286
  // Obtain tools
288
287
  let { print, system } = toolbox
@@ -317,7 +316,6 @@ module.exports = {
317
316
  let subgraphName, directory
318
317
  try {
319
318
  ;[subgraphName, directory] = fixParameters(toolbox.parameters, {
320
- fromExample,
321
319
  allowSimpleName,
322
320
  help,
323
321
  h,
@@ -368,7 +366,7 @@ module.exports = {
368
366
  if (fromExample && subgraphName && directory) {
369
367
  return await initSubgraphFromExample(
370
368
  toolbox,
371
- { allowSimpleName, directory, subgraphName, studio, product },
369
+ { fromExample, allowSimpleName, directory, subgraphName, studio, product },
372
370
  { commands },
373
371
  )
374
372
  }
@@ -455,6 +453,7 @@ module.exports = {
455
453
  await initSubgraphFromExample(
456
454
  toolbox,
457
455
  {
456
+ fromExample: fromExample,
458
457
  subgraphName: inputs.subgraphName,
459
458
  directory: inputs.directory,
460
459
  studio: inputs.studio,
@@ -588,7 +587,7 @@ Make sure to visit the documentation on https://thegraph.com/docs/ for further i
588
587
 
589
588
  const initSubgraphFromExample = async (
590
589
  toolbox,
591
- { allowSimpleName, subgraphName, directory, studio, product },
590
+ { fromExample, allowSimpleName, subgraphName, directory, studio, product },
592
591
  { commands },
593
592
  ) => {
594
593
  let { filesystem, print, system } = toolbox
@@ -612,10 +611,32 @@ const initSubgraphFromExample = async (
612
611
  `Failed to clone example subgraph`,
613
612
  `Warnings while cloning example subgraph`,
614
613
  async spinner => {
615
- await system.run(
616
- `git clone http://github.com/graphprotocol/example-subgraph ${directory}`,
617
- )
618
- return true
614
+ // Create a temporary directory
615
+ const prefix = path.join(os.tmpdir(), 'example-subgraph-')
616
+ const tmpDir = fs.mkdtempSync(prefix)
617
+
618
+ try {
619
+ await system.run(
620
+ `git clone http://github.com/graphprotocol/example-subgraphs ${tmpDir}`
621
+ )
622
+
623
+ // If an example is not specified, use the default one
624
+ if (fromExample === undefined || fromExample === true) {
625
+ fromExample = DEFAULT_EXAMPLE_SUBGRAPH
626
+ }
627
+
628
+ const exampleSubgraphPath = path.join(tmpDir, fromExample);
629
+
630
+ if (!filesystem.exists(exampleSubgraphPath)) {
631
+ return { result: false, error: `Example not found: ${fromExample}` }
632
+ }
633
+
634
+ filesystem.copy(exampleSubgraphPath, directory)
635
+ return true
636
+ }
637
+ finally {
638
+ filesystem.remove(tmpDir)
639
+ }
619
640
  },
620
641
  )
621
642
  if (!cloned) {
@@ -5,6 +5,7 @@ const path = require('path')
5
5
  const AbiCodeGenerator = require('./codegen/abi')
6
6
 
7
7
  const TUPLE_ARRAY_PATTERN = /^tuple\[([0-9]*)\]$/
8
+ const TUPLE_MATRIX_PATTERN = /^tuple\[([0-9]*)\]\[([0-9]*)\]$/
8
9
 
9
10
  const buildOldSignatureParameter = input => {
10
11
  return input.get('type') === 'tuple'
@@ -27,6 +28,13 @@ const buildSignatureParameter = input => {
27
28
  .get('components')
28
29
  .map(component => buildSignatureParameter(component))
29
30
  .join(',')})[${length ? length : ''}]`
31
+ } else if (input.get('type').match(TUPLE_MATRIX_PATTERN)) {
32
+ const length1 = input.get('type').match(TUPLE_MATRIX_PATTERN)[1]
33
+ const length2 = input.get('type').match(TUPLE_MATRIX_PATTERN)[2]
34
+ return `(${input.get('indexed') ? 'indexed ' : ''}${input
35
+ .get('components')
36
+ .map(component => buildSignatureParameter(component))
37
+ .join(',')})[${length1 ? length1 : ''}][${length2 ? length2 : ''}]`
30
38
  } else {
31
39
  return `${input.get('indexed') ? 'indexed ' : ''}${input.get('type')}`
32
40
  }
@@ -362,7 +362,11 @@ module.exports = class AbiCodeGenerator {
362
362
  let tupleGetter = tsCodegen.method(
363
363
  `get ${name}`,
364
364
  [],
365
- util.isTupleArrayType(type) ? `Array<${tupleClassName}>` : tupleClassName,
365
+ util.isTupleMatrixType(type)
366
+ ? `Array<Array<${tupleClassName}>>`
367
+ : util.isTupleArrayType(type)
368
+ ? `Array<${tupleClassName}>`
369
+ : tupleClassName,
366
370
  `
367
371
  return ${
368
372
  isTupleType ? `changetype<${tupleClassName}>(${returnValue})` : `${returnValue}`
@@ -686,6 +690,13 @@ module.exports = class AbiCodeGenerator {
686
690
  const type = inputOrOutput.get('type')
687
691
  return util.isTupleType(type)
688
692
  ? this._tupleTypeName(inputOrOutput, index, tupleParentType, this.abi.name)
693
+ : util.isTupleMatrixType(type)
694
+ ? `Array<Array<${this._tupleTypeName(
695
+ inputOrOutput,
696
+ index,
697
+ tupleParentType,
698
+ this.abi.name,
699
+ )}>>`
689
700
  : util.isTupleArrayType(type)
690
701
  ? `Array<${this._tupleTypeName(
691
702
  inputOrOutput,
@@ -53,7 +53,7 @@ module.exports = class Scaffold {
53
53
  },
54
54
  dependencies: {
55
55
  '@graphprotocol/graph-cli': GRAPH_CLI_VERSION,
56
- '@graphprotocol/graph-ts': `0.27.0`,
56
+ '@graphprotocol/graph-ts': `0.28.0`,
57
57
  },
58
58
  devDependencies: this.protocol.hasEvents() ? { 'matchstick-as': `0.5.0`} : undefined,
59
59
  }),
package/src/subgraph.js CHANGED
@@ -100,17 +100,18 @@ module.exports = class Subgraph {
100
100
  }
101
101
 
102
102
  static validateRepository(manifest, { resolveFile }) {
103
- return manifest.get('repository') !==
104
- 'https://github.com/graphprotocol/example-subgraph'
105
- ? immutable.List()
106
- : immutable.List().push(
103
+ const repository = manifest.get('repository')
104
+
105
+ return /^https:\/\/github\.com\/graphprotocol\/example-subgraphs?$/.test(repository)
106
+ ? immutable.List().push(
107
107
  immutable.fromJS({
108
108
  path: ['repository'],
109
109
  message: `\
110
- The repository is still set to https://github.com/graphprotocol/example-subgraph.
110
+ The repository is still set to ${repository}.
111
111
  Please replace it with a link to your subgraph source code.`,
112
112
  }),
113
113
  )
114
+ : immutable.List()
114
115
  }
115
116
 
116
117
  static validateDescription(manifest, { resolveFile }) {
@@ -15,6 +15,7 @@ describe('Init', () => {
15
15
  'ethereum',
16
16
  '--studio',
17
17
  '--from-example',
18
+ 'ethereum/gravatar',
18
19
  'user/example-subgraph',
19
20
  path.join(ethereumBaseDir, 'from-example'),
20
21
  ],