Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@envelop/core

Package Overview
Dependencies
Maintainers
1
Versions
1362
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@envelop/core - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5-alpha-89abc0f.0

plugins/use-context-per-subscription-event.d.ts

5

create.d.ts

@@ -1,7 +0,4 @@

import { GraphQLSchema } from 'graphql';
import { Envelop, Plugin } from '@envelop/types';
export declare function envelop(options: {
export declare function envelop({ plugins }: {
plugins: Plugin[];
extends?: Envelop[];
initialSchema?: GraphQLSchema;
}): Envelop;

667

index.cjs.js

@@ -8,9 +8,167 @@ 'use strict';

// In ES2015 (or a polyfilled) environment, this will be Symbol.iterator
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
var SYMBOL_ASYNC_ITERATOR = typeof Symbol === 'function' && Symbol.asyncIterator != null ? Symbol.asyncIterator : '@@asyncIterator'; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
/**
* Returns true if the provided object implements the AsyncIterator protocol via
* either implementing a `Symbol.asyncIterator` or `"@@asyncIterator"` method.
*/
// eslint-disable-next-line no-redeclare
function isAsyncIterable(maybeAsyncIterable) {
return typeof (maybeAsyncIterable === null || maybeAsyncIterable === void 0 ? void 0 : maybeAsyncIterable[SYMBOL_ASYNC_ITERATOR]) === 'function';
}
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Given an AsyncIterable and a callback function, return an AsyncIterator
* which produces values mapped via calling the callback function.
*/
function mapAsyncIterator(iterable, callback, rejectCallback) {
// $FlowFixMe[prop-missing]
var iteratorMethod = iterable[SYMBOL_ASYNC_ITERATOR];
var iterator = iteratorMethod.call(iterable);
var $return;
var abruptClose;
if (typeof iterator.return === 'function') {
$return = iterator.return;
abruptClose = function abruptClose(error) {
var rethrow = function rethrow() {
return Promise.reject(error);
};
return $return.call(iterator).then(rethrow, rethrow);
};
}
function mapResult(result) {
return result.done ? result : asyncMapValue(result.value, callback).then(iteratorResult, abruptClose);
}
var mapReject;
if (rejectCallback) {
// Capture rejectCallback to ensure it cannot be null.
var reject = rejectCallback;
mapReject = function mapReject(error) {
return asyncMapValue(error, reject).then(iteratorResult, abruptClose);
};
}
/* TODO: Flow doesn't support symbols as keys:
https://github.com/facebook/flow/issues/3258 */
return _defineProperty({
next: function next() {
return iterator.next().then(mapResult, mapReject);
},
return: function _return() {
return $return ? $return.call(iterator).then(mapResult, mapReject) : Promise.resolve({
value: undefined,
done: true
});
},
throw: function _throw(error) {
if (typeof iterator.throw === 'function') {
return iterator.throw(error).then(mapResult, mapReject);
}
return Promise.reject(error).catch(abruptClose);
}
}, SYMBOL_ASYNC_ITERATOR, function () {
return this;
});
}
function asyncMapValue(value, callback) {
return new Promise(function (resolve) {
return resolve(callback(value));
});
}
function iteratorResult(value) {
return {
value: value,
done: false
};
}
function getExecuteArgs(args) {
return args.length === 1
? args[0]
: {
schema: args[0],
document: args[1],
rootValue: args[2],
contextValue: args[3],
variableValues: args[4],
operationName: args[5],
fieldResolver: args[6],
typeResolver: args[7],
};
}
/**
* Utility function for making a execute function that handles polymorphic arguments.
*/
const makeExecute = (subscribeFn) => (...polyArgs) => subscribeFn(getExecuteArgs(polyArgs));
function getSubscribeArgs(args) {
return args.length === 1
? args[0]
: {
schema: args[0],
document: args[1],
rootValue: args[2],
contextValue: args[3],
variableValues: args[4],
operationName: args[5],
fieldResolver: args[6],
subscribeFieldResolver: args[7],
execute: args[8],
};
}
/**
* Utility function for making a subscribe function that handles polymorphic arguments.
*/
const makeSubscribe = (subscribeFn) => (...polyArgs) => subscribeFn(getSubscribeArgs(polyArgs));
/**
* This is a almost identical port from graphql-js subscribe.
* The only difference is that a custom `execute` function can be injected as an additional argument.
*/
const subscribe = makeSubscribe(async (args) => {
const { schema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver, execute = graphql.execute, } = args;
const resultOrStream = await graphql.createSourceEventStream(schema, document, rootValue, contextValue, variableValues !== null && variableValues !== void 0 ? variableValues : undefined, operationName, subscribeFieldResolver);
if (!isAsyncIterable(resultOrStream)) {
return resultOrStream;
}
// For each payload yielded from a subscription, map it over the normal
// GraphQL `execute` function, with `payload` as the rootValue.
// This implements the "MapSourceToResponseEvent" algorithm described in
// the GraphQL specification. The `execute` function provides the
// "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
// "ExecuteQuery" algorithm, for which `execute` is also used.
const mapSourceToResponse = async (payload) => execute({
schema,
document,
rootValue: payload,
contextValue,
variableValues,
operationName,
fieldResolver,
});
// Map every source value to a ExecutionResult value as described above.
return mapAsyncIterator(resultOrStream, mapSourceToResponse);
});
const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
function envelop(options) {
let schema = options.initialSchema;
function envelop({ plugins }) {
let schema = null;
let initDone = false;
const childPlugins = (options.extends || []).reduce((prev, child) => [...prev, ...child._plugins], []);
const plugins = [...childPlugins, ...options.plugins];
const replaceSchema = (newSchema, ignorePluginIndex = -1) => {

@@ -35,12 +193,28 @@ schema = newSchema;

plugin.onPluginInit({
plugins,
addPlugin: newPlugin => {
plugins.push(newPlugin);
},
setSchema: modifiedSchema => replaceSchema(modifiedSchema, i),
});
}
const customParse = (source, parseOptions) => {
let result = null;
let parseFn = graphql.parse;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onParse &&
plugin.onParse({
const onContextBuildingCbs = [];
const onExecuteCbs = [];
const onParseCbs = [];
const onSubscribeCbs = [];
const onValidateCbs = [];
for (const { onContextBuilding, onExecute, onParse, onSubscribe, onValidate } of plugins) {
onContextBuilding && onContextBuildingCbs.push(onContextBuilding);
onExecute && onExecuteCbs.push(onExecute);
onParse && onParseCbs.push(onParse);
onSubscribe && onSubscribeCbs.push(onSubscribe);
onValidate && onValidateCbs.push(onValidate);
}
const customParse = onParseCbs.length
? (source, parseOptions) => {
let result = null;
let parseFn = graphql.parse;
const afterCalls = [];
for (const onParse of onParseCbs) {
const afterFn = onParse({
params: { source, options: parseOptions },

@@ -55,33 +229,37 @@ parseFn,

});
afterFn && afterCalls.push(afterFn);
}
if (result === null) {
try {
result = parseFn(source, parseOptions);
afterFn && afterCalls.push(afterFn);
}
catch (e) {
result = e;
if (result === null) {
try {
result = parseFn(source, parseOptions);
}
catch (e) {
result = e;
}
}
for (const afterCb of afterCalls) {
afterCb({
replaceParseResult: newResult => {
result = newResult;
},
result,
});
}
if (result === null) {
throw new Error(`Failed to parse document.`);
}
if (result instanceof Error) {
throw result;
}
return result;
}
for (const afterCb of afterCalls) {
afterCb({
replaceParseResult: newResult => {
result = newResult;
},
result,
});
}
if (result instanceof Error) {
throw result;
}
return result;
};
const customValidate = (schema, documentAST, rules, typeInfo, validationOptions) => {
let actualRules = rules ? [...rules] : undefined;
let validateFn = graphql.validate;
let result = null;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onValidate &&
plugin.onValidate({
: graphql.parse;
const customValidate = onValidateCbs.length
? (schema, documentAST, rules, typeInfo, validationOptions) => {
let actualRules = rules ? [...rules] : undefined;
let validateFn = graphql.validate;
let result = null;
const afterCalls = [];
for (const onValidate of onValidateCbs) {
const afterFn = onValidate({
params: {

@@ -108,19 +286,20 @@ schema,

});
afterFn && afterCalls.push(afterFn);
afterFn && afterCalls.push(afterFn);
}
if (!result) {
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions);
}
const valid = result.length === 0;
for (const afterCb of afterCalls) {
afterCb({ valid, result });
}
return result;
}
if (result === null) {
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions);
}
const valid = result.length === 0;
for (const afterCb of afterCalls) {
afterCb({ valid, result });
}
return result;
};
const customContextFactory = async (initialContext) => {
let context = initialContext;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onContextBuilding &&
(await plugin.onContextBuilding({
: graphql.validate;
const customContextFactory = onContextBuildingCbs.length
? async (initialContext) => {
let context = initialContext;
const afterCalls = [];
for (const onContext of onContextBuildingCbs) {
const afterFn = await onContext({
context,

@@ -138,31 +317,20 @@ extendContext: extension => {

},
}));
afterFn && afterCalls.push(afterFn);
});
afterFn && afterCalls.push(afterFn);
}
for (const afterCb of afterCalls) {
afterCb({ context });
}
return context;
}
for (const afterCb of afterCalls) {
afterCb({ context });
}
return context;
};
const beforeExecuteCalls = plugins.filter(p => p.onExecute);
const beforeSubscribeCalls = plugins.filter(p => p.onSubscribe);
const customSubscribe = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
const args = argsOrSchema instanceof graphql.GraphQLSchema
? {
schema: argsOrSchema,
document,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
subscribeFieldResolver,
}
: argsOrSchema;
: (ctx) => ctx;
const customSubscribe = makeSubscribe(async (args) => {
var _a;
const onResolversHandlers = [];
let subscribeFn = graphql.subscribe;
let subscribeFn = subscribe;
const afterCalls = [];
const beforeExecuteSubscriptionHandlers = [];
let context = args.contextValue;
for (const plugin of beforeSubscribeCalls) {
const after = plugin.onSubscribe({
for (const onSubscribe of onSubscribeCbs) {
const after = onSubscribe({
subscribeFn,

@@ -192,2 +360,5 @@ setSubscribeFn: newSubscribeFn => {

}
if (after.onExecuteSubscriptionEvent) {
beforeExecuteSubscriptionHandlers.push(after.onExecuteSubscriptionEvent);
}
}

@@ -198,5 +369,67 @@ }

}
const subscribeExecute = beforeExecuteSubscriptionHandlers.length
? makeExecute(async (args) => {
const onResolversHandlers = [];
let executeFn = graphql.execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const onExecute of beforeExecuteSubscriptionHandlers) {
let stopCalled = false;
const after = onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
}
}
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
});
}
return result;
})
: ((_a = args.execute) !== null && _a !== void 0 ? _a : graphql.execute);
let result = await subscribeFn({
...args,
contextValue: context,
execute: subscribeExecute,
});

@@ -212,76 +445,66 @@ for (const afterCb of afterCalls) {

return result;
};
const customExecute = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => {
const args = argsOrSchema instanceof graphql.GraphQLSchema
? {
schema: argsOrSchema,
document,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver,
}
: argsOrSchema;
const onResolversHandlers = [];
let executeFn = graphql.execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const plugin of beforeExecuteCalls) {
let stopCalled = false;
const after = plugin.onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
});
const customExecute = (onExecuteCbs.length
? makeExecute(async (args) => {
const onResolversHandlers = [];
let executeFn = graphql.execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const onExecute of onExecuteCbs) {
let stopCalled = false;
const after = onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
}
}
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
}
return result;
};
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
});
}
return result;
})
: graphql.execute);
function prepareSchema() {
if (schema[trackedSchemaSymbol]) {
if (!schema || schema[trackedSchemaSymbol]) {
return;

@@ -419,4 +642,5 @@ }

};
return {
onContextBuilding() {
const result = {};
if (options.onContextBuildingMeasurement) {
result.onContextBuilding = () => {
const contextStartTime = process.hrtime();

@@ -426,4 +650,6 @@ return () => {

};
},
onParse({ params }) {
};
}
if (options.onParsingMeasurement) {
result.onParse = ({ params }) => {
const parseStartTime = process.hrtime();

@@ -433,4 +659,6 @@ return () => {

};
},
onValidate({ params }) {
};
}
if (options.onValidationMeasurement) {
result.onValidate = ({ params }) => {
const validateStartTime = process.hrtime();

@@ -440,32 +668,61 @@ return () => {

};
},
onExecute({ args }) {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
}
if (options.onExecutionMeasurement) {
if (options.onResolverMeasurement) {
result.onExecute = ({ args }) => {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
};
},
onSubscribe({ args }) {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
}
else {
result.onExecute = ({ args }) => {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
};
};
},
};
}
}
if (options.onSubscriptionMeasurement) {
if (options.onResolverMeasurement) {
result.onSubscribe = ({ args }) => {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement && options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
};
}
else {
result.onSubscribe = ({ args }) => {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
};
};
}
}
return result;
};

