@graphql-tools/utils 12.0.1 → 12.0.3
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/cjs/index.js +3 -2
- package/cjs/jsutils.js +24 -0
- package/cjs/mergeDeep.js +2 -1
- package/cjs/mergeIncrementalResult.js +23 -8
- package/esm/index.js +2 -1
- package/esm/jsutils.js +21 -0
- package/esm/mergeDeep.js +2 -1
- package/esm/mergeIncrementalResult.js +23 -8
- package/package.json +2 -2
- package/typings/index.d.cts +2 -1
- package/typings/index.d.ts +2 -1
- package/typings/jsutils.d.cts +13 -1
- package/typings/jsutils.d.ts +13 -1
package/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createDeferred = exports.fakePromise = exports.
|
|
3
|
+
exports.createDeferred = exports.fakePromise = exports.mapAsyncIterator = exports.mapMaybePromise = exports.inspect = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
tslib_1.__exportStar(require("./loaders.js"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./helpers.js"), exports);
|
|
@@ -60,9 +60,10 @@ tslib_1.__exportStar(require("./directives.js"), exports);
|
|
|
60
60
|
tslib_1.__exportStar(require("./mergeIncrementalResult.js"), exports);
|
|
61
61
|
tslib_1.__exportStar(require("./debugTimer.js"), exports);
|
|
62
62
|
tslib_1.__exportStar(require("./getDirectiveExtensions.js"), exports);
|
|
63
|
+
var jsutils_js_1 = require("./jsutils.js");
|
|
64
|
+
Object.defineProperty(exports, "mapMaybePromise", { enumerable: true, get: function () { return jsutils_js_1.mapMaybePromise; } });
|
|
63
65
|
var promise_helpers_1 = require("@whatwg-node/promise-helpers");
|
|
64
66
|
Object.defineProperty(exports, "mapAsyncIterator", { enumerable: true, get: function () { return promise_helpers_1.mapAsyncIterator; } });
|
|
65
|
-
Object.defineProperty(exports, "mapMaybePromise", { enumerable: true, get: function () { return promise_helpers_1.mapMaybePromise; } });
|
|
66
67
|
Object.defineProperty(exports, "fakePromise", { enumerable: true, get: function () { return promise_helpers_1.fakePromise; } });
|
|
67
68
|
Object.defineProperty(exports, "createDeferred", { enumerable: true, get: function () { return promise_helpers_1.createDeferredPromise; } });
|
|
68
69
|
tslib_1.__exportStar(require("./registerAbortSignalListener.js"), exports);
|
package/cjs/jsutils.js
CHANGED
|
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.isPromise = void 0;
|
|
4
4
|
exports.isIterableObject = isIterableObject;
|
|
5
5
|
exports.isObjectLike = isObjectLike;
|
|
6
|
+
exports.mapMaybePromise = mapMaybePromise;
|
|
6
7
|
exports.promiseReduce = promiseReduce;
|
|
7
8
|
exports.hasOwnProperty = hasOwnProperty;
|
|
9
|
+
exports.isDangerousObjectKey = isDangerousObjectKey;
|
|
10
|
+
exports.isSafeObjectKey = isSafeObjectKey;
|
|
8
11
|
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
|
|
9
12
|
Object.defineProperty(exports, "isPromise", { enumerable: true, get: function () { return promise_helpers_1.isPromise; } });
|
|
10
13
|
function isIterableObject(value) {
|
|
@@ -13,6 +16,9 @@ function isIterableObject(value) {
|
|
|
13
16
|
function isObjectLike(value) {
|
|
14
17
|
return typeof value === 'object' && value !== null;
|
|
15
18
|
}
|
|
19
|
+
function mapMaybePromise(input, onSuccess, onError) {
|
|
20
|
+
return (0, promise_helpers_1.handleMaybePromise)(() => input, onSuccess, onError);
|
|
21
|
+
}
|
|
16
22
|
function promiseReduce(values, callbackFn, initialValue) {
|
|
17
23
|
let accumulator = initialValue;
|
|
18
24
|
for (const value of values) {
|
|
@@ -23,3 +29,21 @@ function promiseReduce(values, callbackFn, initialValue) {
|
|
|
23
29
|
function hasOwnProperty(obj, prop) {
|
|
24
30
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
25
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* True for keys that must never be used for object-path writes because they
|
|
34
|
+
* reach the prototype chain (`__proto__`, `constructor`, `prototype`).
|
|
35
|
+
*/
|
|
36
|
+
function isDangerousObjectKey(key) {
|
|
37
|
+
return key === '__proto__' || key === 'constructor' || key === 'prototype';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* True when `key` is a primitive string/number that is safe to use for
|
|
41
|
+
* own-property access. Rejects non-primitives (which coerce via `ToPropertyKey`)
|
|
42
|
+
* and {@link isDangerousObjectKey dangerous names}.
|
|
43
|
+
*/
|
|
44
|
+
function isSafeObjectKey(key) {
|
|
45
|
+
if (typeof key !== 'string' && typeof key !== 'number') {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return !isDangerousObjectKey(key);
|
|
49
|
+
}
|
package/cjs/mergeDeep.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mergeDeep = mergeDeep;
|
|
4
4
|
const helpers_js_1 = require("./helpers.js");
|
|
5
|
+
const jsutils_js_1 = require("./jsutils.js");
|
|
5
6
|
function mergeDeep(sources, respectPrototype = false, respectArrays = false, respectArrayLength = false, respectNonEnumerableSymbols = false) {
|
|
6
7
|
if (sources.length === 0) {
|
|
7
8
|
return;
|
|
@@ -65,7 +66,7 @@ function mergeDeep(sources, respectPrototype = false, respectArrays = false, res
|
|
|
65
66
|
}
|
|
66
67
|
for (const key in source) {
|
|
67
68
|
// never let a source key reach the prototype chain
|
|
68
|
-
if (
|
|
69
|
+
if ((0, jsutils_js_1.isDangerousObjectKey)(key)) {
|
|
69
70
|
continue;
|
|
70
71
|
}
|
|
71
72
|
// An own key present with value `undefined` is an explicit override and must win,
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.mergeIncrementalResult = mergeIncrementalResult;
|
|
4
|
+
const jsutils_js_1 = require("./jsutils.js");
|
|
4
5
|
const mergeDeep_js_1 = require("./mergeDeep.js");
|
|
5
6
|
function mergeIncrementalResult({ incrementalResult, executionResult, }) {
|
|
6
7
|
const path = ['data', ...(incrementalResult.path ?? [])];
|
|
7
8
|
if (incrementalResult.items) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Reject the whole items batch if any path segment is unsafe, so a later
|
|
10
|
+
// index increment cannot turn a bad segment into a write at `data.NaN`.
|
|
11
|
+
if (isSafeKeyPath(path)) {
|
|
12
|
+
for (const item of incrementalResult.items) {
|
|
13
|
+
setObjectKeyPath(executionResult, path, item);
|
|
14
|
+
// Increment the last path segment (the array index) to merge the next item at the next index
|
|
15
|
+
path[path.length - 1]++;
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
}
|
|
14
19
|
if (incrementalResult.data) {
|
|
@@ -30,24 +35,34 @@ function mergeIncrementalResult({ incrementalResult, executionResult, }) {
|
|
|
30
35
|
});
|
|
31
36
|
}
|
|
32
37
|
}
|
|
38
|
+
function isSafeKeyPath(keyPath) {
|
|
39
|
+
return keyPath.every(jsutils_js_1.isSafeObjectKey);
|
|
40
|
+
}
|
|
33
41
|
function setObjectKeyPath(obj, keyPath, value) {
|
|
42
|
+
// Validate the full path before creating any parent containers, so a late
|
|
43
|
+
// unsafe segment cannot leave partial writes on executionResult.
|
|
44
|
+
if (!isSafeKeyPath(keyPath)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
34
47
|
let current = obj;
|
|
35
48
|
let i;
|
|
36
49
|
for (i = 0; i < keyPath.length - 1; i++) {
|
|
37
50
|
const key = keyPath[i];
|
|
38
|
-
|
|
51
|
+
// Direct comparison, not only isSafeObjectKey(): that helper already rejects
|
|
52
|
+
// this key, but the check has to sit on the value used as the property name.
|
|
53
|
+
if (key === '__proto__' || !(0, jsutils_js_1.isSafeObjectKey)(key)) {
|
|
39
54
|
return;
|
|
40
55
|
}
|
|
41
|
-
if (current[key] == null) {
|
|
56
|
+
if (!(0, jsutils_js_1.hasOwnProperty)(current, key) || current[key] == null) {
|
|
42
57
|
// Determine if the next key is a number to create an array, otherwise create an object
|
|
43
58
|
current[key] = typeof keyPath[i + 1] === 'number' ? [] : {};
|
|
44
59
|
}
|
|
45
60
|
current = current[key];
|
|
46
61
|
}
|
|
47
62
|
const finalKey = keyPath[i];
|
|
48
|
-
if (finalKey === '__proto__' ||
|
|
63
|
+
if (finalKey === '__proto__' || !(0, jsutils_js_1.isSafeObjectKey)(finalKey)) {
|
|
49
64
|
return;
|
|
50
65
|
}
|
|
51
|
-
const existingValue = current[finalKey];
|
|
66
|
+
const existingValue = (0, jsutils_js_1.hasOwnProperty)(current, finalKey) ? current[finalKey] : undefined;
|
|
52
67
|
current[finalKey] = existingValue != null ? (0, mergeDeep_js_1.mergeDeep)([existingValue, value]) : value;
|
|
53
68
|
}
|
package/esm/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export * from './directives.js';
|
|
|
55
55
|
export * from './mergeIncrementalResult.js';
|
|
56
56
|
export * from './debugTimer.js';
|
|
57
57
|
export * from './getDirectiveExtensions.js';
|
|
58
|
-
export {
|
|
58
|
+
export { mapMaybePromise } from './jsutils.js';
|
|
59
|
+
export { mapAsyncIterator, fakePromise, createDeferredPromise as createDeferred, } from '@whatwg-node/promise-helpers';
|
|
59
60
|
export * from './registerAbortSignalListener.js';
|
|
60
61
|
export * from './getDirectiveValues.js';
|
package/esm/jsutils.js
CHANGED
|
@@ -6,6 +6,9 @@ export function isObjectLike(value) {
|
|
|
6
6
|
return typeof value === 'object' && value !== null;
|
|
7
7
|
}
|
|
8
8
|
export { isPromise };
|
|
9
|
+
export function mapMaybePromise(input, onSuccess, onError) {
|
|
10
|
+
return handleMaybePromise(() => input, onSuccess, onError);
|
|
11
|
+
}
|
|
9
12
|
export function promiseReduce(values, callbackFn, initialValue) {
|
|
10
13
|
let accumulator = initialValue;
|
|
11
14
|
for (const value of values) {
|
|
@@ -16,3 +19,21 @@ export function promiseReduce(values, callbackFn, initialValue) {
|
|
|
16
19
|
export function hasOwnProperty(obj, prop) {
|
|
17
20
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
18
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* True for keys that must never be used for object-path writes because they
|
|
24
|
+
* reach the prototype chain (`__proto__`, `constructor`, `prototype`).
|
|
25
|
+
*/
|
|
26
|
+
export function isDangerousObjectKey(key) {
|
|
27
|
+
return key === '__proto__' || key === 'constructor' || key === 'prototype';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* True when `key` is a primitive string/number that is safe to use for
|
|
31
|
+
* own-property access. Rejects non-primitives (which coerce via `ToPropertyKey`)
|
|
32
|
+
* and {@link isDangerousObjectKey dangerous names}.
|
|
33
|
+
*/
|
|
34
|
+
export function isSafeObjectKey(key) {
|
|
35
|
+
if (typeof key !== 'string' && typeof key !== 'number') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return !isDangerousObjectKey(key);
|
|
39
|
+
}
|
package/esm/mergeDeep.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isSome } from './helpers.js';
|
|
2
|
+
import { isDangerousObjectKey } from './jsutils.js';
|
|
2
3
|
export function mergeDeep(sources, respectPrototype = false, respectArrays = false, respectArrayLength = false, respectNonEnumerableSymbols = false) {
|
|
3
4
|
if (sources.length === 0) {
|
|
4
5
|
return;
|
|
@@ -62,7 +63,7 @@ export function mergeDeep(sources, respectPrototype = false, respectArrays = fal
|
|
|
62
63
|
}
|
|
63
64
|
for (const key in source) {
|
|
64
65
|
// never let a source key reach the prototype chain
|
|
65
|
-
if (key
|
|
66
|
+
if (isDangerousObjectKey(key)) {
|
|
66
67
|
continue;
|
|
67
68
|
}
|
|
68
69
|
// An own key present with value `undefined` is an explicit override and must win,
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
import { hasOwnProperty, isSafeObjectKey } from './jsutils.js';
|
|
1
2
|
import { mergeDeep } from './mergeDeep.js';
|
|
2
3
|
export function mergeIncrementalResult({ incrementalResult, executionResult, }) {
|
|
3
4
|
const path = ['data', ...(incrementalResult.path ?? [])];
|
|
4
5
|
if (incrementalResult.items) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Reject the whole items batch if any path segment is unsafe, so a later
|
|
7
|
+
// index increment cannot turn a bad segment into a write at `data.NaN`.
|
|
8
|
+
if (isSafeKeyPath(path)) {
|
|
9
|
+
for (const item of incrementalResult.items) {
|
|
10
|
+
setObjectKeyPath(executionResult, path, item);
|
|
11
|
+
// Increment the last path segment (the array index) to merge the next item at the next index
|
|
12
|
+
path[path.length - 1]++;
|
|
13
|
+
}
|
|
9
14
|
}
|
|
10
15
|
}
|
|
11
16
|
if (incrementalResult.data) {
|
|
@@ -27,24 +32,34 @@ export function mergeIncrementalResult({ incrementalResult, executionResult, })
|
|
|
27
32
|
});
|
|
28
33
|
}
|
|
29
34
|
}
|
|
35
|
+
function isSafeKeyPath(keyPath) {
|
|
36
|
+
return keyPath.every(isSafeObjectKey);
|
|
37
|
+
}
|
|
30
38
|
function setObjectKeyPath(obj, keyPath, value) {
|
|
39
|
+
// Validate the full path before creating any parent containers, so a late
|
|
40
|
+
// unsafe segment cannot leave partial writes on executionResult.
|
|
41
|
+
if (!isSafeKeyPath(keyPath)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
31
44
|
let current = obj;
|
|
32
45
|
let i;
|
|
33
46
|
for (i = 0; i < keyPath.length - 1; i++) {
|
|
34
47
|
const key = keyPath[i];
|
|
35
|
-
|
|
48
|
+
// Direct comparison, not only isSafeObjectKey(): that helper already rejects
|
|
49
|
+
// this key, but the check has to sit on the value used as the property name.
|
|
50
|
+
if (key === '__proto__' || !isSafeObjectKey(key)) {
|
|
36
51
|
return;
|
|
37
52
|
}
|
|
38
|
-
if (current[key] == null) {
|
|
53
|
+
if (!hasOwnProperty(current, key) || current[key] == null) {
|
|
39
54
|
// Determine if the next key is a number to create an array, otherwise create an object
|
|
40
55
|
current[key] = typeof keyPath[i + 1] === 'number' ? [] : {};
|
|
41
56
|
}
|
|
42
57
|
current = current[key];
|
|
43
58
|
}
|
|
44
59
|
const finalKey = keyPath[i];
|
|
45
|
-
if (finalKey === '__proto__' || finalKey
|
|
60
|
+
if (finalKey === '__proto__' || !isSafeObjectKey(finalKey)) {
|
|
46
61
|
return;
|
|
47
62
|
}
|
|
48
|
-
const existingValue = current[finalKey];
|
|
63
|
+
const existingValue = hasOwnProperty(current, finalKey) ? current[finalKey] : undefined;
|
|
49
64
|
current[finalKey] = existingValue != null ? mergeDeep([existingValue, value]) : value;
|
|
50
65
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-tools/utils",
|
|
3
|
-
"version": "12.0.
|
|
3
|
+
"version": "12.0.3",
|
|
4
4
|
"description": "Common package containing utils and types for GraphQL tools",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@graphql-typed-document-node/core": "^3.1.1",
|
|
11
|
-
"@whatwg-node/promise-helpers": "^
|
|
11
|
+
"@whatwg-node/promise-helpers": "^2.0.0",
|
|
12
12
|
"cross-inspect": "1.0.1",
|
|
13
13
|
"tslib": "^2.4.0"
|
|
14
14
|
},
|
package/typings/index.d.cts
CHANGED
|
@@ -55,6 +55,7 @@ export * from './directives.cjs';
|
|
|
55
55
|
export * from './mergeIncrementalResult.cjs';
|
|
56
56
|
export * from './debugTimer.cjs';
|
|
57
57
|
export * from './getDirectiveExtensions.cjs';
|
|
58
|
-
export {
|
|
58
|
+
export { mapMaybePromise } from './jsutils.cjs';
|
|
59
|
+
export { mapAsyncIterator, fakePromise, createDeferredPromise as createDeferred, } from '@whatwg-node/promise-helpers';
|
|
59
60
|
export * from './registerAbortSignalListener.cjs';
|
|
60
61
|
export * from './getDirectiveValues.cjs';
|
package/typings/index.d.ts
CHANGED
|
@@ -55,6 +55,7 @@ export * from './directives.js';
|
|
|
55
55
|
export * from './mergeIncrementalResult.js';
|
|
56
56
|
export * from './debugTimer.js';
|
|
57
57
|
export * from './getDirectiveExtensions.js';
|
|
58
|
-
export {
|
|
58
|
+
export { mapMaybePromise } from './jsutils.js';
|
|
59
|
+
export { mapAsyncIterator, fakePromise, createDeferredPromise as createDeferred, } from '@whatwg-node/promise-helpers';
|
|
59
60
|
export * from './registerAbortSignalListener.js';
|
|
60
61
|
export * from './getDirectiveValues.js';
|
package/typings/jsutils.d.cts
CHANGED
|
@@ -4,5 +4,17 @@ export declare function isObjectLike(value: unknown): value is {
|
|
|
4
4
|
[key: string]: unknown;
|
|
5
5
|
};
|
|
6
6
|
export { isPromise };
|
|
7
|
+
export declare function mapMaybePromise<TInput, TOutput>(input: MaybePromise<TInput>, onSuccess: (value: TInput) => MaybePromise<TOutput>, onError?: (err: any) => MaybePromise<TOutput>): MaybePromise<TOutput>;
|
|
7
8
|
export declare function promiseReduce<T, U>(values: Iterable<T>, callbackFn: (accumulator: U, currentValue: T) => MaybePromise<U>, initialValue: MaybePromise<U>): MaybePromise<U>;
|
|
8
|
-
export declare function hasOwnProperty(obj: unknown, prop:
|
|
9
|
+
export declare function hasOwnProperty(obj: unknown, prop: PropertyKey): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* True for keys that must never be used for object-path writes because they
|
|
12
|
+
* reach the prototype chain (`__proto__`, `constructor`, `prototype`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function isDangerousObjectKey(key: unknown): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* True when `key` is a primitive string/number that is safe to use for
|
|
17
|
+
* own-property access. Rejects non-primitives (which coerce via `ToPropertyKey`)
|
|
18
|
+
* and {@link isDangerousObjectKey dangerous names}.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isSafeObjectKey(key: unknown): key is string | number;
|
package/typings/jsutils.d.ts
CHANGED
|
@@ -4,5 +4,17 @@ export declare function isObjectLike(value: unknown): value is {
|
|
|
4
4
|
[key: string]: unknown;
|
|
5
5
|
};
|
|
6
6
|
export { isPromise };
|
|
7
|
+
export declare function mapMaybePromise<TInput, TOutput>(input: MaybePromise<TInput>, onSuccess: (value: TInput) => MaybePromise<TOutput>, onError?: (err: any) => MaybePromise<TOutput>): MaybePromise<TOutput>;
|
|
7
8
|
export declare function promiseReduce<T, U>(values: Iterable<T>, callbackFn: (accumulator: U, currentValue: T) => MaybePromise<U>, initialValue: MaybePromise<U>): MaybePromise<U>;
|
|
8
|
-
export declare function hasOwnProperty(obj: unknown, prop:
|
|
9
|
+
export declare function hasOwnProperty(obj: unknown, prop: PropertyKey): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* True for keys that must never be used for object-path writes because they
|
|
12
|
+
* reach the prototype chain (`__proto__`, `constructor`, `prototype`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function isDangerousObjectKey(key: unknown): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* True when `key` is a primitive string/number that is safe to use for
|
|
17
|
+
* own-property access. Rejects non-primitives (which coerce via `ToPropertyKey`)
|
|
18
|
+
* and {@link isDangerousObjectKey dangerous names}.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isSafeObjectKey(key: unknown): key is string | number;
|