@graphprotocol/graph-cli 0.23.2 → 0.25.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 (50) hide show
  1. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/README.md +83 -0
  2. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/ethereum.ts +2 -0
  3. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/common/json.ts +2 -2
  4. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/package.json +2 -7
  5. package/examples/basic-event-handlers/package.json +1 -1
  6. package/examples/basic-event-handlers/yarn.lock +4 -4
  7. package/examples/example-subgraph/package.json +1 -1
  8. package/examples/example-subgraph/yarn.lock +4 -4
  9. package/package.json +1 -1
  10. package/src/codegen/types/index.js +8 -1
  11. package/src/command-helpers/scaffold.js +66 -0
  12. package/src/commands/init.js +128 -92
  13. package/src/migrations/mapping_api_version_0_0_5.js +74 -0
  14. package/src/protocols/ethereum/contract.js +22 -0
  15. package/src/protocols/ethereum/scaffold/manifest.js +32 -0
  16. package/src/protocols/ethereum/scaffold/mapping.js +76 -0
  17. package/src/protocols/ethereum/subgraph.js +0 -14
  18. package/src/protocols/index.js +88 -8
  19. package/src/protocols/near/contract.js +46 -0
  20. package/src/protocols/near/scaffold/manifest.js +16 -0
  21. package/src/protocols/near/scaffold/mapping.js +39 -0
  22. package/src/protocols/near/subgraph.js +1 -23
  23. package/src/{scaffold.test.js → scaffold/ethereum.test.js} +27 -19
  24. package/src/scaffold/index.js +149 -0
  25. package/src/scaffold/mapping.js +49 -0
  26. package/src/scaffold/near.test.js +89 -0
  27. package/src/scaffold/schema.js +62 -0
  28. package/src/subgraph.js +8 -0
  29. package/src/validation/contract.js +56 -0
  30. package/src/validation/index.js +2 -1
  31. package/src/validation/manifest.js +0 -29
  32. package/tests/cli/init/{abis → ethereum/abis}/Marketplace.json +0 -0
  33. package/tests/cli/init/{abis → ethereum/abis}/OverloadedElements.json +0 -0
  34. package/tests/cli/init/{abis → ethereum/abis}/SoloMargin.json +0 -0
  35. package/tests/cli/init/{from-contract-with-abi-and-structs.stderr → ethereum/from-contract-with-abi-and-structs.stderr} +1 -1
  36. package/tests/cli/init/{from-contract-with-abi-and-structs.stdout → ethereum/from-contract-with-abi-and-structs.stdout} +0 -0
  37. package/tests/cli/init/{from-contract-with-abi.stderr → ethereum/from-contract-with-abi.stderr} +1 -1
  38. package/tests/cli/init/{from-contract-with-abi.stdout → ethereum/from-contract-with-abi.stdout} +0 -0
  39. package/tests/cli/init/{from-contract-with-overloaded-elements.stderr → ethereum/from-contract-with-overloaded-elements.stderr} +1 -1
  40. package/tests/cli/init/{from-contract-with-overloaded-elements.stdout → ethereum/from-contract-with-overloaded-elements.stdout} +0 -0
  41. package/tests/cli/init/{from-contract.stderr → ethereum/from-contract.stderr} +1 -1
  42. package/tests/cli/init/{from-contract.stdout → ethereum/from-contract.stdout} +0 -0
  43. package/tests/cli/init/{from-example.stderr → ethereum/from-example.stderr} +0 -0
  44. package/tests/cli/init/{from-example.stdout → ethereum/from-example.stdout} +0 -0
  45. package/tests/cli/init/near/from-contract.stderr +12 -0
  46. package/tests/cli/init/near/from-contract.stdout +12 -0
  47. package/tests/cli/init.test.js +143 -112
  48. package/tests/cli/util.js +56 -41
  49. package/tests/cli/validation/near-is-valid/subgraph.yaml +1 -0
  50. package/src/scaffold.js +0 -364