@@ -486,3 +743,3 @@

var _a;
if (((_a = result.errors) === null || _a === void 0 ? void 0 : _a.length) > 0) {
if ((_a = result.errors) === null || _a === void 0 ? void 0 : _a.length) {
errorHandler(result.errors);

@@ -514,11 +771,43 @@ }

const useCreateContextPerSubscriptionEvent = (createContext) => {
return {
onSubscribe({ args }) {
return {
onExecuteSubscriptionEvent({ executeFn, setExecuteFn }) {
const newExecute = async (..._executionArgs) => {
const executionArgs = getExecuteArgs(_executionArgs);
const context = await createContext({ args });
try {
return executeFn({
...executionArgs,
contextValue: context ? context.contextValue : executionArgs.contextValue,
});
}
finally {
if (context && context.onEnd) {
context.onEnd();
}
}
};
setExecuteFn(newExecute);
},
};
},
};
};
Object.keys(types).forEach(function (k) {
if (k !== 'default') Object.defineProperty(exports, k, {
enumerable: true,
get: function () {
return types[k];
}
});
if (k !== 'default') Object.defineProperty(exports, k, {
enumerable: true,
get: function () {
return types[k];
}
});
});
exports.envelop = envelop;
exports.getExecuteArgs = getExecuteArgs;
exports.getSubscribeArgs = getSubscribeArgs;
exports.makeExecute = makeExecute;
exports.makeSubscribe = makeSubscribe;
exports.useCreateContextPerSubscriptionEvent = useCreateContextPerSubscriptionEvent;
exports.useErrorHandler = useErrorHandler;

@@ -525,0 +814,0 @@ exports.useExtendContext = useExtendContext;

export * from '@envelop/types';
export * from './create';
export * from './util';
export * from './plugins/use-logger';

@@ -9,1 +10,2 @@ export * from './plugins/use-timing';

export * from './plugins/use-payload-formatter';
export * from './plugins/use-context-per-subscription-event';
export * from '@envelop/types';
import { specifiedRules, isIntrospectionType, isObjectType, defaultFieldResolver, parse, validate, GraphQLSchema, subscribe, execute, getOperationAST } from 'graphql';
import { createSourceEventStream, execute, parse, specifiedRules, validate, isIntrospectionType, isObjectType, defaultFieldResolver, getOperationAST } from 'graphql';
// In ES2015 (or a polyfilled) environment, this will be Symbol.iterator
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
var SYMBOL_ASYNC_ITERATOR = typeof Symbol === 'function' && Symbol.asyncIterator != null ? Symbol.asyncIterator : '@@asyncIterator'; // istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
/**
* Returns true if the provided object implements the AsyncIterator protocol via
* either implementing a `Symbol.asyncIterator` or `"@@asyncIterator"` method.
*/
// eslint-disable-next-line no-redeclare
function isAsyncIterable(maybeAsyncIterable) {
return typeof (maybeAsyncIterable === null || maybeAsyncIterable === void 0 ? void 0 : maybeAsyncIterable[SYMBOL_ASYNC_ITERATOR]) === 'function';
}
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Given an AsyncIterable and a callback function, return an AsyncIterator
* which produces values mapped via calling the callback function.
*/
function mapAsyncIterator(iterable, callback, rejectCallback) {
// $FlowFixMe[prop-missing]
var iteratorMethod = iterable[SYMBOL_ASYNC_ITERATOR];
var iterator = iteratorMethod.call(iterable);
var $return;
var abruptClose;
if (typeof iterator.return === 'function') {
$return = iterator.return;
abruptClose = function abruptClose(error) {
var rethrow = function rethrow() {
return Promise.reject(error);
};
return $return.call(iterator).then(rethrow, rethrow);
};
}
function mapResult(result) {
return result.done ? result : asyncMapValue(result.value, callback).then(iteratorResult, abruptClose);
}
var mapReject;
if (rejectCallback) {
// Capture rejectCallback to ensure it cannot be null.
var reject = rejectCallback;
mapReject = function mapReject(error) {
return asyncMapValue(error, reject).then(iteratorResult, abruptClose);
};
}
/* TODO: Flow doesn't support symbols as keys:
https://github.com/facebook/flow/issues/3258 */
return _defineProperty({
next: function next() {
return iterator.next().then(mapResult, mapReject);
},
return: function _return() {
return $return ? $return.call(iterator).then(mapResult, mapReject) : Promise.resolve({
value: undefined,
done: true
});
},
throw: function _throw(error) {
if (typeof iterator.throw === 'function') {
return iterator.throw(error).then(mapResult, mapReject);
}
return Promise.reject(error).catch(abruptClose);
}
}, SYMBOL_ASYNC_ITERATOR, function () {
return this;
});
}
function asyncMapValue(value, callback) {
return new Promise(function (resolve) {
return resolve(callback(value));
});
}
function iteratorResult(value) {
return {
value: value,
done: false
};
}
function getExecuteArgs(args) {
return args.length === 1
? args[0]
: {
schema: args[0],
document: args[1],
rootValue: args[2],
contextValue: args[3],
variableValues: args[4],
operationName: args[5],
fieldResolver: args[6],
typeResolver: args[7],
};
}
/**
* Utility function for making a execute function that handles polymorphic arguments.
*/
const makeExecute = (subscribeFn) => (...polyArgs) => subscribeFn(getExecuteArgs(polyArgs));
function getSubscribeArgs(args) {
return args.length === 1
? args[0]
: {
schema: args[0],
document: args[1],
rootValue: args[2],
contextValue: args[3],
variableValues: args[4],
operationName: args[5],
fieldResolver: args[6],
subscribeFieldResolver: args[7],
execute: args[8],
};
}
/**
* Utility function for making a subscribe function that handles polymorphic arguments.
*/
const makeSubscribe = (subscribeFn) => (...polyArgs) => subscribeFn(getSubscribeArgs(polyArgs));
/**
* This is a almost identical port from graphql-js subscribe.
* The only difference is that a custom `execute` function can be injected as an additional argument.
*/
const subscribe = makeSubscribe(async (args) => {
const { schema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver, execute: execute$1 = execute, } = args;
const resultOrStream = await createSourceEventStream(schema, document, rootValue, contextValue, variableValues !== null && variableValues !== void 0 ? variableValues : undefined, operationName, subscribeFieldResolver);
if (!isAsyncIterable(resultOrStream)) {
return resultOrStream;
}
// For each payload yielded from a subscription, map it over the normal
// GraphQL `execute` function, with `payload` as the rootValue.
// This implements the "MapSourceToResponseEvent" algorithm described in
// the GraphQL specification. The `execute` function provides the
// "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
// "ExecuteQuery" algorithm, for which `execute` is also used.
const mapSourceToResponse = async (payload) => execute$1({
schema,
document,
rootValue: payload,
contextValue,
variableValues,
operationName,
fieldResolver,
});
// Map every source value to a ExecutionResult value as described above.
return mapAsyncIterator(resultOrStream, mapSourceToResponse);
});
const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA');
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS');
function envelop(options) {
let schema = options.initialSchema;
function envelop({ plugins }) {
let schema = null;
let initDone = false;
const childPlugins = (options.extends || []).reduce((prev, child) => [...prev, ...child._plugins], []);
const plugins = [...childPlugins, ...options.plugins];
const replaceSchema = (newSchema, ignorePluginIndex = -1) => {

@@ -30,12 +188,28 @@ schema = newSchema;

plugin.onPluginInit({
plugins,
addPlugin: newPlugin => {
plugins.push(newPlugin);
},
setSchema: modifiedSchema => replaceSchema(modifiedSchema, i),
});
}
const customParse = (source, parseOptions) => {
let result = null;
let parseFn = parse;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onParse &&
plugin.onParse({
const onContextBuildingCbs = [];
const onExecuteCbs = [];
const onParseCbs = [];
const onSubscribeCbs = [];
const onValidateCbs = [];
for (const { onContextBuilding, onExecute, onParse, onSubscribe, onValidate } of plugins) {
onContextBuilding && onContextBuildingCbs.push(onContextBuilding);
onExecute && onExecuteCbs.push(onExecute);
onParse && onParseCbs.push(onParse);
onSubscribe && onSubscribeCbs.push(onSubscribe);
onValidate && onValidateCbs.push(onValidate);
}
const customParse = onParseCbs.length
? (source, parseOptions) => {
let result = null;
let parseFn = parse;
const afterCalls = [];
for (const onParse of onParseCbs) {
const afterFn = onParse({
params: { source, options: parseOptions },

@@ -50,33 +224,37 @@ parseFn,

});
afterFn && afterCalls.push(afterFn);
}
if (result === null) {
try {
result = parseFn(source, parseOptions);
afterFn && afterCalls.push(afterFn);
}
catch (e) {
result = e;
if (result === null) {
try {
result = parseFn(source, parseOptions);
}
catch (e) {
result = e;
}
}
for (const afterCb of afterCalls) {
afterCb({
replaceParseResult: newResult => {
result = newResult;
},
result,
});
}
if (result === null) {
throw new Error(`Failed to parse document.`);
}
if (result instanceof Error) {
throw result;
}
return result;
}
for (const afterCb of afterCalls) {
afterCb({
replaceParseResult: newResult => {
result = newResult;
},
result,
});
}
if (result instanceof Error) {
throw result;
}
return result;
};
const customValidate = (schema, documentAST, rules, typeInfo, validationOptions) => {
let actualRules = rules ? [...rules] : undefined;
let validateFn = validate;
let result = null;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onValidate &&
plugin.onValidate({
: parse;
const customValidate = onValidateCbs.length
? (schema, documentAST, rules, typeInfo, validationOptions) => {
let actualRules = rules ? [...rules] : undefined;
let validateFn = validate;
let result = null;
const afterCalls = [];
for (const onValidate of onValidateCbs) {
const afterFn = onValidate({
params: {

@@ -103,19 +281,20 @@ schema,

});
afterFn && afterCalls.push(afterFn);
afterFn && afterCalls.push(afterFn);
}
if (!result) {
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions);
}
const valid = result.length === 0;
for (const afterCb of afterCalls) {
afterCb({ valid, result });
}
return result;
}
if (result === null) {
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions);
}
const valid = result.length === 0;
for (const afterCb of afterCalls) {
afterCb({ valid, result });
}
return result;
};
const customContextFactory = async (initialContext) => {
let context = initialContext;
const afterCalls = [];
for (const plugin of plugins) {
const afterFn = plugin.onContextBuilding &&
(await plugin.onContextBuilding({
: validate;
const customContextFactory = onContextBuildingCbs.length
? async (initialContext) => {
let context = initialContext;
const afterCalls = [];
for (const onContext of onContextBuildingCbs) {
const afterFn = await onContext({
context,

@@ -133,31 +312,20 @@ extendContext: extension => {

},
}));
afterFn && afterCalls.push(afterFn);
});
afterFn && afterCalls.push(afterFn);
}
for (const afterCb of afterCalls) {
afterCb({ context });
}
return context;
}
for (const afterCb of afterCalls) {
afterCb({ context });
}
return context;
};
const beforeExecuteCalls = plugins.filter(p => p.onExecute);
const beforeSubscribeCalls = plugins.filter(p => p.onSubscribe);
const customSubscribe = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
const args = argsOrSchema instanceof GraphQLSchema
? {
schema: argsOrSchema,
document,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
subscribeFieldResolver,
}
: argsOrSchema;
: (ctx) => ctx;
const customSubscribe = makeSubscribe(async (args) => {
var _a;
const onResolversHandlers = [];
let subscribeFn = subscribe;
const afterCalls = [];
const beforeExecuteSubscriptionHandlers = [];
let context = args.contextValue;
for (const plugin of beforeSubscribeCalls) {
const after = plugin.onSubscribe({
for (const onSubscribe of onSubscribeCbs) {
const after = onSubscribe({
subscribeFn,

@@ -187,2 +355,5 @@ setSubscribeFn: newSubscribeFn => {

}
if (after.onExecuteSubscriptionEvent) {
beforeExecuteSubscriptionHandlers.push(after.onExecuteSubscriptionEvent);
}
}

@@ -193,5 +364,67 @@ }

}
const subscribeExecute = beforeExecuteSubscriptionHandlers.length
? makeExecute(async (args) => {
const onResolversHandlers = [];
let executeFn = execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const onExecute of beforeExecuteSubscriptionHandlers) {
let stopCalled = false;
const after = onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
}
}
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
});
}
return result;
})
: ((_a = args.execute) !== null && _a !== void 0 ? _a : execute);
let result = await subscribeFn({
...args,
contextValue: context,
execute: subscribeExecute,
});

@@ -207,76 +440,66 @@ for (const afterCb of afterCalls) {

return result;
};
const customExecute = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => {
const args = argsOrSchema instanceof GraphQLSchema
? {
schema: argsOrSchema,
document,
rootValue,
contextValue,
variableValues,
operationName,
fieldResolver,
typeResolver,
}
: argsOrSchema;
const onResolversHandlers = [];
let executeFn = execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const plugin of beforeExecuteCalls) {
let stopCalled = false;
const after = plugin.onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
});
const customExecute = (onExecuteCbs.length
? makeExecute(async (args) => {
const onResolversHandlers = [];
let executeFn = execute;
let result;
const afterCalls = [];
let context = args.contextValue;
for (const onExecute of onExecuteCbs) {
let stopCalled = false;
const after = onExecute({
executeFn,
setExecuteFn: newExecuteFn => {
executeFn = newExecuteFn;
},
setResultAndStopExecution: stopResult => {
stopCalled = true;
result = stopResult;
},
extendContext: extension => {
if (typeof extension === 'object') {
context = {
...(context || {}),
...extension,
};
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
else {
throw new Error(`Invalid context extension provided! Expected "object", got: "${JSON.stringify(extension)}" (${typeof extension})`);
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
},
args,
});
if (stopCalled) {
return result;
}
if (after) {
if (after.onExecuteDone) {
afterCalls.push(after.onExecuteDone);
}
if (after.onResolverCalled) {
onResolversHandlers.push(after.onResolverCalled);
}
}
}
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
if (onResolversHandlers.length) {
context[resolversHooksSymbol] = onResolversHandlers;
}
result = await executeFn({
...args,
contextValue: context,
});
}
return result;
};
for (const afterCb of afterCalls) {
afterCb({
result,
setResult: newResult => {
result = newResult;
},
});
}
return result;
})
: execute);
function prepareSchema() {
if (schema[trackedSchemaSymbol]) {
if (!schema || schema[trackedSchemaSymbol]) {
return;

@@ -414,4 +637,5 @@ }

};
return {
onContextBuilding() {
const result = {};
if (options.onContextBuildingMeasurement) {
result.onContextBuilding = () => {
const contextStartTime = process.hrtime();

@@ -421,4 +645,6 @@ return () => {

};
},
onParse({ params }) {
};
}
if (options.onParsingMeasurement) {
result.onParse = ({ params }) => {
const parseStartTime = process.hrtime();

@@ -428,4 +654,6 @@ return () => {

};
},
onValidate({ params }) {
};
}
if (options.onValidationMeasurement) {
result.onValidate = ({ params }) => {
const validateStartTime = process.hrtime();

@@ -435,32 +663,61 @@ return () => {

};
},
onExecute({ args }) {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
}
if (options.onExecutionMeasurement) {
if (options.onResolverMeasurement) {
result.onExecute = ({ args }) => {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
};
},
onSubscribe({ args }) {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
}
else {
result.onExecute = ({ args }) => {
const executeStartTime = process.hrtime();
return {
onExecuteDone: () => {
options.onExecutionMeasurement(args, deltaFrom(executeStartTime));
},
};
};
},
};
}
}
if (options.onSubscriptionMeasurement) {
if (options.onResolverMeasurement) {
result.onSubscribe = ({ args }) => {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
onResolverCalled: ({ info }) => {
const resolverStartTime = process.hrtime();
return () => {
options.onResolverMeasurement && options.onResolverMeasurement(info, deltaFrom(resolverStartTime));
};
},
};
};
}
else {
result.onSubscribe = ({ args }) => {
const subscribeStartTime = process.hrtime();
return {
onSubscribeResult: () => {
options.onSubscriptionMeasurement && options.onSubscriptionMeasurement(args, deltaFrom(subscribeStartTime));
},
};
};
}
}
return result;
};

@@ -481,3 +738,3 @@

var _a;
if (((_a = result.errors) === null || _a === void 0 ? void 0 : _a.length) > 0) {
if ((_a = result.errors) === null || _a === void 0 ? void 0 : _a.length) {
errorHandler(result.errors);

@@ -509,3 +766,30 @@ }

export { envelop, useErrorHandler, useExtendContext, useLogger, usePayloadFormatter, useSchema, useTiming };
const useCreateContextPerSubscriptionEvent = (createContext) => {
return {
onSubscribe({ args }) {
return {
onExecuteSubscriptionEvent({ executeFn, setExecuteFn }) {
const newExecute = async (..._executionArgs) => {
const executionArgs = getExecuteArgs(_executionArgs);
const context = await createContext({ args });
try {
return executeFn({
...executionArgs,
contextValue: context ? context.contextValue : executionArgs.contextValue,
});
}
finally {
if (context && context.onEnd) {
context.onEnd();
}
}
};
setExecuteFn(newExecute);
},
};
},
};
};
export { envelop, getExecuteArgs, getSubscribeArgs, makeExecute, makeSubscribe, useCreateContextPerSubscriptionEvent, useErrorHandler, useExtendContext, useLogger, usePayloadFormatter, useSchema, useTiming };
//# sourceMappingURL=index.esm.js.map
{
"name": "@envelop/core",
"version": "0.1.4",
"version": "0.1.5-alpha-89abc0f.0",
"sideEffects": false,

@@ -9,3 +9,3 @@ "peerDependencies": {

"dependencies": {
"@envelop/types": "0.1.4"
"@envelop/types": "0.1.5-alpha-89abc0f.0"
},

@@ -12,0 +12,0 @@ "repository": {

@@ -15,2 +15,2 @@ import { Plugin } from '@envelop/types';

};
export declare const useTiming: (rawOptions?: TimingPluginOptions) => Plugin;
export declare const useTiming: (rawOptions?: TimingPluginOptions | undefined) => Plugin;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc