graphql-modules 3.0.0-alpha-20231106133212-0b04b56e → 3.0.0
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/README.md +4 -1
- package/application/apollo.d.ts +9 -17
- package/application/execution.d.ts +3 -3
- package/application/subscription.d.ts +3 -3
- package/application/types.d.ts +10 -3
- package/di/injector.d.ts +2 -2
- package/di/providers.d.ts +1 -1
- package/index.js +107 -39
- package/index.mjs +108 -40
- package/module/types.d.ts +0 -4
- package/package.json +3 -2
- package/shared/middleware.d.ts +1 -1
- package/shared/utils.d.ts +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
[](https://graphql.org/conf/2024/?utm_source=github&utm_medium=graphql_modules&utm_campaign=readme)
|
|
2
|
+
|
|
3
|
+
<!-- Uncomment when we remove GraphQL Conf banner -->
|
|
4
|
+
<!-- [](https://graphql-modules.com/) -->
|
|
2
5
|
|
|
3
6
|
[](https://www.npmjs.com/package/graphql-modules)
|
|
4
7
|

|
package/application/apollo.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { DocumentNode,
|
|
1
|
+
import { DocumentNode, GraphQLSchema } from 'graphql';
|
|
2
|
+
import { ExecutionContextBuilder } from './context';
|
|
2
3
|
import { Application } from './types';
|
|
3
4
|
export interface ApolloRequestContext {
|
|
4
5
|
document: DocumentNode;
|
|
@@ -11,20 +12,11 @@ export interface ApolloRequestContext {
|
|
|
11
12
|
} | null;
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
|
-
export
|
|
15
|
-
executor: ApolloExecutor;
|
|
16
|
-
}
|
|
17
|
-
export type ApolloExecutor = (requestContext: ApolloRequestContext) => Promise<ExecutionResult>;
|
|
18
|
-
export interface ApolloGatewayInterface {
|
|
19
|
-
onSchemaLoadOrUpdate(callback: (schemaContext: {
|
|
20
|
-
apiSchema: GraphQLSchema;
|
|
21
|
-
coreSupergraphSdl: string;
|
|
22
|
-
}) => void): () => void;
|
|
23
|
-
load(): Promise<ApolloGatewayLoadResult>;
|
|
24
|
-
stop(): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
export declare function apolloGatewayCreator({ schema, typeDefs, createExecution, }: {
|
|
27
|
-
schema: Application['schema'];
|
|
28
|
-
typeDefs: Application['typeDefs'];
|
|
15
|
+
export declare function apolloExecutorCreator({ createExecution, }: {
|
|
29
16
|
createExecution: Application['createExecution'];
|
|
30
|
-
}): Application['
|
|
17
|
+
}): Application['createApolloExecutor'];
|
|
18
|
+
export declare function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }: {
|
|
19
|
+
createSubscription: Application['createSubscription'];
|
|
20
|
+
contextBuilder: ExecutionContextBuilder;
|
|
21
|
+
schema: GraphQLSchema;
|
|
22
|
+
}): () => GraphQLSchema;
|
|
@@ -3,6 +3,6 @@ import { ExecutionContextBuilder } from './context';
|
|
|
3
3
|
export declare function executionCreator({ contextBuilder, }: {
|
|
4
4
|
contextBuilder: ExecutionContextBuilder;
|
|
5
5
|
}): (options?: {
|
|
6
|
-
execute?: typeof execute
|
|
7
|
-
controller?: import("./types").OperationController
|
|
8
|
-
}
|
|
6
|
+
execute?: typeof execute;
|
|
7
|
+
controller?: import("./types").OperationController;
|
|
8
|
+
}) => typeof execute;
|
|
@@ -3,6 +3,6 @@ import { ExecutionContextBuilder } from './context';
|
|
|
3
3
|
export declare function subscriptionCreator({ contextBuilder, }: {
|
|
4
4
|
contextBuilder: ExecutionContextBuilder;
|
|
5
5
|
}): (options?: {
|
|
6
|
-
subscribe?: typeof subscribe
|
|
7
|
-
controller?: import("./types").OperationController
|
|
8
|
-
}
|
|
6
|
+
subscribe?: typeof subscribe;
|
|
7
|
+
controller?: import("./types").OperationController;
|
|
8
|
+
}) => typeof subscribe;
|
package/application/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { execute, subscribe, DocumentNode, GraphQLSchema, ExecutionResult } from
|
|
|
2
2
|
import type { Provider, Injector } from '../di';
|
|
3
3
|
import type { Resolvers, Module, MockedModule } from '../module/types';
|
|
4
4
|
import type { MiddlewareMap } from '../shared/middleware';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ApolloRequestContext } from './apollo';
|
|
6
6
|
import type { Single } from '../shared/types';
|
|
7
7
|
import type { InternalAppContext } from './application';
|
|
8
8
|
type Execution = typeof execute;
|
|
@@ -56,9 +56,16 @@ export interface Application {
|
|
|
56
56
|
execute?: typeof execute;
|
|
57
57
|
controller?: OperationController;
|
|
58
58
|
}): Execution;
|
|
59
|
-
|
|
59
|
+
/**
|
|
60
|
+
* @deprecated Use `createApolloExecutor`, `createExecution` and `createSubscription` methods instead.
|
|
61
|
+
*/
|
|
62
|
+
createSchemaForApollo(): GraphQLSchema;
|
|
63
|
+
/**
|
|
64
|
+
* Experimental
|
|
65
|
+
*/
|
|
66
|
+
createApolloExecutor(options?: {
|
|
60
67
|
controller?: OperationController;
|
|
61
|
-
}):
|
|
68
|
+
}): ApolloExecutor;
|
|
62
69
|
/**
|
|
63
70
|
* @internal
|
|
64
71
|
*/
|
package/di/injector.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Type, InjectionToken, Provider } from './providers';
|
|
1
|
+
import { Type, InjectionToken, Provider, AbstractType } from './providers';
|
|
2
2
|
import { ResolvedProvider, GlobalProviderMap } from './resolution';
|
|
3
3
|
import { Key } from './registry';
|
|
4
4
|
import { ExecutionContext } from './decorators';
|
|
5
5
|
type ExecutionContextGetter = () => ExecutionContext | never;
|
|
6
6
|
export declare abstract class Injector {
|
|
7
|
-
abstract get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: any): T;
|
|
7
|
+
abstract get<T>(token: Type<T> | InjectionToken<T> | AbstractType<T>, notFoundValue?: any): T;
|
|
8
8
|
}
|
|
9
9
|
export declare class ReflectiveInjector implements Injector {
|
|
10
10
|
displayName: string;
|
package/di/providers.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface FactoryProvider<T> extends BaseProvider<T> {
|
|
|
24
24
|
deps?: any[];
|
|
25
25
|
}
|
|
26
26
|
export interface BaseProvider<T> extends ProviderOptions {
|
|
27
|
-
provide: Type<T> | InjectionToken<T>;
|
|
27
|
+
provide: Type<T> | InjectionToken<T> | AbstractType<T>;
|
|
28
28
|
}
|
|
29
29
|
export interface TypeProvider<T> extends Type<T> {
|
|
30
30
|
}
|
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
const schema = require('@graphql-tools/schema');
|
|
6
6
|
const graphql = require('graphql');
|
|
7
|
+
const wrap = require('@graphql-tools/wrap');
|
|
7
8
|
const ramda = require('ramda');
|
|
8
9
|
|
|
9
10
|
const ERROR_ORIGINAL_ERROR = 'diOriginalError';
|
|
@@ -731,9 +732,9 @@ function tapAsyncIterator(iterable, doneCallback) {
|
|
|
731
732
|
throw error;
|
|
732
733
|
}
|
|
733
734
|
},
|
|
734
|
-
async return() {
|
|
735
|
+
async return(value) {
|
|
735
736
|
try {
|
|
736
|
-
const result = await iterator.return();
|
|
737
|
+
const result = await iterator.return(value);
|
|
737
738
|
return mapResult(result);
|
|
738
739
|
}
|
|
739
740
|
catch (error) {
|
|
@@ -741,7 +742,7 @@ function tapAsyncIterator(iterable, doneCallback) {
|
|
|
741
742
|
throw error;
|
|
742
743
|
}
|
|
743
744
|
},
|
|
744
|
-
|
|
745
|
+
throw(error) {
|
|
745
746
|
doneCallback();
|
|
746
747
|
return iterator.throw(error);
|
|
747
748
|
},
|
|
@@ -768,6 +769,11 @@ function share(factory) {
|
|
|
768
769
|
return cached;
|
|
769
770
|
};
|
|
770
771
|
}
|
|
772
|
+
function uniqueId(isNotUsed) {
|
|
773
|
+
let id;
|
|
774
|
+
while (!isNotUsed((id = Math.random().toString(16).substr(2)))) { }
|
|
775
|
+
return id;
|
|
776
|
+
}
|
|
771
777
|
function isNotSchema(obj) {
|
|
772
778
|
return obj instanceof graphql.GraphQLSchema === false;
|
|
773
779
|
}
|
|
@@ -1050,33 +1056,78 @@ function subscriptionCreator({ contextBuilder, }) {
|
|
|
1050
1056
|
return createSubscription;
|
|
1051
1057
|
}
|
|
1052
1058
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1059
|
+
const CONTEXT_ID = Symbol.for('context-id');
|
|
1060
|
+
function apolloExecutorCreator({ createExecution, }) {
|
|
1061
|
+
return function createApolloExecutor(options) {
|
|
1055
1062
|
const executor = createExecution(options);
|
|
1056
|
-
return {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1063
|
+
return async function executorAdapter(requestContext) {
|
|
1064
|
+
return executor({
|
|
1065
|
+
schema: requestContext.schema,
|
|
1066
|
+
document: requestContext.document,
|
|
1067
|
+
operationName: requestContext.operationName,
|
|
1068
|
+
variableValues: requestContext.request.variables,
|
|
1069
|
+
contextValue: requestContext.context,
|
|
1070
|
+
});
|
|
1071
|
+
};
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
1075
|
+
const createApolloSchema = () => {
|
|
1076
|
+
const sessions = {};
|
|
1077
|
+
const subscription = createSubscription();
|
|
1078
|
+
function getSession(ctx) {
|
|
1079
|
+
if (!ctx[CONTEXT_ID]) {
|
|
1080
|
+
ctx[CONTEXT_ID] = uniqueId((id) => !sessions[id]);
|
|
1081
|
+
const { context, ɵdestroy: destroy } = contextBuilder(ctx);
|
|
1082
|
+
sessions[ctx[CONTEXT_ID]] = {
|
|
1083
|
+
count: 0,
|
|
1084
|
+
session: {
|
|
1085
|
+
context,
|
|
1086
|
+
destroy() {
|
|
1087
|
+
if (--sessions[ctx[CONTEXT_ID]].count === 0) {
|
|
1088
|
+
destroy();
|
|
1089
|
+
delete sessions[ctx[CONTEXT_ID]];
|
|
1090
|
+
delete ctx[CONTEXT_ID];
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1074
1093
|
},
|
|
1075
1094
|
};
|
|
1095
|
+
}
|
|
1096
|
+
sessions[ctx[CONTEXT_ID]].count++;
|
|
1097
|
+
return sessions[ctx[CONTEXT_ID]].session;
|
|
1098
|
+
}
|
|
1099
|
+
return wrap.wrapSchema({
|
|
1100
|
+
schema,
|
|
1101
|
+
batch: true,
|
|
1102
|
+
executor(input) {
|
|
1103
|
+
if (input.operationType === 'subscription') {
|
|
1104
|
+
return subscription({
|
|
1105
|
+
schema,
|
|
1106
|
+
document: input.document,
|
|
1107
|
+
variableValues: input.variables,
|
|
1108
|
+
contextValue: input.context,
|
|
1109
|
+
rootValue: input.rootValue,
|
|
1110
|
+
operationName: input.operationName,
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
// Create an execution context
|
|
1114
|
+
const { context, destroy } = getSession(input.context);
|
|
1115
|
+
// It's important to wrap the executeFn within a promise
|
|
1116
|
+
// so we can easily control the end of execution (with finally)
|
|
1117
|
+
return Promise.resolve()
|
|
1118
|
+
.then(() => graphql.execute({
|
|
1119
|
+
schema,
|
|
1120
|
+
document: input.document,
|
|
1121
|
+
contextValue: context,
|
|
1122
|
+
variableValues: input.variables,
|
|
1123
|
+
rootValue: input.rootValue,
|
|
1124
|
+
operationName: input.operationName,
|
|
1125
|
+
}))
|
|
1126
|
+
.finally(destroy);
|
|
1076
1127
|
},
|
|
1077
|
-
|
|
1078
|
-
};
|
|
1128
|
+
});
|
|
1079
1129
|
};
|
|
1130
|
+
return createApolloSchema;
|
|
1080
1131
|
}
|
|
1081
1132
|
|
|
1082
1133
|
function operationControllerCreator(options) {
|
|
@@ -1173,9 +1224,12 @@ function createApplication(applicationConfig) {
|
|
|
1173
1224
|
});
|
|
1174
1225
|
const createSubscription = subscriptionCreator({ contextBuilder });
|
|
1175
1226
|
const createExecution = executionCreator({ contextBuilder });
|
|
1176
|
-
const
|
|
1227
|
+
const createSchemaForApollo = apolloSchemaCreator({
|
|
1228
|
+
createSubscription,
|
|
1229
|
+
contextBuilder,
|
|
1177
1230
|
schema: schema$1,
|
|
1178
|
-
|
|
1231
|
+
});
|
|
1232
|
+
const createApolloExecutor = apolloExecutorCreator({
|
|
1179
1233
|
createExecution,
|
|
1180
1234
|
});
|
|
1181
1235
|
instantiateSingletonProviders({
|
|
@@ -1190,7 +1244,8 @@ function createApplication(applicationConfig) {
|
|
|
1190
1244
|
createOperationController,
|
|
1191
1245
|
createSubscription,
|
|
1192
1246
|
createExecution,
|
|
1193
|
-
|
|
1247
|
+
createSchemaForApollo,
|
|
1248
|
+
createApolloExecutor,
|
|
1194
1249
|
ɵfactory: applicationFactory,
|
|
1195
1250
|
ɵconfig: config,
|
|
1196
1251
|
};
|
|
@@ -1787,31 +1842,41 @@ function ensureDocumentNode(config, typeDefs) {
|
|
|
1787
1842
|
*/
|
|
1788
1843
|
const MODULE_ID = new InjectionToken('module-id');
|
|
1789
1844
|
|
|
1845
|
+
function lazy(getter) {
|
|
1846
|
+
let called = false;
|
|
1847
|
+
let computedValue;
|
|
1848
|
+
return {
|
|
1849
|
+
get value() {
|
|
1850
|
+
if (!called) {
|
|
1851
|
+
called = true;
|
|
1852
|
+
computedValue = getter();
|
|
1853
|
+
}
|
|
1854
|
+
return computedValue;
|
|
1855
|
+
},
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1790
1858
|
function moduleFactory(config) {
|
|
1791
1859
|
const typeDefs = createTypeDefs(config);
|
|
1792
1860
|
const metadata = metadataFactory(typeDefs, config);
|
|
1793
|
-
const providers = typeof config.providers === 'function'
|
|
1861
|
+
const providers = lazy(() => typeof config.providers === 'function'
|
|
1794
1862
|
? config.providers()
|
|
1795
|
-
: config.providers;
|
|
1863
|
+
: config.providers);
|
|
1796
1864
|
// Filter providers and keep them this way
|
|
1797
1865
|
// so we don't do this filtering multiple times.
|
|
1798
1866
|
// Providers don't change over time, so it's safe to do it.
|
|
1799
|
-
const operationProviders = ReflectiveInjector.resolve(onlyOperationProviders(providers));
|
|
1800
|
-
const singletonProviders = ReflectiveInjector.resolve(onlySingletonProviders(providers));
|
|
1867
|
+
const operationProviders = lazy(() => ReflectiveInjector.resolve(onlyOperationProviders(providers.value)));
|
|
1868
|
+
const singletonProviders = lazy(() => ReflectiveInjector.resolve(onlySingletonProviders(providers.value)));
|
|
1801
1869
|
const mod = {
|
|
1802
1870
|
id: config.id,
|
|
1803
1871
|
config,
|
|
1804
1872
|
metadata,
|
|
1805
1873
|
typeDefs,
|
|
1806
|
-
providers,
|
|
1807
|
-
operationProviders,
|
|
1808
|
-
singletonProviders,
|
|
1809
1874
|
// Factory is called once on application creation,
|
|
1810
1875
|
// before we even handle GraphQL Operation
|
|
1811
1876
|
factory(app) {
|
|
1812
1877
|
const resolvedModule = mod;
|
|
1813
|
-
resolvedModule.singletonProviders = singletonProviders;
|
|
1814
|
-
resolvedModule.operationProviders = operationProviders;
|
|
1878
|
+
resolvedModule.singletonProviders = singletonProviders.value;
|
|
1879
|
+
resolvedModule.operationProviders = operationProviders.value;
|
|
1815
1880
|
// Create a module-level Singleton injector
|
|
1816
1881
|
const injector = ReflectiveInjector.createFromResolved({
|
|
1817
1882
|
name: `Module "${config.id}" (Singleton Scope)`,
|
|
@@ -1898,8 +1963,11 @@ function mockApplication(app) {
|
|
|
1898
1963
|
createExecution(options) {
|
|
1899
1964
|
return sharedFactory().createExecution(options);
|
|
1900
1965
|
},
|
|
1901
|
-
|
|
1902
|
-
return sharedFactory().
|
|
1966
|
+
createSchemaForApollo() {
|
|
1967
|
+
return sharedFactory().createSchemaForApollo();
|
|
1968
|
+
},
|
|
1969
|
+
createApolloExecutor() {
|
|
1970
|
+
return sharedFactory().createApolloExecutor();
|
|
1903
1971
|
},
|
|
1904
1972
|
get ɵfactory() {
|
|
1905
1973
|
return sharedFactory().ɵfactory;
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { makeExecutableSchema } from '@graphql-tools/schema';
|
|
2
|
-
import { GraphQLSchema, execute as execute$1, subscribe,
|
|
2
|
+
import { GraphQLSchema, execute as execute$1, subscribe, visit, Kind, GraphQLScalarType, concatAST, defaultFieldResolver, parse } from 'graphql';
|
|
3
|
+
import { wrapSchema } from '@graphql-tools/wrap';
|
|
3
4
|
import { mergeDeepWith } from 'ramda';
|
|
4
5
|
|
|
5
6
|
const ERROR_ORIGINAL_ERROR = 'diOriginalError';
|
|
@@ -728,9 +729,9 @@ function tapAsyncIterator(iterable, doneCallback) {
|
|
|
728
729
|
throw error;
|
|
729
730
|
}
|
|
730
731
|
},
|
|
731
|
-
async return() {
|
|
732
|
+
async return(value) {
|
|
732
733
|
try {
|
|
733
|
-
const result = await iterator.return();
|
|
734
|
+
const result = await iterator.return(value);
|
|
734
735
|
return mapResult(result);
|
|
735
736
|
}
|
|
736
737
|
catch (error) {
|
|
@@ -738,7 +739,7 @@ function tapAsyncIterator(iterable, doneCallback) {
|
|
|
738
739
|
throw error;
|
|
739
740
|
}
|
|
740
741
|
},
|
|
741
|
-
|
|
742
|
+
throw(error) {
|
|
742
743
|
doneCallback();
|
|
743
744
|
return iterator.throw(error);
|
|
744
745
|
},
|
|
@@ -765,6 +766,11 @@ function share(factory) {
|
|
|
765
766
|
return cached;
|
|
766
767
|
};
|
|
767
768
|
}
|
|
769
|
+
function uniqueId(isNotUsed) {
|
|
770
|
+
let id;
|
|
771
|
+
while (!isNotUsed((id = Math.random().toString(16).substr(2)))) { }
|
|
772
|
+
return id;
|
|
773
|
+
}
|
|
768
774
|
function isNotSchema(obj) {
|
|
769
775
|
return obj instanceof GraphQLSchema === false;
|
|
770
776
|
}
|
|
@@ -1047,33 +1053,78 @@ function subscriptionCreator({ contextBuilder, }) {
|
|
|
1047
1053
|
return createSubscription;
|
|
1048
1054
|
}
|
|
1049
1055
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1056
|
+
const CONTEXT_ID = Symbol.for('context-id');
|
|
1057
|
+
function apolloExecutorCreator({ createExecution, }) {
|
|
1058
|
+
return function createApolloExecutor(options) {
|
|
1052
1059
|
const executor = createExecution(options);
|
|
1053
|
-
return {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1060
|
+
return async function executorAdapter(requestContext) {
|
|
1061
|
+
return executor({
|
|
1062
|
+
schema: requestContext.schema,
|
|
1063
|
+
document: requestContext.document,
|
|
1064
|
+
operationName: requestContext.operationName,
|
|
1065
|
+
variableValues: requestContext.request.variables,
|
|
1066
|
+
contextValue: requestContext.context,
|
|
1067
|
+
});
|
|
1068
|
+
};
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
1072
|
+
const createApolloSchema = () => {
|
|
1073
|
+
const sessions = {};
|
|
1074
|
+
const subscription = createSubscription();
|
|
1075
|
+
function getSession(ctx) {
|
|
1076
|
+
if (!ctx[CONTEXT_ID]) {
|
|
1077
|
+
ctx[CONTEXT_ID] = uniqueId((id) => !sessions[id]);
|
|
1078
|
+
const { context, ɵdestroy: destroy } = contextBuilder(ctx);
|
|
1079
|
+
sessions[ctx[CONTEXT_ID]] = {
|
|
1080
|
+
count: 0,
|
|
1081
|
+
session: {
|
|
1082
|
+
context,
|
|
1083
|
+
destroy() {
|
|
1084
|
+
if (--sessions[ctx[CONTEXT_ID]].count === 0) {
|
|
1085
|
+
destroy();
|
|
1086
|
+
delete sessions[ctx[CONTEXT_ID]];
|
|
1087
|
+
delete ctx[CONTEXT_ID];
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1071
1090
|
},
|
|
1072
1091
|
};
|
|
1092
|
+
}
|
|
1093
|
+
sessions[ctx[CONTEXT_ID]].count++;
|
|
1094
|
+
return sessions[ctx[CONTEXT_ID]].session;
|
|
1095
|
+
}
|
|
1096
|
+
return wrapSchema({
|
|
1097
|
+
schema,
|
|
1098
|
+
batch: true,
|
|
1099
|
+
executor(input) {
|
|
1100
|
+
if (input.operationType === 'subscription') {
|
|
1101
|
+
return subscription({
|
|
1102
|
+
schema,
|
|
1103
|
+
document: input.document,
|
|
1104
|
+
variableValues: input.variables,
|
|
1105
|
+
contextValue: input.context,
|
|
1106
|
+
rootValue: input.rootValue,
|
|
1107
|
+
operationName: input.operationName,
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
// Create an execution context
|
|
1111
|
+
const { context, destroy } = getSession(input.context);
|
|
1112
|
+
// It's important to wrap the executeFn within a promise
|
|
1113
|
+
// so we can easily control the end of execution (with finally)
|
|
1114
|
+
return Promise.resolve()
|
|
1115
|
+
.then(() => execute$1({
|
|
1116
|
+
schema,
|
|
1117
|
+
document: input.document,
|
|
1118
|
+
contextValue: context,
|
|
1119
|
+
variableValues: input.variables,
|
|
1120
|
+
rootValue: input.rootValue,
|
|
1121
|
+
operationName: input.operationName,
|
|
1122
|
+
}))
|
|
1123
|
+
.finally(destroy);
|
|
1073
1124
|
},
|
|
1074
|
-
|
|
1075
|
-
};
|
|
1125
|
+
});
|
|
1076
1126
|
};
|
|
1127
|
+
return createApolloSchema;
|
|
1077
1128
|
}
|
|
1078
1129
|
|
|
1079
1130
|
function operationControllerCreator(options) {
|
|
@@ -1170,9 +1221,12 @@ function createApplication(applicationConfig) {
|
|
|
1170
1221
|
});
|
|
1171
1222
|
const createSubscription = subscriptionCreator({ contextBuilder });
|
|
1172
1223
|
const createExecution = executionCreator({ contextBuilder });
|
|
1173
|
-
const
|
|
1224
|
+
const createSchemaForApollo = apolloSchemaCreator({
|
|
1225
|
+
createSubscription,
|
|
1226
|
+
contextBuilder,
|
|
1174
1227
|
schema,
|
|
1175
|
-
|
|
1228
|
+
});
|
|
1229
|
+
const createApolloExecutor = apolloExecutorCreator({
|
|
1176
1230
|
createExecution,
|
|
1177
1231
|
});
|
|
1178
1232
|
instantiateSingletonProviders({
|
|
@@ -1187,7 +1241,8 @@ function createApplication(applicationConfig) {
|
|
|
1187
1241
|
createOperationController,
|
|
1188
1242
|
createSubscription,
|
|
1189
1243
|
createExecution,
|
|
1190
|
-
|
|
1244
|
+
createSchemaForApollo,
|
|
1245
|
+
createApolloExecutor,
|
|
1191
1246
|
ɵfactory: applicationFactory,
|
|
1192
1247
|
ɵconfig: config,
|
|
1193
1248
|
};
|
|
@@ -1784,31 +1839,41 @@ function ensureDocumentNode(config, typeDefs) {
|
|
|
1784
1839
|
*/
|
|
1785
1840
|
const MODULE_ID = new InjectionToken('module-id');
|
|
1786
1841
|
|
|
1842
|
+
function lazy(getter) {
|
|
1843
|
+
let called = false;
|
|
1844
|
+
let computedValue;
|
|
1845
|
+
return {
|
|
1846
|
+
get value() {
|
|
1847
|
+
if (!called) {
|
|
1848
|
+
called = true;
|
|
1849
|
+
computedValue = getter();
|
|
1850
|
+
}
|
|
1851
|
+
return computedValue;
|
|
1852
|
+
},
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1787
1855
|
function moduleFactory(config) {
|
|
1788
1856
|
const typeDefs = createTypeDefs(config);
|
|
1789
1857
|
const metadata = metadataFactory(typeDefs, config);
|
|
1790
|
-
const providers = typeof config.providers === 'function'
|
|
1858
|
+
const providers = lazy(() => typeof config.providers === 'function'
|
|
1791
1859
|
? config.providers()
|
|
1792
|
-
: config.providers;
|
|
1860
|
+
: config.providers);
|
|
1793
1861
|
// Filter providers and keep them this way
|
|
1794
1862
|
// so we don't do this filtering multiple times.
|
|
1795
1863
|
// Providers don't change over time, so it's safe to do it.
|
|
1796
|
-
const operationProviders = ReflectiveInjector.resolve(onlyOperationProviders(providers));
|
|
1797
|
-
const singletonProviders = ReflectiveInjector.resolve(onlySingletonProviders(providers));
|
|
1864
|
+
const operationProviders = lazy(() => ReflectiveInjector.resolve(onlyOperationProviders(providers.value)));
|
|
1865
|
+
const singletonProviders = lazy(() => ReflectiveInjector.resolve(onlySingletonProviders(providers.value)));
|
|
1798
1866
|
const mod = {
|
|
1799
1867
|
id: config.id,
|
|
1800
1868
|
config,
|
|
1801
1869
|
metadata,
|
|
1802
1870
|
typeDefs,
|
|
1803
|
-
providers,
|
|
1804
|
-
operationProviders,
|
|
1805
|
-
singletonProviders,
|
|
1806
1871
|
// Factory is called once on application creation,
|
|
1807
1872
|
// before we even handle GraphQL Operation
|
|
1808
1873
|
factory(app) {
|
|
1809
1874
|
const resolvedModule = mod;
|
|
1810
|
-
resolvedModule.singletonProviders = singletonProviders;
|
|
1811
|
-
resolvedModule.operationProviders = operationProviders;
|
|
1875
|
+
resolvedModule.singletonProviders = singletonProviders.value;
|
|
1876
|
+
resolvedModule.operationProviders = operationProviders.value;
|
|
1812
1877
|
// Create a module-level Singleton injector
|
|
1813
1878
|
const injector = ReflectiveInjector.createFromResolved({
|
|
1814
1879
|
name: `Module "${config.id}" (Singleton Scope)`,
|
|
@@ -1895,8 +1960,11 @@ function mockApplication(app) {
|
|
|
1895
1960
|
createExecution(options) {
|
|
1896
1961
|
return sharedFactory().createExecution(options);
|
|
1897
1962
|
},
|
|
1898
|
-
|
|
1899
|
-
return sharedFactory().
|
|
1963
|
+
createSchemaForApollo() {
|
|
1964
|
+
return sharedFactory().createSchemaForApollo();
|
|
1965
|
+
},
|
|
1966
|
+
createApolloExecutor() {
|
|
1967
|
+
return sharedFactory().createApolloExecutor();
|
|
1900
1968
|
},
|
|
1901
1969
|
get ɵfactory() {
|
|
1902
1970
|
return sharedFactory().ɵfactory;
|
package/module/types.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { ID, Plural } from '../shared/types';
|
|
|
4
4
|
import { ModuleMetadata } from './metadata';
|
|
5
5
|
import { Provider } from '../di';
|
|
6
6
|
import { MiddlewareMap } from '../shared/middleware';
|
|
7
|
-
import { ResolvedProvider } from '../di/resolution';
|
|
8
7
|
export type TypeDefs = Plural<DocumentNode>;
|
|
9
8
|
export type Resolvers = Plural<Record<string, any>>;
|
|
10
9
|
/**
|
|
@@ -39,12 +38,9 @@ export interface ModuleConfig {
|
|
|
39
38
|
}
|
|
40
39
|
export interface Module {
|
|
41
40
|
id: ID;
|
|
42
|
-
providers?: Provider[];
|
|
43
41
|
typeDefs: DocumentNode[];
|
|
44
42
|
metadata: ModuleMetadata;
|
|
45
43
|
factory: ModuleFactory;
|
|
46
|
-
operationProviders: ResolvedProvider[];
|
|
47
|
-
singletonProviders: ResolvedProvider[];
|
|
48
44
|
config: ModuleConfig;
|
|
49
45
|
}
|
|
50
46
|
export interface MockedModule extends Module {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphql-modules",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Create reusable, maintainable, testable and extendable GraphQL modules",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@graphql-tools/schema": "^10.0.0",
|
|
11
|
+
"@graphql-tools/wrap": "^10.0.0",
|
|
11
12
|
"@graphql-typed-document-node/core": "^3.1.0",
|
|
12
|
-
"ramda": "^0.
|
|
13
|
+
"ramda": "^0.30.0"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"graphql",
|
package/shared/middleware.d.ts
CHANGED
|
@@ -16,6 +16,6 @@ export type MiddlewareMap = {
|
|
|
16
16
|
[field: string]: Middleware[];
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
|
-
export declare function createMiddleware(path: string[], middlewareMap?: MiddlewareMap): (context: MiddlewareContext, next: Next
|
|
19
|
+
export declare function createMiddleware(path: string[], middlewareMap?: MiddlewareMap): (context: MiddlewareContext, next: Next) => Promise<any>;
|
|
20
20
|
export declare function mergeMiddlewareMaps(app: MiddlewareMap, mod: MiddlewareMap): MiddlewareMap;
|
|
21
21
|
export declare function validateMiddlewareMap(middlewareMap: MiddlewareMap, metadata: ModuleMetadata): void;
|
package/shared/utils.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare function isNil<T>(val: T | null | undefined): val is null | undef
|
|
|
4
4
|
export declare function isObject(val: any): boolean;
|
|
5
5
|
export declare function isPrimitive(val: any): val is number | string | boolean | symbol | bigint;
|
|
6
6
|
export declare function isAsyncIterable(obj: any): obj is AsyncIterableIterator<any>;
|
|
7
|
-
export declare function tapAsyncIterator<T
|
|
7
|
+
export declare function tapAsyncIterator<T, TAsyncIterableIterator extends AsyncIterableIterator<T>>(iterable: TAsyncIterableIterator, doneCallback: () => void): TAsyncIterableIterator;
|
|
8
8
|
export declare function once(cb: () => void): () => void;
|
|
9
9
|
export declare function share<T, A>(factory: (arg?: A) => T): (arg?: A) => T;
|
|
10
10
|
export declare function uniqueId(isNotUsed: (id: string) => boolean): string;
|