@@ -0,0 +1,62 @@
1
+ const { ascTypeForProtocol, valueTypeForAsc } = require('../codegen/types')
2
+ const util = require('../codegen/util')
3
+
4
+ const abiEvents = abi =>
5
+ util.disambiguateNames({
6
+ values: abi.data.filter(item => item.get('type') === 'event'),
7
+ getName: event => event.get('name'),
8
+ setName: (event, name) => event.set('_alias', name),
9
+ })
10
+
11
+ const protocolTypeToGraphQL = (protocol, name) => {
12
+ let ascType = ascTypeForProtocol(protocol, name)
13
+ return valueTypeForAsc(ascType)
14
+ }
15
+
16
+ const generateField = ({ name, type, protocolName }) =>
17
+ `${name}: ${protocolTypeToGraphQL(protocolName, type)}! # ${type}`
18
+
19
+ const generateEventFields = ({ index, input, protocolName }) =>
20
+ input.type == 'tuple'
21
+ ? util
22
+ .unrollTuple({ value: input, path: [input.name || `param${index}`], index })
23
+ .map(({ path, type }) => generateField({ name: path.join('_'), type, protocolName }))
24
+ : [generateField({ name: input.name || `param${index}`, type: input.type, protocolName })]
25
+
26
+ const generateEventType = (event, protocolName) => `type ${event._alias} @entity {
27
+ id: ID!
28
+ ${event.inputs
29
+ .reduce(
30
+ (acc, input, index) => acc.concat(generateEventFields({ input, index, protocolName })),
31
+ [],
32
+ )
33
+ .join('\n')}
34
+ }`
35
+
36
+ const generateExampleEntityType = (protocol, events) => {
37
+ if (protocol.hasABIs() && events.length > 0) {
38
+ return `type ExampleEntity @entity {
39
+ id: ID!
40
+ count: BigInt!
41
+ ${events[0].inputs
42
+ .reduce((acc, input, index) => acc.concat(generateEventFields({ input, index, protocolName: protocol.name })), [])
43
+ .slice(0, 2)
44
+ .join('\n')}
45
+ }`
46
+ } else {
47
+ return `type ExampleEntity @entity {
48
+ id: ID!
49
+ block: Bytes!
50
+ count: BigInt!
51
+ }`
52
+ }
53
+ }
54
+
55
+ module.exports = {
56
+ abiEvents,
57
+ protocolTypeToGraphQL,
58
+ generateField,
59
+ generateEventFields,
60
+ generateEventType,
61
+ generateExampleEntityType,
62
+ }
package/src/subgraph.js CHANGED
@@ -145,6 +145,13 @@ At least one such handler must be defined.`,
145
145
  }, immutable.List())
146
146
  }
147
147
 
148
+ static validateContractValues(manifest, protocol) {
149
+ return validation.validateContractValues(
150
+ manifest,
151
+ protocol,
152
+ )
153
+ }
154
+
148
155
  // Validate that data source names are unique, so they don't overwrite each other.
149
156
  static validateUniqueDataSourceNames(manifest) {
150
157
  let names = []
@@ -231,6 +238,7 @@ More than one template named '${name}', template names must be unique.`,
231
238
  ? immutable.List()
