graphql-modules 3.1.2-alpha-20260121024117-e03d9c26de1cfd3971986f82b995963e1cc77056 → 3.1.2-alpha-20260121024633-8af430e29a180a1d00c50c4bf74d342b3518267c
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/cjs/application/apollo.js +81 -0
- package/cjs/application/application.js +149 -0
- package/cjs/application/context.js +144 -0
- package/cjs/application/di.js +48 -0
- package/cjs/application/execution.js +42 -0
- package/cjs/application/operation-controller.js +16 -0
- package/cjs/application/subscription.js +54 -0
- package/cjs/application/tokens.js +20 -0
- package/cjs/application/types.js +0 -0
- package/cjs/di/decorators.js +78 -0
- package/cjs/di/errors.js +87 -0
- package/cjs/di/forward-ref.js +26 -0
- package/cjs/di/index.js +19 -0
- package/cjs/di/injector.js +173 -0
- package/cjs/di/metadata.js +22 -0
- package/cjs/di/providers.js +60 -0
- package/cjs/di/registry.js +44 -0
- package/cjs/di/resolution.js +166 -0
- package/cjs/di/utils.js +44 -0
- package/cjs/index.js +31 -0
- package/cjs/module/factory.js +71 -0
- package/cjs/module/metadata.js +110 -0
- package/cjs/module/module.js +27 -0
- package/cjs/module/resolvers.js +341 -0
- package/cjs/module/tokens.js +21 -0
- package/cjs/module/type-defs.js +24 -0
- package/cjs/module/types.js +0 -0
- package/cjs/package.json +1 -0
- package/cjs/shared/di.js +0 -0
- package/cjs/shared/errors.js +82 -0
- package/cjs/shared/gql.js +12 -0
- package/cjs/shared/middleware.js +109 -0
- package/cjs/shared/types.js +0 -0
- package/cjs/shared/utils.js +115 -0
- package/cjs/testing/di.js +9 -0
- package/cjs/testing/graphql.js +10 -0
- package/cjs/testing/index.js +17 -0
- package/cjs/testing/test-application.js +65 -0
- package/cjs/testing/test-injector.js +22 -0
- package/cjs/testing/test-module.js +270 -0
- package/esm/application/apollo.js +77 -0
- package/esm/application/application.js +146 -0
- package/esm/application/context.js +140 -0
- package/esm/application/di.js +42 -0
- package/esm/application/execution.js +39 -0
- package/esm/application/operation-controller.js +13 -0
- package/esm/application/subscription.js +51 -0
- package/esm/application/tokens.js +17 -0
- package/esm/application/types.js +0 -0
- package/esm/di/decorators.js +72 -0
- package/esm/di/errors.js +79 -0
- package/esm/di/forward-ref.js +22 -0
- package/esm/di/index.js +4 -0
- package/esm/di/injector.js +168 -0
- package/esm/di/metadata.js +17 -0
- package/esm/di/providers.js +50 -0
- package/esm/di/registry.js +40 -0
- package/esm/di/resolution.js +159 -0
- package/esm/di/utils.js +36 -0
- package/esm/index.js +16 -0
- package/esm/module/factory.js +68 -0
- package/esm/module/metadata.js +107 -0
- package/esm/module/module.js +24 -0
- package/esm/module/resolvers.js +337 -0
- package/esm/module/tokens.js +18 -0
- package/esm/module/type-defs.js +21 -0
- package/esm/module/types.js +0 -0
- package/esm/shared/di.js +0 -0
- package/esm/shared/errors.js +69 -0
- package/esm/shared/gql.js +9 -0
- package/esm/shared/middleware.js +103 -0
- package/esm/shared/types.js +0 -0
- package/esm/shared/utils.js +101 -0
- package/esm/testing/di.js +6 -0
- package/esm/testing/graphql.js +7 -0
- package/esm/testing/index.js +14 -0
- package/esm/testing/test-application.js +62 -0
- package/esm/testing/test-injector.js +18 -0
- package/esm/testing/test-module.js +266 -0
- package/package.json +30 -10
- package/typings/application/apollo.d.ts +22 -0
- package/typings/application/application.d.ts +32 -0
- package/typings/application/context.d.ts +24 -0
- package/typings/application/di.d.ts +22 -0
- package/typings/application/execution.d.ts +8 -0
- package/typings/application/operation-controller.d.ts +5 -0
- package/typings/application/subscription.d.ts +8 -0
- package/typings/application/tokens.d.ts +17 -0
- package/typings/application/types.d.ts +130 -0
- package/typings/di/decorators.d.ts +11 -0
- package/typings/di/errors.d.ts +16 -0
- package/typings/di/forward-ref.d.ts +7 -0
- package/typings/di/index.d.ts +5 -0
- package/typings/di/injector.d.ts +50 -0
- package/typings/di/metadata.d.ts +12 -0
- package/typings/di/providers.d.ts +44 -0
- package/typings/di/registry.d.ts +11 -0
- package/typings/di/resolution.d.ts +63 -0
- package/typings/di/utils.d.ts +8 -0
- package/typings/index.d.ts +13 -0
- package/typings/module/factory.d.ts +16 -0
- package/typings/module/metadata.d.ts +12 -0
- package/typings/module/module.d.ts +22 -0
- package/typings/module/resolvers.d.ts +13 -0
- package/typings/module/tokens.d.ts +18 -0
- package/typings/module/type-defs.d.ts +7 -0
- package/typings/module/types.d.ts +51 -0
- package/typings/shared/di.d.ts +3 -0
- package/typings/shared/errors.d.ts +36 -0
- package/typings/shared/gql.d.ts +2 -0
- package/typings/shared/middleware.d.ts +21 -0
- package/typings/shared/types.d.ts +22 -0
- package/typings/shared/utils.d.ts +12 -0
- package/typings/testing/di.d.ts +2 -0
- package/typings/testing/graphql.d.ts +14 -0
- package/typings/testing/index.d.ts +14 -0
- package/typings/testing/test-application.d.ts +2 -0
- package/typings/testing/test-injector.d.ts +4 -0
- package/typings/testing/test-module.d.ts +10 -0
- package/LICENSE.md +0 -21
- package/index.js +0 -2359
- package/index.mjs +0 -2344
- /package/{application/apollo.d.ts → typings/application/apollo.d.cts} +0 -0
- /package/{application/application.d.ts → typings/application/application.d.cts} +0 -0
- /package/{application/context.d.ts → typings/application/context.d.cts} +0 -0
- /package/{application/di.d.ts → typings/application/di.d.cts} +0 -0
- /package/{application/execution.d.ts → typings/application/execution.d.cts} +0 -0
- /package/{application/operation-controller.d.ts → typings/application/operation-controller.d.cts} +0 -0
- /package/{application/subscription.d.ts → typings/application/subscription.d.cts} +0 -0
- /package/{application/tokens.d.ts → typings/application/tokens.d.cts} +0 -0
- /package/{application/types.d.ts → typings/application/types.d.cts} +0 -0
- /package/{di/decorators.d.ts → typings/di/decorators.d.cts} +0 -0
- /package/{di/errors.d.ts → typings/di/errors.d.cts} +0 -0
- /package/{di/forward-ref.d.ts → typings/di/forward-ref.d.cts} +0 -0
- /package/{di/index.d.ts → typings/di/index.d.cts} +0 -0
- /package/{di/injector.d.ts → typings/di/injector.d.cts} +0 -0
- /package/{di/metadata.d.ts → typings/di/metadata.d.cts} +0 -0
- /package/{di/providers.d.ts → typings/di/providers.d.cts} +0 -0
- /package/{di/registry.d.ts → typings/di/registry.d.cts} +0 -0
- /package/{di/resolution.d.ts → typings/di/resolution.d.cts} +0 -0
- /package/{di/utils.d.ts → typings/di/utils.d.cts} +0 -0
- /package/{index.d.ts → typings/index.d.cts} +0 -0
- /package/{module/factory.d.ts → typings/module/factory.d.cts} +0 -0
- /package/{module/metadata.d.ts → typings/module/metadata.d.cts} +0 -0
- /package/{module/module.d.ts → typings/module/module.d.cts} +0 -0
- /package/{module/resolvers.d.ts → typings/module/resolvers.d.cts} +0 -0
- /package/{module/tokens.d.ts → typings/module/tokens.d.cts} +0 -0
- /package/{module/type-defs.d.ts → typings/module/type-defs.d.cts} +0 -0
- /package/{module/types.d.ts → typings/module/types.d.cts} +0 -0
- /package/{shared/di.d.ts → typings/shared/di.d.cts} +0 -0
- /package/{shared/errors.d.ts → typings/shared/errors.d.cts} +0 -0
- /package/{shared/gql.d.ts → typings/shared/gql.d.cts} +0 -0
- /package/{shared/middleware.d.ts → typings/shared/middleware.d.cts} +0 -0
- /package/{shared/types.d.ts → typings/shared/types.d.cts} +0 -0
- /package/{shared/utils.d.ts → typings/shared/utils.d.cts} +0 -0
- /package/{testing/di.d.ts → typings/testing/di.d.cts} +0 -0
- /package/{testing/graphql.d.ts → typings/testing/graphql.d.cts} +0 -0
- /package/{testing/index.d.ts → typings/testing/index.d.cts} +0 -0
- /package/{testing/test-application.d.ts → typings/testing/test-application.d.cts} +0 -0
- /package/{testing/test-injector.d.ts → typings/testing/test-injector.d.cts} +0 -0
- /package/{testing/test-module.d.ts → typings/testing/test-module.d.cts} +0 -0
package/index.js
DELETED
|
@@ -1,2359 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var schema = require('@graphql-tools/schema');
|
|
4
|
-
var graphql = require('graphql');
|
|
5
|
-
var async_context = require('#async-context');
|
|
6
|
-
var wrap = require('@graphql-tools/wrap');
|
|
7
|
-
var ramda = require('ramda');
|
|
8
|
-
|
|
9
|
-
const ERROR_ORIGINAL_ERROR = 'diOriginalError';
|
|
10
|
-
function getOriginalError(error) {
|
|
11
|
-
return error[ERROR_ORIGINAL_ERROR];
|
|
12
|
-
}
|
|
13
|
-
function wrappedError(message, originalError) {
|
|
14
|
-
const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
|
|
15
|
-
const error = Error(msg);
|
|
16
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
17
|
-
return error;
|
|
18
|
-
}
|
|
19
|
-
function stringify(token) {
|
|
20
|
-
if (typeof token === 'string') {
|
|
21
|
-
return token;
|
|
22
|
-
}
|
|
23
|
-
if (token == null) {
|
|
24
|
-
return '' + token;
|
|
25
|
-
}
|
|
26
|
-
if (token.name) {
|
|
27
|
-
return `${token.name}`;
|
|
28
|
-
}
|
|
29
|
-
const res = token.toString();
|
|
30
|
-
const newLineIndex = res.indexOf('\n');
|
|
31
|
-
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function invalidProviderError(provider) {
|
|
35
|
-
return Error(`Invalid provider - only instances of Provider and Type are allowed, got: ${provider}`);
|
|
36
|
-
}
|
|
37
|
-
function noInjectableError(type) {
|
|
38
|
-
return Error(`Missing @Injectable decorator for '${stringify(type)}'`);
|
|
39
|
-
}
|
|
40
|
-
function noAnnotationError(typeOrFunc, params) {
|
|
41
|
-
const signature = [];
|
|
42
|
-
for (let i = 0, len = params.length; i < len; i++) {
|
|
43
|
-
const parameter = params[i];
|
|
44
|
-
if (!parameter.type) {
|
|
45
|
-
signature.push('?');
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
signature.push(stringify(parameter.type));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return Error("Cannot resolve all parameters for '" +
|
|
52
|
-
stringify(typeOrFunc) +
|
|
53
|
-
"'(" +
|
|
54
|
-
signature.join(', ') +
|
|
55
|
-
'). ' +
|
|
56
|
-
"Make sure that all the parameters are decorated with Inject or have valid type annotations and that '" +
|
|
57
|
-
stringify(typeOrFunc) +
|
|
58
|
-
"' is decorated with Injectable.");
|
|
59
|
-
}
|
|
60
|
-
function cyclicDependencyError(injector, key) {
|
|
61
|
-
return injectionError(injector, key, function () {
|
|
62
|
-
return `Cannot instantiate cyclic dependency!${constructResolvingPath(this.keys)}`;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
function noProviderError(injector, key) {
|
|
66
|
-
return injectionError(injector, key, function () {
|
|
67
|
-
const first = stringify(this.keys[0].token);
|
|
68
|
-
return `No provider for ${first}!${constructResolvingPath(this.keys)}`;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
function instantiationError(injector, originalException, key) {
|
|
72
|
-
return injectionError(injector, key, function () {
|
|
73
|
-
const first = stringify(this.keys[0].token);
|
|
74
|
-
return `Error during instantiation of ${first}: ${getOriginalError(this).message}${constructResolvingPath(this.keys)}`;
|
|
75
|
-
}, originalException);
|
|
76
|
-
}
|
|
77
|
-
function injectionError(injector, key, constructResolvingMessage, originalError) {
|
|
78
|
-
const error = (originalError ? wrappedError('', originalError) : Error());
|
|
79
|
-
error.addKey = addKey;
|
|
80
|
-
error.keys = [key];
|
|
81
|
-
error.constructResolvingMessage =
|
|
82
|
-
function wrappedConstructResolvingMessage() {
|
|
83
|
-
return (constructResolvingMessage.call(this) + ` - in ${injector.displayName}`);
|
|
84
|
-
};
|
|
85
|
-
error.message = error.constructResolvingMessage();
|
|
86
|
-
error[ERROR_ORIGINAL_ERROR] = originalError;
|
|
87
|
-
return error;
|
|
88
|
-
}
|
|
89
|
-
function constructResolvingPath(keys) {
|
|
90
|
-
if (keys.length > 1) {
|
|
91
|
-
const reversed = findFirstClosedCycle(keys.slice().reverse());
|
|
92
|
-
const tokenStrs = reversed.map((k) => stringify(k.token));
|
|
93
|
-
return ' (' + tokenStrs.join(' -> ') + ')';
|
|
94
|
-
}
|
|
95
|
-
return '';
|
|
96
|
-
}
|
|
97
|
-
function findFirstClosedCycle(keys) {
|
|
98
|
-
const res = [];
|
|
99
|
-
for (let i = 0; i < keys.length; ++i) {
|
|
100
|
-
if (res.indexOf(keys[i]) > -1) {
|
|
101
|
-
res.push(keys[i]);
|
|
102
|
-
return res;
|
|
103
|
-
}
|
|
104
|
-
res.push(keys[i]);
|
|
105
|
-
}
|
|
106
|
-
return res;
|
|
107
|
-
}
|
|
108
|
-
function addKey(key) {
|
|
109
|
-
this.keys.push(key);
|
|
110
|
-
this.message = this.constructResolvingMessage();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const INJECTABLE = Symbol('di:injectable');
|
|
114
|
-
function readInjectableMetadata(type, throwOnMissing) {
|
|
115
|
-
const meta = type[INJECTABLE];
|
|
116
|
-
if (!meta && throwOnMissing) {
|
|
117
|
-
throw noInjectableError(type);
|
|
118
|
-
}
|
|
119
|
-
return meta;
|
|
120
|
-
}
|
|
121
|
-
function ensureInjectableMetadata(type) {
|
|
122
|
-
if (!readInjectableMetadata(type)) {
|
|
123
|
-
const meta = {
|
|
124
|
-
params: [],
|
|
125
|
-
};
|
|
126
|
-
type[INJECTABLE] = meta;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const Type = Function;
|
|
131
|
-
/// @ts-ignore
|
|
132
|
-
class InjectionToken {
|
|
133
|
-
constructor(_desc) {
|
|
134
|
-
this._desc = _desc;
|
|
135
|
-
}
|
|
136
|
-
toString() {
|
|
137
|
-
return `InjectionToken ${this._desc}`;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function isType(v) {
|
|
141
|
-
return typeof v === 'function' && v !== Object;
|
|
142
|
-
}
|
|
143
|
-
exports.Scope = void 0;
|
|
144
|
-
(function (Scope) {
|
|
145
|
-
Scope[Scope["Singleton"] = 0] = "Singleton";
|
|
146
|
-
Scope[Scope["Operation"] = 1] = "Operation";
|
|
147
|
-
})(exports.Scope || (exports.Scope = {}));
|
|
148
|
-
function onlySingletonProviders(providers = []) {
|
|
149
|
-
return providers.filter((provider) => {
|
|
150
|
-
if (isType(provider)) {
|
|
151
|
-
const { options } = readInjectableMetadata(provider, true);
|
|
152
|
-
return (options === null || options === void 0 ? void 0 : options.scope) !== exports.Scope.Operation;
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
return provider.scope !== exports.Scope.Operation;
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
function onlyOperationProviders(providers = []) {
|
|
160
|
-
return providers.filter((provider) => {
|
|
161
|
-
if (isType(provider)) {
|
|
162
|
-
const { options } = readInjectableMetadata(provider, true);
|
|
163
|
-
return (options === null || options === void 0 ? void 0 : options.scope) === exports.Scope.Operation;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
return provider.scope === exports.Scope.Operation;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
function isClassProvider(provider) {
|
|
171
|
-
return typeof provider.useClass !== 'undefined';
|
|
172
|
-
}
|
|
173
|
-
function isFactoryProvider(provider) {
|
|
174
|
-
return typeof provider.useFactory !== 'undefined';
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function ensureReflect() {
|
|
178
|
-
if (!(Reflect && Reflect.getOwnMetadata)) {
|
|
179
|
-
throw 'reflect-metadata shim is required when using class decorators';
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
function Injectable(options) {
|
|
183
|
-
return (target) => {
|
|
184
|
-
var _a;
|
|
185
|
-
ensureReflect();
|
|
186
|
-
const params = (Reflect.getMetadata('design:paramtypes', target) || []).map((param) => (isType(param) ? param : null));
|
|
187
|
-
const existingMeta = readInjectableMetadata(target);
|
|
188
|
-
const meta = {
|
|
189
|
-
params: ((_a = existingMeta === null || existingMeta === void 0 ? void 0 : existingMeta.params) === null || _a === void 0 ? void 0 : _a.length) > 0 && params.length === 0
|
|
190
|
-
? existingMeta === null || existingMeta === void 0 ? void 0 : existingMeta.params
|
|
191
|
-
: params.map((param, i) => {
|
|
192
|
-
var _a;
|
|
193
|
-
const existingParam = (_a = existingMeta === null || existingMeta === void 0 ? void 0 : existingMeta.params) === null || _a === void 0 ? void 0 : _a[i];
|
|
194
|
-
return {
|
|
195
|
-
type: (existingParam === null || existingParam === void 0 ? void 0 : existingParam.type) || param,
|
|
196
|
-
optional: typeof (existingParam === null || existingParam === void 0 ? void 0 : existingParam.optional) === 'boolean'
|
|
197
|
-
? existingParam.optional
|
|
198
|
-
: false,
|
|
199
|
-
};
|
|
200
|
-
}),
|
|
201
|
-
options: {
|
|
202
|
-
...((existingMeta === null || existingMeta === void 0 ? void 0 : existingMeta.options) || {}),
|
|
203
|
-
...(options || {}),
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
target[INJECTABLE] = meta;
|
|
207
|
-
return target;
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
function Optional() {
|
|
211
|
-
return (target, _, index) => {
|
|
212
|
-
ensureReflect();
|
|
213
|
-
ensureInjectableMetadata(target);
|
|
214
|
-
const meta = readInjectableMetadata(target);
|
|
215
|
-
meta.params[index] = {
|
|
216
|
-
...meta.params[index],
|
|
217
|
-
optional: true,
|
|
218
|
-
};
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
function Inject(type) {
|
|
222
|
-
return (target, _, index) => {
|
|
223
|
-
ensureReflect();
|
|
224
|
-
ensureInjectableMetadata(target);
|
|
225
|
-
const meta = readInjectableMetadata(target);
|
|
226
|
-
meta.params[index] = {
|
|
227
|
-
type,
|
|
228
|
-
optional: false,
|
|
229
|
-
};
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
function ExecutionContext() {
|
|
233
|
-
return (obj, propertyKey) => {
|
|
234
|
-
ensureReflect();
|
|
235
|
-
const target = obj.constructor;
|
|
236
|
-
ensureInjectableMetadata(target);
|
|
237
|
-
const meta = readInjectableMetadata(target);
|
|
238
|
-
if (!meta.options) {
|
|
239
|
-
meta.options = {};
|
|
240
|
-
}
|
|
241
|
-
if (!meta.options.executionContextIn) {
|
|
242
|
-
meta.options.executionContextIn = [];
|
|
243
|
-
}
|
|
244
|
-
meta.options.executionContextIn.push(propertyKey);
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const forwardRefSymbol = Symbol('__forward_ref__');
|
|
249
|
-
/**
|
|
250
|
-
* Useful in "circular dependencies of modules" situation
|
|
251
|
-
*/
|
|
252
|
-
function forwardRef(forwardRefFn) {
|
|
253
|
-
forwardRefFn[forwardRefSymbol] = forwardRef;
|
|
254
|
-
forwardRefFn.toString = function () {
|
|
255
|
-
return stringify(this());
|
|
256
|
-
};
|
|
257
|
-
return forwardRefFn;
|
|
258
|
-
}
|
|
259
|
-
function resolveForwardRef(type) {
|
|
260
|
-
if (typeof type === 'function' &&
|
|
261
|
-
type.hasOwnProperty(forwardRefSymbol) &&
|
|
262
|
-
type[forwardRefSymbol] === forwardRef) {
|
|
263
|
-
return type();
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
return type;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
class Key {
|
|
271
|
-
constructor(token, id) {
|
|
272
|
-
this.token = token;
|
|
273
|
-
this.id = id;
|
|
274
|
-
if (!token) {
|
|
275
|
-
throw new Error('Token must be defined!');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Returns a stringified token.
|
|
280
|
-
*/
|
|
281
|
-
get displayName() {
|
|
282
|
-
return stringify(this.token);
|
|
283
|
-
}
|
|
284
|
-
static get(token) {
|
|
285
|
-
return _globalKeyRegistry.get(resolveForwardRef(token));
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
class GlobalKeyRegistry {
|
|
289
|
-
constructor() {
|
|
290
|
-
this._allKeys = new Map();
|
|
291
|
-
}
|
|
292
|
-
get(token) {
|
|
293
|
-
if (token instanceof Key) {
|
|
294
|
-
return token;
|
|
295
|
-
}
|
|
296
|
-
if (this._allKeys.has(token)) {
|
|
297
|
-
return this._allKeys.get(token);
|
|
298
|
-
}
|
|
299
|
-
const newKey = new Key(token, _globalKeyRegistry.numberOfKeys);
|
|
300
|
-
this._allKeys.set(token, newKey);
|
|
301
|
-
return newKey;
|
|
302
|
-
}
|
|
303
|
-
get numberOfKeys() {
|
|
304
|
-
return this._allKeys.size;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
const _globalKeyRegistry = new GlobalKeyRegistry();
|
|
308
|
-
|
|
309
|
-
const _EMPTY_LIST = [];
|
|
310
|
-
class ResolvedProvider {
|
|
311
|
-
constructor(key, factory) {
|
|
312
|
-
this.key = key;
|
|
313
|
-
this.factory = factory;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
class ResolvedFactory {
|
|
317
|
-
constructor(
|
|
318
|
-
/**
|
|
319
|
-
* Factory function which can return an instance of an object represented by a key.
|
|
320
|
-
*/
|
|
321
|
-
factory,
|
|
322
|
-
/**
|
|
323
|
-
* Arguments (dependencies) to the `factory` function.
|
|
324
|
-
*/
|
|
325
|
-
dependencies,
|
|
326
|
-
/**
|
|
327
|
-
* Methods invoked within ExecutionContext.
|
|
328
|
-
*/
|
|
329
|
-
executionContextIn,
|
|
330
|
-
/**
|
|
331
|
-
* Has onDestroy hook
|
|
332
|
-
*/
|
|
333
|
-
hasOnDestroyHook,
|
|
334
|
-
/**
|
|
335
|
-
* Is Global
|
|
336
|
-
*/
|
|
337
|
-
isGlobal) {
|
|
338
|
-
this.factory = factory;
|
|
339
|
-
this.dependencies = dependencies;
|
|
340
|
-
this.executionContextIn = executionContextIn;
|
|
341
|
-
this.hasOnDestroyHook = hasOnDestroyHook;
|
|
342
|
-
this.isGlobal = isGlobal;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
class Dependency {
|
|
346
|
-
constructor(key, optional) {
|
|
347
|
-
this.key = key;
|
|
348
|
-
this.optional = optional;
|
|
349
|
-
}
|
|
350
|
-
static fromKey(key) {
|
|
351
|
-
return new Dependency(key, false);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
function resolveProviders(providers) {
|
|
355
|
-
const normalized = normalizeProviders(providers, []);
|
|
356
|
-
const resolved = normalized.map(resolveProvider);
|
|
357
|
-
const resolvedProviderMap = mergeResolvedProviders(resolved, new Map());
|
|
358
|
-
return Array.from(resolvedProviderMap.values());
|
|
359
|
-
}
|
|
360
|
-
function resolveProvider(provider) {
|
|
361
|
-
return new ResolvedProvider(Key.get(provider.provide), resolveFactory(provider));
|
|
362
|
-
}
|
|
363
|
-
function mergeResolvedProviders(providers, normalizedProvidersMap) {
|
|
364
|
-
for (let i = 0; i < providers.length; i++) {
|
|
365
|
-
const provider = providers[i];
|
|
366
|
-
normalizedProvidersMap.set(provider.key.id, provider);
|
|
367
|
-
}
|
|
368
|
-
return normalizedProvidersMap;
|
|
369
|
-
}
|
|
370
|
-
function normalizeProviders(providers, res) {
|
|
371
|
-
providers.forEach((token) => {
|
|
372
|
-
if (token instanceof Type) {
|
|
373
|
-
res.push({ provide: token, useClass: token });
|
|
374
|
-
}
|
|
375
|
-
else if (token &&
|
|
376
|
-
typeof token === 'object' &&
|
|
377
|
-
token.provide !== undefined) {
|
|
378
|
-
res.push(token);
|
|
379
|
-
}
|
|
380
|
-
else if (token instanceof Array) {
|
|
381
|
-
normalizeProviders(token, res);
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
throw invalidProviderError(token);
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
return res;
|
|
388
|
-
}
|
|
389
|
-
function resolveFactory(provider) {
|
|
390
|
-
let factoryFn;
|
|
391
|
-
let resolvedDeps = _EMPTY_LIST;
|
|
392
|
-
let executionContextIn = _EMPTY_LIST;
|
|
393
|
-
let hasOnDestroyHook = false;
|
|
394
|
-
let isGlobal;
|
|
395
|
-
if (isClassProvider(provider)) {
|
|
396
|
-
const useClass = resolveForwardRef(provider.useClass);
|
|
397
|
-
factoryFn = makeFactory(useClass);
|
|
398
|
-
resolvedDeps = dependenciesFor(useClass);
|
|
399
|
-
executionContextIn = executionContextInFor(useClass);
|
|
400
|
-
isGlobal = globalFor(useClass);
|
|
401
|
-
hasOnDestroyHook = typeof useClass.prototype.onDestroy === 'function';
|
|
402
|
-
}
|
|
403
|
-
else if (isFactoryProvider(provider)) {
|
|
404
|
-
factoryFn = provider.useFactory;
|
|
405
|
-
resolvedDeps = constructDependencies(provider.useFactory, provider.deps || []);
|
|
406
|
-
isGlobal = provider.global;
|
|
407
|
-
if (provider.executionContextIn) {
|
|
408
|
-
executionContextIn = provider.executionContextIn;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
factoryFn = () => provider.useValue;
|
|
413
|
-
resolvedDeps = _EMPTY_LIST;
|
|
414
|
-
isGlobal = provider.global;
|
|
415
|
-
}
|
|
416
|
-
return new ResolvedFactory(factoryFn, resolvedDeps, executionContextIn, hasOnDestroyHook, isGlobal !== null && isGlobal !== void 0 ? isGlobal : false);
|
|
417
|
-
}
|
|
418
|
-
function dependenciesFor(type) {
|
|
419
|
-
const { params } = readInjectableMetadata(type, true);
|
|
420
|
-
if (!params) {
|
|
421
|
-
return [];
|
|
422
|
-
}
|
|
423
|
-
if (params.some((p) => p.type == null)) {
|
|
424
|
-
throw noAnnotationError(type, params);
|
|
425
|
-
}
|
|
426
|
-
return params.map((p) => extractToken(p, params));
|
|
427
|
-
}
|
|
428
|
-
function executionContextInFor(type) {
|
|
429
|
-
const { options } = readInjectableMetadata(type, true);
|
|
430
|
-
if ((options === null || options === void 0 ? void 0 : options.executionContextIn) &&
|
|
431
|
-
options.executionContextIn !== _EMPTY_LIST) {
|
|
432
|
-
return options === null || options === void 0 ? void 0 : options.executionContextIn;
|
|
433
|
-
}
|
|
434
|
-
return [];
|
|
435
|
-
}
|
|
436
|
-
function globalFor(type) {
|
|
437
|
-
var _a;
|
|
438
|
-
const { options } = readInjectableMetadata(type);
|
|
439
|
-
return (_a = options === null || options === void 0 ? void 0 : options.global) !== null && _a !== void 0 ? _a : false;
|
|
440
|
-
}
|
|
441
|
-
function constructDependencies(typeOrFunc, dependencies) {
|
|
442
|
-
if (!dependencies) {
|
|
443
|
-
return dependenciesFor(typeOrFunc);
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
const params = dependencies.map((d) => ({ type: d, optional: false }));
|
|
447
|
-
return params.map((t) => extractToken(t, params));
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
function extractToken(param, params) {
|
|
451
|
-
const token = resolveForwardRef(param.type);
|
|
452
|
-
if (token) {
|
|
453
|
-
return createDependency(token, param.optional);
|
|
454
|
-
}
|
|
455
|
-
throw noAnnotationError(param.type, params);
|
|
456
|
-
}
|
|
457
|
-
function createDependency(token, optional) {
|
|
458
|
-
return new Dependency(Key.get(token), optional);
|
|
459
|
-
}
|
|
460
|
-
function makeFactory(t) {
|
|
461
|
-
return (...args) => new t(...args);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
const _THROW_IF_NOT_FOUND = new Object();
|
|
465
|
-
const UNDEFINED = new Object();
|
|
466
|
-
const NOT_FOUND = new Object();
|
|
467
|
-
function notInExecutionContext() {
|
|
468
|
-
throw new Error('Not in execution context');
|
|
469
|
-
}
|
|
470
|
-
// Publicly available Injector.
|
|
471
|
-
// We use ReflectiveInjector everywhere
|
|
472
|
-
// but we don't want to leak its API to everyone
|
|
473
|
-
class Injector {
|
|
474
|
-
}
|
|
475
|
-
class ReflectiveInjector {
|
|
476
|
-
constructor({ name, providers, parent, fallbackParent, globalProvidersMap = new Map(), }) {
|
|
477
|
-
this._constructionCounter = 0;
|
|
478
|
-
this._executionContextGetter = notInExecutionContext;
|
|
479
|
-
this.displayName = name;
|
|
480
|
-
this._parent = parent || null;
|
|
481
|
-
this._fallbackParent = fallbackParent || null;
|
|
482
|
-
this._providers = providers;
|
|
483
|
-
this._globalProvidersMap = globalProvidersMap;
|
|
484
|
-
const len = this._providers.length;
|
|
485
|
-
this._keyIds = new Array(len);
|
|
486
|
-
this._objs = new Array(len);
|
|
487
|
-
for (let i = 0; i < len; i++) {
|
|
488
|
-
this._keyIds[i] = this._providers[i].key.id;
|
|
489
|
-
this._objs[i] = UNDEFINED;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
static createFromResolved({ name, providers, parent, fallbackParent, globalProvidersMap, }) {
|
|
493
|
-
return new ReflectiveInjector({
|
|
494
|
-
name,
|
|
495
|
-
providers,
|
|
496
|
-
parent,
|
|
497
|
-
fallbackParent,
|
|
498
|
-
globalProvidersMap,
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
static resolve(providers) {
|
|
502
|
-
return resolveProviders(providers);
|
|
503
|
-
}
|
|
504
|
-
get parent() {
|
|
505
|
-
return this._parent;
|
|
506
|
-
}
|
|
507
|
-
get fallbackParent() {
|
|
508
|
-
return this._fallbackParent;
|
|
509
|
-
}
|
|
510
|
-
get(token, notFoundValue = _THROW_IF_NOT_FOUND) {
|
|
511
|
-
return this._getByKey(Key.get(token), notFoundValue);
|
|
512
|
-
}
|
|
513
|
-
setExecutionContextGetter(getter) {
|
|
514
|
-
this._executionContextGetter = getter;
|
|
515
|
-
}
|
|
516
|
-
_getByKey(key, notFoundValue) {
|
|
517
|
-
let inj = this;
|
|
518
|
-
function getObj() {
|
|
519
|
-
while (inj instanceof ReflectiveInjector) {
|
|
520
|
-
const inj_ = inj;
|
|
521
|
-
const obj = inj_._getObjByKeyId(key.id);
|
|
522
|
-
if (obj !== UNDEFINED) {
|
|
523
|
-
return obj;
|
|
524
|
-
}
|
|
525
|
-
inj = inj_._parent;
|
|
526
|
-
}
|
|
527
|
-
return NOT_FOUND;
|
|
528
|
-
}
|
|
529
|
-
const resolvedValue = getObj();
|
|
530
|
-
if (resolvedValue !== NOT_FOUND) {
|
|
531
|
-
return resolvedValue;
|
|
532
|
-
}
|
|
533
|
-
// search in fallback Injector
|
|
534
|
-
if (this._fallbackParent) {
|
|
535
|
-
inj = this._fallbackParent;
|
|
536
|
-
const resolvedFallbackValue = getObj();
|
|
537
|
-
if (resolvedFallbackValue !== NOT_FOUND) {
|
|
538
|
-
return resolvedFallbackValue;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
if (inj !== null) {
|
|
542
|
-
return inj.get(key.token, notFoundValue);
|
|
543
|
-
}
|
|
544
|
-
return this._throwOrNull(key, notFoundValue);
|
|
545
|
-
}
|
|
546
|
-
_isObjectDefinedByKeyId(keyId) {
|
|
547
|
-
for (let i = 0; i < this._keyIds.length; i++) {
|
|
548
|
-
if (this._keyIds[i] === keyId) {
|
|
549
|
-
return this._objs[i] !== UNDEFINED;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
return false;
|
|
553
|
-
}
|
|
554
|
-
_getObjByKeyId(keyId) {
|
|
555
|
-
var _a, _b;
|
|
556
|
-
if ((_a = this._globalProvidersMap) === null || _a === void 0 ? void 0 : _a.has(keyId)) {
|
|
557
|
-
return (_b = this._globalProvidersMap.get(keyId)) === null || _b === void 0 ? void 0 : _b._getObjByKeyId(keyId);
|
|
558
|
-
}
|
|
559
|
-
for (let i = 0; i < this._keyIds.length; i++) {
|
|
560
|
-
if (this._keyIds[i] === keyId) {
|
|
561
|
-
if (this._objs[i] === UNDEFINED) {
|
|
562
|
-
this._objs[i] = this._new(this._providers[i]);
|
|
563
|
-
}
|
|
564
|
-
return this._objs[i];
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return UNDEFINED;
|
|
568
|
-
}
|
|
569
|
-
_throwOrNull(key, notFoundValue) {
|
|
570
|
-
if (notFoundValue !== _THROW_IF_NOT_FOUND) {
|
|
571
|
-
return notFoundValue;
|
|
572
|
-
}
|
|
573
|
-
else {
|
|
574
|
-
throw noProviderError(this, key);
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
instantiateAll() {
|
|
578
|
-
this._providers.forEach((provider) => {
|
|
579
|
-
this._getByKey(provider.key, _THROW_IF_NOT_FOUND);
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
_instantiateProvider(provider) {
|
|
583
|
-
const factory = provider.factory.factory;
|
|
584
|
-
let deps;
|
|
585
|
-
try {
|
|
586
|
-
deps = provider.factory.dependencies.map((dep) => this._getByDependency(dep));
|
|
587
|
-
}
|
|
588
|
-
catch (e) {
|
|
589
|
-
if (e.addKey) {
|
|
590
|
-
e.addKey(provider.key);
|
|
591
|
-
}
|
|
592
|
-
throw e;
|
|
593
|
-
}
|
|
594
|
-
let obj;
|
|
595
|
-
try {
|
|
596
|
-
obj = factory(...deps);
|
|
597
|
-
// attach execution context getter
|
|
598
|
-
if (provider.factory.executionContextIn.length > 0) {
|
|
599
|
-
for (const prop of provider.factory.executionContextIn) {
|
|
600
|
-
Object.defineProperty(obj, prop, {
|
|
601
|
-
get: () => {
|
|
602
|
-
return this._executionContextGetter();
|
|
603
|
-
},
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
catch (e) {
|
|
609
|
-
throw instantiationError(this, e, provider.key);
|
|
610
|
-
}
|
|
611
|
-
return obj;
|
|
612
|
-
}
|
|
613
|
-
_getByDependency(dep) {
|
|
614
|
-
return this._getByKey(dep.key, dep.optional ? null : _THROW_IF_NOT_FOUND);
|
|
615
|
-
}
|
|
616
|
-
_new(provider) {
|
|
617
|
-
if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
|
|
618
|
-
throw cyclicDependencyError(this, provider.key);
|
|
619
|
-
}
|
|
620
|
-
return this._instantiateProvider(provider);
|
|
621
|
-
}
|
|
622
|
-
_getMaxNumberOfObjects() {
|
|
623
|
-
return this._objs.length;
|
|
624
|
-
}
|
|
625
|
-
toString() {
|
|
626
|
-
return this.displayName;
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
class ModuleNonUniqueIdError extends ExtendableBuiltin(Error) {
|
|
631
|
-
constructor(message, ...rest) {
|
|
632
|
-
super(composeMessage(message, ...rest));
|
|
633
|
-
this.name = this.constructor.name;
|
|
634
|
-
this.message = composeMessage(message, ...rest);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
class ModuleDuplicatedError extends ExtendableBuiltin(Error) {
|
|
638
|
-
constructor(message, ...rest) {
|
|
639
|
-
super(composeMessage(message, ...rest));
|
|
640
|
-
this.name = this.constructor.name;
|
|
641
|
-
this.message = composeMessage(message, ...rest);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
class ExtraResolverError extends ExtendableBuiltin(Error) {
|
|
645
|
-
constructor(message, ...rest) {
|
|
646
|
-
super(composeMessage(message, ...rest));
|
|
647
|
-
this.name = this.constructor.name;
|
|
648
|
-
this.message = composeMessage(message, ...rest);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
class ExtraMiddlewareError extends ExtendableBuiltin(Error) {
|
|
652
|
-
constructor(message, ...rest) {
|
|
653
|
-
super(composeMessage(message, ...rest));
|
|
654
|
-
this.name = this.constructor.name;
|
|
655
|
-
this.message = composeMessage(message, ...rest);
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
class ResolverDuplicatedError extends ExtendableBuiltin(Error) {
|
|
659
|
-
constructor(message, ...rest) {
|
|
660
|
-
super(composeMessage(message, ...rest));
|
|
661
|
-
this.name = this.constructor.name;
|
|
662
|
-
this.message = composeMessage(message, ...rest);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
class ResolverInvalidError extends ExtendableBuiltin(Error) {
|
|
666
|
-
constructor(message, ...rest) {
|
|
667
|
-
super(composeMessage(message, ...rest));
|
|
668
|
-
this.name = this.constructor.name;
|
|
669
|
-
this.message = composeMessage(message, ...rest);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
class NonDocumentNodeError extends ExtendableBuiltin(Error) {
|
|
673
|
-
constructor(message, ...rest) {
|
|
674
|
-
super(composeMessage(message, ...rest));
|
|
675
|
-
this.name = this.constructor.name;
|
|
676
|
-
this.message = composeMessage(message, ...rest);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
// helpers
|
|
680
|
-
function useLocation({ dirname, id }) {
|
|
681
|
-
return dirname
|
|
682
|
-
? `Module "${id}" located at ${dirname}`
|
|
683
|
-
: [
|
|
684
|
-
`Module "${id}"`,
|
|
685
|
-
`Hint: pass __dirname to "dirname" option of your modules to get more insightful errors`,
|
|
686
|
-
].join('\n');
|
|
687
|
-
}
|
|
688
|
-
function ExtendableBuiltin(cls) {
|
|
689
|
-
function ExtendableBuiltin() {
|
|
690
|
-
cls.apply(this, arguments);
|
|
691
|
-
}
|
|
692
|
-
ExtendableBuiltin.prototype = Object.create(cls.prototype);
|
|
693
|
-
Object.setPrototypeOf(ExtendableBuiltin, cls);
|
|
694
|
-
return ExtendableBuiltin;
|
|
695
|
-
}
|
|
696
|
-
function composeMessage(...lines) {
|
|
697
|
-
return lines.join('\n');
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
function flatten(arr) {
|
|
701
|
-
return Array.prototype.concat(...arr);
|
|
702
|
-
}
|
|
703
|
-
function isDefined(val) {
|
|
704
|
-
return !isNil(val);
|
|
705
|
-
}
|
|
706
|
-
function isNil(val) {
|
|
707
|
-
return val === null || typeof val === 'undefined';
|
|
708
|
-
}
|
|
709
|
-
function isPrimitive(val) {
|
|
710
|
-
return ['number', 'string', 'boolean', 'symbol', 'bigint'].includes(typeof val);
|
|
711
|
-
}
|
|
712
|
-
function isAsyncIterable(obj) {
|
|
713
|
-
return obj && typeof obj[Symbol.asyncIterator] === 'function';
|
|
714
|
-
}
|
|
715
|
-
function tapAsyncIterator(iterable, doneCallback) {
|
|
716
|
-
const iteratorMethod = iterable[Symbol.asyncIterator];
|
|
717
|
-
const iterator = iteratorMethod.call(iterable);
|
|
718
|
-
function mapResult(result) {
|
|
719
|
-
if (result.done) {
|
|
720
|
-
doneCallback();
|
|
721
|
-
}
|
|
722
|
-
return result;
|
|
723
|
-
}
|
|
724
|
-
return {
|
|
725
|
-
async next() {
|
|
726
|
-
try {
|
|
727
|
-
let result = await iterator.next();
|
|
728
|
-
return mapResult(result);
|
|
729
|
-
}
|
|
730
|
-
catch (error) {
|
|
731
|
-
doneCallback();
|
|
732
|
-
throw error;
|
|
733
|
-
}
|
|
734
|
-
},
|
|
735
|
-
async return(value) {
|
|
736
|
-
try {
|
|
737
|
-
const result = await iterator.return(value);
|
|
738
|
-
return mapResult(result);
|
|
739
|
-
}
|
|
740
|
-
catch (error) {
|
|
741
|
-
doneCallback();
|
|
742
|
-
throw error;
|
|
743
|
-
}
|
|
744
|
-
},
|
|
745
|
-
throw(error) {
|
|
746
|
-
doneCallback();
|
|
747
|
-
return iterator.throw(error);
|
|
748
|
-
},
|
|
749
|
-
[Symbol.asyncIterator]() {
|
|
750
|
-
return this;
|
|
751
|
-
},
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
|
-
function once(cb) {
|
|
755
|
-
let called = false;
|
|
756
|
-
return () => {
|
|
757
|
-
if (!called) {
|
|
758
|
-
called = true;
|
|
759
|
-
cb();
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
function share(factory) {
|
|
764
|
-
let cached = null;
|
|
765
|
-
return (arg) => {
|
|
766
|
-
if (!cached) {
|
|
767
|
-
cached = factory(arg);
|
|
768
|
-
}
|
|
769
|
-
return cached;
|
|
770
|
-
};
|
|
771
|
-
}
|
|
772
|
-
function uniqueId(isNotUsed) {
|
|
773
|
-
let id;
|
|
774
|
-
while (!isNotUsed((id = Math.random().toString(16).substr(2)))) { }
|
|
775
|
-
return id;
|
|
776
|
-
}
|
|
777
|
-
function isNotSchema(obj) {
|
|
778
|
-
return obj instanceof graphql.GraphQLSchema === false;
|
|
779
|
-
}
|
|
780
|
-
function merge(source, target) {
|
|
781
|
-
const result = {
|
|
782
|
-
...source,
|
|
783
|
-
...target,
|
|
784
|
-
};
|
|
785
|
-
function attachSymbols(obj) {
|
|
786
|
-
const symbols = Object.getOwnPropertySymbols(obj);
|
|
787
|
-
for (const symbol of symbols) {
|
|
788
|
-
result[symbol] = obj[symbol];
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
if (source) {
|
|
792
|
-
attachSymbols(source);
|
|
793
|
-
}
|
|
794
|
-
attachSymbols(target);
|
|
795
|
-
return result;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
function instantiateSingletonProviders({ appInjector, modulesMap, }) {
|
|
799
|
-
appInjector.instantiateAll();
|
|
800
|
-
modulesMap.forEach((mod) => {
|
|
801
|
-
mod.injector.instantiateAll();
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
function createGlobalProvidersMap({ modules, scope, }) {
|
|
805
|
-
const globalProvidersMap = {};
|
|
806
|
-
const propType = scope === exports.Scope.Singleton ? 'singletonProviders' : 'operationProviders';
|
|
807
|
-
modules.forEach((mod) => {
|
|
808
|
-
mod[propType].forEach((provider) => {
|
|
809
|
-
if (provider.factory.isGlobal) {
|
|
810
|
-
const key = provider.key.id;
|
|
811
|
-
if (globalProvidersMap[key]) {
|
|
812
|
-
throw duplicatedGlobalTokenError(provider, [
|
|
813
|
-
mod.id,
|
|
814
|
-
globalProvidersMap[key],
|
|
815
|
-
]);
|
|
816
|
-
}
|
|
817
|
-
globalProvidersMap[key] = mod.id;
|
|
818
|
-
}
|
|
819
|
-
});
|
|
820
|
-
});
|
|
821
|
-
return globalProvidersMap;
|
|
822
|
-
}
|
|
823
|
-
function attachGlobalProvidersMap({ injector, globalProvidersMap, moduleInjectorGetter, }) {
|
|
824
|
-
injector._globalProvidersMap = {
|
|
825
|
-
has(key) {
|
|
826
|
-
return typeof globalProvidersMap[key] === 'string';
|
|
827
|
-
},
|
|
828
|
-
get(key) {
|
|
829
|
-
return moduleInjectorGetter(globalProvidersMap[key]);
|
|
830
|
-
},
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
function duplicatedGlobalTokenError(provider, modules) {
|
|
834
|
-
return Error([
|
|
835
|
-
`Failed to define '${provider.key.displayName}' token as global.`,
|
|
836
|
-
`Token provided by two modules: '${modules.join("', '")}'`,
|
|
837
|
-
].join(' '));
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
/**
|
|
841
|
-
* @api
|
|
842
|
-
* `CONTEXT` is an InjectionToken representing the provided `GraphQLModules.GlobalContext`
|
|
843
|
-
*
|
|
844
|
-
* @example
|
|
845
|
-
*
|
|
846
|
-
* ```typescript
|
|
847
|
-
* import { CONTEXT, Inject, Injectable } from 'graphql-modules';
|
|
848
|
-
*
|
|
849
|
-
* (A)Injectable()
|
|
850
|
-
* export class Data {
|
|
851
|
-
* constructor((A)Inject(CONTEXT) private context: GraphQLModules.GlobalContext) {}
|
|
852
|
-
* }
|
|
853
|
-
* ```
|
|
854
|
-
*/
|
|
855
|
-
const CONTEXT = new InjectionToken('context');
|
|
856
|
-
|
|
857
|
-
function createContextBuilder({ appInjector, modulesMap, appLevelOperationProviders, singletonGlobalProvidersMap, operationGlobalProvidersMap, }) {
|
|
858
|
-
// This is very critical. It creates an execution context.
|
|
859
|
-
// It has to run on every operation.
|
|
860
|
-
const contextBuilder = (context) => {
|
|
861
|
-
// Cache for context per module
|
|
862
|
-
let contextCache = {};
|
|
863
|
-
// A list of providers with OnDestroy hooks
|
|
864
|
-
// It's a tuple because we want to know which Injector controls the provider
|
|
865
|
-
// and we want to know if the provider was even instantiated.
|
|
866
|
-
let providersToDestroy = [];
|
|
867
|
-
function registerProvidersToDestroy(injector) {
|
|
868
|
-
injector._providers.forEach((provider) => {
|
|
869
|
-
if (provider.factory.hasOnDestroyHook) {
|
|
870
|
-
// keep provider key's id (it doesn't change over time)
|
|
871
|
-
// and related injector
|
|
872
|
-
providersToDestroy.push([injector, provider.key.id]);
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
let appContext;
|
|
877
|
-
attachGlobalProvidersMap({
|
|
878
|
-
injector: appInjector,
|
|
879
|
-
globalProvidersMap: singletonGlobalProvidersMap,
|
|
880
|
-
moduleInjectorGetter(moduleId) {
|
|
881
|
-
return modulesMap.get(moduleId).injector;
|
|
882
|
-
},
|
|
883
|
-
});
|
|
884
|
-
appInjector.setExecutionContextGetter(function executionContextGetter() {
|
|
885
|
-
var _a;
|
|
886
|
-
return (((_a = async_context.getAsyncContext()) === null || _a === void 0 ? void 0 : _a.getApplicationContext()) || appContext);
|
|
887
|
-
});
|
|
888
|
-
function createModuleExecutionContextGetter(moduleId) {
|
|
889
|
-
return function moduleExecutionContextGetter() {
|
|
890
|
-
var _a;
|
|
891
|
-
return (((_a = async_context.getAsyncContext()) === null || _a === void 0 ? void 0 : _a.getModuleContext(moduleId)) ||
|
|
892
|
-
getModuleContext(moduleId, context));
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
modulesMap.forEach((mod, moduleId) => {
|
|
896
|
-
mod.injector.setExecutionContextGetter(createModuleExecutionContextGetter(moduleId));
|
|
897
|
-
});
|
|
898
|
-
// As the name of the Injector says, it's an Operation scoped Injector
|
|
899
|
-
// Application level
|
|
900
|
-
// Operation scoped - means it's created and destroyed on every GraphQL Operation
|
|
901
|
-
const operationAppInjector = ReflectiveInjector.createFromResolved({
|
|
902
|
-
name: 'App (Operation Scope)',
|
|
903
|
-
providers: appLevelOperationProviders.concat(ReflectiveInjector.resolve([
|
|
904
|
-
{
|
|
905
|
-
provide: CONTEXT,
|
|
906
|
-
useValue: context,
|
|
907
|
-
},
|
|
908
|
-
])),
|
|
909
|
-
parent: appInjector,
|
|
910
|
-
});
|
|
911
|
-
// Create a context for application-level ExecutionContext
|
|
912
|
-
appContext = merge(context, {
|
|
913
|
-
injector: operationAppInjector,
|
|
914
|
-
});
|
|
915
|
-
// Track Providers with OnDestroy hooks
|
|
916
|
-
registerProvidersToDestroy(operationAppInjector);
|
|
917
|
-
function getModuleContext(moduleId, ctx) {
|
|
918
|
-
var _a;
|
|
919
|
-
// Reuse a context or create if not available
|
|
920
|
-
if (!contextCache[moduleId]) {
|
|
921
|
-
// We're interested in operation-scoped providers only
|
|
922
|
-
const providers = (_a = modulesMap.get(moduleId)) === null || _a === void 0 ? void 0 : _a.operationProviders;
|
|
923
|
-
// Create module-level Operation-scoped Injector
|
|
924
|
-
const operationModuleInjector = ReflectiveInjector.createFromResolved({
|
|
925
|
-
name: `Module "${moduleId}" (Operation Scope)`,
|
|
926
|
-
providers: providers.concat(ReflectiveInjector.resolve([
|
|
927
|
-
{
|
|
928
|
-
provide: CONTEXT,
|
|
929
|
-
useFactory() {
|
|
930
|
-
return contextCache[moduleId];
|
|
931
|
-
},
|
|
932
|
-
},
|
|
933
|
-
])),
|
|
934
|
-
// This injector has a priority
|
|
935
|
-
parent: modulesMap.get(moduleId).injector,
|
|
936
|
-
// over this one
|
|
937
|
-
fallbackParent: operationAppInjector,
|
|
938
|
-
});
|
|
939
|
-
// Same as on application level, we need to collect providers with OnDestroy hooks
|
|
940
|
-
registerProvidersToDestroy(operationModuleInjector);
|
|
941
|
-
contextCache[moduleId] = merge(ctx, {
|
|
942
|
-
injector: operationModuleInjector,
|
|
943
|
-
moduleId,
|
|
944
|
-
});
|
|
945
|
-
}
|
|
946
|
-
return contextCache[moduleId];
|
|
947
|
-
}
|
|
948
|
-
const sharedContext = merge(
|
|
949
|
-
// We want to pass the received context
|
|
950
|
-
context || {}, {
|
|
951
|
-
// Here's something very crutial
|
|
952
|
-
// It's a function that is used in module's context creation
|
|
953
|
-
ɵgetModuleContext: getModuleContext,
|
|
954
|
-
});
|
|
955
|
-
attachGlobalProvidersMap({
|
|
956
|
-
injector: operationAppInjector,
|
|
957
|
-
globalProvidersMap: operationGlobalProvidersMap,
|
|
958
|
-
moduleInjectorGetter(moduleId) {
|
|
959
|
-
return getModuleContext(moduleId, sharedContext).injector;
|
|
960
|
-
},
|
|
961
|
-
});
|
|
962
|
-
const env = {
|
|
963
|
-
ɵdestroy: once(() => {
|
|
964
|
-
providersToDestroy.forEach(([injector, keyId]) => {
|
|
965
|
-
// If provider was instantiated
|
|
966
|
-
if (injector._isObjectDefinedByKeyId(keyId)) {
|
|
967
|
-
// call its OnDestroy hook
|
|
968
|
-
injector._getObjByKeyId(keyId).onDestroy();
|
|
969
|
-
}
|
|
970
|
-
});
|
|
971
|
-
contextCache = {};
|
|
972
|
-
}),
|
|
973
|
-
ɵinjector: operationAppInjector,
|
|
974
|
-
context: sharedContext,
|
|
975
|
-
};
|
|
976
|
-
return {
|
|
977
|
-
...env,
|
|
978
|
-
runWithContext(cb) {
|
|
979
|
-
return async_context.runWithAsyncContext({
|
|
980
|
-
getApplicationContext() {
|
|
981
|
-
return appContext;
|
|
982
|
-
},
|
|
983
|
-
getModuleContext(moduleId) {
|
|
984
|
-
return getModuleContext(moduleId, context);
|
|
985
|
-
},
|
|
986
|
-
}, cb, env);
|
|
987
|
-
},
|
|
988
|
-
};
|
|
989
|
-
};
|
|
990
|
-
return contextBuilder;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
function executionCreator({ contextBuilder, }) {
|
|
994
|
-
const createExecution = (options) => {
|
|
995
|
-
// Custom or original execute function
|
|
996
|
-
const executeFn = (options === null || options === void 0 ? void 0 : options.execute) || graphql.execute;
|
|
997
|
-
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, typeResolver) => {
|
|
998
|
-
function perform({ context, ɵdestroy: destroy, }) {
|
|
999
|
-
const executionArgs = isNotSchema(argsOrSchema)
|
|
1000
|
-
? {
|
|
1001
|
-
...argsOrSchema,
|
|
1002
|
-
contextValue: context,
|
|
1003
|
-
}
|
|
1004
|
-
: {
|
|
1005
|
-
schema: argsOrSchema,
|
|
1006
|
-
document: document,
|
|
1007
|
-
rootValue,
|
|
1008
|
-
contextValue: context,
|
|
1009
|
-
variableValues,
|
|
1010
|
-
operationName,
|
|
1011
|
-
fieldResolver,
|
|
1012
|
-
typeResolver,
|
|
1013
|
-
};
|
|
1014
|
-
// It's important to wrap the executeFn within a promise
|
|
1015
|
-
// so we can easily control the end of execution (with finally)
|
|
1016
|
-
return Promise.resolve()
|
|
1017
|
-
.then(() => executeFn(executionArgs))
|
|
1018
|
-
.finally(destroy);
|
|
1019
|
-
}
|
|
1020
|
-
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1021
|
-
return perform(options.controller);
|
|
1022
|
-
}
|
|
1023
|
-
return contextBuilder(isNotSchema(argsOrSchema)
|
|
1024
|
-
? argsOrSchema.contextValue
|
|
1025
|
-
: contextValue).runWithContext(perform);
|
|
1026
|
-
};
|
|
1027
|
-
};
|
|
1028
|
-
return createExecution;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
function subscriptionCreator({ contextBuilder, }) {
|
|
1032
|
-
const createSubscription = (options) => {
|
|
1033
|
-
// Custom or original subscribe function
|
|
1034
|
-
const subscribeFn = (options === null || options === void 0 ? void 0 : options.subscribe) || graphql.subscribe;
|
|
1035
|
-
return (argsOrSchema, document, rootValue, contextValue, variableValues, operationName, fieldResolver, subscribeFieldResolver) => {
|
|
1036
|
-
function perform({ context, ɵdestroy: destroy, }) {
|
|
1037
|
-
const subscriptionArgs = isNotSchema(argsOrSchema)
|
|
1038
|
-
? {
|
|
1039
|
-
...argsOrSchema,
|
|
1040
|
-
contextValue: context,
|
|
1041
|
-
}
|
|
1042
|
-
: {
|
|
1043
|
-
schema: argsOrSchema,
|
|
1044
|
-
document: document,
|
|
1045
|
-
rootValue,
|
|
1046
|
-
contextValue: context,
|
|
1047
|
-
variableValues,
|
|
1048
|
-
operationName,
|
|
1049
|
-
fieldResolver,
|
|
1050
|
-
subscribeFieldResolver,
|
|
1051
|
-
};
|
|
1052
|
-
let isIterable = false;
|
|
1053
|
-
// It's important to wrap the subscribeFn within a promise
|
|
1054
|
-
// so we can easily control the end of subscription (with finally)
|
|
1055
|
-
return Promise.resolve()
|
|
1056
|
-
.then(() => subscribeFn(subscriptionArgs))
|
|
1057
|
-
.then((sub) => {
|
|
1058
|
-
if (isAsyncIterable(sub)) {
|
|
1059
|
-
isIterable = true;
|
|
1060
|
-
return tapAsyncIterator(sub, destroy);
|
|
1061
|
-
}
|
|
1062
|
-
return sub;
|
|
1063
|
-
})
|
|
1064
|
-
.finally(() => {
|
|
1065
|
-
if (!isIterable) {
|
|
1066
|
-
destroy();
|
|
1067
|
-
}
|
|
1068
|
-
});
|
|
1069
|
-
}
|
|
1070
|
-
if (options === null || options === void 0 ? void 0 : options.controller) {
|
|
1071
|
-
return perform(options.controller);
|
|
1072
|
-
}
|
|
1073
|
-
return contextBuilder(isNotSchema(argsOrSchema)
|
|
1074
|
-
? argsOrSchema.contextValue
|
|
1075
|
-
: contextValue).runWithContext(perform);
|
|
1076
|
-
};
|
|
1077
|
-
};
|
|
1078
|
-
return createSubscription;
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
const CONTEXT_ID = Symbol.for('context-id');
|
|
1082
|
-
function apolloExecutorCreator({ createExecution, }) {
|
|
1083
|
-
return function createApolloExecutor(options) {
|
|
1084
|
-
const executor = createExecution(options);
|
|
1085
|
-
return async function executorAdapter(requestContext) {
|
|
1086
|
-
return executor({
|
|
1087
|
-
schema: requestContext.schema,
|
|
1088
|
-
document: requestContext.document,
|
|
1089
|
-
operationName: requestContext.operationName,
|
|
1090
|
-
variableValues: requestContext.request.variables,
|
|
1091
|
-
contextValue: requestContext.context,
|
|
1092
|
-
});
|
|
1093
|
-
};
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
|
-
function apolloSchemaCreator({ createSubscription, contextBuilder, schema, }) {
|
|
1097
|
-
const createApolloSchema = () => {
|
|
1098
|
-
const sessions = {};
|
|
1099
|
-
const subscription = createSubscription();
|
|
1100
|
-
function getSession(ctx, { context, ɵdestroy: destroy }) {
|
|
1101
|
-
if (!ctx[CONTEXT_ID]) {
|
|
1102
|
-
ctx[CONTEXT_ID] = uniqueId((id) => !sessions[id]);
|
|
1103
|
-
sessions[ctx[CONTEXT_ID]] = {
|
|
1104
|
-
count: 0,
|
|
1105
|
-
session: {
|
|
1106
|
-
context,
|
|
1107
|
-
destroy() {
|
|
1108
|
-
if (--sessions[ctx[CONTEXT_ID]].count === 0) {
|
|
1109
|
-
destroy();
|
|
1110
|
-
delete sessions[ctx[CONTEXT_ID]];
|
|
1111
|
-
delete ctx[CONTEXT_ID];
|
|
1112
|
-
}
|
|
1113
|
-
},
|
|
1114
|
-
},
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
|
-
sessions[ctx[CONTEXT_ID]].count++;
|
|
1118
|
-
return sessions[ctx[CONTEXT_ID]].session;
|
|
1119
|
-
}
|
|
1120
|
-
return wrap.wrapSchema({
|
|
1121
|
-
schema,
|
|
1122
|
-
batch: true,
|
|
1123
|
-
executor(input) {
|
|
1124
|
-
if (input.operationType === 'subscription') {
|
|
1125
|
-
return subscription({
|
|
1126
|
-
schema,
|
|
1127
|
-
document: input.document,
|
|
1128
|
-
variableValues: input.variables,
|
|
1129
|
-
contextValue: input.context,
|
|
1130
|
-
rootValue: input.rootValue,
|
|
1131
|
-
operationName: input.operationName,
|
|
1132
|
-
});
|
|
1133
|
-
}
|
|
1134
|
-
// Create an execution context and run within it
|
|
1135
|
-
return contextBuilder(input.context).runWithContext((env) => {
|
|
1136
|
-
const { context, destroy } = getSession(input.context, env);
|
|
1137
|
-
// It's important to wrap the executeFn within a promise
|
|
1138
|
-
// so we can easily control the end of execution (with finally)
|
|
1139
|
-
return Promise.resolve()
|
|
1140
|
-
.then(() => graphql.execute({
|
|
1141
|
-
schema,
|
|
1142
|
-
document: input.document,
|
|
1143
|
-
contextValue: context,
|
|
1144
|
-
variableValues: input.variables,
|
|
1145
|
-
rootValue: input.rootValue,
|
|
1146
|
-
operationName: input.operationName,
|
|
1147
|
-
}))
|
|
1148
|
-
.finally(destroy);
|
|
1149
|
-
});
|
|
1150
|
-
},
|
|
1151
|
-
});
|
|
1152
|
-
};
|
|
1153
|
-
return createApolloSchema;
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
function operationControllerCreator(options) {
|
|
1157
|
-
const { contextBuilder } = options;
|
|
1158
|
-
return (input) => {
|
|
1159
|
-
const operation = contextBuilder(input.context);
|
|
1160
|
-
const ɵdestroy = input.autoDestroy ? operation.ɵdestroy : () => { };
|
|
1161
|
-
return {
|
|
1162
|
-
context: operation.context,
|
|
1163
|
-
injector: operation.ɵinjector,
|
|
1164
|
-
destroy: operation.ɵdestroy,
|
|
1165
|
-
ɵdestroy,
|
|
1166
|
-
};
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
/**
|
|
1171
|
-
* @api
|
|
1172
|
-
* Creates Application out of Modules. Accepts `ApplicationConfig`.
|
|
1173
|
-
*
|
|
1174
|
-
* @example
|
|
1175
|
-
*
|
|
1176
|
-
* ```typescript
|
|
1177
|
-
* import { createApplication } from 'graphql-modules';
|
|
1178
|
-
* import { usersModule } from './users';
|
|
1179
|
-
* import { postsModule } from './posts';
|
|
1180
|
-
* import { commentsModule } from './comments';
|
|
1181
|
-
*
|
|
1182
|
-
* const app = createApplication({
|
|
1183
|
-
* modules: [
|
|
1184
|
-
* usersModule,
|
|
1185
|
-
* postsModule,
|
|
1186
|
-
* commentsModule
|
|
1187
|
-
* ]
|
|
1188
|
-
* })
|
|
1189
|
-
* ```
|
|
1190
|
-
*/
|
|
1191
|
-
function createApplication(applicationConfig) {
|
|
1192
|
-
function applicationFactory(cfg) {
|
|
1193
|
-
const config = cfg || applicationConfig;
|
|
1194
|
-
const providers = config.providers && typeof config.providers === 'function'
|
|
1195
|
-
? config.providers()
|
|
1196
|
-
: config.providers;
|
|
1197
|
-
// Creates an Injector with singleton classes at application level
|
|
1198
|
-
const appSingletonProviders = ReflectiveInjector.resolve(onlySingletonProviders(providers));
|
|
1199
|
-
const appInjector = ReflectiveInjector.createFromResolved({
|
|
1200
|
-
name: 'App (Singleton Scope)',
|
|
1201
|
-
providers: appSingletonProviders,
|
|
1202
|
-
});
|
|
1203
|
-
// Filter Operation-scoped providers, and keep it here
|
|
1204
|
-
// so we don't do it over and over again
|
|
1205
|
-
const appOperationProviders = ReflectiveInjector.resolve(onlyOperationProviders(providers));
|
|
1206
|
-
const middlewareMap = config.middlewares || {};
|
|
1207
|
-
// Validations
|
|
1208
|
-
ensureModuleUniqueIds(config.modules);
|
|
1209
|
-
// Create all modules
|
|
1210
|
-
const modules = config.modules.map((mod) => mod.factory({
|
|
1211
|
-
injector: appInjector,
|
|
1212
|
-
middlewares: middlewareMap,
|
|
1213
|
-
}));
|
|
1214
|
-
const modulesMap = createModulesMap(modules);
|
|
1215
|
-
const singletonGlobalProvidersMap = createGlobalProvidersMap({
|
|
1216
|
-
modules,
|
|
1217
|
-
scope: exports.Scope.Singleton,
|
|
1218
|
-
});
|
|
1219
|
-
const operationGlobalProvidersMap = createGlobalProvidersMap({
|
|
1220
|
-
modules,
|
|
1221
|
-
scope: exports.Scope.Operation,
|
|
1222
|
-
});
|
|
1223
|
-
attachGlobalProvidersMap({
|
|
1224
|
-
injector: appInjector,
|
|
1225
|
-
globalProvidersMap: singletonGlobalProvidersMap,
|
|
1226
|
-
moduleInjectorGetter(moduleId) {
|
|
1227
|
-
return modulesMap.get(moduleId).injector;
|
|
1228
|
-
},
|
|
1229
|
-
});
|
|
1230
|
-
// Creating a schema, flattening the typedefs and resolvers
|
|
1231
|
-
// is not expensive since it happens only once
|
|
1232
|
-
const typeDefs = flatten(modules.map((mod) => mod.typeDefs));
|
|
1233
|
-
const resolvers = modules.map((mod) => mod.resolvers).filter(isDefined);
|
|
1234
|
-
const schema$1 = (applicationConfig.schemaBuilder || schema.makeExecutableSchema)({
|
|
1235
|
-
typeDefs,
|
|
1236
|
-
resolvers,
|
|
1237
|
-
});
|
|
1238
|
-
const contextBuilder = createContextBuilder({
|
|
1239
|
-
appInjector,
|
|
1240
|
-
appLevelOperationProviders: appOperationProviders,
|
|
1241
|
-
modulesMap: modulesMap,
|
|
1242
|
-
singletonGlobalProvidersMap,
|
|
1243
|
-
operationGlobalProvidersMap,
|
|
1244
|
-
});
|
|
1245
|
-
const createOperationController = operationControllerCreator({
|
|
1246
|
-
contextBuilder,
|
|
1247
|
-
});
|
|
1248
|
-
const createSubscription = subscriptionCreator({ contextBuilder });
|
|
1249
|
-
const createExecution = executionCreator({ contextBuilder });
|
|
1250
|
-
const createSchemaForApollo = apolloSchemaCreator({
|
|
1251
|
-
createSubscription,
|
|
1252
|
-
contextBuilder,
|
|
1253
|
-
schema: schema$1,
|
|
1254
|
-
});
|
|
1255
|
-
const createApolloExecutor = apolloExecutorCreator({
|
|
1256
|
-
createExecution,
|
|
1257
|
-
});
|
|
1258
|
-
instantiateSingletonProviders({
|
|
1259
|
-
appInjector,
|
|
1260
|
-
modulesMap,
|
|
1261
|
-
});
|
|
1262
|
-
return {
|
|
1263
|
-
typeDefs,
|
|
1264
|
-
resolvers,
|
|
1265
|
-
schema: schema$1,
|
|
1266
|
-
injector: appInjector,
|
|
1267
|
-
createOperationController,
|
|
1268
|
-
createSubscription,
|
|
1269
|
-
createExecution,
|
|
1270
|
-
createSchemaForApollo,
|
|
1271
|
-
createApolloExecutor,
|
|
1272
|
-
ɵfactory: applicationFactory,
|
|
1273
|
-
ɵconfig: config,
|
|
1274
|
-
};
|
|
1275
|
-
}
|
|
1276
|
-
return applicationFactory();
|
|
1277
|
-
}
|
|
1278
|
-
function createModulesMap(modules) {
|
|
1279
|
-
var _a;
|
|
1280
|
-
const modulesMap = new Map();
|
|
1281
|
-
for (const module of modules) {
|
|
1282
|
-
if (modulesMap.has(module.id)) {
|
|
1283
|
-
const location = module.metadata.dirname;
|
|
1284
|
-
const existingLocation = (_a = modulesMap.get(module.id)) === null || _a === void 0 ? void 0 : _a.metadata.dirname;
|
|
1285
|
-
const info = [];
|
|
1286
|
-
if (existingLocation) {
|
|
1287
|
-
info.push(`Already registered module located at: ${existingLocation}`);
|
|
1288
|
-
}
|
|
1289
|
-
if (location) {
|
|
1290
|
-
info.push(`Duplicated module located at: ${location}`);
|
|
1291
|
-
}
|
|
1292
|
-
throw new ModuleDuplicatedError(`Module "${module.id}" already exists`, ...info);
|
|
1293
|
-
}
|
|
1294
|
-
modulesMap.set(module.id, module);
|
|
1295
|
-
}
|
|
1296
|
-
return modulesMap;
|
|
1297
|
-
}
|
|
1298
|
-
function ensureModuleUniqueIds(modules) {
|
|
1299
|
-
const collisions = modules
|
|
1300
|
-
.filter((mod, i, all) => i !== all.findIndex((m) => m.id === mod.id))
|
|
1301
|
-
.map((m) => m.id);
|
|
1302
|
-
if (collisions.length) {
|
|
1303
|
-
throw new ModuleNonUniqueIdError(`Modules with non-unique ids: ${collisions.join(', ')}`, `All modules should have unique ids, please locate and fix them.`);
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
function metadataFactory(typeDefs, config) {
|
|
1308
|
-
const implemented = {};
|
|
1309
|
-
const extended = {};
|
|
1310
|
-
function collectObjectDefinition(node) {
|
|
1311
|
-
if (!implemented[node.name.value]) {
|
|
1312
|
-
implemented[node.name.value] = [];
|
|
1313
|
-
}
|
|
1314
|
-
if (node.fields && node.fields.length > 0) {
|
|
1315
|
-
implemented[node.name.value].push(...node.fields.map((field) => field.name.value));
|
|
1316
|
-
}
|
|
1317
|
-
if (node.kind === graphql.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1318
|
-
implemented[node.name.value].push('__isTypeOf');
|
|
1319
|
-
}
|
|
1320
|
-
if (node.kind === graphql.Kind.OBJECT_TYPE_DEFINITION) {
|
|
1321
|
-
implemented[node.name.value].push('__resolveReference');
|
|
1322
|
-
implemented[node.name.value].push('__resolveObject');
|
|
1323
|
-
}
|
|
1324
|
-
if (node.kind === graphql.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
1325
|
-
implemented[node.name.value].push('__resolveType');
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
function collectObjectExtension(node) {
|
|
1329
|
-
if (node.fields) {
|
|
1330
|
-
if (!extended[node.name.value]) {
|
|
1331
|
-
extended[node.name.value] = [];
|
|
1332
|
-
}
|
|
1333
|
-
node.fields.forEach((field) => {
|
|
1334
|
-
extended[node.name.value].push(field.name.value);
|
|
1335
|
-
});
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
for (const doc of typeDefs) {
|
|
1339
|
-
graphql.visit(doc, {
|
|
1340
|
-
// Object
|
|
1341
|
-
ObjectTypeDefinition(node) {
|
|
1342
|
-
collectObjectDefinition(node);
|
|
1343
|
-
},
|
|
1344
|
-
ObjectTypeExtension(node) {
|
|
1345
|
-
collectObjectExtension(node);
|
|
1346
|
-
},
|
|
1347
|
-
// Interface
|
|
1348
|
-
InterfaceTypeDefinition(node) {
|
|
1349
|
-
collectObjectDefinition(node);
|
|
1350
|
-
},
|
|
1351
|
-
InterfaceTypeExtension(node) {
|
|
1352
|
-
collectObjectExtension(node);
|
|
1353
|
-
},
|
|
1354
|
-
// Union
|
|
1355
|
-
UnionTypeDefinition(node) {
|
|
1356
|
-
if (!implemented[node.name.value]) {
|
|
1357
|
-
implemented[node.name.value] = [];
|
|
1358
|
-
}
|
|
1359
|
-
if (node.types) {
|
|
1360
|
-
implemented[node.name.value].push(...node.types.map((type) => type.name.value));
|
|
1361
|
-
}
|
|
1362
|
-
implemented[node.name.value].push('__resolveType');
|
|
1363
|
-
},
|
|
1364
|
-
UnionTypeExtension(node) {
|
|
1365
|
-
if (node.types) {
|
|
1366
|
-
if (!extended[node.name.value]) {
|
|
1367
|
-
extended[node.name.value] = [];
|
|
1368
|
-
}
|
|
1369
|
-
extended[node.name.value].push(...node.types.map((type) => type.name.value));
|
|
1370
|
-
}
|
|
1371
|
-
},
|
|
1372
|
-
// Input
|
|
1373
|
-
InputObjectTypeDefinition(node) {
|
|
1374
|
-
collectObjectDefinition(node);
|
|
1375
|
-
},
|
|
1376
|
-
InputObjectTypeExtension(node) {
|
|
1377
|
-
collectObjectExtension(node);
|
|
1378
|
-
},
|
|
1379
|
-
// Enum
|
|
1380
|
-
EnumTypeDefinition(node) {
|
|
1381
|
-
if (node.values) {
|
|
1382
|
-
if (!implemented[node.name.value]) {
|
|
1383
|
-
implemented[node.name.value] = [];
|
|
1384
|
-
}
|
|
1385
|
-
implemented[node.name.value].push(...node.values.map((value) => value.name.value));
|
|
1386
|
-
}
|
|
1387
|
-
},
|
|
1388
|
-
EnumTypeExtension(node) {
|
|
1389
|
-
if (node.values) {
|
|
1390
|
-
if (!extended[node.name.value]) {
|
|
1391
|
-
extended[node.name.value] = [];
|
|
1392
|
-
}
|
|
1393
|
-
extended[node.name.value].push(...node.values.map((value) => value.name.value));
|
|
1394
|
-
}
|
|
1395
|
-
},
|
|
1396
|
-
// Scalar
|
|
1397
|
-
ScalarTypeDefinition(node) {
|
|
1398
|
-
if (!implemented.__scalars) {
|
|
1399
|
-
implemented.__scalars = [];
|
|
1400
|
-
}
|
|
1401
|
-
implemented.__scalars.push(node.name.value);
|
|
1402
|
-
},
|
|
1403
|
-
});
|
|
1404
|
-
}
|
|
1405
|
-
return {
|
|
1406
|
-
id: config.id,
|
|
1407
|
-
typeDefs,
|
|
1408
|
-
implements: implemented,
|
|
1409
|
-
extends: extended,
|
|
1410
|
-
dirname: config.dirname,
|
|
1411
|
-
};
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
function compose(middleware) {
|
|
1415
|
-
if (!Array.isArray(middleware)) {
|
|
1416
|
-
throw new TypeError('Middleware stack must be an array!');
|
|
1417
|
-
}
|
|
1418
|
-
for (const fn of middleware) {
|
|
1419
|
-
if (typeof fn !== 'function') {
|
|
1420
|
-
throw new TypeError('Middleware must be composed of functions!');
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
return function composed(context, next) {
|
|
1424
|
-
// last called middleware
|
|
1425
|
-
let index = -1;
|
|
1426
|
-
function dispatch(i) {
|
|
1427
|
-
if (i <= index) {
|
|
1428
|
-
return Promise.reject(new Error('next() called multiple times'));
|
|
1429
|
-
}
|
|
1430
|
-
index = i;
|
|
1431
|
-
const fn = i === middleware.length ? next : middleware[i];
|
|
1432
|
-
if (!fn) {
|
|
1433
|
-
return Promise.resolve();
|
|
1434
|
-
}
|
|
1435
|
-
try {
|
|
1436
|
-
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
|
|
1437
|
-
}
|
|
1438
|
-
catch (err) {
|
|
1439
|
-
return Promise.reject(err);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
return dispatch(0);
|
|
1443
|
-
};
|
|
1444
|
-
}
|
|
1445
|
-
function createMiddleware(path, middlewareMap) {
|
|
1446
|
-
const middlewares = middlewareMap ? pickMiddlewares(path, middlewareMap) : [];
|
|
1447
|
-
return compose(middlewares);
|
|
1448
|
-
}
|
|
1449
|
-
function mergeMiddlewareMaps(app, mod) {
|
|
1450
|
-
const merge = (left, right) => {
|
|
1451
|
-
return ramda.mergeDeepWith((l, r) => {
|
|
1452
|
-
if (Array.isArray(l)) {
|
|
1453
|
-
return l.concat(r || []);
|
|
1454
|
-
}
|
|
1455
|
-
return merge(l, r);
|
|
1456
|
-
}, left, right);
|
|
1457
|
-
};
|
|
1458
|
-
return merge(app, mod);
|
|
1459
|
-
}
|
|
1460
|
-
function pickMiddlewares(path, middlewareMap) {
|
|
1461
|
-
var _a;
|
|
1462
|
-
const middlewares = [];
|
|
1463
|
-
const [type, field] = path;
|
|
1464
|
-
if ((_a = middlewareMap['*']) === null || _a === void 0 ? void 0 : _a['*']) {
|
|
1465
|
-
middlewares.push(...middlewareMap['*']['*']);
|
|
1466
|
-
}
|
|
1467
|
-
const typeMap = middlewareMap[type];
|
|
1468
|
-
if (typeMap) {
|
|
1469
|
-
if (typeMap['*']) {
|
|
1470
|
-
middlewares.push(...typeMap['*']);
|
|
1471
|
-
}
|
|
1472
|
-
if (field && typeMap[field]) {
|
|
1473
|
-
middlewares.push(...typeMap[field]);
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
return middlewares.filter(isDefined);
|
|
1477
|
-
}
|
|
1478
|
-
function validateMiddlewareMap(middlewareMap, metadata) {
|
|
1479
|
-
const exists = checkExistence(metadata);
|
|
1480
|
-
for (const typeName in middlewareMap.types) {
|
|
1481
|
-
if (middlewareMap.types.hasOwnProperty(typeName)) {
|
|
1482
|
-
const typeMiddlewareMap = middlewareMap[typeName];
|
|
1483
|
-
if (!exists.type(typeName)) {
|
|
1484
|
-
throw new ExtraMiddlewareError(`Cannot apply a middleware to non existing "${typeName}" type`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
|
|
1485
|
-
}
|
|
1486
|
-
for (const fieldName in typeMiddlewareMap[typeName]) {
|
|
1487
|
-
if (typeMiddlewareMap[typeName].hasOwnProperty(fieldName)) {
|
|
1488
|
-
if (!exists.field(typeName, fieldName)) {
|
|
1489
|
-
throw new ExtraMiddlewareError(`Cannot apply a middleware to non existing "${typeName}.${fieldName}" type.field`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
/**
|
|
1497
|
-
* Helps to make sure a middleware has a corresponding type/field definition.
|
|
1498
|
-
* We don't want to pass a module-level middlewares that are not related to the module.
|
|
1499
|
-
* Not because it's dangerous but to prevent unused middlewares.
|
|
1500
|
-
*/
|
|
1501
|
-
function checkExistence(metadata) {
|
|
1502
|
-
return {
|
|
1503
|
-
type(name) {
|
|
1504
|
-
var _a, _b;
|
|
1505
|
-
return isDefined(((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[name]) || ((_b = metadata.extends) === null || _b === void 0 ? void 0 : _b[name]));
|
|
1506
|
-
},
|
|
1507
|
-
field(type, name) {
|
|
1508
|
-
var _a, _b, _c, _d;
|
|
1509
|
-
return isDefined(((_b = (_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.includes(name)) ||
|
|
1510
|
-
((_d = (_c = metadata.extends) === null || _c === void 0 ? void 0 : _c[type]) === null || _d === void 0 ? void 0 : _d.includes(name)));
|
|
1511
|
-
},
|
|
1512
|
-
};
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
const resolverMetadataProp = Symbol('metadata');
|
|
1516
|
-
function createResolvers(config, metadata, app) {
|
|
1517
|
-
const ensure = ensureImplements(metadata);
|
|
1518
|
-
const normalizedModuleMiddlewareMap = config.middlewares || {};
|
|
1519
|
-
const middlewareMap = mergeMiddlewareMaps(app.middlewareMap, normalizedModuleMiddlewareMap);
|
|
1520
|
-
validateMiddlewareMap(normalizedModuleMiddlewareMap, metadata);
|
|
1521
|
-
const resolvers = addDefaultResolvers(mergeResolvers(config), middlewareMap, config);
|
|
1522
|
-
// Wrap resolvers
|
|
1523
|
-
for (const typeName in resolvers) {
|
|
1524
|
-
if (resolvers.hasOwnProperty(typeName)) {
|
|
1525
|
-
const obj = resolvers[typeName];
|
|
1526
|
-
if (isScalarResolver(obj)) {
|
|
1527
|
-
continue;
|
|
1528
|
-
}
|
|
1529
|
-
else if (isEnumResolver(obj)) {
|
|
1530
|
-
continue;
|
|
1531
|
-
}
|
|
1532
|
-
else if (obj && typeof obj === 'object') {
|
|
1533
|
-
for (const fieldName in obj) {
|
|
1534
|
-
if (obj.hasOwnProperty(fieldName)) {
|
|
1535
|
-
ensure.type(typeName, fieldName);
|
|
1536
|
-
const path = [typeName, fieldName];
|
|
1537
|
-
// function
|
|
1538
|
-
if (isResolveFn(obj[fieldName])) {
|
|
1539
|
-
const resolver = wrapResolver({
|
|
1540
|
-
config,
|
|
1541
|
-
resolver: obj[fieldName],
|
|
1542
|
-
middlewareMap,
|
|
1543
|
-
path,
|
|
1544
|
-
isTypeResolver: fieldName === '__isTypeOf' || fieldName === '__resolveType',
|
|
1545
|
-
isReferenceResolver: fieldName === '__resolveReference',
|
|
1546
|
-
isObjectResolver: fieldName === '__resolveObject',
|
|
1547
|
-
});
|
|
1548
|
-
resolvers[typeName][fieldName] = resolver;
|
|
1549
|
-
}
|
|
1550
|
-
else if (isResolveOptions(obj[fieldName])) {
|
|
1551
|
-
// { resolve }
|
|
1552
|
-
if (isDefined(obj[fieldName].resolve)) {
|
|
1553
|
-
const resolver = wrapResolver({
|
|
1554
|
-
config,
|
|
1555
|
-
resolver: obj[fieldName].resolve,
|
|
1556
|
-
middlewareMap,
|
|
1557
|
-
path,
|
|
1558
|
-
});
|
|
1559
|
-
resolvers[typeName][fieldName].resolve = resolver;
|
|
1560
|
-
}
|
|
1561
|
-
// { subscribe }
|
|
1562
|
-
if (isDefined(obj[fieldName].subscribe)) {
|
|
1563
|
-
const resolver = wrapResolver({
|
|
1564
|
-
config,
|
|
1565
|
-
resolver: obj[fieldName].subscribe,
|
|
1566
|
-
middlewareMap,
|
|
1567
|
-
path,
|
|
1568
|
-
});
|
|
1569
|
-
resolvers[typeName][fieldName].subscribe = resolver;
|
|
1570
|
-
}
|
|
1571
|
-
if (isDefined(obj[fieldName].extensions)) {
|
|
1572
|
-
// Do NOT add a resolve if one is not specified, it will cause
|
|
1573
|
-
// change in behavior in systems like `grafast`
|
|
1574
|
-
resolvers[typeName][fieldName].extensions =
|
|
1575
|
-
obj[fieldName].extensions;
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
return resolvers;
|
|
1584
|
-
}
|
|
1585
|
-
/**
|
|
1586
|
-
* Wrap a resolver so we use module's context instead of app context.
|
|
1587
|
-
* Use a middleware if available.
|
|
1588
|
-
* Attach metadata to a resolver (we will see if it's helpful, probably in error handling)
|
|
1589
|
-
*/
|
|
1590
|
-
function wrapResolver({ resolver, config, path, middlewareMap, isTypeResolver, isReferenceResolver, isObjectResolver, }) {
|
|
1591
|
-
if (isTypeResolver || isReferenceResolver) {
|
|
1592
|
-
const wrappedResolver = (root, context, info) => {
|
|
1593
|
-
const ctx = {
|
|
1594
|
-
root,
|
|
1595
|
-
context: isReferenceResolver
|
|
1596
|
-
? context.ɵgetModuleContext(config.id, context)
|
|
1597
|
-
: // We mark the context object as possibly undefined,
|
|
1598
|
-
// because graphql-jit for some reason doesn't pass it for isTypeOf or resolveType methods
|
|
1599
|
-
context === null || context === void 0 ? void 0 : context.ɵgetModuleContext(config.id, context),
|
|
1600
|
-
info,
|
|
1601
|
-
};
|
|
1602
|
-
return resolver(ctx.root, ctx.context, ctx.info);
|
|
1603
|
-
};
|
|
1604
|
-
writeResolverMetadata(wrappedResolver, config);
|
|
1605
|
-
return wrappedResolver;
|
|
1606
|
-
}
|
|
1607
|
-
if (isObjectResolver) {
|
|
1608
|
-
const wrappedResolver = (root, fields, context, info) => {
|
|
1609
|
-
const moduleContext = context.ɵgetModuleContext(config.id, context);
|
|
1610
|
-
return resolver(root, fields, moduleContext, info);
|
|
1611
|
-
};
|
|
1612
|
-
writeResolverMetadata(wrappedResolver, config);
|
|
1613
|
-
return wrappedResolver;
|
|
1614
|
-
}
|
|
1615
|
-
const middleware = createMiddleware(path, middlewareMap);
|
|
1616
|
-
const wrappedResolver = (root, args, context, info) => {
|
|
1617
|
-
const ctx = {
|
|
1618
|
-
root,
|
|
1619
|
-
args,
|
|
1620
|
-
context: context.ɵgetModuleContext(config.id, context),
|
|
1621
|
-
info,
|
|
1622
|
-
};
|
|
1623
|
-
return middleware(ctx, () => resolver(ctx.root, ctx.args, ctx.context, ctx.info));
|
|
1624
|
-
};
|
|
1625
|
-
writeResolverMetadata(wrappedResolver, config);
|
|
1626
|
-
return wrappedResolver;
|
|
1627
|
-
}
|
|
1628
|
-
/**
|
|
1629
|
-
* We iterate over every defined resolver and check if it's valid and not duplicated
|
|
1630
|
-
*/
|
|
1631
|
-
function mergeResolvers(config) {
|
|
1632
|
-
if (!config.resolvers) {
|
|
1633
|
-
return {};
|
|
1634
|
-
}
|
|
1635
|
-
const resolvers = Array.isArray(config.resolvers)
|
|
1636
|
-
? config.resolvers
|
|
1637
|
-
: [config.resolvers];
|
|
1638
|
-
const container = {};
|
|
1639
|
-
for (const currentResolvers of resolvers) {
|
|
1640
|
-
for (const typeName in currentResolvers) {
|
|
1641
|
-
if (currentResolvers.hasOwnProperty(typeName)) {
|
|
1642
|
-
const value = currentResolvers[typeName];
|
|
1643
|
-
if (isNil(value)) {
|
|
1644
|
-
continue;
|
|
1645
|
-
}
|
|
1646
|
-
else if (isScalarResolver(value)) {
|
|
1647
|
-
addScalar({ typeName, resolver: value, container, config });
|
|
1648
|
-
}
|
|
1649
|
-
else if (isEnumResolver(value)) {
|
|
1650
|
-
addEnum({ typeName, resolver: value, container, config });
|
|
1651
|
-
}
|
|
1652
|
-
else if (value && typeof value === 'object') {
|
|
1653
|
-
addObject({ typeName, fields: value, container, config });
|
|
1654
|
-
}
|
|
1655
|
-
else {
|
|
1656
|
-
throw new ResolverInvalidError(`Resolver of "${typeName}" is invalid`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
return container;
|
|
1662
|
-
}
|
|
1663
|
-
function addObject({ typeName, fields, container, config, }) {
|
|
1664
|
-
if (!container[typeName]) {
|
|
1665
|
-
container[typeName] = {};
|
|
1666
|
-
}
|
|
1667
|
-
for (const fieldName in fields) {
|
|
1668
|
-
if (fields.hasOwnProperty(fieldName)) {
|
|
1669
|
-
const resolver = fields[fieldName];
|
|
1670
|
-
if (isResolveFn(resolver)) {
|
|
1671
|
-
if (container[typeName][fieldName]) {
|
|
1672
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}"`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1673
|
-
}
|
|
1674
|
-
writeResolverMetadata(resolver, config);
|
|
1675
|
-
container[typeName][fieldName] = resolver;
|
|
1676
|
-
}
|
|
1677
|
-
else if (isResolveOptions(resolver)) {
|
|
1678
|
-
if (!container[typeName][fieldName]) {
|
|
1679
|
-
container[typeName][fieldName] = {};
|
|
1680
|
-
}
|
|
1681
|
-
// resolve
|
|
1682
|
-
if (isDefined(resolver.resolve)) {
|
|
1683
|
-
if (container[typeName][fieldName].resolve) {
|
|
1684
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (resolve method)`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1685
|
-
}
|
|
1686
|
-
writeResolverMetadata(resolver.resolve, config);
|
|
1687
|
-
container[typeName][fieldName].resolve = resolver.resolve;
|
|
1688
|
-
}
|
|
1689
|
-
// subscribe
|
|
1690
|
-
if (isDefined(resolver.subscribe)) {
|
|
1691
|
-
if (container[typeName][fieldName].subscribe) {
|
|
1692
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (subscribe method)`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1693
|
-
}
|
|
1694
|
-
writeResolverMetadata(resolver.subscribe, config);
|
|
1695
|
-
container[typeName][fieldName].subscribe = resolver.subscribe;
|
|
1696
|
-
}
|
|
1697
|
-
// extensions
|
|
1698
|
-
if (isDefined(resolver.extensions)) {
|
|
1699
|
-
if (container[typeName][fieldName].extensions) {
|
|
1700
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (extensions object)`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1701
|
-
}
|
|
1702
|
-
writeResolverMetadata(resolver.extensions, config);
|
|
1703
|
-
container[typeName][fieldName].extensions = resolver.extensions;
|
|
1704
|
-
}
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
function addScalar({ typeName, resolver, container, config, }) {
|
|
1710
|
-
if (container[typeName]) {
|
|
1711
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of scalar "${typeName}"`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1712
|
-
}
|
|
1713
|
-
writeResolverMetadata(resolver.parseLiteral, config);
|
|
1714
|
-
writeResolverMetadata(resolver.parseValue, config);
|
|
1715
|
-
writeResolverMetadata(resolver.serialize, config);
|
|
1716
|
-
container[typeName] = resolver;
|
|
1717
|
-
}
|
|
1718
|
-
function addEnum({ typeName, resolver, container, config, }) {
|
|
1719
|
-
if (!container[typeName]) {
|
|
1720
|
-
container[typeName] = {};
|
|
1721
|
-
}
|
|
1722
|
-
for (const key in resolver) {
|
|
1723
|
-
if (resolver.hasOwnProperty(key)) {
|
|
1724
|
-
const value = resolver[key];
|
|
1725
|
-
if (container[typeName][key]) {
|
|
1726
|
-
throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${key}" enum value`, useLocation({ dirname: config.dirname, id: config.id }));
|
|
1727
|
-
}
|
|
1728
|
-
container[typeName][key] = value;
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
/**
|
|
1733
|
-
* Helps to make sure a resolver has a corresponding type/field definition.
|
|
1734
|
-
* We don't want to pass resolve function that are not related to the module.
|
|
1735
|
-
*/
|
|
1736
|
-
function ensureImplements(metadata) {
|
|
1737
|
-
return {
|
|
1738
|
-
type(name, field) {
|
|
1739
|
-
var _a, _b;
|
|
1740
|
-
const type = []
|
|
1741
|
-
.concat((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[name], (_b = metadata.extends) === null || _b === void 0 ? void 0 : _b[name])
|
|
1742
|
-
.filter(isDefined);
|
|
1743
|
-
if (type === null || type === void 0 ? void 0 : type.includes(field)) {
|
|
1744
|
-
return true;
|
|
1745
|
-
}
|
|
1746
|
-
const id = `"${name}.${field}"`;
|
|
1747
|
-
throw new ExtraResolverError(`Resolver of "${id}" type cannot be implemented`, `${id} is not defined`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
|
|
1748
|
-
},
|
|
1749
|
-
scalar(name) {
|
|
1750
|
-
var _a;
|
|
1751
|
-
if ((((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a.__scalars) || []).includes(name)) {
|
|
1752
|
-
return true;
|
|
1753
|
-
}
|
|
1754
|
-
throw new ExtraResolverError(`Resolver of "${name}" scalar cannot be implemented`, `${name} is not defined`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
|
|
1755
|
-
},
|
|
1756
|
-
};
|
|
1757
|
-
}
|
|
1758
|
-
function writeResolverMetadata(resolver, config) {
|
|
1759
|
-
if (!resolver) {
|
|
1760
|
-
return;
|
|
1761
|
-
}
|
|
1762
|
-
resolver[resolverMetadataProp] = {
|
|
1763
|
-
moduleId: config.id,
|
|
1764
|
-
};
|
|
1765
|
-
}
|
|
1766
|
-
/**
|
|
1767
|
-
* In order to use middlewares on fields
|
|
1768
|
-
* that are defined in SDL but have no implemented resolvers,
|
|
1769
|
-
* we would have to recreate GraphQLSchema and wrap resolve functions.
|
|
1770
|
-
*
|
|
1771
|
-
* Since we can't access GraphQLSchema on a module level
|
|
1772
|
-
* and recreating GraphQLSchema seems unreasonable,
|
|
1773
|
-
* we can create default resolvers instead.
|
|
1774
|
-
*
|
|
1775
|
-
* @example
|
|
1776
|
-
*
|
|
1777
|
-
* gql`
|
|
1778
|
-
* type Query {
|
|
1779
|
-
* me: User!
|
|
1780
|
-
* }
|
|
1781
|
-
*
|
|
1782
|
-
* type User {
|
|
1783
|
-
* name: String!
|
|
1784
|
-
* }
|
|
1785
|
-
* `
|
|
1786
|
-
*
|
|
1787
|
-
* The resolver of `Query.me` is implemented and resolver of `User.name` is not.
|
|
1788
|
-
* In case where a middleware wants to intercept the resolver of `User.name`,
|
|
1789
|
-
* we use a default field resolver from `graphql` package
|
|
1790
|
-
* and put it next to other defined resolvers.
|
|
1791
|
-
*
|
|
1792
|
-
* This way our current logic of wrapping resolvers and running
|
|
1793
|
-
* middleware functions stays untouched.
|
|
1794
|
-
*/
|
|
1795
|
-
function addDefaultResolvers(resolvers, middlewareMap, config) {
|
|
1796
|
-
const container = resolvers;
|
|
1797
|
-
const sdl = Array.isArray(config.typeDefs)
|
|
1798
|
-
? graphql.concatAST(config.typeDefs)
|
|
1799
|
-
: config.typeDefs;
|
|
1800
|
-
function hasMiddleware(typeName, fieldName) {
|
|
1801
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1802
|
-
return ((((_b = (_a = middlewareMap['*']) === null || _a === void 0 ? void 0 : _a['*']) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
1803
|
-
((_d = (_c = middlewareMap[typeName]) === null || _c === void 0 ? void 0 : _c['*']) === null || _d === void 0 ? void 0 : _d.length) ||
|
|
1804
|
-
((_f = (_e = middlewareMap[typeName]) === null || _e === void 0 ? void 0 : _e[fieldName]) === null || _f === void 0 ? void 0 : _f.length)) > 0);
|
|
1805
|
-
}
|
|
1806
|
-
sdl.definitions.forEach((definition) => {
|
|
1807
|
-
if (definition.kind === graphql.Kind.OBJECT_TYPE_DEFINITION ||
|
|
1808
|
-
definition.kind === graphql.Kind.OBJECT_TYPE_EXTENSION) {
|
|
1809
|
-
// Right now we only support Object type
|
|
1810
|
-
if (definition.fields) {
|
|
1811
|
-
const typeName = definition.name.value;
|
|
1812
|
-
definition.fields.forEach((field) => {
|
|
1813
|
-
var _a;
|
|
1814
|
-
const fieldName = field.name.value;
|
|
1815
|
-
if (!((_a = container[typeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) &&
|
|
1816
|
-
hasMiddleware(typeName, fieldName)) {
|
|
1817
|
-
if (!container[typeName]) {
|
|
1818
|
-
container[typeName] = {};
|
|
1819
|
-
}
|
|
1820
|
-
container[typeName][fieldName] = graphql.defaultFieldResolver;
|
|
1821
|
-
}
|
|
1822
|
-
});
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
});
|
|
1826
|
-
return container;
|
|
1827
|
-
}
|
|
1828
|
-
//
|
|
1829
|
-
// Resolver helpers
|
|
1830
|
-
//
|
|
1831
|
-
function isResolveFn(value) {
|
|
1832
|
-
return typeof value === 'function';
|
|
1833
|
-
}
|
|
1834
|
-
function isResolveOptions(value) {
|
|
1835
|
-
return (isDefined(value.resolve) ||
|
|
1836
|
-
isDefined(value.subscribe) ||
|
|
1837
|
-
isDefined(value.extensions));
|
|
1838
|
-
}
|
|
1839
|
-
function isScalarResolver(obj) {
|
|
1840
|
-
return obj instanceof graphql.GraphQLScalarType;
|
|
1841
|
-
}
|
|
1842
|
-
function isEnumResolver(obj) {
|
|
1843
|
-
return Object.values(obj).every(isPrimitive);
|
|
1844
|
-
}
|
|
1845
|
-
|
|
1846
|
-
/**
|
|
1847
|
-
* Create a list of DocumentNode objects based on Module's config.
|
|
1848
|
-
* Add a location, so we get richer errors.
|
|
1849
|
-
*/
|
|
1850
|
-
function createTypeDefs(config) {
|
|
1851
|
-
const typeDefs = Array.isArray(config.typeDefs)
|
|
1852
|
-
? config.typeDefs
|
|
1853
|
-
: [config.typeDefs];
|
|
1854
|
-
ensureDocumentNode(config, typeDefs);
|
|
1855
|
-
return typeDefs;
|
|
1856
|
-
}
|
|
1857
|
-
function ensureDocumentNode(config, typeDefs) {
|
|
1858
|
-
function ensureEach(doc, i) {
|
|
1859
|
-
if ((doc === null || doc === void 0 ? void 0 : doc.kind) !== graphql.Kind.DOCUMENT) {
|
|
1860
|
-
throw new NonDocumentNodeError(`Expected parsed document but received ${typeof doc} at index ${i} in typeDefs list`, useLocation(config));
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
typeDefs.forEach(ensureEach);
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
/**
|
|
1867
|
-
* @api
|
|
1868
|
-
* `MODULE_ID` is an InjectionToken representing module's ID
|
|
1869
|
-
*
|
|
1870
|
-
* @example
|
|
1871
|
-
* ```typescript
|
|
1872
|
-
* import { MODULE_ID, Inject, Injectable } from 'graphql-modules';
|
|
1873
|
-
*
|
|
1874
|
-
* (A)Injectable()
|
|
1875
|
-
* export class Data {
|
|
1876
|
-
* constructor((A)Inject(MODULE_ID) moduleId: string) {
|
|
1877
|
-
* console.log(`Data used in ${moduleId} module`)
|
|
1878
|
-
* }
|
|
1879
|
-
* }
|
|
1880
|
-
* ```
|
|
1881
|
-
*/
|
|
1882
|
-
const MODULE_ID = new InjectionToken('module-id');
|
|
1883
|
-
|
|
1884
|
-
function lazy(getter) {
|
|
1885
|
-
let called = false;
|
|
1886
|
-
let computedValue;
|
|
1887
|
-
return {
|
|
1888
|
-
get value() {
|
|
1889
|
-
if (!called) {
|
|
1890
|
-
called = true;
|
|
1891
|
-
computedValue = getter();
|
|
1892
|
-
}
|
|
1893
|
-
return computedValue;
|
|
1894
|
-
},
|
|
1895
|
-
};
|
|
1896
|
-
}
|
|
1897
|
-
function moduleFactory(config) {
|
|
1898
|
-
const typeDefs = createTypeDefs(config);
|
|
1899
|
-
const metadata = metadataFactory(typeDefs, config);
|
|
1900
|
-
const providers = lazy(() => typeof config.providers === 'function'
|
|
1901
|
-
? config.providers()
|
|
1902
|
-
: config.providers);
|
|
1903
|
-
// Filter providers and keep them this way
|
|
1904
|
-
// so we don't do this filtering multiple times.
|
|
1905
|
-
// Providers don't change over time, so it's safe to do it.
|
|
1906
|
-
const operationProviders = lazy(() => ReflectiveInjector.resolve(onlyOperationProviders(providers.value)));
|
|
1907
|
-
const singletonProviders = lazy(() => ReflectiveInjector.resolve(onlySingletonProviders(providers.value)));
|
|
1908
|
-
const mod = {
|
|
1909
|
-
id: config.id,
|
|
1910
|
-
config,
|
|
1911
|
-
metadata,
|
|
1912
|
-
typeDefs,
|
|
1913
|
-
// Factory is called once on application creation,
|
|
1914
|
-
// before we even handle GraphQL Operation
|
|
1915
|
-
factory(app) {
|
|
1916
|
-
const resolvedModule = mod;
|
|
1917
|
-
resolvedModule.singletonProviders = singletonProviders.value;
|
|
1918
|
-
resolvedModule.operationProviders = operationProviders.value;
|
|
1919
|
-
// Create a module-level Singleton injector
|
|
1920
|
-
const injector = ReflectiveInjector.createFromResolved({
|
|
1921
|
-
name: `Module "${config.id}" (Singleton Scope)`,
|
|
1922
|
-
providers: resolvedModule.singletonProviders.concat(resolveProviders([
|
|
1923
|
-
{
|
|
1924
|
-
// with module's id, useful in Logging and stuff
|
|
1925
|
-
provide: MODULE_ID,
|
|
1926
|
-
useValue: config.id,
|
|
1927
|
-
},
|
|
1928
|
-
])),
|
|
1929
|
-
parent: app.injector,
|
|
1930
|
-
});
|
|
1931
|
-
// We attach injector property to existing `mod` object
|
|
1932
|
-
// because we want to keep references
|
|
1933
|
-
// that are later on used in testing utils
|
|
1934
|
-
resolvedModule.injector = injector;
|
|
1935
|
-
// Create resolvers object based on module's config
|
|
1936
|
-
// It involves wrapping a resolver with middlewares
|
|
1937
|
-
// and other things like validation
|
|
1938
|
-
resolvedModule.resolvers = createResolvers(config, metadata, {
|
|
1939
|
-
middlewareMap: app.middlewares,
|
|
1940
|
-
});
|
|
1941
|
-
return resolvedModule;
|
|
1942
|
-
},
|
|
1943
|
-
};
|
|
1944
|
-
return mod;
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
/**
|
|
1948
|
-
* @api
|
|
1949
|
-
* Creates a Module, an element used by Application. Accepts `ModuleConfig`.
|
|
1950
|
-
*
|
|
1951
|
-
* @example
|
|
1952
|
-
*
|
|
1953
|
-
* ```typescript
|
|
1954
|
-
* import { createModule, gql } from 'graphql-modules';
|
|
1955
|
-
*
|
|
1956
|
-
* export const usersModule = createModule({
|
|
1957
|
-
* id: 'users',
|
|
1958
|
-
* typeDefs: gql`
|
|
1959
|
-
* // GraphQL SDL
|
|
1960
|
-
* `,
|
|
1961
|
-
* resolvers: {
|
|
1962
|
-
* // ...
|
|
1963
|
-
* }
|
|
1964
|
-
* });
|
|
1965
|
-
* ```
|
|
1966
|
-
*/
|
|
1967
|
-
function createModule(config) {
|
|
1968
|
-
return moduleFactory(config);
|
|
1969
|
-
}
|
|
1970
|
-
|
|
1971
|
-
function gql(literals) {
|
|
1972
|
-
const result = typeof literals === 'string' ? literals : literals[0];
|
|
1973
|
-
const parsed = graphql.parse(result);
|
|
1974
|
-
if (!parsed || parsed.kind !== graphql.Kind.DOCUMENT) {
|
|
1975
|
-
throw new Error('Not a valid GraphQL document.');
|
|
1976
|
-
}
|
|
1977
|
-
return parsed;
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
function mockApplication(app) {
|
|
1981
|
-
function mockedFactory(newConfig) {
|
|
1982
|
-
const sharedFactory = share(() => app.ɵfactory(newConfig));
|
|
1983
|
-
return {
|
|
1984
|
-
get typeDefs() {
|
|
1985
|
-
return sharedFactory().typeDefs;
|
|
1986
|
-
},
|
|
1987
|
-
get resolvers() {
|
|
1988
|
-
return sharedFactory().resolvers;
|
|
1989
|
-
},
|
|
1990
|
-
get schema() {
|
|
1991
|
-
return sharedFactory().schema;
|
|
1992
|
-
},
|
|
1993
|
-
get injector() {
|
|
1994
|
-
return sharedFactory().injector;
|
|
1995
|
-
},
|
|
1996
|
-
createOperationController(options) {
|
|
1997
|
-
return sharedFactory().createOperationController(options);
|
|
1998
|
-
},
|
|
1999
|
-
createSubscription(options) {
|
|
2000
|
-
return sharedFactory().createSubscription(options);
|
|
2001
|
-
},
|
|
2002
|
-
createExecution(options) {
|
|
2003
|
-
return sharedFactory().createExecution(options);
|
|
2004
|
-
},
|
|
2005
|
-
createSchemaForApollo() {
|
|
2006
|
-
return sharedFactory().createSchemaForApollo();
|
|
2007
|
-
},
|
|
2008
|
-
createApolloExecutor() {
|
|
2009
|
-
return sharedFactory().createApolloExecutor();
|
|
2010
|
-
},
|
|
2011
|
-
get ɵfactory() {
|
|
2012
|
-
return sharedFactory().ɵfactory;
|
|
2013
|
-
},
|
|
2014
|
-
get ɵconfig() {
|
|
2015
|
-
return sharedFactory().ɵconfig;
|
|
2016
|
-
},
|
|
2017
|
-
replaceModule(newModule) {
|
|
2018
|
-
const config = sharedFactory().ɵconfig;
|
|
2019
|
-
return mockedFactory({
|
|
2020
|
-
...config,
|
|
2021
|
-
modules: config.modules.map((mod) => mod.id === newModule.ɵoriginalModule.id ? newModule : mod),
|
|
2022
|
-
});
|
|
2023
|
-
},
|
|
2024
|
-
addProviders(newProviders) {
|
|
2025
|
-
const config = sharedFactory().ɵconfig;
|
|
2026
|
-
const existingProviders = typeof config.providers === 'function'
|
|
2027
|
-
? config.providers()
|
|
2028
|
-
: config.providers;
|
|
2029
|
-
const providers = Array.isArray(existingProviders)
|
|
2030
|
-
? existingProviders.concat(newProviders)
|
|
2031
|
-
: newProviders;
|
|
2032
|
-
return mockedFactory({
|
|
2033
|
-
...config,
|
|
2034
|
-
providers,
|
|
2035
|
-
});
|
|
2036
|
-
},
|
|
2037
|
-
};
|
|
2038
|
-
}
|
|
2039
|
-
return mockedFactory();
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
function mockModule(testedModule, overrideConfig) {
|
|
2043
|
-
const sourceProviders = typeof testedModule.config.providers === 'function'
|
|
2044
|
-
? testedModule.config.providers()
|
|
2045
|
-
: testedModule.config.providers;
|
|
2046
|
-
const overrideProviders = typeof overrideConfig.providers === 'function'
|
|
2047
|
-
? overrideConfig.providers()
|
|
2048
|
-
: overrideConfig.providers;
|
|
2049
|
-
const newModule = createModule({
|
|
2050
|
-
...testedModule.config,
|
|
2051
|
-
providers: [...(sourceProviders || []), ...(overrideProviders || [])],
|
|
2052
|
-
});
|
|
2053
|
-
newModule['ɵoriginalModule'] = testedModule;
|
|
2054
|
-
return newModule;
|
|
2055
|
-
}
|
|
2056
|
-
function testModule(testedModule, config) {
|
|
2057
|
-
var _a;
|
|
2058
|
-
const mod = transformModule(testedModule, config);
|
|
2059
|
-
const modules = [mod].concat((_a = config === null || config === void 0 ? void 0 : config.modules) !== null && _a !== void 0 ? _a : []);
|
|
2060
|
-
return createApplication({
|
|
2061
|
-
...(config || {}),
|
|
2062
|
-
modules,
|
|
2063
|
-
providers: config === null || config === void 0 ? void 0 : config.providers,
|
|
2064
|
-
middlewares: config === null || config === void 0 ? void 0 : config.middlewares,
|
|
2065
|
-
});
|
|
2066
|
-
}
|
|
2067
|
-
function transformModule(mod, config) {
|
|
2068
|
-
const transforms = [];
|
|
2069
|
-
if (config === null || config === void 0 ? void 0 : config.replaceExtensions) {
|
|
2070
|
-
transforms.push((m) => moduleFactory({
|
|
2071
|
-
...m.config,
|
|
2072
|
-
typeDefs: replaceExtensions(m.typeDefs),
|
|
2073
|
-
}));
|
|
2074
|
-
}
|
|
2075
|
-
if (config === null || config === void 0 ? void 0 : config.typeDefs) {
|
|
2076
|
-
transforms.push((m) => moduleFactory({
|
|
2077
|
-
...m.config,
|
|
2078
|
-
typeDefs: m.typeDefs.concat(config.typeDefs),
|
|
2079
|
-
}));
|
|
2080
|
-
}
|
|
2081
|
-
if (config === null || config === void 0 ? void 0 : config.inheritTypeDefs) {
|
|
2082
|
-
transforms.push((m) => moduleFactory({
|
|
2083
|
-
...m.config,
|
|
2084
|
-
typeDefs: inheritTypeDefs(m.typeDefs, config.inheritTypeDefs),
|
|
2085
|
-
}));
|
|
2086
|
-
}
|
|
2087
|
-
if (config === null || config === void 0 ? void 0 : config.resolvers) {
|
|
2088
|
-
transforms.push((m) => {
|
|
2089
|
-
const resolvers = m.config.resolvers
|
|
2090
|
-
? Array.isArray(m.config.resolvers)
|
|
2091
|
-
? m.config.resolvers
|
|
2092
|
-
: [m.config.resolvers]
|
|
2093
|
-
: [];
|
|
2094
|
-
return moduleFactory({
|
|
2095
|
-
...m.config,
|
|
2096
|
-
resolvers: resolvers.concat(config.resolvers),
|
|
2097
|
-
});
|
|
2098
|
-
});
|
|
2099
|
-
}
|
|
2100
|
-
if (config === null || config === void 0 ? void 0 : config.providers) {
|
|
2101
|
-
transforms.push((m) => {
|
|
2102
|
-
const sourceProviders = typeof m.config.providers === 'function'
|
|
2103
|
-
? m.config.providers()
|
|
2104
|
-
: m.config.providers;
|
|
2105
|
-
const overrideProviders = typeof config.providers === 'function'
|
|
2106
|
-
? config.providers()
|
|
2107
|
-
: config.providers;
|
|
2108
|
-
return moduleFactory({
|
|
2109
|
-
...m.config,
|
|
2110
|
-
providers: [...(sourceProviders || []), ...(overrideProviders || [])],
|
|
2111
|
-
});
|
|
2112
|
-
});
|
|
2113
|
-
}
|
|
2114
|
-
if (transforms) {
|
|
2115
|
-
return transforms.reduce((m, transform) => transform(m), mod);
|
|
2116
|
-
}
|
|
2117
|
-
return mod;
|
|
2118
|
-
}
|
|
2119
|
-
function inheritTypeDefs(originalTypeDefs, modules) {
|
|
2120
|
-
const original = graphql.concatAST(originalTypeDefs);
|
|
2121
|
-
const typeDefs = treeshakeTypesDefs(original, modules.reduce((typeDefs, externalMod) => typeDefs.concat(externalMod.typeDefs), []));
|
|
2122
|
-
return typeDefs;
|
|
2123
|
-
}
|
|
2124
|
-
function replaceExtensions(typeDefs) {
|
|
2125
|
-
const types = [];
|
|
2126
|
-
const extensions = [];
|
|
2127
|
-
// List all object types
|
|
2128
|
-
typeDefs.forEach((doc) => {
|
|
2129
|
-
graphql.visit(doc, {
|
|
2130
|
-
ObjectTypeDefinition(node) {
|
|
2131
|
-
types.push(node.name.value);
|
|
2132
|
-
},
|
|
2133
|
-
});
|
|
2134
|
-
});
|
|
2135
|
-
// turn object type extensions into object types
|
|
2136
|
-
return typeDefs.map((doc) => {
|
|
2137
|
-
return graphql.visit(doc, {
|
|
2138
|
-
ObjectTypeExtension(node) {
|
|
2139
|
-
// only if object type doesn't exist
|
|
2140
|
-
if (extensions.includes(node.name.value) ||
|
|
2141
|
-
types.includes(node.name.value)) {
|
|
2142
|
-
return node;
|
|
2143
|
-
}
|
|
2144
|
-
return {
|
|
2145
|
-
...node,
|
|
2146
|
-
kind: graphql.Kind.OBJECT_TYPE_DEFINITION,
|
|
2147
|
-
};
|
|
2148
|
-
},
|
|
2149
|
-
});
|
|
2150
|
-
});
|
|
2151
|
-
}
|
|
2152
|
-
function treeshakeTypesDefs(originalSource, sources) {
|
|
2153
|
-
const namedTypes = originalSource.definitions.filter(isNamedTypeDefinition);
|
|
2154
|
-
const typesToVisit = namedTypes.map((def) => def.name.value);
|
|
2155
|
-
const rootFields = namedTypes.reduce((acc, node) => {
|
|
2156
|
-
const typeName = node.name.value;
|
|
2157
|
-
if (isRootType(typeName) && hasFields(node)) {
|
|
2158
|
-
if (!acc[typeName]) {
|
|
2159
|
-
acc[typeName] = [];
|
|
2160
|
-
}
|
|
2161
|
-
node.fields.forEach((field) => {
|
|
2162
|
-
acc[typeName].push(field.name.value);
|
|
2163
|
-
});
|
|
2164
|
-
}
|
|
2165
|
-
return acc;
|
|
2166
|
-
}, {});
|
|
2167
|
-
const schema = graphql.concatAST([originalSource].concat(sources));
|
|
2168
|
-
const involvedTypes = new Set(visitTypes(schema, typesToVisit, rootFields));
|
|
2169
|
-
return {
|
|
2170
|
-
kind: graphql.Kind.DOCUMENT,
|
|
2171
|
-
definitions: schema.definitions.filter((def) => {
|
|
2172
|
-
var _a, _b;
|
|
2173
|
-
if (isNamedTypeDefinition(def)) {
|
|
2174
|
-
const typeName = def.name.value;
|
|
2175
|
-
if (!involvedTypes.has(def.name.value)) {
|
|
2176
|
-
return false;
|
|
2177
|
-
}
|
|
2178
|
-
if ((_a = rootFields[typeName]) === null || _a === void 0 ? void 0 : _a.length) {
|
|
2179
|
-
const rootType = def;
|
|
2180
|
-
if ((_b = rootType.fields) === null || _b === void 0 ? void 0 : _b.every((field) => !rootFields[typeName].includes(field.name.value))) {
|
|
2181
|
-
return false;
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
return true;
|
|
2186
|
-
}),
|
|
2187
|
-
};
|
|
2188
|
-
}
|
|
2189
|
-
function isNamedTypeDefinition(def) {
|
|
2190
|
-
return (!!def &&
|
|
2191
|
-
def.kind !== graphql.Kind.SCHEMA_DEFINITION &&
|
|
2192
|
-
def.kind !== graphql.Kind.SCHEMA_EXTENSION);
|
|
2193
|
-
}
|
|
2194
|
-
function visitTypes(schema, types, rootFields) {
|
|
2195
|
-
const visitedTypes = [];
|
|
2196
|
-
const scalars = schema.definitions
|
|
2197
|
-
.filter((def) => def.kind === graphql.Kind.SCALAR_TYPE_DEFINITION ||
|
|
2198
|
-
def.kind === graphql.Kind.SCALAR_TYPE_EXTENSION)
|
|
2199
|
-
.map((def) => def.name.value);
|
|
2200
|
-
for (const typeName of types) {
|
|
2201
|
-
collectType(typeName);
|
|
2202
|
-
}
|
|
2203
|
-
return visitedTypes;
|
|
2204
|
-
function collectField(field, parentTypeName) {
|
|
2205
|
-
var _a;
|
|
2206
|
-
if (parentTypeName &&
|
|
2207
|
-
isRootType(parentTypeName) &&
|
|
2208
|
-
((_a = rootFields[parentTypeName]) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
2209
|
-
!rootFields[parentTypeName].includes(field.name.value)) {
|
|
2210
|
-
return;
|
|
2211
|
-
}
|
|
2212
|
-
collectType(resolveType(field.type));
|
|
2213
|
-
if (field.arguments) {
|
|
2214
|
-
field.arguments.forEach((arg) => {
|
|
2215
|
-
collectType(resolveType(arg.type));
|
|
2216
|
-
});
|
|
2217
|
-
}
|
|
2218
|
-
if (field.directives) {
|
|
2219
|
-
field.directives.forEach((directive) => {
|
|
2220
|
-
collectType(directive.name.value);
|
|
2221
|
-
});
|
|
2222
|
-
}
|
|
2223
|
-
}
|
|
2224
|
-
function collectType(typeName) {
|
|
2225
|
-
if (visitedTypes.includes(typeName)) {
|
|
2226
|
-
return;
|
|
2227
|
-
}
|
|
2228
|
-
if (isScalar(typeName)) {
|
|
2229
|
-
visitedTypes.push(typeName);
|
|
2230
|
-
return;
|
|
2231
|
-
}
|
|
2232
|
-
const types = findTypes(typeName);
|
|
2233
|
-
visitedTypes.push(typeName);
|
|
2234
|
-
types.forEach((type) => {
|
|
2235
|
-
if (hasFields(type)) {
|
|
2236
|
-
type.fields.forEach((field) => {
|
|
2237
|
-
collectField(field, typeName);
|
|
2238
|
-
});
|
|
2239
|
-
}
|
|
2240
|
-
if (hasTypes(type)) {
|
|
2241
|
-
type.types.forEach((t) => {
|
|
2242
|
-
collectType(resolveType(t));
|
|
2243
|
-
});
|
|
2244
|
-
}
|
|
2245
|
-
if (hasInterfaces(type)) {
|
|
2246
|
-
type.interfaces.forEach((i) => {
|
|
2247
|
-
collectType(resolveType(i));
|
|
2248
|
-
});
|
|
2249
|
-
}
|
|
2250
|
-
});
|
|
2251
|
-
}
|
|
2252
|
-
function resolveType(type) {
|
|
2253
|
-
if (type.kind === 'ListType') {
|
|
2254
|
-
return resolveType(type.type);
|
|
2255
|
-
}
|
|
2256
|
-
if (type.kind === 'NonNullType') {
|
|
2257
|
-
return resolveType(type.type);
|
|
2258
|
-
}
|
|
2259
|
-
return type.name.value;
|
|
2260
|
-
}
|
|
2261
|
-
function isScalar(name) {
|
|
2262
|
-
return scalars
|
|
2263
|
-
.concat(['String', 'Boolean', 'Int', 'ID', 'Float'])
|
|
2264
|
-
.includes(name);
|
|
2265
|
-
}
|
|
2266
|
-
function findTypes(typeName) {
|
|
2267
|
-
const types = schema.definitions.filter((def) => isNamedTypeDefinition(def) && def.name.value === typeName);
|
|
2268
|
-
if (!types.length) {
|
|
2269
|
-
throw new Error(`Missing type "${typeName}"`);
|
|
2270
|
-
}
|
|
2271
|
-
return types;
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
function hasInterfaces(def) {
|
|
2275
|
-
return (hasPropValue(def, 'interfaces') &&
|
|
2276
|
-
[
|
|
2277
|
-
graphql.Kind.OBJECT_TYPE_DEFINITION,
|
|
2278
|
-
graphql.Kind.OBJECT_TYPE_EXTENSION,
|
|
2279
|
-
graphql.Kind.INTERFACE_TYPE_DEFINITION,
|
|
2280
|
-
graphql.Kind.INTERFACE_TYPE_EXTENSION,
|
|
2281
|
-
].includes(def.kind));
|
|
2282
|
-
}
|
|
2283
|
-
function hasTypes(def) {
|
|
2284
|
-
return ([graphql.Kind.UNION_TYPE_DEFINITION, graphql.Kind.UNION_TYPE_EXTENSION].includes(def.kind) && hasPropValue(def, 'types'));
|
|
2285
|
-
}
|
|
2286
|
-
function hasFields(def) {
|
|
2287
|
-
return ([
|
|
2288
|
-
graphql.Kind.OBJECT_TYPE_DEFINITION,
|
|
2289
|
-
graphql.Kind.OBJECT_TYPE_EXTENSION,
|
|
2290
|
-
graphql.Kind.INTERFACE_TYPE_DEFINITION,
|
|
2291
|
-
graphql.Kind.INTERFACE_TYPE_EXTENSION,
|
|
2292
|
-
graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION,
|
|
2293
|
-
graphql.Kind.INPUT_OBJECT_TYPE_EXTENSION,
|
|
2294
|
-
].includes(def.kind) && hasPropValue(def, 'fields'));
|
|
2295
|
-
}
|
|
2296
|
-
function hasPropValue(obj, prop) {
|
|
2297
|
-
return Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop];
|
|
2298
|
-
}
|
|
2299
|
-
function isRootType(typeName) {
|
|
2300
|
-
return (typeName === 'Query' ||
|
|
2301
|
-
typeName === 'Mutation' ||
|
|
2302
|
-
typeName === 'Subscription');
|
|
2303
|
-
}
|
|
2304
|
-
|
|
2305
|
-
function testInjector(providers) {
|
|
2306
|
-
const resolvedProviders = ReflectiveInjector.resolve([
|
|
2307
|
-
{ provide: CONTEXT, useValue: {} },
|
|
2308
|
-
...providers,
|
|
2309
|
-
]);
|
|
2310
|
-
const injector = ReflectiveInjector.createFromResolved({
|
|
2311
|
-
name: 'test',
|
|
2312
|
-
providers: resolvedProviders,
|
|
2313
|
-
});
|
|
2314
|
-
injector.instantiateAll();
|
|
2315
|
-
return injector;
|
|
2316
|
-
}
|
|
2317
|
-
function readProviderOptions(provider) {
|
|
2318
|
-
return readInjectableMetadata(provider, true).options;
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2321
|
-
function execute(app, inputs, options) {
|
|
2322
|
-
const executor = app.createExecution(options);
|
|
2323
|
-
return executor({
|
|
2324
|
-
schema: app.schema,
|
|
2325
|
-
...inputs,
|
|
2326
|
-
});
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
|
-
function provideEmpty(token) {
|
|
2330
|
-
return {
|
|
2331
|
-
provide: token,
|
|
2332
|
-
useValue: {},
|
|
2333
|
-
};
|
|
2334
|
-
}
|
|
2335
|
-
|
|
2336
|
-
const testkit = {
|
|
2337
|
-
mockApplication,
|
|
2338
|
-
mockModule,
|
|
2339
|
-
testModule,
|
|
2340
|
-
testInjector,
|
|
2341
|
-
readProviderOptions,
|
|
2342
|
-
provideEmpty,
|
|
2343
|
-
execute,
|
|
2344
|
-
};
|
|
2345
|
-
|
|
2346
|
-
exports.CONTEXT = CONTEXT;
|
|
2347
|
-
exports.ExecutionContext = ExecutionContext;
|
|
2348
|
-
exports.Inject = Inject;
|
|
2349
|
-
exports.Injectable = Injectable;
|
|
2350
|
-
exports.InjectionToken = InjectionToken;
|
|
2351
|
-
exports.Injector = Injector;
|
|
2352
|
-
exports.MODULE_ID = MODULE_ID;
|
|
2353
|
-
exports.Optional = Optional;
|
|
2354
|
-
exports.createApplication = createApplication;
|
|
2355
|
-
exports.createModule = createModule;
|
|
2356
|
-
exports.forwardRef = forwardRef;
|
|
2357
|
-
exports.gql = gql;
|
|
2358
|
-
exports.metadataFactory = metadataFactory;
|
|
2359
|
-
exports.testkit = testkit;
|