@graphql-tools/utils 8.6.0-alpha-c3063363.0 → 8.6.1-alpha-b935d9b2.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.
@@ -8,3 +8,4 @@ interface AggregateErrorConstructor {
8
8
  }
9
9
  declare let AggregateErrorImpl: AggregateErrorConstructor;
10
10
  export { AggregateErrorImpl as AggregateError };
11
+ export declare function isAggregateError(error: Error): error is AggregateError;
package/executor.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ExecutionResult, ExecutionRequest } from './Interfaces';
2
2
  declare type MaybePromise<T> = Promise<T> | T;
3
- declare type MaybeAsyncIterableIterator<T> = AsyncIterableIterator<T> | T;
4
- export declare type AsyncExecutor<TBaseContext = Record<string, any>, TBaseExtensions = Record<string, any>> = <TReturn = any, TArgs = Record<string, any>, TContext extends TBaseContext = TBaseContext, TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions>(request: ExecutionRequest<TArgs, TContext, TRoot, TExtensions>) => Promise<MaybeAsyncIterableIterator<ExecutionResult<TReturn>>>;
3
+ declare type MaybeAsyncIterable<T> = AsyncIterable<T> | T;
4
+ export declare type AsyncExecutor<TBaseContext = Record<string, any>, TBaseExtensions = Record<string, any>> = <TReturn = any, TArgs = Record<string, any>, TContext extends TBaseContext = TBaseContext, TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions>(request: ExecutionRequest<TArgs, TContext, TRoot, TExtensions>) => Promise<MaybeAsyncIterable<ExecutionResult<TReturn>>>;
5
5
  export declare type SyncExecutor<TBaseContext = Record<string, any>, TBaseExtensions = Record<string, any>> = <TReturn = any, TArgs = Record<string, any>, TContext extends TBaseContext = TBaseContext, TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions>(request: ExecutionRequest<TArgs, TContext, TRoot, TExtensions>) => ExecutionResult<TReturn>;
6
- export declare type Executor<TBaseContext = Record<string, any>, TBaseExtensions = Record<string, any>> = <TReturn = any, TArgs = Record<string, any>, TContext extends TBaseContext = TBaseContext, TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions>(request: ExecutionRequest<TArgs, TContext, TRoot, TExtensions>) => MaybePromise<MaybeAsyncIterableIterator<ExecutionResult<TReturn>>>;
6
+ export declare type Executor<TBaseContext = Record<string, any>, TBaseExtensions = Record<string, any>> = <TReturn = any, TArgs = Record<string, any>, TContext extends TBaseContext = TBaseContext, TRoot = any, TExtensions extends TBaseExtensions = TBaseExtensions>(request: ExecutionRequest<TArgs, TContext, TRoot, TExtensions>) => MaybePromise<MaybeAsyncIterable<ExecutionResult<TReturn>>>;
7
7
  export {};
package/index.d.ts CHANGED
@@ -48,4 +48,3 @@ export * from './inspect';
48
48
  export * from './memoize';
49
49
  export * from './fixSchemaAst';
50
50
  export * from './getOperationASTFromRequest';
51
- export * from './path';
package/index.js CHANGED
@@ -69,9 +69,27 @@ function assertSome(input, message = 'Value should be something') {
69
69
  }
70
70
  }
71
71
 
72
+ if (typeof AggregateError === 'undefined') {
73
+ class AggregateErrorClass extends Error {
74
+ constructor(errors, message = '') {
75
+ super(message);
76
+ this.errors = errors;
77
+ this.name = 'AggregateError';
78
+ Error.captureStackTrace(this, AggregateErrorClass);
79
+ }
80
+ }
81
+ exports.AggregateError = function (errors, message) {
82
+ return new AggregateErrorClass(errors, message);
83
+ };
84
+ }
85
+ else {
86
+ exports.AggregateError = AggregateError;
87
+ }
88
+ function isAggregateError(error) {
89
+ return 'errors' in error && Array.isArray(error['errors']);
90
+ }
91
+
72
92
  // Taken from graphql-js
73
- // https://github.com/graphql/graphql-js/blob/main/src/jsutils/inspect.ts
74
- /* eslint-disable @typescript-eslint/ban-types */
75
93
  const MAX_ARRAY_LENGTH = 10;
76
94
  const MAX_RECURSIVE_DEPTH = 2;