232
239
  : immutable.List.of(
233
240
  ...protocolSubgraph.validateManifest(),
241
+ ...Subgraph.validateContractValues(manifest, protocol),
234
242
  ...Subgraph.validateUniqueDataSourceNames(manifest),
235
243
  ...Subgraph.validateUniqueTemplateNames(manifest),
236
244
  ...Subgraph.validateHandlers(manifest, protocol, protocolSubgraph),
@@ -0,0 +1,56 @@
1
+ const immutable = require('immutable')
2
+
3
+ const validateContract = (value, ProtocolContract) => {
4
+ const contract = new ProtocolContract(value)
5
+
6
+ const { valid, error } = contract.validate()
7
+
8
+ if (!valid) {
9
+ return {
10
+ valid,
11
+ error: `Contract ${ProtocolContract.identifierName()} is invalid: ${value}\n${error}`,
12
+ }
13
+ }
14
+
15
+ return { valid, error }
16
+ }
17
+
18
+ const validateContractValues = (manifest, protocol) => {
19
+ const ProtocolContract = protocol.getContract()
20
+
21
+ const fieldName = ProtocolContract.identifierName()
22
+
23
+ return manifest
24
+ .get('dataSources')
25
+ .filter(dataSource => protocol.isValidKindName(dataSource.get('kind')))
26
+ .reduce((errors, dataSource, dataSourceIndex) => {
27
+ let path = ['dataSources', dataSourceIndex, 'source', fieldName]
28
+
29
+ // No need to validate if the source has no contract field
30
+ if (!dataSource.get('source').has(fieldName)) {
31
+ return errors
32
+ }
33
+
34
+ let contractValue = dataSource.getIn(['source', fieldName])
35
+
36
+
37
+ const { valid, error } = validateContract(contractValue, ProtocolContract)
38
+
39
+ // Validate whether the contract is valid for the protocol
40
+ if (valid) {
41
+ return errors
42
+ } else {
43
+ return errors.push(
44
+ immutable.fromJS({
45
+ path,
46
+ message: error,
47
+ }),
48
+ )
49
+ }
50
+ }, immutable.List())
51
+ }
52
+
53
+ module.exports = {
54
+ validateContract,
55
+ validateContractValues,
56
+ }
@@ -1,5 +1,6 @@
1
1
  module.exports = {
2
2
  validateSchema: require('./schema').validateSchema,
3
3
  validateManifest: require('./manifest').validateManifest,
4
- validateContractValues: require('./manifest').validateContractValues,
4
+ validateContractValues: require('./contract').validateContractValues,
5
+ validateContract: require('./contract').validateContract,
5
6
  }
@@ -282,35 +282,6 @@ const validateManifest = (value, type, schema, protocol, { resolveFile }) => {
282
282
  return validateDataSourceNetworks(value, protocol)
283
283
  }
284
284
 
285
- const validateContractValues = (manifest, protocol, fieldName, validator, errorMessage) =>
286
- manifest
287
- .get('dataSources')
288
- .filter(dataSource => protocol.isValidKindName(dataSource.get('kind')))
289
- .reduce((errors, dataSource, dataSourceIndex) => {
290
- let path = ['dataSources', dataSourceIndex, 'source', fieldName]
291
-
292
- // No need to validate if the source has no contract field
293
- if (!dataSource.get('source').has(fieldName)) {
294
- return errors
295
- }
296
-
297
- let contractValue = dataSource.getIn(['source', fieldName])
298
-
299
- // Validate whether the contract is valid
300
- if (validator(contractValue)) {
301
- return errors
302
- } else {
303
- return errors.push(
304
- immutable.fromJS({
305
- path,
306
- message: `\
307
- Contract ${fieldName} is invalid: ${contractValue}${errorMessage ? `\n${errorMessage}` : ''}`,
308
- }),
309
- )
310
- }
311
- }, immutable.List())
312
-
313
285
  module.exports = {
314
286
  validateManifest,
315
- validateContractValues,
316
287
  }
@@ -1,5 +1,5 @@
1
1
  - Create subgraph scaffold
2
- Generate subgraph from ABI
2
+ Generate subgraph
3
3
  - Create subgraph scaffold
4
4
  Write subgraph to directory
5
5
  - Create subgraph scaffold
@@ -1,5 +1,5 @@
1
1
  - Create subgraph scaffold
2
- Generate subgraph from ABI
2
+ Generate subgraph
3
3
  - Create subgraph scaffold
4
4
  Write subgraph to directory
5
5
  - Create subgraph scaffold
@@ -1,5 +1,5 @@
1
1
  - Create subgraph scaffold
2
- Generate subgraph from ABI
2
+ Generate subgraph
3
3
  - Create subgraph scaffold
4
4
  Write subgraph to directory
5
5
  - Create subgraph scaffold
@@ -1,7 +1,7 @@
1
1
  - Fetching ABI from Etherscan
2
2
  ✔ Fetching ABI from Etherscan
3
3
  - Create subgraph scaffold
4
- Generate subgraph from ABI
4
+ Generate subgraph
5
5
  - Create subgraph scaffold
6
6
  Write subgraph to directory
7
7
  - Create subgraph scaffold
@@ -0,0 +1,12 @@
1
+ - Create subgraph scaffold
2
+ Generate subgraph
3
+ - Create subgraph scaffold
4
+ Write subgraph to directory
5
+ - Create subgraph scaffold
6
+ ✔ Create subgraph scaffold
7
+ - Initialize subgraph repository
8
+ ✔ Initialize subgraph repository
9
+ - Install dependencies with yarn
10
+ ✔ Install dependencies with yarn
11
+ - Generate ABI and schema types with yarn codegen
12
+ ✔ Generate ABI and schema types with yarn codegen
@@ -0,0 +1,12 @@
1
+
2
+ Subgraph user/near-from-contract created in from-contract
3
+
4
+ Next steps:
5
+
6
+ 1. Run `graph auth` to authenticate with your deploy key.
7
+
8
+ 2. Type `cd from-contract` to enter the subgraph.
9
+
10
+ 3. Run `yarn deploy` to deploy the subgraph.
11
+
12
+ Make sure to visit the documentation on https://thegraph.com/docs/ for further information.
@@ -1,125 +1,156 @@
1
- const fs = require('fs-extra')
2
1
  const path = require('path')
3
2
  const { cliTest } = require('./util')
4
3
 
5
4
  describe('Init', () => {
6
- let baseDir = path.join(__dirname, 'init')
5
+ const baseDir = path.join(__dirname, 'init')
7
6
 
8
- let subgraphDir1 = path.join(baseDir, 'from-example')
9
- let subgraphDir2 = path.join(baseDir, 'from-contract')
10
- let subgraphDir3 = path.join(baseDir, 'from-contract-with-abi')
11
- let subgraphDir4 = path.join(baseDir, 'from-contract-with-abi-and-structs')
12
- let subgraphDir5 = path.join(baseDir, 'from-contract-with-overloaded-elements')
7
+ describe('Ethereum', () => {
8
+ const ethereumBaseDir = path.join(baseDir, 'ethereum')
13
9
 
14
- const removeSubgraphDirs = () => {
15
- if (fs.existsSync(subgraphDir1)) {
16
- fs.removeSync(subgraphDir1)
17
- }
18
- if (fs.existsSync(subgraphDir2)) {
19
- fs.removeSync(subgraphDir2)
20
- }
21
- if (fs.existsSync(subgraphDir3)) {
22
- fs.removeSync(subgraphDir3)
23
- }
24
- if (fs.existsSync(subgraphDir4)) {
25
- fs.removeSync(subgraphDir4)
26
- }
27
- if (fs.existsSync(subgraphDir5)) {
28
- fs.removeSync(subgraphDir5)
29
- }
30
- }
10
+ cliTest(
11
+ 'From example',
12
+ [
13
+ 'init',
14
+ '--protocol',
15
+ 'ethereum',
16
+ '--studio',
17
+ '--from-example',
18
+ 'user/example-subgraph',
19
+ path.join(ethereumBaseDir, 'from-example'),
20
+ ],
21
+ path.join('init', 'ethereum', 'from-example'),
22
+ {
23
+ exitCode: 0,
24
+ timeout: 100000,
25
+ cwd: ethereumBaseDir,
26
+ deleteDir: true,
27
+ },
28
+ )
31
29
 
32
- beforeAll(removeSubgraphDirs)
33
- afterAll(removeSubgraphDirs)
30
+ cliTest(
31
+ 'From contract',
32
+ [
33
+ 'init',
34
+ '--protocol',
35
+ 'ethereum',
36
+ '--studio',
37
+ '--from-contract',
38
+ '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d',
39
+ '--network',
40
+ 'mainnet',
41
+ 'user/subgraph-from-contract',
42
+ path.join(ethereumBaseDir, 'from-contract'),
43
+ ],
44
+ path.join('init', 'ethereum', 'from-contract'),
45
+ {
46
+ exitCode: 0,
47
+ timeout: 100000,
48
+ cwd: ethereumBaseDir,
49
+ deleteDir: true,
50
+ },
51
+ )
34
52
 
35
- cliTest(
36
- 'From example',
37
- [
38
- 'init',
39
- '--studio',
40
- '--from-example',
41
- 'user/example-subgraph',
42
- subgraphDir1
43
- ],
44
- 'init/from-example',
45
- {
46
- exitCode: 0,
47
- timeout: 100000,
48
- cwd: baseDir,
49
- },
50
- )
53
+ cliTest(
54
+ 'From contract with abi',
55
+ [
56
+ 'init',
57
+ '--protocol',
58
+ 'ethereum',
59
+ '--studio',
60
+ '--from-contract',
61
+ '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d',
62
+ '--abi',
63
+ path.join(ethereumBaseDir, 'abis', 'Marketplace.json'),
64
+ '--network',
65
+ 'mainnet',
66
+ 'user/subgraph-from-contract-with-abi',
67
+ path.join(ethereumBaseDir, 'from-contract-with-abi'),
68
+ ],
69
+ path.join('init', 'ethereum', 'from-contract-with-abi'),
70
+ {
71
+ exitCode: 0,
72
+ timeout: 100000,
73
+ cwd: ethereumBaseDir,
74
+ deleteDir: true,
75
+ },
76
+ )
51
77
 
52
- cliTest(
53
- 'From contract',
54
- [
55
- 'init',
56
- '--studio',
57
- '--from-contract',
58
- '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d',
59
- '--network',
60
- 'mainnet',
61
- 'user/subgraph-from-contract',
62
- subgraphDir2,
63
- ],
64
- 'init/from-contract',
65
- {
66
- exitCode: 0,
67
- timeout: 100000,
68
- cwd: baseDir,
69
- },
70
- )
78
+ cliTest(
79
+ 'From contract with abi and structs',
80
+ [
81
+ 'init',
82
+ '--protocol',
83
+ 'ethereum',
84
+ '--studio',
85
+ '--from-contract',
86
+ '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
87
+ '--abi',
88
+ path.join(ethereumBaseDir, 'abis', 'SoloMargin.json'),
89
+ '--network',
90
+ 'mainnet',
91
+ 'user/subgraph-from-contract-with-abi-and-structs',
92
+ path.join(ethereumBaseDir, 'from-contract-with-abi-and-structs'),
93
+ ],
94
+ path.join('init', 'ethereum', 'from-contract-with-abi-and-structs'),
95
+ {
96
+ exitCode: 0,
97
+ timeout: 100000,
98
+ cwd: ethereumBaseDir,
99
+ deleteDir: true,
100
+ },
101
+ )
71
102
 
72
- cliTest(
73
- 'From contract with abi',
74
- [
75
- 'init',
76
- '--studio',
77
- '--from-contract',
78
- '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d',
79
- '--abi',
80
- path.join(baseDir, 'abis', 'Marketplace.json'),
81
- '--network',
82
- 'mainnet',
83
- 'user/subgraph-from-contract-with-abi',
84
- subgraphDir3,
85
- ],
86
- 'init/from-contract-with-abi',
87
- { exitCode: 0, timeout: 100000, cwd: baseDir },
88
- )
103
+ cliTest(
104
+ 'From contract with overloaded elements',
105
+ [
106
+ 'init',
107
+ '--protocol',
108
+ 'ethereum',
109
+ '--studio',
110
+ '--from-contract',
111
+ '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
112
+ '--abi',
113
+ path.join(ethereumBaseDir, 'abis', 'OverloadedElements.json'),
114
+ '--network',
115
+ 'mainnet',
116
+ 'user/subgraph-from-contract-with-overloaded-elements',
117
+ path.join(ethereumBaseDir, 'from-contract-with-overloaded-elements'),
118
+ ],
119
+ path.join('init', 'ethereum', 'from-contract-with-overloaded-elements'),
120
+ {
121
+ exitCode: 0,
122
+ timeout: 100000,
123
+ cwd: ethereumBaseDir,
124
+ deleteDir: true,
125
+ },
126
+ )
127
+ })
89
128
 
90
- cliTest(
91
- 'From contract with abi and structs',
92
- [
93
- 'init',
94
- '--studio',
95
- '--from-contract',
96
- '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
97
- '--abi',
98
- path.join(baseDir, 'abis', 'SoloMargin.json'),
99
- '--network',
100
- 'mainnet',
101
- 'user/subgraph-from-contract-with-abi-and-structs',
102
- subgraphDir4,
103
- ],
104
- 'init/from-contract-with-abi-and-structs',
105
- { exitCode: 0, timeout: 100000, cwd: baseDir },
106
- )
129
+ describe('NEAR', () => {
130
+ const nearBaseDir = path.join(baseDir, 'near')
107
131
 
108
- cliTest(
109
- 'From contract with overloaded elements',
110
- [
111
- 'init',
112
- '--studio',
113
- '--from-contract',
114
- '0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e',
115
- '--abi',
116
- path.join(baseDir, 'abis', 'OverloadedElements.json'),
117
- '--network',
118
- 'mainnet',
119
- 'user/subgraph-from-contract-with-overloaded-elements',
120
- subgraphDir5,
121
- ],
122
- 'init/from-contract-with-overloaded-elements',
123
- { exitCode: 0, timeout: 100000, cwd: baseDir },
124
- )
132
+ cliTest(
133
+ 'From contract',
134
+ [
135
+ 'init',
136
+ '--protocol',
137
+ 'near',
138
+ '--product',
139
+ 'hosted-service',
140
+ '--from-contract',
141
+ 'app.good-morning.near',
142
+ '--network',
143
+ 'near-mainnet',
144
+ 'user/near-from-contract',
145
+ path.join(nearBaseDir, 'from-contract'),
146
+ ],
147
+ path.join('init', 'near', 'from-contract'),
148
+ {
149
+ exitCode: 0,
150
+ timeout: 100000,
151
+ cwd: nearBaseDir,
152
+ deleteDir: true,
153
+ },
154
+ )
155
+ })
125
156
  })
package/tests/cli/util.js CHANGED
@@ -1,57 +1,72 @@
1
- const fs = require('fs')
1
+ const fs = require('fs-extra')
2
2
  const path = require('path')
3
3
  const spawn = require('spawn-command')
4
4
  const stripAnsi = require('strip-ansi')
5
5
 
6
- const cliTest = (title, args, testPath, options) => {
6
+ // Deletes folder if:
7
+ // - flag is true
8
+ // - folder exists
9
+ const deleteDir = (dir, flag) => {
10
+ if (flag && fs.existsSync(dir)) {
11
+ fs.removeSync(dir)
12
+ }
13
+ }
14
+
15
+ const resolvePath = p => path.join(__dirname, p)
16
+
17
+ const cliTest = (title, args, testPath, options = {}) => {
7
18
  test(
8
19
  title,
9
20
  async () => {
10
- const resolvePath = p => path.join(__dirname, p)
11
-
12
- // Use the provided cwd if desired
13
- let cwd =
14
- options !== undefined && options.cwd ? options.cwd : resolvePath(`./${testPath}`)
21
+ try {
22
+ deleteDir(resolvePath(`./${testPath}`), options.deleteDir)
15
23
 
16
- let [exitCode, stdout, stderr] = await runGraphCli(args, cwd)
24
+ // Use the provided cwd if desired
25
+ let cwd =
26
+ options.cwd ? options.cwd : resolvePath(`./${testPath}`)
17
27
 
18
- let expectedExitCode = undefined
19
- if (options !== undefined && options.exitCode !== undefined) {
20
- expectedExitCode = options.exitCode
21
- }
22
- let expectedStdout = undefined
23
- try {
24
- expectedStdout = fs.readFileSync(resolvePath(`./${testPath}.stdout`), 'utf-8')
25
- } catch (e) {}
28
+ let [exitCode, stdout, stderr] = await runGraphCli(args, cwd)
26
29
 
27
- let expectedStderr = undefined
28
- try {
29
- expectedStderr = fs.readFileSync(resolvePath(`./${testPath}.stderr`), 'utf-8')
30
- } catch (e) {}
31
-
32
- if (expectedStderr !== undefined) {
33
- // For some reason the error sometimes comes in stdout, then
34
- // stderr comes empty.
35
- //
36
- // If that's the case, we should throw it so it's easier
37
- // to debug the error.
38
- //
39
- // TODO: investigate why that happens (somewhere it should
40
- // be using console.error or print.error for example) so this
41
- // check can be removed.
42
- if (stderr.length === 0 && stdout.length !== 0) {
43
- throw new Error(stdout)
30
+ let expectedExitCode = undefined
31
+ if (options.exitCode !== undefined) {
32
+ expectedExitCode = options.exitCode
44
33
  }
45
- expect(stripAnsi(stderr)).toBe(expectedStderr)
46
- }
47
- if (expectedExitCode !== undefined) {
48
- expect(exitCode).toBe(expectedExitCode)
49
- }
50
- if (expectedStdout !== undefined) {
51
- expect(stripAnsi(stdout)).toBe(expectedStdout)
34
+ let expectedStdout = undefined
35
+ try {
36
+ expectedStdout = fs.readFileSync(resolvePath(`./${testPath}.stdout`), 'utf-8')
37
+ } catch (e) {}
38
+
39
+ let expectedStderr = undefined
40
+ try {
41
+ expectedStderr = fs.readFileSync(resolvePath(`./${testPath}.stderr`), 'utf-8')
42
+ } catch (e) {}
43
+
44
+ if (expectedStderr !== undefined) {
45
+ // For some reason the error sometimes comes in stdout, then
46
+ // stderr comes empty.
47
+ //
48
+ // If that's the case, we should throw it so it's easier
49
+ // to debug the error.
50
+ //
51
+ // TODO: investigate why that happens (somewhere it should
52
+ // be using console.error or print.error for example) so this
53
+ // check can be removed.
54
+ if (stderr.length === 0 && stdout.length !== 0) {
55
+ throw new Error(stdout)
56
+ }
57
+ expect(stripAnsi(stderr)).toBe(expectedStderr)
58
+ }
59
+ if (expectedExitCode !== undefined) {
60
+ expect(exitCode).toBe(expectedExitCode)
61
+ }
62
+ if (expectedStdout !== undefined) {
63
+ expect(stripAnsi(stdout)).toBe(expectedStdout)
64
+ }
65
+ } finally {
66
+ deleteDir(resolvePath(`./${testPath}`), options.deleteDir)
52
67
  }
53
68
  },
54
- (options !== undefined && options.timeout) || undefined,
69
+ options.timeout || undefined,
55
70
  )
56
71
  }
57
72
 
@@ -6,6 +6,7 @@ schema:
6
6
  dataSources:
7
7
  - kind: near
8
8
  name: NearSubgraph
9
+ network: near-mainnet
9
10
  source:
10
11
  account: wnear.flux-dev
11
12
  startBlock: 1