@graphprotocol/graph-cli 0.56.0 → 0.56.1-alpha-20230831035057-3d319d2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @graphprotocol/graph-cli
2
2
 
3
+ ## 0.56.1-alpha-20230831035057-3d319d2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1433](https://github.com/graphprotocol/graph-tooling/pull/1433)
8
+ [`3d319d2`](https://github.com/graphprotocol/graph-tooling/commit/3d319d2bf39856b1e8e106b16302bbe40d3028b5)
9
+ Thanks [@saihaj](https://github.com/saihaj)! - when generating nested tuples make sure they are
10
+ non-nullable
11
+
12
+ - [#1433](https://github.com/graphprotocol/graph-tooling/pull/1433)
13
+ [`8287a05`](https://github.com/graphprotocol/graph-tooling/commit/8287a058f9991bb7fa5591142af6dd17cf2fb77d)
14
+ Thanks [@saihaj](https://github.com/saihaj)! - 2D arrays are valid entities
15
+
3
16
  ## 0.56.0
4
17
 
5
18
  ### Minor Changes
package/dist/debug.js CHANGED
@@ -11,6 +11,12 @@ debug_1.default.formatters.M = immutableMap => {
11
11
  if (immutableMap.toMap != null) {
12
12
  return JSON.stringify(immutableMap.toMap());
13
13
  }
14
+ if (typeof immutableMap.toJS === 'function') {
15
+ return JSON.stringify(immutableMap.toJS());
16
+ }
17
+ if (typeof immutableMap === 'object') {
18
+ return JSON.stringify(immutableMap);
19
+ }
14
20
  return immutableMap;
15
21
  };
16
22
  exports.default = debug_1.default;
@@ -46,14 +46,18 @@ const protocolTypeToGraphQL = (protocol, name) => {
46
46
  // TODO: this is a hack to make array type non-nullable
47
47
  // We should refactor the way we convert the Values from ASC to GraphQL
48
48
  // For arrays we always want non-nullable children
49
- return convertedType.endsWith(']') ? convertedType.replace(']', '!]') : convertedType;
49
+ return convertedType.endsWith(']') ? convertedType.replace(/\]/g, '!]') : convertedType;
50
50
  };
51
51
  exports.protocolTypeToGraphQL = protocolTypeToGraphQL;
52
52
  const generateField = ({ name, type, protocolName, }) => `${name}: ${(0, exports.protocolTypeToGraphQL)(protocolName, type)}! # ${type}`;
53
53
  exports.generateField = generateField;
54
54
  const generateEventFields = ({ index, input, protocolName, }) => input.type == 'tuple'
55
55
  ? util
56
- .unrollTuple({ value: input, path: [input.name || `param${index}`], index })
56
+ .unrollTuple({
57
+ value: input,
58
+ path: [input.name || `param${index}`],
59
+ index,
60
+ })
57
61
  .map(({ path, type }) => (0, exports.generateField)({ name: path.join('_'), type, protocolName }))
58
62
  : [
59
63
  (0, exports.generateField)({
package/dist/subgraph.js CHANGED
@@ -49,8 +49,9 @@ const buildCombinedWarning = (filename, warnings) => warnings.size > 0
49
49
  : null;
50
50
  class Subgraph {
51
51
  static async validate(data, protocol, { resolveFile }) {
52
- subgraphDebug(`Validating Subgraph with protocol "%s"`, protocol);
52
+ subgraphDebug.extend('validate')('Validating Subgraph with protocol %M', protocol);
53
53
  if (protocol.name == null) {
54
+ subgraphDebug.extend('validate')('Protocol has no name, skipping validation');
54
55
  return immutable_1.default.fromJS([
55
56
  {
56
57
  path: [],
@@ -66,13 +67,18 @@ class Subgraph {
66
67
  return definition.name.value === 'SubgraphManifest';
67
68
  });
68
69
  // Validate the subgraph manifest using this schema
69
- return validation.validateManifest(data, rootType, schema, protocol, { resolveFile });
70
+ return validation.validateManifest(data, rootType, schema, protocol, {
71
+ resolveFile,
72
+ });
70
73
  }
71
74
  static validateSchema(manifest, { resolveFile }) {
75
+ subgraphDebug.extend('validate')('Validating schema in manifest');
72
76
  const filename = resolveFile(manifest.getIn(['schema', 'file']));
77
+ subgraphDebug.extend('validate')('Loaded schema from %s', filename);
73
78
  const validationErrors = validation.validateSchema(filename);
74
79
  let errors;
75
80
  if (validationErrors.size > 0) {
81
+ subgraphDebug.extend('validate')('Schema validation failed for %s', filename);
76
82
  errors = validationErrors.groupBy(error => error.get('entity')).sort();
77
83
  const msg = errors.reduce((msg, errors, entity) => {
78
84
  errors = errors.groupBy((error) => error.get('directive'));
@@ -94,6 +100,7 @@ class Subgraph {
94
100
  }
95
101
  }
96
102
  static validateRepository(manifest) {
103
+ subgraphDebug.extend('validate')('Validating repository in manifest');
97
104
  const repository = manifest.get('repository');
98
105
  return /^https:\/\/github\.com\/graphprotocol\/graph-tooling?$/.test(repository) ||
99
106
  // For legacy reasons, we should error on example subgraphs
@@ -107,6 +114,7 @@ Please replace it with a link to your subgraph source code.`,
107
114
  : immutable_1.default.List();
108
115
  }
109
116
  static validateDescription(manifest) {
117
+ subgraphDebug.extend('validate')('Validating description in manifest');
110
118
  // TODO: Maybe implement this in the future for each protocol example description
111
119
  return manifest.get('description', '').startsWith('Gravatar for ')
112
120
  ? immutable_1.default.List().push(immutable_1.default.fromJS({
@@ -118,6 +126,7 @@ Please update it to tell users more about your subgraph.`,
118
126
  : immutable_1.default.List();
119
127
  }
120
128
  static validateHandlers(manifest, protocol, protocolSubgraph) {
129
+ subgraphDebug.extend('validate')('Validating handlers for protocol %s', protocol?.name);
121
130
  return manifest
122
131
  .get('dataSources')
123
132
  .filter((dataSource) => protocol.isValidKindName(dataSource.get('kind')))
@@ -125,7 +134,7 @@ Please update it to tell users more about your subgraph.`,
125
134
  const path = ['dataSources', dataSourceIndex, 'mapping'];
126
135
  const mapping = dataSource.get('mapping');
127
136
  const handlerTypes = protocolSubgraph.handlerTypes();
128
- subgraphDebug('Validating dataSource "%s" handlers with %d handlers types defined for protocol', dataSource.get('name'), handlerTypes.size);
137
+ subgraphDebug.extend('validate')('Validating dataSource "%s" handlers with %d handlers types defined for protocol', dataSource.get('name'), handlerTypes.size);
129
138
  if (handlerTypes.size == 0) {
130
139
  return errors;
131
140
  }
@@ -144,13 +153,16 @@ At least one such handler must be defined.`,
144
153
  }, immutable_1.default.List());
145
154
  }
146
155
  static validateContractValues(manifest, protocol) {
156
+ subgraphDebug.extend('validate')('Validating contract values for protocol %s', protocol?.name);
147
157
  if (!protocol.hasContract()) {
158
+ subgraphDebug.extend('validate')('Protocol has no contract, skipping validation');
148
159
  return immutable_1.default.List();
149
160
  }
150
161
  return validation.validateContractValues(manifest, protocol);
151
162
  }
152
163
  // Validate that data source names are unique, so they don't overwrite each other.
153
164
  static validateUniqueDataSourceNames(manifest) {
165
+ subgraphDebug.extend('validate')('Validating that data source names are unique');
154
166
  const names = [];
155
167
  return manifest
156
168
  .get('dataSources')
@@ -158,6 +170,7 @@ At least one such handler must be defined.`,
158
170
  const path = ['dataSources', dataSourceIndex, 'name'];
159
171
  const name = dataSource.get('name');
160
172
  if (names.includes(name)) {
173
+ subgraphDebug.extend('validate')("Found duplicate data source name '%s', adding error");
161
174
  errors = errors.push(immutable_1.default.fromJS({
162
175
  path,
163
176
  message: `\
@@ -169,6 +182,7 @@ More than one data source named '${name}', data source names must be unique.`,
169
182
  }, immutable_1.default.List());
170
183
  }
171
184
  static validateUniqueTemplateNames(manifest) {
185
+ subgraphDebug.extend('validate')('Validating that template names are unique');
172
186
  const names = [];
173
187
  return manifest
174
188
  .get('templates', immutable_1.default.List())
@@ -176,6 +190,7 @@ More than one data source named '${name}', data source names must be unique.`,
176
190
  const path = ['templates', templateIndex, 'name'];
177
191
  const name = template.get('name');
178
192
  if (names.includes(name)) {
193
+ subgraphDebug.extend('validate')("Found duplicate template name '%s', adding error");
179
194
  errors = errors.push(immutable_1.default.fromJS({
180
195
  path,
181
196
  message: `\
@@ -202,21 +217,30 @@ More than one template named '${name}', template names must be unique.`,
202
217
  data = require(path_1.default.resolve(filename));
203
218
  }
204
219
  else {
220
+ subgraphDebug('Loading manifest from %s', filename);
205
221
  const raw_data = await fs_extra_1.default.readFile(filename, 'utf-8');
222
+ subgraphDebug('Checking for file data sources in %s', filename);
206
223
  has_file_data_sources = raw_data.includes('kind: file');
224
+ subgraphDebug('Parsing manifest from %s', filename);
207
225
  data = yaml_1.default.parse(raw_data);
208
226
  }
209
227
  // Helper to resolve files relative to the subgraph manifest
210
228
  const resolveFile = maybeRelativeFile => path_1.default.resolve(path_1.default.dirname(filename), maybeRelativeFile);
211
229
  // TODO: Validation for file data sources
212
230
  if (!has_file_data_sources) {
213
- const manifestErrors = await Subgraph.validate(data, protocol, { resolveFile });
231
+ subgraphDebug('Validating manifest from %s', filename);
232
+ const manifestErrors = await Subgraph.validate(data, protocol, {
233
+ resolveFile,
234
+ });
214
235
  if (manifestErrors.size > 0) {
236
+ subgraphDebug('Manifest validation failed for %s', filename);
215
237
  throwCombinedError(filename, manifestErrors);
216
238
  }
217
239
  }
218
240
  const manifest = immutable_1.default.fromJS(data);
241
+ subgraphDebug.extend('manifest')('Loaded: %M', manifest);
219
242
  // Validate the schema
243
+ subgraphDebug.extend('manifest')('Validating schema');
220
244
  Subgraph.validateSchema(manifest, { resolveFile });
221
245
  // Perform other validations
222
246
  const protocolSubgraph = protocol.getSubgraph({
@@ -30,6 +30,8 @@ exports.validateSchema = exports.typeSuggestion = void 0;
30
30
  const fs_1 = __importDefault(require("fs"));
31
31
  const graphql = __importStar(require("graphql/language"));
32
32
  const immutable_1 = __importDefault(require("immutable"));
33
+ const debug_1 = __importDefault(require("../debug"));
34
+ const validateDebugger = (0, debug_1.default)('graph-cli:validation');
33
35
  const List = immutable_1.default.List;
34
36
  const Set = immutable_1.default.Set;
35
37
  // Builtin scalar types
@@ -101,18 +103,23 @@ const parseSchema = (doc) => {
101
103
  throw new Error(`Invalid GraphQL schema: ${e}`);
102
104
  }
103
105
  };
104
- const validateEntityDirective = (def) => def.directives.find((directive) => directive.name.value === 'entity')
105
- ? List()
106
- : immutable_1.default.fromJS([
107
- {
108
- loc: def.loc,
109
- entity: def.name.value,
110
- message: `Defined without @entity directive`,
111
- },
112
- ]);
106
+ const validateEntityDirective = (def) => {
107
+ validateDebugger('Validating entity directive for %s', def?.name?.value);
108
+ return def.directives.find((directive) => directive.name.value === 'entity')
109
+ ? List()
110
+ : immutable_1.default.fromJS([
111
+ {
112
+ loc: def.loc,
113
+ entity: def.name.value,
114
+ message: `Defined without @entity directive`,
115
+ },
116
+ ]);
117
+ };
113
118
  const validateEntityID = (def) => {
119
+ validateDebugger('Validating entity ID for %s', def?.name?.value);
114
120
  const idField = def.fields.find((field) => field.name.value === 'id');
115
121
  if (idField === undefined) {
122
+ validateDebugger('Entity %s has no id field', def?.name?.value);
116
123
  return immutable_1.default.fromJS([
117
124
  {
118
125
  loc: def.loc,
@@ -126,8 +133,10 @@ const validateEntityID = (def) => {
126
133
  (idField.type.type.name.value === 'ID' ||
127
134
  idField.type.type.name.value === 'Bytes' ||
128
135
  idField.type.type.name.value === 'String')) {
136
+ validateDebugger('Entity %s has valid id field', def?.name?.value);
129
137
  return List();
130
138
  }
139
+ validateDebugger('Entity %s has invalid id field', def?.name?.value);
131
140
  return immutable_1.default.fromJS([
132
141
  {
133
142
  loc: idField.loc,
@@ -136,52 +145,80 @@ const validateEntityID = (def) => {
136
145
  },
137
146
  ]);
138
147
  };
139
- const validateListFieldType = (def, field) => field.type.kind === 'NonNullType' &&
140
- field.type.kind === 'ListType' &&
141
- field.type.type.kind !== 'NonNullType'
142
- ? immutable_1.default.fromJS([
143
- {
144
- loc: field.loc,
145
- entity: def.name.value,
146
- message: `\
147
- Field '${field.name.value}':
148
- Field has type [${field.type.type.name.value}]! but
149
- must have type [${field.type.type.name.value}!]!
150
-
151
- Reason: Lists with null elements are not supported.`,
152
- },
153
- ])
154
- : field.type.kind === 'ListType' && field.type.type.kind !== 'NonNullType'
148
+ const validateListFieldType = (def, field) => {
149
+ validateDebugger('Validating list field type for %s', def?.name?.value);
150
+ return field.type.kind === 'NonNullType' &&
151
+ field.type.kind === 'ListType' &&
152
+ field.type.type.kind !== 'NonNullType'
155
153
  ? immutable_1.default.fromJS([
156
154
  {
157
155
  loc: field.loc,
158
156
  entity: def.name.value,
159
157
  message: `\
160
158
  Field '${field.name.value}':
161
- Field has type [${field.type.type.name.value}] but
162
- must have type [${field.type.type.name.value}!]
159
+ Field has type [${field.type.type.name.value}]! but
160
+ must have type [${field.type.type.name.value}!]!
163
161
 
164
162
  Reason: Lists with null elements are not supported.`,
165
163
  },
166
164
  ])
167
- : List();
165
+ : field.type.kind === 'ListType' && field.type.type.kind !== 'NonNullType'
166
+ ? immutable_1.default.fromJS([
167
+ {
168
+ loc: field.loc,
169
+ entity: def.name.value,
170
+ message: `\
171
+ Field '${field.name.value}':
172
+ Field has type [${field.type.type.name.value}] but
173
+ must have type [${field.type.type.name.value}!]
174
+
175
+ Reason: Lists with null elements are not supported.`,
176
+ },
177
+ ])
178
+ : List();
179
+ };
168
180
  const unwrapType = (type) => {
169
- const innerTypeFromList = (listType) => listType.type.kind === 'NonNullType' ? innerTypeFromNonNull(listType.type) : listType.type;
170
- const innerTypeFromNonNull = (nonNullType) => nonNullType.type.kind === 'ListType' ? innerTypeFromList(nonNullType.type) : nonNullType.type;
181
+ validateDebugger.extend('definition')('Unwrapping type %M', type);
182
+ const innerTypeFromList = (listType) => {
183
+ validateDebugger.extend('unwrapType').extend('definition')('Unwrapping list type %M', listType);
184
+ if (listType.type.kind === 'NonNullType') {
185
+ validateDebugger.extend('unwrapType').extend('innerTypeFromList')('Returning non-null list type');
186
+ return innerTypeFromNonNull(listType.type);
187
+ }
188
+ validateDebugger.extend('unwrapType').extend('innerTypeFromList')('Returning list type');
189
+ return unwrapType(listType.type);
190
+ };
191
+ const innerTypeFromNonNull = (nonNullType) => {
192
+ validateDebugger.extend('unwrapType').extend('definition')('Unwrapping non-null type %M', nonNullType);
193
+ if (nonNullType.type.kind === 'ListType') {
194
+ validateDebugger.extend('unwrapType').extend('innerTypeFromNonNull')('Returning non-null list type');
195
+ return innerTypeFromList(nonNullType.type);
196
+ }
197
+ validateDebugger.extend('unwrapType').extend('innerTypeFromNonNull')('Returning non-null type');
198
+ return unwrapType(nonNullType.type);
199
+ };
171
200
  // Obtain the inner-most type from the field
172
- return type.kind === 'NonNullType'
173
- ? innerTypeFromNonNull(type)
174
- : type.kind === 'ListType'
175
- ? innerTypeFromList(type)
176
- : type;
177
- };
178
- const gatherLocalTypes = (defs) => defs
179
- .filter(def => def.kind === 'ObjectTypeDefinition' ||
180
- def.kind === 'EnumTypeDefinition' ||
181
- def.kind === 'InterfaceTypeDefinition')
182
- .map(def =>
183
- // @ts-expect-error TODO: name field does not exist on definition, really?
184
- def.name.value);
201
+ if (type.kind === 'NonNullType') {
202
+ validateDebugger('Returning inner type from non-null type');
203
+ return innerTypeFromNonNull(type);
204
+ }
205
+ if (type.kind === 'ListType') {
206
+ validateDebugger('Returning inner type from list type');
207
+ return innerTypeFromList(type);
208
+ }
209
+ validateDebugger('Returning inner type');
210
+ return type;
211
+ };
212
+ const gatherLocalTypes = (defs) => {
213
+ validateDebugger('Gathering local types');
214
+ return defs
215
+ .filter(def => def.kind === 'ObjectTypeDefinition' ||
216
+ def.kind === 'EnumTypeDefinition' ||
217
+ def.kind === 'InterfaceTypeDefinition')
218
+ .map(def =>
219
+ // @ts-expect-error TODO: name field does not exist on definition, really?
220
+ def.name.value);
221
+ };
185
222
  const gatherImportedTypes = (defs) => defs
186
223
  .filter(def => def.kind === 'ObjectTypeDefinition' &&
187
224
  def.name.value == RESERVED_TYPE &&
@@ -206,19 +243,28 @@ def.directives
206
243
  }
207
244
  return flattened;
208
245
  }, [])), []);
209
- const entityTypeByName = (defs, name) => defs
210
- .filter(def => def.kind === 'InterfaceTypeDefinition' ||
211
- (def.kind === 'ObjectTypeDefinition' &&
212
- def.directives.find((directive) => directive.name.value === 'entity')))
213
- .find(def => def.name.value === name);
214
- const fieldTargetEntityName = (field) => unwrapType(field.type).name.value;
246
+ const entityTypeByName = (defs, name) => {
247
+ validateDebugger('Looking up entity type %s', name);
248
+ return defs
249
+ .filter(def => def.kind === 'InterfaceTypeDefinition' ||
250
+ (def.kind === 'ObjectTypeDefinition' &&
251
+ def.directives.find((directive) => directive.name.value === 'entity')))
252
+ .find(def => def.name.value === name);
253
+ };
254
+ const fieldTargetEntityName = (field) => {
255
+ validateDebugger('Looking up field target entity name for %s', field?.name?.value);
256
+ return unwrapType(field.type).name.value;
257
+ };
215
258
  const fieldTargetEntity = (defs, field) => entityTypeByName(defs, fieldTargetEntityName(field));
216
259
  const validateInnerFieldType = (defs, def, field) => {
260
+ validateDebugger('Validating inner field type for %s', def?.name?.value);
217
261
  const innerType = unwrapType(field.type);
218
262
  // Get the name of the type
219
263
  const typeName = innerType.name.value;
264
+ validateDebugger('Inner field type name: %s', typeName);
220
265
  // Look up a possible suggestion for the type to catch common mistakes
221
266
  const suggestion = (0, exports.typeSuggestion)(typeName);
267
+ validateDebugger('Inner field type suggestion: %s', suggestion);
222
268
  // Collect all types that we can use here: built-ins + entities + enums + interfaces
223
269
  const availableTypes = List.of(...BUILTIN_SCALAR_TYPES, ...gatherLocalTypes(defs), ...gatherImportedTypes(defs));
224
270
  // Check whether the type name is available, otherwise return an error
@@ -292,6 +338,7 @@ does not exist on type '${targetEntity.name.value}'`,
292
338
  ]);
293
339
  }
294
340
  const backrefTypeName = unwrapType(derivedFromField.type);
341
+ validateDebugger.extend('definition')('Backref type name: %M', backrefTypeName);
295
342
  const backRefEntity = entityTypeByName(defs, backrefTypeName.name.value);
296
343
  // The field we are deriving from must either have type 'def' or one of the
297
344
  // interface types that 'def' is implementing
@@ -682,6 +729,7 @@ const validateImportDirectiveArgumentFrom = (def, directive, argument) => {
682
729
  }, List());
683
730
  };
684
731
  const validateImportDirectiveFields = (def, directive) => {
732
+ validateDebugger('Validating import directive fields: %s', def?.name?.value);
685
733
  return directive.arguments.reduce((errors, argument) => {
686
734
  return errors.concat(['types', 'from'].includes(argument.name.value)
687
735
  ? List([])
@@ -695,6 +743,7 @@ const validateImportDirectiveFields = (def, directive) => {
695
743
  }, List([]));
696
744
  };
697
745
  const validateImportDirectiveTypes = (def, directive) => {
746
+ validateDebugger('Validating import directive types: %s', def?.name?.value);
698
747
  const types = directive.arguments.find((argument) => argument.name.value == 'types');
699
748
  return types
700
749
  ? validateImportDirectiveArgumentTypes(def, directive, types)
@@ -707,6 +756,7 @@ const validateImportDirectiveTypes = (def, directive) => {
707
756
  ]);
708
757
  };
709
758
  const validateImportDirectiveFrom = (def, directive) => {
759
+ validateDebugger('Validating import directive from: %s', def?.name?.value);
710
760
  const from = directive.arguments.find((argument) => argument.name.value == 'from');
711
761
  return from
712
762
  ? validateImportDirectiveArgumentFrom(def, directive, from)
@@ -718,13 +768,19 @@ const validateImportDirectiveFrom = (def, directive) => {
718
768
  }),
719
769
  ]);
720
770
  };
721
- const validateImportDirective = (def, directive) => List.of(...validateImportDirectiveFields(def, directive), ...validateImportDirectiveTypes(def, directive), ...validateImportDirectiveFrom(def, directive));
771
+ const validateImportDirective = (def, directive) => {
772
+ validateDebugger('Validating import directive: %s', def?.name?.value);
773
+ return List.of(...validateImportDirectiveFields(def, directive), ...validateImportDirectiveTypes(def, directive), ...validateImportDirectiveFrom(def, directive));
774
+ };
722
775
  const validateFulltext = (def, directive) => List.of(...validateFulltextFields(def, directive), ...validateFulltextName(def, directive), ...validateFulltextLanguage(def, directive), ...validateFulltextAlgorithm(def, directive), ...validateFulltextInclude(def, directive));
723
776
  const validateSubgraphSchemaDirective = (def, directive) => {
777
+ validateDebugger('Validating subgraph schema directive: %s', def?.name?.value);
724
778
  if (directive.name.value == 'import') {
779
+ validateDebugger('Validating import directive: %s', def?.name?.value);
725
780
  return validateImportDirective(def, directive);
726
781
  }
727
782
  if (directive.name.value == 'fulltext') {
783
+ validateDebugger('Validating fulltext directive: %s', def?.name?.value);
728
784
  return validateFulltext(def, directive);
729
785
  }
730
786
  return List([
@@ -735,32 +791,52 @@ const validateSubgraphSchemaDirective = (def, directive) => {
735
791
  }),
736
792
  ]);
737
793
  };
738
- const validateSubgraphSchemaDirectives = (def) => def.directives.reduce((errors, directive) => errors.concat(validateSubgraphSchemaDirective(def, directive)), List());
739
- const validateTypeHasNoFields = (def) => def.fields.length
740
- ? List([
741
- immutable_1.default.fromJS({
742
- loc: def.name.loc,
743
- entity: def.name.value,
744
- message: `${def.name.value} type is not allowed any fields by convention`,
745
- }),
746
- ])
747
- : List();
794
+ const validateSubgraphSchemaDirectives = (def) => {
795
+ validateDebugger('Validating subgraph schema directives: %s', def?.name?.value);
796
+ return def.directives.reduce((errors, directive) => errors.concat(validateSubgraphSchemaDirective(def, directive)), List());
797
+ };
798
+ const validateTypeHasNoFields = (def) => {
799
+ validateDebugger('Validating type has no fields: %s', def?.name?.value);
800
+ return def.fields.length
801
+ ? List([
802
+ immutable_1.default.fromJS({
803
+ loc: def.name.loc,
804
+ entity: def.name.value,
805
+ message: `${def.name.value} type is not allowed any fields by convention`,
806
+ }),
807
+ ])
808
+ : List();
809
+ };
748
810
  const validateAtLeastOneExtensionField = (_def) => List();
749
811
  const typeDefinitionValidators = {
750
- ObjectTypeDefinition: (defs, def) => def.name && def.name.value == RESERVED_TYPE
751
- ? List.of(...validateSubgraphSchemaDirectives(def), ...validateTypeHasNoFields(def))
752
- : List.of(...validateEntityDirective(def), ...validateEntityID(def), ...validateEntityFields(defs, def), ...validateNoImportDirective(def), ...validateNoFulltext(def)),
753
- ObjectTypeExtension: (_defs, def) => validateAtLeastOneExtensionField(def),
754
- };
755
- const validateTypeDefinition = (defs, def) => typeDefinitionValidators[def.kind] === undefined
756
- ? List()
757
- : typeDefinitionValidators[def.kind](defs, def);
758
- const validateTypeDefinitions = (defs) => defs.reduce((errors, def) => errors.concat(validateTypeDefinition(defs, def)), List());
812
+ ObjectTypeDefinition: (defs, def) => {
813
+ validateDebugger('Validating object type definition: %s', def?.name?.value);
814
+ return def.name && def.name.value == RESERVED_TYPE
815
+ ? List.of(...validateSubgraphSchemaDirectives(def), ...validateTypeHasNoFields(def))
816
+ : List.of(...validateEntityDirective(def), ...validateEntityID(def), ...validateEntityFields(defs, def), ...validateNoImportDirective(def), ...validateNoFulltext(def));
817
+ },
818
+ ObjectTypeExtension: (_defs, def) => {
819
+ validateDebugger('Validating object type extension: %s', def?.name?.value);
820
+ return validateAtLeastOneExtensionField(def);
821
+ },
822
+ };
823
+ const validateTypeDefinition = (defs, def) => {
824
+ validateDebugger.extend('definition')('Validating type definition: %M', def);
825
+ return typeDefinitionValidators[def.kind] === undefined
826
+ ? List()
827
+ : typeDefinitionValidators[def.kind](defs, def);
828
+ };
829
+ const validateTypeDefinitions = (defs) => {
830
+ validateDebugger('Validating type definitions');
831
+ return defs.reduce((errors, def) => errors.concat(validateTypeDefinition(defs, def)), List());
832
+ };
759
833
  const validateNamingCollisionsInTypes = (types) => {
834
+ validateDebugger('Validating naming collisions in types');
760
835
  let seen = Set();
761
836
  let conflicting = Set();
762
837
  return types.reduce((errors, type) => {
763
838
  if (seen.has(type) && !conflicting.has(type)) {
839
+ validateDebugger('Found naming collision');
764
840
  errors = errors.push(immutable_1.default.fromJS({
765
841
  loc: { start: 1, end: 1 },
766
842
  entity: type,
@@ -774,10 +850,16 @@ const validateNamingCollisionsInTypes = (types) => {
774
850
  return errors;
775
851
  }, List());
776
852
  };
777
- const validateNamingCollisions = (local, imported) => validateNamingCollisionsInTypes(local.concat(imported));
853
+ const validateNamingCollisions = (local, imported) => {
854
+ validateDebugger('Validating naming collisions');
855
+ return validateNamingCollisionsInTypes(local.concat(imported));
856
+ };
778
857
  const validateSchema = (filename) => {
858
+ validateDebugger('Validating schema: %s', filename);
779
859
  const doc = loadSchema(filename);
860
+ validateDebugger('Loaded schema: %s', filename);
780
861
  const schema = parseSchema(doc);
862
+ validateDebugger.extend('schema')('Parsed schema: %M', schema);
781
863
  return List.of(...validateTypeDefinitions(schema.definitions), ...validateNamingCollisions(gatherLocalTypes(schema.definitions), gatherImportedTypes(schema.definitions)));
782
864
  };
783
865
  exports.validateSchema = validateSchema;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.56.0",
2
+ "version": "0.56.1-alpha-20230831035057-3d319d2",
3
3
  "commands": {
4
4
  "add": {
5
5
  "id": "add",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.56.0",
3
+ "version": "0.56.1-alpha-20230831035057-3d319d2",
4
4
  "description": "CLI for building for and deploying to The Graph",
5
5
  "license": "(Apache-2.0 OR MIT)",
6
6
  "engines": {