@graphql-tools/utils 8.6.0 → 8.6.1

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 (3) hide show
  1. package/index.js +66 -45
  2. package/index.mjs +66 -45
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -226,7 +226,7 @@ function getArgumentValues(def, node, variableValues = {}) {
226
226
  let isNull = valueNode.kind === graphql.Kind.NULL;
227
227
  if (valueNode.kind === graphql.Kind.VARIABLE) {
228
228
  const variableName = valueNode.name.value;
229
- if (variableValues == null || !variableMap[variableName]) {
229
+ if (variableValues == null || variableMap[variableName] == null) {
230
230
  if (defaultValue !== undefined) {
231
231
  coercedValues[name] = defaultValue;
232
232
  }
@@ -3207,57 +3207,54 @@ function addTypes(schema, newTypesOrDirectives) {
3207
3207
  * @param options Additional options for removing unused types from the schema
3208
3208
  */
3209
3209
  function pruneSchema(schema, options = {}) {
3210
- const pruningContext = {
3211
- schema,
3212
- unusedTypes: Object.create(null),
3213
- implementations: Object.create(null),
3214
- };
3215
- for (const typeName in schema.getTypeMap()) {
3216
- const type = schema.getType(typeName);
3217
- if (type && 'getInterfaces' in type) {
3218
- for (const iface of type.getInterfaces()) {
3219
- const implementations = getImplementations(pruningContext, iface);
3220
- if (implementations == null) {
3221
- pruningContext.implementations[iface.name] = Object.create(null);
3222
- }
3223
- pruningContext.implementations[iface.name][type.name] = true;
3224
- }
3210
+ const pruningContext = createPruningContext(schema);
3211
+ visitTypes(pruningContext);
3212
+ const types = Object.values(schema.getTypeMap());
3213
+ const typesToPrune = new Set();
3214
+ for (const type of types) {
3215
+ if (type.name.startsWith('__')) {
3216
+ continue;
3225
3217
  }
3226
- }
3227
- visitTypes(pruningContext, schema);
3228
- return mapSchema(schema, {
3229
- [exports.MapperKind.TYPE]: (type) => {
3230
- // If we should NOT prune the type, return it immediately as unmodified
3231
- if (options.skipPruning && options.skipPruning(type)) {
3232
- return type;
3218
+ // If we should NOT prune the type, return it immediately as unmodified
3219
+ if (options.skipPruning && options.skipPruning(type)) {
3220
+ continue;
3221
+ }
3222
+ if (graphql.isObjectType(type) || graphql.isInputObjectType(type)) {
3223
+ if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3224
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3225
+ typesToPrune.add(type.name);
3233
3226
  }
3234
- if (graphql.isObjectType(type) || graphql.isInputObjectType(type)) {
3235
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3236
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3237
- return null;
3238
- }
3227
+ }
3228
+ else if (graphql.isUnionType(type)) {
3229
+ if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3230
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3231
+ typesToPrune.add(type.name);
3239
3232
  }
3240
- else if (graphql.isUnionType(type)) {
3241
- if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3242
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3243
- return null;
3244
- }
3233
+ }
3234
+ else if (graphql.isInterfaceType(type)) {
3235
+ const implementations = getImplementations(pruningContext, type);
3236
+ if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3237
+ (implementations && !Object.keys(implementations).length && !options.skipUnimplementedInterfacesPruning) ||
3238
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3239
+ typesToPrune.add(type.name);
3245
3240
  }
3246
- else if (graphql.isInterfaceType(type)) {
3247
- const implementations = getImplementations(pruningContext, type);
3248
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3249
- (implementations && !Object.keys(implementations).length && !options.skipUnimplementedInterfacesPruning) ||
3250
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3251
- return null;
3252
- }
3241
+ }
3242
+ else {
3243
+ if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3244
+ typesToPrune.add(type.name);
3253
3245
  }
3254
- else {
3255
- if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3256
- return null;
3257
- }
3246
+ }
3247
+ }
3248
+ // TODO: consider not returning a new schema if there was nothing to prune. This would be a breaking change.
3249
+ const prunedSchema = mapSchema(schema, {
3250
+ [exports.MapperKind.TYPE]: (type) => {
3251
+ if (typesToPrune.has(type.name)) {
3252
+ return null;
3258
3253
  }
3259
3254
  },
3260
3255
  });
3256
+ // if we pruned something, we need to prune again in case there are now objects without fields
3257
+ return typesToPrune.size ? pruneSchema(prunedSchema, options) : prunedSchema;
3261
3258
  }
3262
3259
  function visitOutputType(visitedTypes, pruningContext, type) {
3263
3260
  if (visitedTypes[type.name]) {
@@ -3297,6 +3294,29 @@ function visitOutputType(visitedTypes, pruningContext, type) {
3297
3294
  }
3298
3295
  }
3299
3296
  }
3297
+ /**
3298
+ * Initialize a pruneContext given a schema.
3299
+ */
3300
+ function createPruningContext(schema) {
3301
+ const pruningContext = {
3302
+ schema,
3303
+ unusedTypes: Object.create(null),
3304
+ implementations: Object.create(null),
3305
+ };
3306
+ for (const typeName in schema.getTypeMap()) {
3307
+ const type = schema.getType(typeName);
3308
+ if (type && 'getInterfaces' in type) {
3309
+ for (const iface of type.getInterfaces()) {
3310
+ const implementations = getImplementations(pruningContext, iface);
3311
+ if (implementations == null) {
3312
+ pruningContext.implementations[iface.name] = Object.create(null);
3313
+ }
3314
+ pruningContext.implementations[iface.name][type.name] = true;
3315
+ }
3316
+ }
3317
+ }
3318
+ return pruningContext;
3319
+ }
3300
3320
  /**
3301
3321
  * Get the implementations of an interface. May return undefined.
3302
3322
  */
@@ -3318,7 +3338,8 @@ function visitInputType(visitedTypes, pruningContext, type) {
3318
3338
  }
3319
3339
  }
3320
3340
  }
3321
- function visitTypes(pruningContext, schema) {
3341
+ function visitTypes(pruningContext) {
3342
+ const schema = pruningContext.schema;
3322
3343
  for (const typeName in schema.getTypeMap()) {
3323
3344
  if (!typeName.startsWith('__')) {
3324
3345
  pruningContext.unusedTypes[typeName] = true;
package/index.mjs CHANGED
@@ -223,7 +223,7 @@ function getArgumentValues(def, node, variableValues = {}) {
223
223
  let isNull = valueNode.kind === Kind.NULL;
224
224
  if (valueNode.kind === Kind.VARIABLE) {
225
225
  const variableName = valueNode.name.value;
226
- if (variableValues == null || !variableMap[variableName]) {
226
+ if (variableValues == null || variableMap[variableName] == null) {
227
227
  if (defaultValue !== undefined) {
228
228
  coercedValues[name] = defaultValue;
229
229
  }
@@ -3205,57 +3205,54 @@ function addTypes(schema, newTypesOrDirectives) {
3205
3205
  * @param options Additional options for removing unused types from the schema
3206
3206
  */
3207
3207
  function pruneSchema(schema, options = {}) {
3208
- const pruningContext = {
3209
- schema,
3210
- unusedTypes: Object.create(null),
3211
- implementations: Object.create(null),
3212
- };
3213
- for (const typeName in schema.getTypeMap()) {
3214
- const type = schema.getType(typeName);
3215
- if (type && 'getInterfaces' in type) {
3216
- for (const iface of type.getInterfaces()) {
3217
- const implementations = getImplementations(pruningContext, iface);
3218
- if (implementations == null) {
3219
- pruningContext.implementations[iface.name] = Object.create(null);
3220
- }
3221
- pruningContext.implementations[iface.name][type.name] = true;
3222
- }
3208
+ const pruningContext = createPruningContext(schema);
3209
+ visitTypes(pruningContext);
3210
+ const types = Object.values(schema.getTypeMap());
3211
+ const typesToPrune = new Set();
3212
+ for (const type of types) {
3213
+ if (type.name.startsWith('__')) {
3214
+ continue;
3223
3215
  }
3224
- }
3225
- visitTypes(pruningContext, schema);
3226
- return mapSchema(schema, {
3227
- [MapperKind.TYPE]: (type) => {
3228
- // If we should NOT prune the type, return it immediately as unmodified
3229
- if (options.skipPruning && options.skipPruning(type)) {
3230
- return type;
3216
+ // If we should NOT prune the type, return it immediately as unmodified
3217
+ if (options.skipPruning && options.skipPruning(type)) {
3218
+ continue;
3219
+ }
3220
+ if (isObjectType(type) || isInputObjectType(type)) {
3221
+ if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3222
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3223
+ typesToPrune.add(type.name);
3231
3224
  }
3232
- if (isObjectType(type) || isInputObjectType(type)) {
3233
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3234
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3235
- return null;
3236
- }
3225
+ }
3226
+ else if (isUnionType(type)) {
3227
+ if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3228
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3229
+ typesToPrune.add(type.name);
3237
3230
  }
3238
- else if (isUnionType(type)) {
3239
- if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3240
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3241
- return null;
3242
- }
3231
+ }
3232
+ else if (isInterfaceType(type)) {
3233
+ const implementations = getImplementations(pruningContext, type);
3234
+ if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3235
+ (implementations && !Object.keys(implementations).length && !options.skipUnimplementedInterfacesPruning) ||
3236
+ (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3237
+ typesToPrune.add(type.name);
3243
3238
  }
3244
- else if (isInterfaceType(type)) {
3245
- const implementations = getImplementations(pruningContext, type);
3246
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3247
- (implementations && !Object.keys(implementations).length && !options.skipUnimplementedInterfacesPruning) ||
3248
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3249
- return null;
3250
- }
3239
+ }
3240
+ else {
3241
+ if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3242
+ typesToPrune.add(type.name);
3251
3243
  }
3252
- else {
3253
- if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3254
- return null;
3255
- }
3244
+ }
3245
+ }
3246
+ // TODO: consider not returning a new schema if there was nothing to prune. This would be a breaking change.
3247
+ const prunedSchema = mapSchema(schema, {
3248
+ [MapperKind.TYPE]: (type) => {
3249
+ if (typesToPrune.has(type.name)) {
3250
+ return null;
3256
3251
  }
3257
3252
  },
3258
3253
  });
3254
+ // if we pruned something, we need to prune again in case there are now objects without fields
3255
+ return typesToPrune.size ? pruneSchema(prunedSchema, options) : prunedSchema;
3259
3256
  }
3260
3257
  function visitOutputType(visitedTypes, pruningContext, type) {
3261
3258
  if (visitedTypes[type.name]) {
@@ -3295,6 +3292,29 @@ function visitOutputType(visitedTypes, pruningContext, type) {
3295
3292
  }
3296
3293
  }
3297
3294
  }
3295
+ /**
3296
+ * Initialize a pruneContext given a schema.
3297
+ */
3298
+ function createPruningContext(schema) {
3299
+ const pruningContext = {
3300
+ schema,
3301
+ unusedTypes: Object.create(null),
3302
+ implementations: Object.create(null),
3303
+ };
3304
+ for (const typeName in schema.getTypeMap()) {
3305
+ const type = schema.getType(typeName);
3306
+ if (type && 'getInterfaces' in type) {
3307
+ for (const iface of type.getInterfaces()) {
3308
+ const implementations = getImplementations(pruningContext, iface);
3309
+ if (implementations == null) {
3310
+ pruningContext.implementations[iface.name] = Object.create(null);
3311
+ }
3312
+ pruningContext.implementations[iface.name][type.name] = true;
3313
+ }
3314
+ }
3315
+ }
3316
+ return pruningContext;
3317
+ }
3298
3318
  /**
3299
3319
  * Get the implementations of an interface. May return undefined.
3300
3320
  */
@@ -3316,7 +3336,8 @@ function visitInputType(visitedTypes, pruningContext, type) {
3316
3336
  }
3317
3337
  }
3318
3338
  }
3319
- function visitTypes(pruningContext, schema) {
3339
+ function visitTypes(pruningContext) {
3340
+ const schema = pruningContext.schema;
3320
3341
  for (const typeName in schema.getTypeMap()) {
3321
3342
  if (!typeName.startsWith('__')) {
3322
3343
  pruningContext.unusedTypes[typeName] = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-tools/utils",
3
- "version": "8.6.0",
3
+ "version": "8.6.1",
4
4
  "description": "Common package containing utils and types for GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {