@envelop/core
Advanced tools
Comparing version 0.0.1 to 0.0.2
import { GraphQLSchema } from 'graphql'; | ||
import { Envelop, Plugin } from '@envelop/types'; | ||
export declare function envelop(serverOptions: { | ||
export declare function envelop(options: { | ||
plugins: Plugin[]; | ||
extends?: Envelop[]; | ||
initialSchema?: GraphQLSchema; | ||
}): Envelop; |
129
index.cjs.js
@@ -10,9 +10,11 @@ 'use strict'; | ||
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS'); | ||
function envelop(serverOptions) { | ||
let schema = serverOptions.initialSchema; | ||
function envelop(options) { | ||
let schema = options.initialSchema; | ||
let initDone = false; | ||
const childPlugins = (options.extends || []).reduce((prev, child) => [...prev, ...child._plugins], []); | ||
const plugins = [...childPlugins, ...options.plugins]; | ||
const replaceSchema = (newSchema) => { | ||
schema = newSchema; | ||
if (initDone) { | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
plugin.onSchemaChange && plugin.onSchemaChange({ schema }); | ||
@@ -22,3 +24,3 @@ } | ||
}; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
plugin.onPluginInit && | ||
@@ -29,10 +31,10 @@ plugin.onPluginInit({ | ||
} | ||
const customParse = (source, options) => { | ||
const customParse = (source, parseOptions) => { | ||
let result = null; | ||
let parseFn = graphql.parse; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onParse && | ||
plugin.onParse({ | ||
params: { source, options }, | ||
params: { source, options: parseOptions }, | ||
parseFn, | ||
@@ -50,3 +52,3 @@ setParseFn: newFn => { | ||
try { | ||
result = parseFn(source, options); | ||
result = parseFn(source, parseOptions); | ||
} | ||
@@ -70,3 +72,3 @@ catch (e) { | ||
}; | ||
const customValidate = (schema, documentAST, rules, typeInfo, options) => { | ||
const customValidate = (schema, documentAST, rules, typeInfo, validationOptions) => { | ||
let actualRules = rules ? [...rules] : undefined; | ||
@@ -76,3 +78,3 @@ let validateFn = graphql.validate; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onValidate && | ||
@@ -85,3 +87,3 @@ plugin.onValidate({ | ||
typeInfo, | ||
options, | ||
options: validationOptions, | ||
}, | ||
@@ -105,3 +107,3 @@ validateFn, | ||
if (result === null) { | ||
result = validateFn(schema, documentAST, actualRules, typeInfo, options); | ||
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions); | ||
} | ||
@@ -117,3 +119,3 @@ const valid = result.length === 0; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onContextBuilding && | ||
@@ -141,3 +143,66 @@ (await plugin.onContextBuilding({ | ||
}; | ||
const beforeExecuteCalls = serverOptions.plugins.filter(p => p.onExecute); | ||
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; | ||
const onResolversHandlers = []; | ||
let subscribeFn = graphql.subscribe; | ||
const afterCalls = []; | ||
let context = args.contextValue; | ||
for (const plugin of beforeSubscribeCalls) { | ||
const after = plugin.onSubscribe({ | ||
subscribeFn, | ||
setSubscribeFn: newSubscribeFn => { | ||
subscribeFn = newSubscribeFn; | ||
}, | ||
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 (after) { | ||
if (after.onSubscribeResult) { | ||
afterCalls.push(after.onSubscribeResult); | ||
} | ||
if (after.onResolverCalled) { | ||
onResolversHandlers.push(after.onResolverCalled); | ||
} | ||
} | ||
} | ||
if (onResolversHandlers.length) { | ||
context[resolversHooksSymbol] = onResolversHandlers; | ||
} | ||
let result = await subscribeFn({ | ||
...args, | ||
contextValue: context, | ||
}); | ||
for (const afterCb of afterCalls) { | ||
afterCb({ | ||
result, | ||
setResult: newResult => { | ||
result = newResult; | ||
}, | ||
}); | ||
} | ||
return result; | ||
}; | ||
const customExecute = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => { | ||
@@ -247,3 +312,3 @@ const args = argsOrSchema instanceof graphql.GraphQLSchema | ||
initDone = true; | ||
return () => { | ||
const envelop = () => { | ||
prepareSchema(); | ||
@@ -255,5 +320,10 @@ return { | ||
execute: customExecute, | ||
schema, | ||
subscribe: customSubscribe, | ||
get schema() { | ||
return schema; | ||
}, | ||
}; | ||
}; | ||
envelop._plugins = plugins; | ||
return envelop; | ||
} | ||
@@ -278,2 +348,10 @@ | ||
}, | ||
onSubscribe({ args }) { | ||
options.logFn('subscribe-start', { args }); | ||
return { | ||
onSubscribeResult: ({ result }) => { | ||
options.logFn('subscribe-end', { args, result }); | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -286,4 +364,5 @@ }; | ||
onExecutionMeasurement: (args, timing) => console.log(`Operation execution "${args.operationName}" done in ${timing.ms}ms`), | ||
onSubscriptionMeasurement: (args, timing) => console.log(`Operation subsctiption "${args.operationName}" done in ${timing.ms}ms`), | ||
onParsingMeasurement: (source, timing) => console.log(`Parsing "${source}" done in ${timing.ms}ms`), | ||
onValidationMeasurement: (document, timing) => { var _a; return console.log(`Validation "${(_a = graphql.getOperationAST(document).name) === null || _a === void 0 ? void 0 : _a.value}" done in ${timing.ms}ms`); }, | ||
onValidationMeasurement: (document, timing) => { var _a, _b; return console.log(`Validation "${((_b = (_a = graphql.getOperationAST(document)) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.value) || '-'}" done in ${timing.ms}ms`); }, | ||
onResolverMeasurement: (info, timing) => console.log(`\tResolver of "${info.parentType.toString()}.${info.fieldName}" done in ${timing.ms}ms`), | ||
@@ -323,3 +402,3 @@ onContextBuildingMeasurement: (timing) => console.log(`Context building done in ${timing.ms}ms`), | ||
return () => { | ||
options.onValidationMeasurement(params[1], deltaFrom(validateStartTime)); | ||
options.onValidationMeasurement(params.documentAST, deltaFrom(validateStartTime)); | ||
}; | ||
@@ -341,2 +420,16 @@ }, | ||
}, | ||
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)); | ||
}; | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -343,0 +436,0 @@ }; |
131
index.esm.js
export * from '@envelop/types'; | ||
import { specifiedRules, isIntrospectionType, isObjectType, defaultFieldResolver, parse, validate, GraphQLSchema, execute, getOperationAST } from 'graphql'; | ||
import { specifiedRules, isIntrospectionType, isObjectType, defaultFieldResolver, parse, validate, GraphQLSchema, subscribe, execute, getOperationAST } from 'graphql'; | ||
const trackedSchemaSymbol = Symbol('TRACKED_SCHEMA'); | ||
const resolversHooksSymbol = Symbol('RESOLVERS_HOOKS'); | ||
function envelop(serverOptions) { | ||
let schema = serverOptions.initialSchema; | ||
function envelop(options) { | ||
let schema = options.initialSchema; | ||
let initDone = false; | ||
const childPlugins = (options.extends || []).reduce((prev, child) => [...prev, ...child._plugins], []); | ||
const plugins = [...childPlugins, ...options.plugins]; | ||
const replaceSchema = (newSchema) => { | ||
schema = newSchema; | ||
if (initDone) { | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
plugin.onSchemaChange && plugin.onSchemaChange({ schema }); | ||
@@ -17,3 +19,3 @@ } | ||
}; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
plugin.onPluginInit && | ||
@@ -24,10 +26,10 @@ plugin.onPluginInit({ | ||
} | ||
const customParse = (source, options) => { | ||
const customParse = (source, parseOptions) => { | ||
let result = null; | ||
let parseFn = parse; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onParse && | ||
plugin.onParse({ | ||
params: { source, options }, | ||
params: { source, options: parseOptions }, | ||
parseFn, | ||
@@ -45,3 +47,3 @@ setParseFn: newFn => { | ||
try { | ||
result = parseFn(source, options); | ||
result = parseFn(source, parseOptions); | ||
} | ||
@@ -65,3 +67,3 @@ catch (e) { | ||
}; | ||
const customValidate = (schema, documentAST, rules, typeInfo, options) => { | ||
const customValidate = (schema, documentAST, rules, typeInfo, validationOptions) => { | ||
let actualRules = rules ? [...rules] : undefined; | ||
@@ -71,3 +73,3 @@ let validateFn = validate; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onValidate && | ||
@@ -80,3 +82,3 @@ plugin.onValidate({ | ||
typeInfo, | ||
options, | ||
options: validationOptions, | ||
}, | ||
@@ -100,3 +102,3 @@ validateFn, | ||
if (result === null) { | ||
result = validateFn(schema, documentAST, actualRules, typeInfo, options); | ||
result = validateFn(schema, documentAST, actualRules, typeInfo, validationOptions); | ||
} | ||
@@ -112,3 +114,3 @@ const valid = result.length === 0; | ||
const afterCalls = []; | ||
for (const plugin of serverOptions.plugins) { | ||
for (const plugin of plugins) { | ||
const afterFn = plugin.onContextBuilding && | ||
@@ -136,3 +138,66 @@ (await plugin.onContextBuilding({ | ||
}; | ||
const beforeExecuteCalls = serverOptions.plugins.filter(p => p.onExecute); | ||
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; | ||
const onResolversHandlers = []; | ||
let subscribeFn = subscribe; | ||
const afterCalls = []; | ||
let context = args.contextValue; | ||
for (const plugin of beforeSubscribeCalls) { | ||
const after = plugin.onSubscribe({ | ||
subscribeFn, | ||
setSubscribeFn: newSubscribeFn => { | ||
subscribeFn = newSubscribeFn; | ||
}, | ||
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 (after) { | ||
if (after.onSubscribeResult) { | ||
afterCalls.push(after.onSubscribeResult); | ||
} | ||
if (after.onResolverCalled) { | ||
onResolversHandlers.push(after.onResolverCalled); | ||
} | ||
} | ||
} | ||
if (onResolversHandlers.length) { | ||
context[resolversHooksSymbol] = onResolversHandlers; | ||
} | ||
let result = await subscribeFn({ | ||
...args, | ||
contextValue: context, | ||
}); | ||
for (const afterCb of afterCalls) { | ||
afterCb({ | ||
result, | ||
setResult: newResult => { | ||
result = newResult; | ||
}, | ||
}); | ||
} | ||
return result; | ||
}; | ||
const customExecute = async (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => { | ||
@@ -242,3 +307,3 @@ const args = argsOrSchema instanceof GraphQLSchema | ||
initDone = true; | ||
return () => { | ||
const envelop = () => { | ||
prepareSchema(); | ||
@@ -250,5 +315,10 @@ return { | ||
execute: customExecute, | ||
schema, | ||
subscribe: customSubscribe, | ||
get schema() { | ||
return schema; | ||
}, | ||
}; | ||
}; | ||
envelop._plugins = plugins; | ||
return envelop; | ||
} | ||
@@ -273,2 +343,10 @@ | ||
}, | ||
onSubscribe({ args }) { | ||
options.logFn('subscribe-start', { args }); | ||
return { | ||
onSubscribeResult: ({ result }) => { | ||
options.logFn('subscribe-end', { args, result }); | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -281,4 +359,5 @@ }; | ||
onExecutionMeasurement: (args, timing) => console.log(`Operation execution "${args.operationName}" done in ${timing.ms}ms`), | ||
onSubscriptionMeasurement: (args, timing) => console.log(`Operation subsctiption "${args.operationName}" done in ${timing.ms}ms`), | ||
onParsingMeasurement: (source, timing) => console.log(`Parsing "${source}" done in ${timing.ms}ms`), | ||
onValidationMeasurement: (document, timing) => { var _a; return console.log(`Validation "${(_a = getOperationAST(document).name) === null || _a === void 0 ? void 0 : _a.value}" done in ${timing.ms}ms`); }, | ||
onValidationMeasurement: (document, timing) => { var _a, _b; return console.log(`Validation "${((_b = (_a = getOperationAST(document)) === null || _a === void 0 ? void 0 : _a.name) === null || _b === void 0 ? void 0 : _b.value) || '-'}" done in ${timing.ms}ms`); }, | ||
onResolverMeasurement: (info, timing) => console.log(`\tResolver of "${info.parentType.toString()}.${info.fieldName}" done in ${timing.ms}ms`), | ||
@@ -318,3 +397,3 @@ onContextBuildingMeasurement: (timing) => console.log(`Context building done in ${timing.ms}ms`), | ||
return () => { | ||
options.onValidationMeasurement(params[1], deltaFrom(validateStartTime)); | ||
options.onValidationMeasurement(params.documentAST, deltaFrom(validateStartTime)); | ||
}; | ||
@@ -336,2 +415,16 @@ }, | ||
}, | ||
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)); | ||
}; | ||
}, | ||
}; | ||
}, | ||
}; | ||
@@ -338,0 +431,0 @@ }; |
{ | ||
"name": "@envelop/core", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"sideEffects": false, | ||
"peerDependencies": { | ||
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0", | ||
"graphql-helix": "^1.2.0" | ||
"graphql": "^14.0.0 || ^15.0.0" | ||
}, | ||
"dependencies": { | ||
"@envelop/types": "0.0.1" | ||
"@envelop/types": "0.0.2" | ||
}, | ||
@@ -12,0 +11,0 @@ "author": "Dotan Simha <dotansimha@gmail.com>", |
import { Plugin } from '@envelop/types'; | ||
import { DocumentNode, ExecutionArgs, GraphQLResolveInfo, Source } from 'graphql'; | ||
import { DocumentNode, ExecutionArgs, GraphQLResolveInfo, Source, SubscriptionArgs } from 'graphql'; | ||
export declare type ResultTiming = { | ||
@@ -10,2 +10,3 @@ ms: number; | ||
onExecutionMeasurement?: (args: ExecutionArgs, timing: ResultTiming) => void; | ||
onSubscriptionMeasurement?: (args: SubscriptionArgs, timing: ResultTiming) => void; | ||
onParsingMeasurement?: (source: Source | string, timing: ResultTiming) => void; | ||
@@ -12,0 +13,0 @@ onValidationMeasurement?: (document: DocumentNode, timing: ResultTiming) => void; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
96098
2
902
+ Added@envelop/types@0.0.2(transitive)
- Removed@envelop/types@0.0.1(transitive)
- Removedgraphql-helix@1.13.0(transitive)
Updated@envelop/types@0.0.2