Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
private async _updateRequest(
request: string,
options: RequestOptions,
context: RequestContext,
): Promise {
const updatedRequest = options.fragments ? RequestParser._concatFragments(request, options.fragments) : request;
const ast = parse(updatedRequest);
const operationDefinitions = getOperationDefinitions(ast);
if (operationDefinitions.length > 1) {
return Promise.reject(new TypeError("@graphql-box/request-parser expected one operation, but got multiple."));
}
RequestParser._addOperationToContext(operationDefinitions, context);
const _this = this;
const typeInfo = new TypeInfo(this._schema);
let fragmentDefinitions: FragmentDefinitionNodeMap | undefined;
const variableTypes: VariableTypesMap = {};
try {
const updatedAST = visit(ast, {
enter(
node: ASTNode,
private _onMessage = async ({ data }: MessageEvent): Promise => {
if (!isPlainObject(data)) return;
const { context, method, result, type } = data as MessageResponsePayload;
if (type !== GRAPHQL_BOX || !isPlainObject(result)) return;
const { _cacheMetadata, ...otherProps } = result;
const response: MaybeRequestResult = { ...otherProps };
if (_cacheMetadata) response._cacheMetadata = rehydrateCacheMetadata(_cacheMetadata);
if (method === REQUEST) {
const pending = this._pending.get(context.boxID);
if (!pending) return;
pending.resolve(response);
} else if (method === SUBSCRIBE) {
this._eventEmitter.emit(context.boxID, response);
}
};
rootValue: rootValue || this._rootValue,
schema: this._schema,
subscribeFieldResolver: subscribeFieldResolver || this._subscribeFieldResolver,
};
try {
const subscribeResult = await this._subscribe(subscribeArgs);
if (isAsyncIterable(subscribeResult)) {
forAwaitEach(subscribeResult, async ({ data, errors }: ExecutionResult) => {
const resolvedResult = await subscriberResolver({ data, errors });
this._eventEmitter.emit(hash, resolvedResult);
});
}
const eventAsyncIterator = new EventAsyncIterator(this._eventEmitter, hash);
return eventAsyncIterator.getIterator();
} catch (error) {
return Promise.reject(error);
}
}
}
private _filterField(
field: FieldNode,
fieldPathChecklist: FieldPathChecklist,
ancestorRequestFieldPath: string,
context: RequestContext,
): boolean {
const fieldsAndTypeNames = getChildFields(field);
if (!fieldsAndTypeNames) return false;
for (let i = fieldsAndTypeNames.length - 1; i >= 0; i -= 1) {
const { fieldNode: childField, typeName: childTypeName } = fieldsAndTypeNames[i];
const childFieldName = getName(childField);
if (childFieldName === this._typeIDKey || childFieldName === TYPE_NAME_KEY) continue;
const { requestFieldPath } = CacheManager._getFieldKeysAndPaths(childField, {
requestFieldPath: ancestorRequestFieldPath,
});
const { hasData, typeUnused } = CacheManager._checkFieldPathChecklist(
fieldPathChecklist.get(requestFieldPath),
childTypeName,
);
private _filterQuery(
{ ast }: RequestData,
{ fieldPathChecklist }: CachedResponseData,
context: RequestContext,
): void {
const queryNode = getOperationDefinitions(ast, context.operation)[0];
const fieldsAndTypeNames = getChildFields(queryNode);
if (!fieldsAndTypeNames) return;
for (let i = fieldsAndTypeNames.length - 1; i >= 0; i -= 1) {
const { fieldNode } = fieldsAndTypeNames[i];
const { requestFieldPath } = CacheManager._getFieldKeysAndPaths(fieldNode, {
requestFieldPath: context.operation,
});
if (this._filterField(fieldNode, fieldPathChecklist, requestFieldPath, context)) {
deleteChildFields(queryNode, fieldNode);
}
}
context.queryFiltered = true;
}
private _addFieldToNode(node: FieldNode | InlineFragmentNode, key: string): void {
if (!hasChildFields(node, key)) {
const mockAST = parse(`{${key}}`);
const queryNode = getOperationDefinitions(mockAST, QUERY)[0];
const fieldsAndTypeNames = getChildFields(queryNode, key);
if (!fieldsAndTypeNames) return;
const { fieldNode } = fieldsAndTypeNames[0];
addChildField(node, fieldNode, this._schema, key);
}
}
private _filterIDsAndTypeNames(field: FieldNode): boolean {
const fieldsAndTypeNames = getChildFields(field);
if (!fieldsAndTypeNames || fieldsAndTypeNames.length > 3) return false;
const fieldNames = fieldsAndTypeNames.map(({ fieldNode }) => getName(fieldNode) as string);
if (fieldNames.length === 2 && fieldNames.every(name => name === this._typeIDKey || name === TYPE_NAME_KEY)) {
deleteChildFields(
field,
fieldsAndTypeNames.map(({ fieldNode }) => fieldNode),
);
return true;
}
if ((fieldNames.length === 1 && fieldNames[0] === this._typeIDKey) || fieldNames[0] === TYPE_NAME_KEY) {
const { fieldNode } = fieldsAndTypeNames[0];
deleteChildFields(field, fieldNode);
private async _setDataEntityAndRequestFieldPathCacheEntries(
requestData: RequestData,
responseData: ResponseDataForCaching,
options: RequestOptions,
context: RequestContext,
): Promise {
const operationNode = getOperationDefinitions(requestData.ast, context.operation)[0];
const fieldsAndTypeNames = getChildFields(operationNode);
if (!fieldsAndTypeNames) return;
await Promise.all(
fieldsAndTypeNames.map(({ fieldNode }) => {
return this._parseFieldDataEntityAndRequestFieldPathCacheEntryData(
fieldNode,
{ requestFieldPath: context.operation },
responseData,
options,
context,
);
}),
);
}
fieldPathChecklist.get(requestFieldPath),
childTypeName,
);
if (hasData || typeUnused) {
if (!hasChildFields(childField)) {
deleteChildFields(field, childField);
} else if (this._filterField(childField, fieldPathChecklist, requestFieldPath, context)) {
deleteChildFields(field, childField);
}
}
}
this._filterInlineFragments(field);
this._filterIDsAndTypeNames(field);
return !hasChildFields(field);
}
private _addFieldToNode(node: FieldNode | InlineFragmentNode, key: string): void {
if (!hasChildFields(node, key)) {
const mockAST = parse(`{${key}}`);
const queryNode = getOperationDefinitions(mockAST, QUERY)[0];
const fieldsAndTypeNames = getChildFields(queryNode, key);
if (!fieldsAndTypeNames) return;
const { fieldNode } = fieldsAndTypeNames[0];
addChildField(node, fieldNode, this._schema, key);
}
}