77
95
  /**
@@ -92,10 +110,22 @@ function formatValue(value, seenValues) {
92
110
  return String(value);
93
111
  }
94
112
  }
113
+ function formatError(value) {
114
+ if (value instanceof graphql.GraphQLError) {
115
+ return value.toString();
116
+ }
117
+ return `${value.name}: ${value.message};\n ${value.stack}`;
118
+ }
95
119
  function formatObjectValue(value, previouslySeenValues) {
96
120
  if (value === null) {
97
121
  return 'null';
98
122
  }
123
+ if (value instanceof Error) {
124
+ if (isAggregateError(value)) {
125
+ return formatError(value) + '\n' + formatArray(value.errors, previouslySeenValues);
126
+ }
127
+ return formatError(value);
128
+ }
99
129
  if (previouslySeenValues.includes(value)) {
100
130
  return '[Circular]';
101
131
  }
@@ -176,7 +206,6 @@ function getArgumentValues(def, node, variableValues = {}) {
176
206
  [key]: value,
177
207
  }), {});
178
208
  const coercedValues = {};
179
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
180
209
  const argumentNodes = (_a = node.arguments) !== null && _a !== void 0 ? _a : [];
181
210
  const argNodeMap = argumentNodes.reduce((prev, arg) => ({
182
211
  ...prev,
@@ -1013,10 +1042,10 @@ function astFromScalarType(type, schema, pathToDirectivesInExtensions) {
1013
1042
  const directives = directivesInExtensions
1014
1043
  ? makeDirectiveNodes(schema, directivesInExtensions)
1015
1044
  : ((_a = type.astNode) === null || _a === void 0 ? void 0 : _a.directives) || [];
1016
- if (type['specifiedByUrl'] &&
1017
- !directives.some(directiveNode => directiveNode.name.value === 'specifiedBy')) {
1045
+ const specifiedByValue = (type['specifiedByUrl'] || type['specifiedByURL']);
1046
+ if (specifiedByValue && !directives.some(directiveNode => directiveNode.name.value === 'specifiedBy')) {
1018
1047
  const specifiedByArgs = {
1019
- url: type['specifiedByUrl'],
1048
+ url: specifiedByValue,
1020
1049
  };
1021
1050
  directives.push(makeDirectiveNode('specifiedBy', specifiedByArgs));
1022
1051
  }
@@ -1164,21 +1193,6 @@ function makeDirectiveNodes(schema, directiveValues) {
1164
1193
  return directiveNodes;
1165
1194
  }
1166
1195
 
1167
- exports.AggregateError = globalThis.AggregateError;
1168
- if (typeof exports.AggregateError === 'undefined') {
1169
- class AggregateErrorClass extends Error {
1170
- constructor(errors, message = '') {
1171
- super(message);
1172
- this.errors = errors;
1173
- this.name = 'AggregateError';
1174
- Error.captureStackTrace(this, AggregateErrorClass);
1175
- }
1176
- }
1177
- exports.AggregateError = function (errors, message) {
1178
- return new AggregateErrorClass(errors, message);
1179
- };
1180
- }
1181
-
1182
1196
  async function validateGraphQlDocuments(schema, documentFiles, effectiveRules = createDefaultRules()) {
1183
1197
  const allFragmentMap = new Map();
1184
1198
  const documentFileObjectsToValidate = [];
@@ -3193,57 +3207,54 @@ function addTypes(schema, newTypesOrDirectives) {
3193
3207
  * @param options Additional options for removing unused types from the schema
3194
3208
  */
3195
3209
  function pruneSchema(schema, options = {}) {
3196
- const pruningContext = {
3197
- schema,
3198
- unusedTypes: Object.create(null),
3199
- implementations: Object.create(null),
3200
- };
3201
- for (const typeName in schema.getTypeMap()) {
3202
- const type = schema.getType(typeName);
3203
- if (type && 'getInterfaces' in type) {
3204
- for (const iface of type.getInterfaces()) {
3205
- const implementations = getImplementations(pruningContext, iface);
3206
- if (implementations == null) {
3207
- pruningContext.implementations[iface.name] = Object.create(null);
3208
- }
3209
- pruningContext.implementations[iface.name][type.name] = true;
3210
- }
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;
3211
3217
  }
3212
- }
3213
- visitTypes(pruningContext, schema);
3214
- return mapSchema(schema, {
3215
- [exports.MapperKind.TYPE]: (type) => {
3216
- // If we should NOT prune the type, return it immediately as unmodified
3217
- if (options.skipPruning && options.skipPruning(type)) {
3218
- 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);
3219
3226
  }
3220
- if (graphql.isObjectType(type) || graphql.isInputObjectType(type)) {
3221
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3222
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3223
- return null;
3224
- }
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);
3225
3232
  }
3226
- else if (graphql.isUnionType(type)) {
3227
- if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3228
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3229
- return null;
3230
- }
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);
3231
3240
  }
3232
- else if (graphql.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
- return null;
3238
- }
3241
+ }
3242
+ else {
3243
+ if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3244
+ typesToPrune.add(type.name);
3239
3245
  }
3240
- else {
3241
- if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3242
- return null;
3243
- }
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;
3244
3253
  }
3245
3254
  },
3246
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;
3247
3258
  }
3248
3259
  function visitOutputType(visitedTypes, pruningContext, type) {
3249
3260
  if (visitedTypes[type.name]) {
@@ -3283,6 +3294,29 @@ function visitOutputType(visitedTypes, pruningContext, type) {
3283
3294
  }
3284
3295
  }
3285
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
+ }
3286
3320
  /**
3287
3321
  * Get the implementations of an interface. May return undefined.
3288
3322
  */
@@ -3304,7 +3338,8 @@ function visitInputType(visitedTypes, pruningContext, type) {
3304
3338
  }
3305
3339
  }
3306
3340
  }
3307
- function visitTypes(pruningContext, schema) {
3341
+ function visitTypes(pruningContext) {
3342
+ const schema = pruningContext.schema;
3308
3343
  for (const typeName in schema.getTypeMap()) {
3309
3344
  if (!typeName.startsWith('__')) {
3310
3345
  pruningContext.unusedTypes[typeName] = true;
@@ -3323,7 +3358,6 @@ function visitTypes(pruningContext, schema) {
3323
3358
  }
3324
3359
  }
3325
3360
 
3326
- // eslint-disable-next-line @typescript-eslint/ban-types
3327
3361
  function mergeDeep(sources, respectPrototype = false) {
3328
3362
  const target = sources[0] || {};
3329
3363
  const output = {};
@@ -4152,24 +4186,64 @@ function valueMatchesCriteria(value, criteria) {
4152
4186
  }
4153
4187
 
4154
4188
  function isAsyncIterable(value) {
4155
- return typeof value === 'object' && value != null && Symbol.asyncIterator in value;
4189
+ return (typeof value === 'object' &&
4190
+ value != null &&
4191
+ Symbol.asyncIterator in value &&
4192
+ typeof value[Symbol.asyncIterator] === 'function');
4156
4193
  }
4157
4194
 
4158
4195
  function isDocumentNode(object) {
4159
4196
  return object && typeof object === 'object' && 'kind' in object && object.kind === graphql.Kind.DOCUMENT;
4160
4197
  }
4161
4198
 
4162
- function withCancel(asyncIteratorLike, onCancel) {
4163
- const asyncIterator = asyncIteratorLike[Symbol.asyncIterator]();
4164
- if (!asyncIterator.return) {
4165
- asyncIterator.return = () => Promise.resolve({ value: undefined, done: true });
4166
- }
4167
- const savedReturn = asyncIterator.return.bind(asyncIterator);
4168
- asyncIterator.return = () => {
4169
- onCancel();
4170
- return savedReturn();
4199
+ async function defaultAsyncIteratorReturn(value) {
4200
+ return { value, done: true };
4201
+ }
4202
+ const proxyMethodFactory = memoize2(function proxyMethodFactory(target, targetMethod) {
4203
+ return function proxyMethod(...args) {
4204
+ return Reflect.apply(targetMethod, target, args);
4171
4205
  };
4172
- return asyncIterator;
4206
+ });
4207
+ function getAsyncIteratorWithCancel(asyncIterator, onCancel) {
4208
+ return new Proxy(asyncIterator, {
4209
+ has(asyncIterator, prop) {
4210
+ if (prop === 'return') {
4211
+ return true;
4212
+ }
4213
+ return Reflect.has(asyncIterator, prop);
4214
+ },
4215
+ get(asyncIterator, prop, receiver) {
4216
+ const existingPropValue = Reflect.get(asyncIterator, prop, receiver);
4217
+ if (prop === 'return') {
4218
+ const existingReturn = existingPropValue || defaultAsyncIteratorReturn;
4219
+ return async function returnWithCancel(value) {
4220
+ const returnValue = await onCancel(value);
4221
+ return Reflect.apply(existingReturn, asyncIterator, [returnValue]);
4222
+ };
4223
+ }
4224
+ else if (typeof existingPropValue === 'function') {
4225
+ return proxyMethodFactory(asyncIterator, existingPropValue);
4226
+ }
4227
+ return existingPropValue;
4228
+ },
4229
+ });
4230
+ }
4231
+ function getAsyncIterableWithCancel(asyncIterable, onCancel) {
4232
+ return new Proxy(asyncIterable, {
4233
+ get(asyncIterable, prop, receiver) {
4234
+ const existingPropValue = Reflect.get(asyncIterable, prop, receiver);
4235
+ if (Symbol.asyncIterator === prop) {
4236
+ return function asyncIteratorFactory() {
4237
+ const asyncIterator = Reflect.apply(existingPropValue, asyncIterable, []);
4238
+ return getAsyncIteratorWithCancel(asyncIterator, onCancel);
4239
+ };
4240
+ }
4241
+ else if (typeof existingPropValue === 'function') {
4242
+ return proxyMethodFactory(asyncIterable, existingPropValue);
4243
+ }
4244
+ return existingPropValue;
4245
+ },
4246
+ });
4173
4247
  }
4174
4248
 
4175
4249
  function buildFixedSchema(schema, options) {
@@ -4193,17 +4267,6 @@ function fixSchemaAst(schema, options) {
4193
4267
  return schema;
4194
4268
  }
4195
4269
 
4196
- function joinPaths(...paths) {
4197
- const seperator = paths.some(path => path.includes('\\')) ? '\\' : '/';
4198
- return paths.join(seperator);
4199
- }
4200
- function isAbsolutePath(path) {
4201
- if (path.includes('\\')) {
4202
- return path[1] === ':';
4203
- }
4204
- return path.startsWith('/');
4205
- }
4206
-
4207
4270
  exports.addTypes = addTypes;
4208
4271
  exports.appendObjectFields = appendObjectFields;
4209
4272
  exports.asArray = asArray;
@@ -4239,6 +4302,8 @@ exports.fixSchemaAst = fixSchemaAst;
4239
4302
  exports.forEachDefaultValue = forEachDefaultValue;
4240
4303
  exports.forEachField = forEachField;
4241
4304
  exports.getArgumentValues = getArgumentValues;
4305
+ exports.getAsyncIterableWithCancel = getAsyncIterableWithCancel;
4306
+ exports.getAsyncIteratorWithCancel = getAsyncIteratorWithCancel;
4242
4307
  exports.getBlockStringIndentation = getBlockStringIndentation;
4243
4308
  exports.getBuiltInForStub = getBuiltInForStub;
4244
4309
  exports.getComment = getComment;
@@ -4265,7 +4330,7 @@ exports.healSchema = healSchema;
4265
4330
  exports.healTypes = healTypes;
4266
4331
  exports.implementsAbstractType = implementsAbstractType;
4267
4332
  exports.inspect = inspect;
4268
- exports.isAbsolutePath = isAbsolutePath;
4333
+ exports.isAggregateError = isAggregateError;
4269
4334
  exports.isAsyncIterable = isAsyncIterable;
4270
4335
  exports.isDescribable = isDescribable;
4271
4336
  exports.isDocumentNode = isDocumentNode;
@@ -4273,7 +4338,6 @@ exports.isDocumentString = isDocumentString;
4273
4338
  exports.isNamedStub = isNamedStub;
4274
4339
  exports.isSome = isSome;
4275
4340
  exports.isValidPath = isValidPath;
4276
- exports.joinPaths = joinPaths;
4277
4341
  exports.makeDeprecatedDirective = makeDeprecatedDirective;
4278
4342
  exports.makeDirectiveNode = makeDirectiveNode;
4279
4343
  exports.makeDirectiveNodes = makeDirectiveNodes;
@@ -4314,4 +4378,4 @@ exports.valueMatchesCriteria = valueMatchesCriteria;
4314
4378
  exports.visitData = visitData;
4315
4379
  exports.visitErrors = visitErrors;
4316
4380
  exports.visitResult = visitResult;
4317
- exports.withCancel = withCancel;
4381
+ exports.withCancel = getAsyncIterableWithCancel;
package/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { parse, isNonNullType, GraphQLError, Kind, valueFromAST, print, isObjectType, isListType, isSpecifiedDirective, astFromValue, isSpecifiedScalarType, isIntrospectionType, isInterfaceType, isUnionType, isInputObjectType, isEnumType, isScalarType, GraphQLDeprecatedDirective, specifiedRules, concatAST, validate, versionInfo, buildClientSchema, visit, TokenKind, Source, isTypeSystemDefinitionNode, getNamedType, GraphQLString, GraphQLNonNull, GraphQLList, GraphQLID, GraphQLBoolean, GraphQLFloat, GraphQLInt, GraphQLObjectType, GraphQLInterfaceType, GraphQLInputObjectType, GraphQLDirective, GraphQLUnionType, GraphQLEnumType, GraphQLScalarType, isNamedType, getNullableType, isLeafType, GraphQLSchema, isDirective, isCompositeType, doTypesOverlap, getOperationAST, getDirectiveValues, GraphQLSkipDirective, GraphQLIncludeDirective, typeFromAST, isAbstractType, getOperationRootType, TypeNameMetaFieldDef, buildASTSchema } from 'graphql';
1
+ import { parse, GraphQLError, isNonNullType, Kind, valueFromAST, print, isObjectType, isListType, isSpecifiedDirective, astFromValue, isSpecifiedScalarType, isIntrospectionType, isInterfaceType, isUnionType, isInputObjectType, isEnumType, isScalarType, GraphQLDeprecatedDirective, specifiedRules, concatAST, validate, versionInfo, buildClientSchema, visit, TokenKind, Source, isTypeSystemDefinitionNode, getNamedType, GraphQLString, GraphQLNonNull, GraphQLList, GraphQLID, GraphQLBoolean, GraphQLFloat, GraphQLInt, GraphQLObjectType, GraphQLInterfaceType, GraphQLInputObjectType, GraphQLDirective, GraphQLUnionType, GraphQLEnumType, GraphQLScalarType, isNamedType, getNullableType, isLeafType, GraphQLSchema, isDirective, isCompositeType, doTypesOverlap, getOperationAST, getDirectiveValues, GraphQLSkipDirective, GraphQLIncludeDirective, typeFromAST, isAbstractType, getOperationRootType, TypeNameMetaFieldDef, buildASTSchema } from 'graphql';
2
2
 
3
3
  const asArray = (fns) => (Array.isArray(fns) ? fns : fns ? [fns] : []);
4
4
  const invalidDocRegex = /\.[a-z0-9]+$/i;
@@ -65,9 +65,28 @@ function assertSome(input, message = 'Value should be something') {
65
65
  }
66
66
  }
67
67
 
68
+ let AggregateErrorImpl;
69
+ if (typeof AggregateError === 'undefined') {
70
+ class AggregateErrorClass extends Error {
71
+ constructor(errors, message = '') {
72
+ super(message);
73
+ this.errors = errors;
74
+ this.name = 'AggregateError';
75
+ Error.captureStackTrace(this, AggregateErrorClass);
76
+ }
77
+ }
78
+ AggregateErrorImpl = function (errors, message) {
79
+ return new AggregateErrorClass(errors, message);
80
+ };
81
+ }
82
+ else {
83
+ AggregateErrorImpl = AggregateError;
84
+ }
85
+ function isAggregateError(error) {
86
+ return 'errors' in error && Array.isArray(error['errors']);
87
+ }
88
+
68
89
  // Taken from graphql-js
69
- // https://github.com/graphql/graphql-js/blob/main/src/jsutils/inspect.ts
70
- /* eslint-disable @typescript-eslint/ban-types */
71
90
  const MAX_ARRAY_LENGTH = 10;
72
91
  const MAX_RECURSIVE_DEPTH = 2;
73
92
  /**
@@ -88,10 +107,22 @@ function formatValue(value, seenValues) {
88
107
  return String(value);
89
108
  }
90
109
  }
110
+ function formatError(value) {
111
+ if (value instanceof GraphQLError) {
112
+ return value.toString();
113
+ }
114
+ return `${value.name}: ${value.message};\n ${value.stack}`;
115
+ }
91
116
  function formatObjectValue(value, previouslySeenValues) {
92
117
  if (value === null) {
93
118
  return 'null';
94
119
  }
120
+ if (value instanceof Error) {
121
+ if (isAggregateError(value)) {
122
+ return formatError(value) + '\n' + formatArray(value.errors, previouslySeenValues);
123
+ }
124
+ return formatError(value);
125
+ }
95
126
  if (previouslySeenValues.includes(value)) {
96
127
  return '[Circular]';
97
128
  }
@@ -172,7 +203,6 @@ function getArgumentValues(def, node, variableValues = {}) {
172
203
  [key]: value,
173
204
  }), {});
174
205
  const coercedValues = {};
175
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
176
206
  const argumentNodes = (_a = node.arguments) !== null && _a !== void 0 ? _a : [];
177
207
  const argNodeMap = argumentNodes.reduce((prev, arg) => ({
178
208
  ...prev,
@@ -1009,10 +1039,10 @@ function astFromScalarType(type, schema, pathToDirectivesInExtensions) {
1009
1039
  const directives = directivesInExtensions
1010
1040
  ? makeDirectiveNodes(schema, directivesInExtensions)
1011
1041
  : ((_a = type.astNode) === null || _a === void 0 ? void 0 : _a.directives) || [];
1012
- if (type['specifiedByUrl'] &&
1013
- !directives.some(directiveNode => directiveNode.name.value === 'specifiedBy')) {
1042
+ const specifiedByValue = (type['specifiedByUrl'] || type['specifiedByURL']);
1043
+ if (specifiedByValue && !directives.some(directiveNode => directiveNode.name.value === 'specifiedBy')) {
1014
1044
  const specifiedByArgs = {
1015
- url: type['specifiedByUrl'],
1045
+ url: specifiedByValue,
1016
1046
  };
1017
1047
  directives.push(makeDirectiveNode('specifiedBy', specifiedByArgs));
1018
1048
  }
@@ -1160,21 +1190,6 @@ function makeDirectiveNodes(schema, directiveValues) {
1160
1190
  return directiveNodes;
1161
1191
  }
1162
1192
 
1163
- let AggregateErrorImpl = globalThis.AggregateError;
1164
- if (typeof AggregateErrorImpl === 'undefined') {
1165
- class AggregateErrorClass extends Error {
1166
- constructor(errors, message = '') {
1167
- super(message);
1168
- this.errors = errors;
1169
- this.name = 'AggregateError';
1170
- Error.captureStackTrace(this, AggregateErrorClass);
1171
- }
1172
- }
1173
- AggregateErrorImpl = function (errors, message) {
1174
- return new AggregateErrorClass(errors, message);
1175
- };
1176
- }
1177
-
1178
1193
  async function validateGraphQlDocuments(schema, documentFiles, effectiveRules = createDefaultRules()) {
1179
1194
  const allFragmentMap = new Map();
1180
1195
  const documentFileObjectsToValidate = [];
@@ -3190,57 +3205,54 @@ function addTypes(schema, newTypesOrDirectives) {
3190
3205
  * @param options Additional options for removing unused types from the schema
3191
3206
  */
3192
3207
  function pruneSchema(schema, options = {}) {
3193
- const pruningContext = {
3194
- schema,
3195
- unusedTypes: Object.create(null),
3196
- implementations: Object.create(null),
3197
- };
3198
- for (const typeName in schema.getTypeMap()) {
3199
- const type = schema.getType(typeName);
3200
- if (type && 'getInterfaces' in type) {
3201
- for (const iface of type.getInterfaces()) {
3202
- const implementations = getImplementations(pruningContext, iface);
3203
- if (implementations == null) {
3204
- pruningContext.implementations[iface.name] = Object.create(null);
3205
- }
3206
- pruningContext.implementations[iface.name][type.name] = true;
3207
- }
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;
3208
3215
  }
3209
- }
3210
- visitTypes(pruningContext, schema);
3211
- return mapSchema(schema, {
3212
- [MapperKind.TYPE]: (type) => {
3213
- // If we should NOT prune the type, return it immediately as unmodified
3214
- if (options.skipPruning && options.skipPruning(type)) {
3215
- 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);
3216
3224
  }
3217
- if (isObjectType(type) || isInputObjectType(type)) {
3218
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3219
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3220
- return null;
3221
- }
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);
3222
3230
  }
3223
- else if (isUnionType(type)) {
3224
- if ((!type.getTypes().length && !options.skipEmptyUnionPruning) ||
3225
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3226
- return null;
3227
- }
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);
3228
3238
  }
3229
- else if (isInterfaceType(type)) {
3230
- const implementations = getImplementations(pruningContext, type);
3231
- if ((!Object.keys(type.getFields()).length && !options.skipEmptyCompositeTypePruning) ||
3232
- (implementations && !Object.keys(implementations).length && !options.skipUnimplementedInterfacesPruning) ||
3233
- (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning)) {
3234
- return null;
3235
- }
3239
+ }
3240
+ else {
3241
+ if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3242
+ typesToPrune.add(type.name);
3236
3243
  }
3237
- else {
3238
- if (pruningContext.unusedTypes[type.name] && !options.skipUnusedTypesPruning) {
3239
- return null;
3240
- }
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;
3241
3251
  }
3242
3252
  },
3243
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;
3244
3256
  }
3245
3257
  function visitOutputType(visitedTypes, pruningContext, type) {
3246
3258
  if (visitedTypes[type.name]) {
@@ -3280,6 +3292,29 @@ function visitOutputType(visitedTypes, pruningContext, type) {
3280
3292
  }
3281
3293
  }
3282
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
+ }
3283
3318
  /**
3284
3319
  * Get the implementations of an interface. May return undefined.
3285
3320
  */
@@ -3301,7 +3336,8 @@ function visitInputType(visitedTypes, pruningContext, type) {
3301
3336
  }
3302
3337
  }
3303
3338
  }
3304
- function visitTypes(pruningContext, schema) {
3339
+ function visitTypes(pruningContext) {
3340
+ const schema = pruningContext.schema;
3305
3341
  for (const typeName in schema.getTypeMap()) {
3306
3342
  if (!typeName.startsWith('__')) {
3307
3343
  pruningContext.unusedTypes[typeName] = true;
@@ -3320,7 +3356,6 @@ function visitTypes(pruningContext, schema) {
3320
3356
  }
3321
3357
  }
3322
3358
 
3323
- // eslint-disable-next-line @typescript-eslint/ban-types
3324
3359
  function mergeDeep(sources, respectPrototype = false) {
3325
3360
  const target = sources[0] || {};
3326
3361
  const output = {};
@@ -4149,24 +4184,64 @@ function valueMatchesCriteria(value, criteria) {
4149
4184
  }
4150
4185
 
4151
4186
  function isAsyncIterable(value) {
4152
- return typeof value === 'object' && value != null && Symbol.asyncIterator in value;
4187
+ return (typeof value === 'object' &&
4188
+ value != null &&
4189
+ Symbol.asyncIterator in value &&
4190
+ typeof value[Symbol.asyncIterator] === 'function');
4153
4191
  }
4154
4192
 
4155
4193
  function isDocumentNode(object) {
4156
4194
  return object && typeof object === 'object' && 'kind' in object && object.kind === Kind.DOCUMENT;
4157
4195
  }
4158
4196
 
4159
- function withCancel(asyncIteratorLike, onCancel) {
4160
- const asyncIterator = asyncIteratorLike[Symbol.asyncIterator]();
4161
- if (!asyncIterator.return) {
4162
- asyncIterator.return = () => Promise.resolve({ value: undefined, done: true });
4163
- }
4164
- const savedReturn = asyncIterator.return.bind(asyncIterator);
4165
- asyncIterator.return = () => {
4166
- onCancel();
4167
- return savedReturn();
4197
+ async function defaultAsyncIteratorReturn(value) {
4198
+ return { value, done: true };
4199
+ }
4200
+ const proxyMethodFactory = memoize2(function proxyMethodFactory(target, targetMethod) {
4201
+ return function proxyMethod(...args) {
4202
+ return Reflect.apply(targetMethod, target, args);
4168
4203
  };
4169
- return asyncIterator;
4204
+ });
4205
+ function getAsyncIteratorWithCancel(asyncIterator, onCancel) {
4206
+ return new Proxy(asyncIterator, {
4207
+ has(asyncIterator, prop) {
4208
+ if (prop === 'return') {
4209
+ return true;
4210
+ }
4211
+ return Reflect.has(asyncIterator, prop);
4212
+ },
4213
+ get(asyncIterator, prop, receiver) {
4214
+ const existingPropValue = Reflect.get(asyncIterator, prop, receiver);
4215
+ if (prop === 'return') {
4216
+ const existingReturn = existingPropValue || defaultAsyncIteratorReturn;
4217
+ return async function returnWithCancel(value) {
4218
+ const returnValue = await onCancel(value);
4219
+ return Reflect.apply(existingReturn, asyncIterator, [returnValue]);
4220
+ };
4221
+ }
4222
+ else if (typeof existingPropValue === 'function') {
4223
+ return proxyMethodFactory(asyncIterator, existingPropValue);
4224
+ }
4225
+ return existingPropValue;
4226
+ },
4227
+ });
4228
+ }
4229
+ function getAsyncIterableWithCancel(asyncIterable, onCancel) {
4230
+ return new Proxy(asyncIterable, {
4231
+ get(asyncIterable, prop, receiver) {
4232
+ const existingPropValue = Reflect.get(asyncIterable, prop, receiver);
4233
+ if (Symbol.asyncIterator === prop) {
4234
+ return function asyncIteratorFactory() {
4235
+ const asyncIterator = Reflect.apply(existingPropValue, asyncIterable, []);
4236
+ return getAsyncIteratorWithCancel(asyncIterator, onCancel);
4237
+ };
4238
+ }
4239
+ else if (typeof existingPropValue === 'function') {
4240
+ return proxyMethodFactory(asyncIterable, existingPropValue);
4241
+ }
4242
+ return existingPropValue;
4243
+ },
4244
+ });
4170
4245
  }
4171
4246
 
4172
4247
  function buildFixedSchema(schema, options) {
@@ -4190,15 +4265,4 @@ function fixSchemaAst(schema, options) {
4190
4265
  return schema;
4191
4266
  }
4192
4267
 
4193
- function joinPaths(...paths) {
4194
- const seperator = paths.some(path => path.includes('\\')) ? '\\' : '/';
4195
- return paths.join(seperator);
4196
- }
4197
- function isAbsolutePath(path) {
4198
- if (path.includes('\\')) {
4199
- return path[1] === ':';
4200
- }
4201
- return path.startsWith('/');
4202
- }
4203
-
4204
- export { AggregateErrorImpl as AggregateError, MapperKind, addTypes, appendObjectFields, asArray, assertSome, astFromArg, astFromDirective, astFromEnumType, astFromEnumValue, astFromField, astFromInputField, astFromInputObjectType, astFromInterfaceType, astFromObjectType, astFromScalarType, astFromSchema, astFromUnionType, astFromValueUntyped, buildOperationNodeForField, checkValidationErrors, collectComment, collectFields, collectSubFields, compareNodes, compareStrings, correctASTNodes, createDefaultRules, createNamedStub, createStub, createVariableNameGenerator, dedentBlockStringValue, filterSchema, fixSchemaAst, forEachDefaultValue, forEachField, getArgumentValues, getBlockStringIndentation, getBuiltInForStub, getComment, getDefinedRootType, getDeprecatableDirectiveNodes, getDescription, getDirective, getDirectiveInExtensions, getDirectiveNodes, getDirectives, getDirectivesInExtensions, getDocumentNodeFromSchema, getFieldsWithDirectives, getImplementingTypes, getLeadingCommentBlock, getOperationASTFromDocument, getOperationASTFromRequest, getResolversFromSchema, getResponseKeyFromInfo, getRootTypeMap, getRootTypeNames, getRootTypes, healSchema, healTypes, implementsAbstractType, inspect, isAbsolutePath, isAsyncIterable, isDescribable, isDocumentNode, isDocumentString, isNamedStub, isSome, isValidPath, joinPaths, makeDeprecatedDirective, makeDirectiveNode, makeDirectiveNodes, mapAsyncIterator, mapSchema, memoize1, memoize2, memoize2of4, memoize3, memoize4, memoize5, mergeDeep, modifyObjectFields, nodeToString, observableToAsyncIterable, parseGraphQLJSON, parseGraphQLSDL, parseInputValue, parseInputValueLiteral, parseSelectionSet, printComment, printSchemaWithDirectives, printWithComments, pruneSchema, pushComment, relocatedError, removeObjectFields, renameType, resetComments, rewireTypes, selectObjectFields, serializeInputValue, transformCommentsToDescriptions, transformInputValue, updateArgument, validateGraphQlDocuments, valueMatchesCriteria, visitData, visitErrors, visitResult, withCancel };
4268
+ export { AggregateErrorImpl as AggregateError, MapperKind, addTypes, appendObjectFields, asArray, assertSome, astFromArg, astFromDirective, astFromEnumType, astFromEnumValue, astFromField, astFromInputField, astFromInputObjectType, astFromInterfaceType, astFromObjectType, astFromScalarType, astFromSchema, astFromUnionType, astFromValueUntyped, buildOperationNodeForField, checkValidationErrors, collectComment, collectFields, collectSubFields, compareNodes, compareStrings, correctASTNodes, createDefaultRules, createNamedStub, createStub, createVariableNameGenerator, dedentBlockStringValue, filterSchema, fixSchemaAst, forEachDefaultValue, forEachField, getArgumentValues, getAsyncIterableWithCancel, getAsyncIteratorWithCancel, getBlockStringIndentation, getBuiltInForStub, getComment, getDefinedRootType, getDeprecatableDirectiveNodes, getDescription, getDirective, getDirectiveInExtensions, getDirectiveNodes, getDirectives, getDirectivesInExtensions, getDocumentNodeFromSchema, getFieldsWithDirectives, getImplementingTypes, getLeadingCommentBlock, getOperationASTFromDocument, getOperationASTFromRequest, getResolversFromSchema, getResponseKeyFromInfo, getRootTypeMap, getRootTypeNames, getRootTypes, healSchema, healTypes, implementsAbstractType, inspect, isAggregateError, isAsyncIterable, isDescribable, isDocumentNode, isDocumentString, isNamedStub, isSome, isValidPath, makeDeprecatedDirective, makeDirectiveNode, makeDirectiveNodes, mapAsyncIterator, mapSchema, memoize1, memoize2, memoize2of4, memoize3, memoize4, memoize5, mergeDeep, modifyObjectFields, nodeToString, observableToAsyncIterable, parseGraphQLJSON, parseGraphQLSDL, parseInputValue, parseInputValueLiteral, parseSelectionSet, printComment, printSchemaWithDirectives, printWithComments, pruneSchema, pushComment, relocatedError, removeObjectFields, renameType, resetComments, rewireTypes, selectObjectFields, serializeInputValue, transformCommentsToDescriptions, transformInputValue, updateArgument, validateGraphQlDocuments, valueMatchesCriteria, visitData, visitErrors, visitResult, getAsyncIterableWithCancel as withCancel };
@@ -1 +1 @@
1
- export declare function isAsyncIterable<T>(value: any): value is AsyncIterableIterator<T>;
1
+ export declare function isAsyncIterable<T>(value: any): value is AsyncIterable<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-tools/utils",
3
- "version": "8.6.0-alpha-c3063363.0",
3
+ "version": "8.6.1-alpha-b935d9b2.0",
4
4
  "description": "Common package containing utils and types for GraphQL tools",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -30,6 +30,7 @@
30
30
  "./*": {
31
31
  "require": "./*.js",
32
32
  "import": "./*.mjs"
33
- }
33
+ },
34
+ "./package.json": "./package.json"
34
35
  }
35
36
  }
package/withCancel.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export declare function withCancel<T>(asyncIteratorLike: {
2
- [Symbol.asyncIterator](): AsyncIterator<T>;
3
- }, onCancel: () => void): AsyncIterator<T | undefined>;
1
+ export declare function getAsyncIteratorWithCancel<T, TReturn = any>(asyncIterator: AsyncIterator<T>, onCancel: (value?: TReturn) => void | Promise<void>): AsyncIterator<T>;
2
+ export declare function getAsyncIterableWithCancel<T, TAsyncIterable extends AsyncIterable<T>, TReturn = any>(asyncIterable: TAsyncIterable, onCancel: (value?: TReturn) => void | Promise<void>): TAsyncIterable;
3
+ export { getAsyncIterableWithCancel as withCancel };
package/path.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function joinPaths(...paths: string[]): string;
2
- export declare function isAbsolutePath(path: string): boolean;