@graphql-tools/delegate 12.1.3 → 12.1.4-alpha-bcfb2c1cde3a349458d33360e3f4a5f19eb134db
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 +11 -0
- package/dist/index.cjs +20 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +20 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @graphql-tools/delegate
|
|
2
2
|
|
|
3
|
+
## 12.1.4-alpha-bcfb2c1cde3a349458d33360e3f4a5f19eb134db
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#2600](https://github.com/graphql-hive/gateway/pull/2600) [`01a84ac`](https://github.com/graphql-hive/gateway/commit/01a84acdfea10b1b78bec729d5b530047f68ee4a) Thanks [@enisdenjo](https://github.com/enisdenjo)! - Drop prototype polluting keys from subgraph results before merging them
|
|
9
|
+
|
|
10
|
+
Response keys named `__proto__`, `constructor` or `prototype`, which a client can produce with a field alias, were only filtered at the top level of a merged result. Nested occurrences were passed to `mergeDeep`, which walks the prototype chain and could end up writing to `Object.prototype` or `Function.prototype`.
|
|
11
|
+
|
|
12
|
+
Such keys are now removed at every depth of a subgraph result before it takes part in a merge, and `projectDataSelectionSet` no longer treats an inherited property as an already projected field.
|
|
13
|
+
|
|
3
14
|
## 12.1.3
|
|
4
15
|
### Patch Changes
|
|
5
16
|
|
package/dist/index.cjs
CHANGED
|
@@ -75,6 +75,22 @@ const prototypePollutingKeys = [
|
|
|
75
75
|
function isPrototypePollutingKey(key) {
|
|
76
76
|
return prototypePollutingKeys.includes(key);
|
|
77
77
|
}
|
|
78
|
+
function removePrototypePollutingKeys(value) {
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
for (const item of value) {
|
|
81
|
+
removePrototypePollutingKeys(item);
|
|
82
|
+
}
|
|
83
|
+
} else if (value && typeof value === "object" && !(value instanceof Error)) {
|
|
84
|
+
for (const key of Object.keys(value)) {
|
|
85
|
+
if (isPrototypePollutingKey(key)) {
|
|
86
|
+
delete value[key];
|
|
87
|
+
} else {
|
|
88
|
+
removePrototypePollutingKeys(value[key]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
78
94
|
|
|
79
95
|
const leftOverByDelegationPlan = /* @__PURE__ */ new WeakMap();
|
|
80
96
|
const PLAN_LEFT_OVER = Symbol("PLAN_LEFT_OVER");
|
|
@@ -188,7 +204,9 @@ function handleResolverResult(resolverResult, subschema, selectionSet, object, c
|
|
|
188
204
|
continue;
|
|
189
205
|
}
|
|
190
206
|
const existingPropValue = object[responseKey];
|
|
191
|
-
const sourcePropValue =
|
|
207
|
+
const sourcePropValue = removePrototypePollutingKeys(
|
|
208
|
+
resolverResult[responseKey]
|
|
209
|
+
);
|
|
192
210
|
if (responseKey === "__typename" && existingPropValue !== sourcePropValue && graphql.isAbstractType(subschema.transformedSchema.getType(sourcePropValue))) {
|
|
193
211
|
continue;
|
|
194
212
|
}
|
|
@@ -3564,5 +3582,6 @@ exports.isSubschema = isSubschema;
|
|
|
3564
3582
|
exports.isSubschemaConfig = isSubschemaConfig;
|
|
3565
3583
|
exports.leftOverByDelegationPlan = leftOverByDelegationPlan;
|
|
3566
3584
|
exports.mergeFields = mergeFields;
|
|
3585
|
+
exports.removePrototypePollutingKeys = removePrototypePollutingKeys;
|
|
3567
3586
|
exports.resolveExternalValue = resolveExternalValue;
|
|
3568
3587
|
exports.subtractSelectionSets = subtractSelectionSets;
|
package/dist/index.d.cts
CHANGED
|
@@ -235,7 +235,16 @@ declare const getTypeInfoWithType: (schema: GraphQLSchema, type: Maybe<GraphQLTy
|
|
|
235
235
|
declare const prototypePollutingKeys: readonly ["__proto__", "constructor", "prototype"];
|
|
236
236
|
type PrototypePollutingKey = (typeof prototypePollutingKeys)[number];
|
|
237
237
|
declare function isPrototypePollutingKey(key: string): key is PrototypePollutingKey;
|
|
238
|
+
/**
|
|
239
|
+
* Removes prototype polluting keys from the given value, in place and at every depth.
|
|
240
|
+
*
|
|
241
|
+
* Response data coming from a subgraph can contain keys such as `__proto__` or
|
|
242
|
+
* `constructor` when the client aliases a field to one of those names. Deep merging
|
|
243
|
+
* such data walks the prototype chain and can end up writing to `Object.prototype` or
|
|
244
|
+
* `Function.prototype`, so the keys are dropped before any merge happens.
|
|
245
|
+
*/
|
|
246
|
+
declare function removePrototypePollutingKeys<T>(value: T): T;
|
|
238
247
|
|
|
239
248
|
declare const handleOverrideByDelegation: (info: GraphQLResolveInfo$1, context: any, overrideHandler: OverrideHandler) => boolean;
|
|
240
249
|
|
|
241
|
-
export { type BatchingOptions, type CreateProxyingResolverFn, type Deferred, type DelegationContext, type DelegationPlanBuilder, type DelegationPlanLeftOver, EMPTY_OBJECT, type ExternalObject, FIELD_SUBSCHEMA_MAP_SYMBOL, type ICreateProxyingResolverOptions, type ICreateRequest, type IDelegateRequestOptions, type IDelegateToSchemaOptions, type MergedFieldConfig, type MergedTypeConfig, type MergedTypeEntryPoint, type MergedTypeInfo, type MergedTypeResolver, type MergedTypeResolverOptions, OBJECT_SUBSCHEMA_SYMBOL, type OverrideHandler, PLAN_LEFT_OVER, type RequestTransform, type ResultTransform, type SchemaTransform, type StitchingInfo, Subschema, type SubschemaConfig, type Transform, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, resolveExternalValue, subtractSelectionSets };
|
|
250
|
+
export { type BatchingOptions, type CreateProxyingResolverFn, type Deferred, type DelegationContext, type DelegationPlanBuilder, type DelegationPlanLeftOver, EMPTY_OBJECT, type ExternalObject, FIELD_SUBSCHEMA_MAP_SYMBOL, type ICreateProxyingResolverOptions, type ICreateRequest, type IDelegateRequestOptions, type IDelegateToSchemaOptions, type MergedFieldConfig, type MergedTypeConfig, type MergedTypeEntryPoint, type MergedTypeInfo, type MergedTypeResolver, type MergedTypeResolverOptions, OBJECT_SUBSCHEMA_SYMBOL, type OverrideHandler, PLAN_LEFT_OVER, type RequestTransform, type ResultTransform, type SchemaTransform, type StitchingInfo, Subschema, type SubschemaConfig, type Transform, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, removePrototypePollutingKeys, resolveExternalValue, subtractSelectionSets };
|
package/dist/index.d.ts
CHANGED
|
@@ -235,7 +235,16 @@ declare const getTypeInfoWithType: (schema: GraphQLSchema, type: Maybe<GraphQLTy
|
|
|
235
235
|
declare const prototypePollutingKeys: readonly ["__proto__", "constructor", "prototype"];
|
|
236
236
|
type PrototypePollutingKey = (typeof prototypePollutingKeys)[number];
|
|
237
237
|
declare function isPrototypePollutingKey(key: string): key is PrototypePollutingKey;
|
|
238
|
+
/**
|
|
239
|
+
* Removes prototype polluting keys from the given value, in place and at every depth.
|
|
240
|
+
*
|
|
241
|
+
* Response data coming from a subgraph can contain keys such as `__proto__` or
|
|
242
|
+
* `constructor` when the client aliases a field to one of those names. Deep merging
|
|
243
|
+
* such data walks the prototype chain and can end up writing to `Object.prototype` or
|
|
244
|
+
* `Function.prototype`, so the keys are dropped before any merge happens.
|
|
245
|
+
*/
|
|
246
|
+
declare function removePrototypePollutingKeys<T>(value: T): T;
|
|
238
247
|
|
|
239
248
|
declare const handleOverrideByDelegation: (info: GraphQLResolveInfo$1, context: any, overrideHandler: OverrideHandler) => boolean;
|
|
240
249
|
|
|
241
|
-
export { type BatchingOptions, type CreateProxyingResolverFn, type Deferred, type DelegationContext, type DelegationPlanBuilder, type DelegationPlanLeftOver, EMPTY_OBJECT, type ExternalObject, FIELD_SUBSCHEMA_MAP_SYMBOL, type ICreateProxyingResolverOptions, type ICreateRequest, type IDelegateRequestOptions, type IDelegateToSchemaOptions, type MergedFieldConfig, type MergedTypeConfig, type MergedTypeEntryPoint, type MergedTypeInfo, type MergedTypeResolver, type MergedTypeResolverOptions, OBJECT_SUBSCHEMA_SYMBOL, type OverrideHandler, PLAN_LEFT_OVER, type RequestTransform, type ResultTransform, type SchemaTransform, type StitchingInfo, Subschema, type SubschemaConfig, type Transform, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, resolveExternalValue, subtractSelectionSets };
|
|
250
|
+
export { type BatchingOptions, type CreateProxyingResolverFn, type Deferred, type DelegationContext, type DelegationPlanBuilder, type DelegationPlanLeftOver, EMPTY_OBJECT, type ExternalObject, FIELD_SUBSCHEMA_MAP_SYMBOL, type ICreateProxyingResolverOptions, type ICreateRequest, type IDelegateRequestOptions, type IDelegateToSchemaOptions, type MergedFieldConfig, type MergedTypeConfig, type MergedTypeEntryPoint, type MergedTypeInfo, type MergedTypeResolver, type MergedTypeResolverOptions, OBJECT_SUBSCHEMA_SYMBOL, type OverrideHandler, PLAN_LEFT_OVER, type RequestTransform, type ResultTransform, type SchemaTransform, type StitchingInfo, Subschema, type SubschemaConfig, type Transform, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, removePrototypePollutingKeys, resolveExternalValue, subtractSelectionSets };
|
package/dist/index.js
CHANGED
|
@@ -75,6 +75,22 @@ const prototypePollutingKeys = [
|
|
|
75
75
|
function isPrototypePollutingKey(key) {
|
|
76
76
|
return prototypePollutingKeys.includes(key);
|
|
77
77
|
}
|
|
78
|
+
function removePrototypePollutingKeys(value) {
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
for (const item of value) {
|
|
81
|
+
removePrototypePollutingKeys(item);
|
|
82
|
+
}
|
|
83
|
+
} else if (value && typeof value === "object" && !(value instanceof Error)) {
|
|
84
|
+
for (const key of Object.keys(value)) {
|
|
85
|
+
if (isPrototypePollutingKey(key)) {
|
|
86
|
+
delete value[key];
|
|
87
|
+
} else {
|
|
88
|
+
removePrototypePollutingKeys(value[key]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
78
94
|
|
|
79
95
|
const leftOverByDelegationPlan = /* @__PURE__ */ new WeakMap();
|
|
80
96
|
const PLAN_LEFT_OVER = Symbol("PLAN_LEFT_OVER");
|
|
@@ -188,7 +204,9 @@ function handleResolverResult(resolverResult, subschema, selectionSet, object, c
|
|
|
188
204
|
continue;
|
|
189
205
|
}
|
|
190
206
|
const existingPropValue = object[responseKey];
|
|
191
|
-
const sourcePropValue =
|
|
207
|
+
const sourcePropValue = removePrototypePollutingKeys(
|
|
208
|
+
resolverResult[responseKey]
|
|
209
|
+
);
|
|
192
210
|
if (responseKey === "__typename" && existingPropValue !== sourcePropValue && isAbstractType(subschema.transformedSchema.getType(sourcePropValue))) {
|
|
193
211
|
continue;
|
|
194
212
|
}
|
|
@@ -3525,4 +3543,4 @@ function subtractSelectionSets(selectionSetA, selectionSetB, fragments = {}) {
|
|
|
3525
3543
|
};
|
|
3526
3544
|
}
|
|
3527
3545
|
|
|
3528
|
-
export { EMPTY_OBJECT, FIELD_SUBSCHEMA_MAP_SYMBOL, OBJECT_SUBSCHEMA_SYMBOL, PLAN_LEFT_OVER, Subschema, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, resolveExternalValue, subtractSelectionSets };
|
|
3546
|
+
export { EMPTY_OBJECT, FIELD_SUBSCHEMA_MAP_SYMBOL, OBJECT_SUBSCHEMA_SYMBOL, PLAN_LEFT_OVER, Subschema, Transformer, UNPATHED_ERRORS_SYMBOL, annotateExternalObject, applySchemaTransforms, cloneSubschemaConfig, createRequest, defaultMergedResolver, delegateRequest, delegateToSchema, extractUnavailableFields, extractUnavailableFieldsFromSelectionSet, getActualFieldNodes, getDelegatingOperation, getPlanLeftOverFromParent, getSubschema, getTypeInfo, getTypeInfoWithType, getUnpathedErrors, handleOverrideByDelegation, handleResolverResult, isExternalObject, isPrototypePollutingKey, isSubschema, isSubschemaConfig, leftOverByDelegationPlan, mergeFields, removePrototypePollutingKeys, resolveExternalValue, subtractSelectionSets };
|
package/package.json
CHANGED