@graphprotocol/graph-cli 0.37.2-alpha-20221219142030-0cf2a37 → 0.37.2

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.
@@ -1,4 +1,5 @@
1
1
  const fs = require('fs-extra')
2
+ const immutable = require('immutable')
2
3
  const path = require('path')
3
4
  const prettier = require('prettier')
4
5
  const graphql = require('graphql/language')
@@ -119,14 +120,14 @@ module.exports = class TypeGenerator {
119
120
  }
120
121
 
121
122
  async loadSchema(subgraph) {
122
- let maybeRelativePath = subgraph.schema?.file
123
+ let maybeRelativePath = subgraph.getIn(['schema', 'file'])
123
124
  let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
124
125
  return await withSpinner(
125
126
  `Load GraphQL schema from ${displayPath(absolutePath)}`,
126
127
  `Failed to load GraphQL schema from ${displayPath(absolutePath)}`,
127
128
  `Warnings while loading GraphQL schema from ${displayPath(absolutePath)}`,
128
129
  async spinner => {
129
- let maybeRelativePath = subgraph.schema?.file
130
+ let maybeRelativePath = subgraph.getIn(['schema', 'file'])
130
131
  let absolutePath = path.resolve(this.sourceDir, maybeRelativePath)
131
132
  return Schema.load(absolutePath)
132
133
  },
@@ -168,7 +169,7 @@ module.exports = class TypeGenerator {
168
169
  async spinner => {
169
170
  // Combine the generated code for all templates
170
171
  let codeSegments = subgraph
171
- .get('templates', [])
172
+ .get('templates', immutable.List())
172
173
  .reduce((codeSegments, template) => {
173
174
  step(
174
175
  spinner,
@@ -188,7 +189,7 @@ module.exports = class TypeGenerator {
188
189
  }
189
190
 
190
191
  return codeSegments.concat(codeGenerator.generateTypes())
191
- }, [])
192
+ }, immutable.List())
192
193
 
193
194
  if (!codeSegments.isEmpty()) {
194
195
  let code = prettier.format([GENERATED_FILE_NOTE, ...codeSegments].join('\n'), {
@@ -213,11 +214,11 @@ module.exports = class TypeGenerator {
213
214
  files.push(this.options.subgraphManifest)
214
215
 
215
216
  // Add the GraphQL schema to the watched files
216
- files.push(subgraph.schema?.file)
217
+ files.push(subgraph.getIn(['schema', 'file']))
217
218
 
218
219
  // Add all file paths specified in manifest
219
220
  subgraph.get('dataSources').map(dataSource => {
220
- dataSource.mapping?.abis.map(abi => {
221
+ dataSource.getIn(['mapping', 'abis']).map(abi => {
221
222
  files.push(abi.get('file'))
222
223
  })
223
224
  })
@@ -1,3 +1,5 @@
1
+ const immutable = require('immutable')
2
+
1
3
  const validateContract = (value, ProtocolContract) => {
2
4
  const contract = new ProtocolContract(value)
3
5
 
@@ -29,7 +31,8 @@ const validateContractValues = (manifest, protocol) => {
29
31
  return errors
30
32
  }
31
33
 
32
- let contractValue = dataSource.source[fieldName]
34
+ let contractValue = dataSource.getIn(['source', fieldName])
35
+
33
36
 
34
37
  const { valid, error } = validateContract(contractValue, ProtocolContract)
35
38
 
@@ -37,12 +40,14 @@ const validateContractValues = (manifest, protocol) => {
37
40
  if (valid) {
38
41
  return errors
39
42
  } else {
40
- return errors.push({
41
- path,
42
- message: error,
43
- })
43
+ return errors.push(
44
+ immutable.fromJS({
45
+ path,
46
+ message: error,
47
+ }),
48
+ )
44
49
  }
45
- }, [])
50
+ }, immutable.List())
46
51
  }
47
52
 
48
53
  module.exports = {
@@ -1,16 +1,20 @@
1
+ const immutable = require('immutable')
1
2
  const yaml = require('js-yaml')
2
3
  const path = require('path')
3
4
 
4
5
  const Protocol = require('../protocols')
5
6
 
7
+ const List = immutable.List
8
+ const Map = immutable.Map
9
+
6
10
  /**
7
11
  * Returns a user-friendly type name for a value.
8
12
  */
9
13
  const typeName = value =>
10
- Array.isArray(value) ? 'list' : typeof value === 'object' ? 'map' : typeof value
14
+ List.isList(value) ? 'list' : Map.isMap(value) ? 'map' : typeof value
11
15
 
12
16
  /**
13
- * Converts a plain JavaScript value to a YAML string.
17
+ * Converts an immutable or plain JavaScript value to a YAML string.
14
18
  */
15
19
  const toYAML = x =>
16
20
  yaml
@@ -23,7 +27,9 @@ const toYAML = x =>
23
27
  * Looks up the type of a field in a GraphQL object type.
24
28
  */
25
29
  const getFieldType = (type, fieldName) => {
26
- let fieldDef = type.get('fields').find(field => field.name?.value === fieldName)
30
+ let fieldDef = type
31
+ .get('fields')
32
+ .find(field => field.getIn(['name', 'value']) === fieldName)
27
33
 
28
34
  return fieldDef !== undefined ? fieldDef.get('type') : undefined
29
35
  }
@@ -35,17 +41,20 @@ const resolveType = (schema, type) =>
35
41
  type.has('type')
36
42
  ? resolveType(schema, type.get('type'))
37
43
  : type.get('kind') === 'NamedType'
38
- ? schema.get('definitions').find(def => def.name?.value === type.name?.value)
44
+ ? schema
45
+ .get('definitions')
46
+ .find(def => def.getIn(['name', 'value']) === type.getIn(['name', 'value']))
39
47
  : 'resolveType: unimplemented'
40
48
 
41
49
  /**
42
50
  * A map of supported validators.
43
51
  */
44
- const validators = Object.freeze({
45
- ScalarTypeDefinition: (value, ctx) => validators.get(ctx.type?.name?.value)(value, ctx),
52
+ const validators = immutable.fromJS({
53
+ ScalarTypeDefinition: (value, ctx) =>
54
+ validators.get(ctx.getIn(['type', 'name', 'value']))(value, ctx),
46
55
 
47
56
  UnionTypeDefinition: (value, ctx) => {
48
- const unionVariants = ctx.type?.types
57
+ const unionVariants = ctx.getIn(['type', 'types'])
49
58
 
50
59
  let errors = List()
51
60
 
@@ -74,12 +83,12 @@ const validators = Object.freeze({
74
83
  value,
75
84
  ctx.update('type', type => type.get('type')),
76
85
  )
77
- : [
86
+ : immutable.fromJS([
78
87
  {
79
88
  path: ctx.get('path'),
80
89
  message: `No value provided`,
81
90
  },
82
- ],
91
+ ]),
83
92
 
84
93
  ListType: (value, ctx) =>
85
94
  List.isList(value)
@@ -95,17 +104,18 @@ const validators = Object.freeze({
95
104
  ),
96
105
  List(),
97
106
  )
98
- : [
107
+ : immutable.fromJS([
99
108
  {
100
109
  path: ctx.get('path'),
101
110
  message: `Expected list, found ${typeName(value)}:\n${toYAML(value)}`,
102
111
  },
103
- ],
112
+ ]),
104
113
 
105
114
  ObjectTypeDefinition: (value, ctx) => {
106
115
  return Map.isMap(value)
107
- ? ctx.type?.fields
108
- .map(fieldDef => fieldDef.name?.value)
116
+ ? ctx
117
+ .getIn(['type', 'fields'])
118
+ .map(fieldDef => fieldDef.getIn(['name', 'value']))
109
119
  .concat(value.keySeq())
110
120
  .toSet()
111
121
  .reduce(
@@ -121,97 +131,97 @@ const validators = Object.freeze({
121
131
  )
122
132
  : errors.push(
123
133
  key == 'templates' && ctx.get('protocol').hasTemplates()
124
- ? {
134
+ ? immutable.fromJS({
125
135
  path: ctx.get('path'),
126
136
  message:
127
137
  `The way to declare data source templates has changed, ` +
128
138
  `please move the templates from inside data sources to ` +
129
139
  `a \`templates:\` field at the top level of the manifest.`,
130
- }
131
- : {
140
+ })
141
+ : immutable.fromJS({
132
142
  path: ctx.get('path'),
133
143
  message: `Unexpected key in map: ${key}`,
134
- },
144
+ }),
135
145
  ),
136
146
  List(),
137
147
  )
138
- : [
148
+ : immutable.fromJS([
139
149
  {
140
150
  path: ctx.get('path'),
141
151
  message: `Expected map, found ${typeName(value)}:\n${toYAML(value)}`,
142
152
  },
143
- ]
153
+ ])
144
154
  },
145
155
 
146
156
  EnumTypeDefinition: (value, ctx) => {
147
- const enumValues = ctx.type?.values.map(v => {
148
- return v.name?.value
157
+ const enumValues = ctx.getIn(['type', 'values']).map((v) => {
158
+ return v.getIn(['name', 'value'])
149
159
  })
150
160
 
151
161
  const allowedValues = enumValues.toArray().join(', ')
152
162
 
153
163
  return enumValues.includes(value)
154
- ? []
155
- : [
156
- {
157
- path: ctx.get('path'),
158
- message: `Unexpected enum value: ${value}, allowed values: ${allowedValues}`,
159
- },
160
- ]
164
+ ? List()
165
+ : immutable.fromJS([
166
+ {
167
+ path: ctx.get('path'),
168
+ message: `Unexpected enum value: ${value}, allowed values: ${allowedValues}`,
169
+ },
170
+ ])
161
171
  },
162
172
 
163
173
  String: (value, ctx) =>
164
174
  typeof value === 'string'
165
175
  ? List()
166
- : [
176
+ : immutable.fromJS([
167
177
  {
168
178
  path: ctx.get('path'),
169
179
  message: `Expected string, found ${typeName(value)}:\n${toYAML(value)}`,
170
180
  },
171
- ],
181
+ ]),
172
182
 
173
183
  BigInt: (value, ctx) =>
174
184
  typeof value === 'number'
175
- ? []
176
- : [
185
+ ? List()
186
+ : immutable.fromJS([
177
187
  {
178
188
  path: ctx.get('path'),
179
189
  message: `Expected BigInt, found ${typeName(value)}:\n${toYAML(value)}`,
180
190
  },
181
- ],
191
+ ]),
182
192
 
183
193
  File: (value, ctx) =>
184
194
  typeof value === 'string'
185
195
  ? require('fs').existsSync(ctx.get('resolveFile')(value))
186
- ? []
187
- : [
196
+ ? List()
197
+ : immutable.fromJS([
188
198
  {
189
199
  path: ctx.get('path'),
190
200
  message: `File does not exist: ${path.relative(process.cwd(), value)}`,
191
201
  },
192
- ]
193
- : [
202
+ ])
203
+ : immutable.fromJS([
194
204
  {
195
205
  path: ctx.get('path'),
196
206
  message: `Expected filename, found ${typeName(value)}:\n${value}`,
197
207
  },
198
- ],
208
+ ]),
199
209
 
200
210
  Boolean: (value, ctx) =>
201
211
  typeof value === 'boolean'
202
- ? []
203
- : [
212
+ ? List()
213
+ : immutable.fromJS([
204
214
  {
205
215
  path: ctx.get('path'),
206
216
  message: `Expected true or false, found ${typeName(value)}:\n${toYAML(
207
217
  value,
208
218
  )}`,
209
219
  },
210
- ],
220
+ ]),
211
221
  })
212
222
 
213
223
  const validateValue = (value, ctx) => {
214
- let kind = ctx.type?.kind
224
+ let kind = ctx.getIn(['type', 'kind'])
215
225
  let validator = validators.get(kind)
216
226
 
217
227
  if (validator !== undefined) {
@@ -219,17 +229,17 @@ const validateValue = (value, ctx) => {
219
229
  // type is wrapped in a `NonNullType`, the validator for that `NonNullType`
220
230
  // will catch the missing/unset value
221
231
  if (kind !== 'NonNullType' && (value === undefined || value === null)) {
222
- return []
232
+ return List()
223
233
  } else {
224
234
  return validator(value, ctx)
225
235
  }
226
236
  } else {
227
- return [
237
+ return immutable.fromJS([
228
238
  {
229
239
  path: ctx.get('path'),
230
240
  message: `No validator for unsupported schema type: ${kind}`,
231
241
  },
232
- ]
242
+ ])
233
243
  }
234
244
  }
235
245
 
@@ -241,7 +251,7 @@ const validateValue = (value, ctx) => {
241
251
  // { name: 'contract3', kind: 'near', network: 'near-mainnet' },
242
252
  // ]
243
253
  //
244
- // Into JS structure like this (protocol kind is normalized):
254
+ // Into Immutable JS structure like this (protocol kind is normalized):
245
255
  // {
246
256
  // ethereum: {
247
257
  // mainnet: ['contract0', 'contract1'],
@@ -252,17 +262,15 @@ const validateValue = (value, ctx) => {
252
262
  // },
253
263
  // }
254
264
  const dataSourceListToMap = dataSources =>
255
- dataSources.reduce((protocolKinds, dataSource) => {
256
- const dataSourceName = Protocol.normalizeName(dataSource.kind)
257
- if (!protocolKinds[dataSourceName]) {
258
- protocolKinds[dataSourceName] = {}
259
- }
260
- if (!protocolKinds[dataSourceName][dataSource.network]) {
261
- protocolKinds[dataSourceName][dataSource.network] = []
262
- }
263
- protocolKinds[dataSourceName][dataSource.network].push(dataSource.name)
264
- return protocolKinds
265
- }, {})
265
+ dataSources
266
+ .reduce(
267
+ (protocolKinds, dataSource) =>
268
+ protocolKinds.update(Protocol.normalizeName(dataSource.kind), networks =>
269
+ (networks || immutable.OrderedMap()).update(dataSource.network, dataSourceNames =>
270
+ (dataSourceNames || immutable.OrderedSet()).add(dataSource.name)),
271
+ ),
272
+ immutable.OrderedMap(),
273
+ )
266
274
 
267
275
  const validateDataSourceProtocolAndNetworks = value => {
268
276
  const dataSources = [...value.dataSources, ...(value.templates || [])]
@@ -270,7 +278,7 @@ const validateDataSourceProtocolAndNetworks = value => {
270
278
  const protocolNetworkMap = dataSourceListToMap(dataSources)
271
279
 
272
280
  if (protocolNetworkMap.size > 1) {
273
- return [
281
+ return immutable.fromJS([
274
282
  {
275
283
  path: [],
276
284
  message: `Conflicting protocol kinds used in data sources and templates:
@@ -281,22 +289,18 @@ ${protocolNetworkMap
281
289
  protocolKind === undefined
282
290
  ? 'Data sources and templates having no protocol kind set'
283
291
  : `Data sources and templates using '${protocolKind}'`
284
- }:\n${dataSourceNames
285
- .valueSeq()
286
- .flatten()
287
- .map(ds => ` - ${ds}`)
288
- .join('\n')}`,
292
+ }:\n${dataSourceNames.valueSeq().flatten().map(ds => ` - ${ds}`).join('\n')}`,
289
293
  )
290
294
  .join('\n')}
291
295
  Recommendation: Make all data sources and templates use the same protocol kind.`,
292
296
  },
293
- ]
297
+ ])
294
298
  }
295
299
 
296
300
  const networks = protocolNetworkMap.first()
297
301
 
298
302
  if (networks.size > 1) {
299
- return [
303
+ return immutable.fromJS([
300
304
  {
301
305
  path: [],
302
306
  message: `Conflicting networks used in data sources and templates:
@@ -312,30 +316,33 @@ ${networks
312
316
  .join('\n')}
313
317
  Recommendation: Make all data sources and templates use the same network name.`,
314
318
  },
315
- ]
319
+ ])
316
320
  }
317
321
 
318
- return []
322
+ return List()
319
323
  }
320
324
 
321
325
  const validateManifest = (value, type, schema, protocol, { resolveFile }) => {
322
326
  // Validate manifest using the GraphQL schema that defines its structure
323
327
  let errors =
324
328
  value !== null && value !== undefined
325
- ? validateValue(value, {
326
- schema: schema,
327
- type: type,
328
- path: [],
329
- errors: [],
330
- resolveFile,
331
- protocol,
332
- })
333
- : [
329
+ ? validateValue(
330
+ immutable.fromJS(value),
331
+ immutable.fromJS({
332
+ schema: schema,
333
+ type: type,
334
+ path: [],
335
+ errors: [],
336
+ resolveFile,
337
+ protocol,
338
+ }),
339
+ )
340
+ : immutable.fromJS([
334
341
  {
335
342
  path: [],
336
343
  message: `Expected non-empty value, found ${typeName(value)}:\n ${value}`,
337
344
  },
338
- ]
345
+ ])
339
346
 
340
347
  // Fail early because a broken manifest prevents us from performing
341
348
  // additional validation steps