graphql-modules 3.1.2-alpha-20260121024117-e03d9c26de1cfd3971986f82b995963e1cc77056 → 3.1.2-alpha-20260121025807-95ab4fb1994c3cf68c88a7cf234efd8f99f92ed1

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.
Files changed (165) hide show
  1. package/cjs/application/apollo.js +81 -0
  2. package/cjs/application/application.js +149 -0
  3. package/cjs/application/context.js +144 -0
  4. package/cjs/application/di.js +48 -0
  5. package/cjs/application/execution.js +42 -0
  6. package/cjs/application/operation-controller.js +16 -0
  7. package/cjs/application/subscription.js +54 -0
  8. package/cjs/application/tokens.js +20 -0
  9. package/cjs/application/types.js +0 -0
  10. package/cjs/async-context.browser.mjs +7 -0
  11. package/cjs/async-context.node.cjs +14 -0
  12. package/cjs/di/decorators.js +78 -0
  13. package/cjs/di/errors.js +87 -0
  14. package/cjs/di/forward-ref.js +26 -0
  15. package/cjs/di/index.js +19 -0
  16. package/cjs/di/injector.js +173 -0
  17. package/cjs/di/metadata.js +22 -0
  18. package/cjs/di/providers.js +60 -0
  19. package/cjs/di/registry.js +44 -0
  20. package/cjs/di/resolution.js +166 -0
  21. package/cjs/di/utils.js +44 -0
  22. package/cjs/index.js +31 -0
  23. package/cjs/module/factory.js +71 -0
  24. package/cjs/module/metadata.js +110 -0
  25. package/cjs/module/module.js +27 -0
  26. package/cjs/module/resolvers.js +341 -0
  27. package/cjs/module/tokens.js +21 -0
  28. package/cjs/module/type-defs.js +24 -0
  29. package/cjs/module/types.js +0 -0
  30. package/cjs/package.json +9 -0
  31. package/cjs/shared/di.js +0 -0
  32. package/cjs/shared/errors.js +82 -0
  33. package/cjs/shared/gql.js +12 -0
  34. package/cjs/shared/middleware.js +109 -0
  35. package/cjs/shared/types.js +0 -0
  36. package/cjs/shared/utils.js +115 -0
  37. package/cjs/testing/di.js +9 -0
  38. package/cjs/testing/graphql.js +10 -0
  39. package/cjs/testing/index.js +17 -0
  40. package/cjs/testing/test-application.js +65 -0
  41. package/cjs/testing/test-injector.js +22 -0
  42. package/cjs/testing/test-module.js +270 -0
  43. package/esm/application/apollo.js +77 -0
  44. package/esm/application/application.js +146 -0
  45. package/esm/application/context.js +140 -0
  46. package/esm/application/di.js +42 -0
  47. package/esm/application/execution.js +39 -0
  48. package/esm/application/operation-controller.js +13 -0
  49. package/esm/application/subscription.js +51 -0
  50. package/esm/application/tokens.js +17 -0
  51. package/esm/application/types.js +0 -0
  52. package/esm/async-context.browser.mjs +7 -0
  53. package/esm/async-context.node.cjs +14 -0
  54. package/esm/di/decorators.js +72 -0
  55. package/esm/di/errors.js +79 -0
  56. package/esm/di/forward-ref.js +22 -0
  57. package/esm/di/index.js +4 -0
  58. package/esm/di/injector.js +168 -0
  59. package/esm/di/metadata.js +17 -0
  60. package/esm/di/providers.js +50 -0
  61. package/esm/di/registry.js +40 -0
  62. package/esm/di/resolution.js +159 -0
  63. package/esm/di/utils.js +36 -0
  64. package/esm/index.js +16 -0
  65. package/esm/module/factory.js +68 -0
  66. package/esm/module/metadata.js +107 -0
  67. package/esm/module/module.js +24 -0
  68. package/esm/module/resolvers.js +337 -0
  69. package/esm/module/tokens.js +18 -0
  70. package/esm/module/type-defs.js +21 -0
  71. package/esm/module/types.js +0 -0
  72. package/esm/shared/di.js +0 -0
  73. package/esm/shared/errors.js +69 -0
  74. package/esm/shared/gql.js +9 -0
  75. package/esm/shared/middleware.js +103 -0
  76. package/esm/shared/types.js +0 -0
  77. package/esm/shared/utils.js +101 -0
  78. package/esm/testing/di.js +6 -0
  79. package/esm/testing/graphql.js +7 -0
  80. package/esm/testing/index.js +14 -0
  81. package/esm/testing/test-application.js +62 -0
  82. package/esm/testing/test-injector.js +18 -0
  83. package/esm/testing/test-module.js +266 -0
  84. package/package.json +29 -9
  85. package/typings/application/apollo.d.ts +22 -0
  86. package/typings/application/application.d.ts +32 -0
  87. package/typings/application/context.d.ts +24 -0
  88. package/typings/application/di.d.ts +22 -0
  89. package/typings/application/execution.d.ts +8 -0
  90. package/typings/application/operation-controller.d.ts +5 -0
  91. package/typings/application/subscription.d.ts +8 -0
  92. package/typings/application/tokens.d.ts +17 -0
  93. package/typings/application/types.d.ts +130 -0
  94. package/typings/di/decorators.d.ts +11 -0
  95. package/typings/di/errors.d.ts +16 -0
  96. package/typings/di/forward-ref.d.ts +7 -0
  97. package/typings/di/index.d.ts +5 -0
  98. package/typings/di/injector.d.ts +50 -0
  99. package/typings/di/metadata.d.ts +12 -0
  100. package/typings/di/providers.d.ts +44 -0
  101. package/typings/di/registry.d.ts +11 -0
  102. package/typings/di/resolution.d.ts +63 -0
  103. package/typings/di/utils.d.ts +8 -0
  104. package/typings/index.d.ts +13 -0
  105. package/typings/module/factory.d.ts +16 -0
  106. package/typings/module/metadata.d.ts +12 -0
  107. package/typings/module/module.d.ts +22 -0
  108. package/typings/module/resolvers.d.ts +13 -0
  109. package/typings/module/tokens.d.ts +18 -0
  110. package/typings/module/type-defs.d.ts +7 -0
  111. package/typings/module/types.d.ts +51 -0
  112. package/typings/shared/di.d.ts +3 -0
  113. package/typings/shared/errors.d.ts +36 -0
  114. package/typings/shared/gql.d.ts +2 -0
  115. package/typings/shared/middleware.d.ts +21 -0
  116. package/typings/shared/types.d.ts +22 -0
  117. package/typings/shared/utils.d.ts +12 -0
  118. package/typings/testing/di.d.ts +2 -0
  119. package/typings/testing/graphql.d.ts +14 -0
  120. package/typings/testing/index.d.ts +14 -0
  121. package/typings/testing/test-application.d.ts +2 -0
  122. package/typings/testing/test-injector.d.ts +4 -0
  123. package/typings/testing/test-module.d.ts +10 -0
  124. package/LICENSE.md +0 -21
  125. package/index.js +0 -2359
  126. package/index.mjs +0 -2344
  127. /package/{application/apollo.d.ts → typings/application/apollo.d.cts} +0 -0
  128. /package/{application/application.d.ts → typings/application/application.d.cts} +0 -0
  129. /package/{application/context.d.ts → typings/application/context.d.cts} +0 -0
  130. /package/{application/di.d.ts → typings/application/di.d.cts} +0 -0
  131. /package/{application/execution.d.ts → typings/application/execution.d.cts} +0 -0
  132. /package/{application/operation-controller.d.ts → typings/application/operation-controller.d.cts} +0 -0
  133. /package/{application/subscription.d.ts → typings/application/subscription.d.cts} +0 -0
  134. /package/{application/tokens.d.ts → typings/application/tokens.d.cts} +0 -0
  135. /package/{application/types.d.ts → typings/application/types.d.cts} +0 -0
  136. /package/{di/decorators.d.ts → typings/di/decorators.d.cts} +0 -0
  137. /package/{di/errors.d.ts → typings/di/errors.d.cts} +0 -0
  138. /package/{di/forward-ref.d.ts → typings/di/forward-ref.d.cts} +0 -0
  139. /package/{di/index.d.ts → typings/di/index.d.cts} +0 -0
  140. /package/{di/injector.d.ts → typings/di/injector.d.cts} +0 -0
  141. /package/{di/metadata.d.ts → typings/di/metadata.d.cts} +0 -0
  142. /package/{di/providers.d.ts → typings/di/providers.d.cts} +0 -0
  143. /package/{di/registry.d.ts → typings/di/registry.d.cts} +0 -0
  144. /package/{di/resolution.d.ts → typings/di/resolution.d.cts} +0 -0
  145. /package/{di/utils.d.ts → typings/di/utils.d.cts} +0 -0
  146. /package/{index.d.ts → typings/index.d.cts} +0 -0
  147. /package/{module/factory.d.ts → typings/module/factory.d.cts} +0 -0
  148. /package/{module/metadata.d.ts → typings/module/metadata.d.cts} +0 -0
  149. /package/{module/module.d.ts → typings/module/module.d.cts} +0 -0
  150. /package/{module/resolvers.d.ts → typings/module/resolvers.d.cts} +0 -0
  151. /package/{module/tokens.d.ts → typings/module/tokens.d.cts} +0 -0
  152. /package/{module/type-defs.d.ts → typings/module/type-defs.d.cts} +0 -0
  153. /package/{module/types.d.ts → typings/module/types.d.cts} +0 -0
  154. /package/{shared/di.d.ts → typings/shared/di.d.cts} +0 -0
  155. /package/{shared/errors.d.ts → typings/shared/errors.d.cts} +0 -0
  156. /package/{shared/gql.d.ts → typings/shared/gql.d.cts} +0 -0
  157. /package/{shared/middleware.d.ts → typings/shared/middleware.d.cts} +0 -0
  158. /package/{shared/types.d.ts → typings/shared/types.d.cts} +0 -0
  159. /package/{shared/utils.d.ts → typings/shared/utils.d.cts} +0 -0
  160. /package/{testing/di.d.ts → typings/testing/di.d.cts} +0 -0
  161. /package/{testing/graphql.d.ts → typings/testing/graphql.d.cts} +0 -0
  162. /package/{testing/index.d.ts → typings/testing/index.d.cts} +0 -0
  163. /package/{testing/test-application.d.ts → typings/testing/test-application.d.cts} +0 -0
  164. /package/{testing/test-injector.d.ts → typings/testing/test-injector.d.cts} +0 -0
  165. /package/{testing/test-module.d.ts → typings/testing/test-module.d.cts} +0 -0
@@ -0,0 +1,337 @@
1
+ import { GraphQLScalarType, concatAST, Kind, defaultFieldResolver, } from 'graphql';
2
+ import { useLocation, ExtraResolverError, ResolverDuplicatedError, ResolverInvalidError, } from './../shared/errors';
3
+ import { isNil, isDefined, isPrimitive } from '../shared/utils';
4
+ import { createMiddleware, mergeMiddlewareMaps, validateMiddlewareMap, } from '../shared/middleware';
5
+ const resolverMetadataProp = Symbol('metadata');
6
+ export function createResolvers(config, metadata, app) {
7
+ const ensure = ensureImplements(metadata);
8
+ const normalizedModuleMiddlewareMap = config.middlewares || {};
9
+ const middlewareMap = mergeMiddlewareMaps(app.middlewareMap, normalizedModuleMiddlewareMap);
10
+ validateMiddlewareMap(normalizedModuleMiddlewareMap, metadata);
11
+ const resolvers = addDefaultResolvers(mergeResolvers(config), middlewareMap, config);
12
+ // Wrap resolvers
13
+ for (const typeName in resolvers) {
14
+ if (resolvers.hasOwnProperty(typeName)) {
15
+ const obj = resolvers[typeName];
16
+ if (isScalarResolver(obj)) {
17
+ continue;
18
+ }
19
+ else if (isEnumResolver(obj)) {
20
+ continue;
21
+ }
22
+ else if (obj && typeof obj === 'object') {
23
+ for (const fieldName in obj) {
24
+ if (obj.hasOwnProperty(fieldName)) {
25
+ ensure.type(typeName, fieldName);
26
+ const path = [typeName, fieldName];
27
+ // function
28
+ if (isResolveFn(obj[fieldName])) {
29
+ const resolver = wrapResolver({
30
+ config,
31
+ resolver: obj[fieldName],
32
+ middlewareMap,
33
+ path,
34
+ isTypeResolver: fieldName === '__isTypeOf' || fieldName === '__resolveType',
35
+ isReferenceResolver: fieldName === '__resolveReference',
36
+ isObjectResolver: fieldName === '__resolveObject',
37
+ });
38
+ resolvers[typeName][fieldName] = resolver;
39
+ }
40
+ else if (isResolveOptions(obj[fieldName])) {
41
+ // { resolve }
42
+ if (isDefined(obj[fieldName].resolve)) {
43
+ const resolver = wrapResolver({
44
+ config,
45
+ resolver: obj[fieldName].resolve,
46
+ middlewareMap,
47
+ path,
48
+ });
49
+ resolvers[typeName][fieldName].resolve = resolver;
50
+ }
51
+ // { subscribe }
52
+ if (isDefined(obj[fieldName].subscribe)) {
53
+ const resolver = wrapResolver({
54
+ config,
55
+ resolver: obj[fieldName].subscribe,
56
+ middlewareMap,
57
+ path,
58
+ });
59
+ resolvers[typeName][fieldName].subscribe = resolver;
60
+ }
61
+ if (isDefined(obj[fieldName].extensions)) {
62
+ // Do NOT add a resolve if one is not specified, it will cause
63
+ // change in behavior in systems like `grafast`
64
+ resolvers[typeName][fieldName].extensions =
65
+ obj[fieldName].extensions;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ return resolvers;
74
+ }
75
+ /**
76
+ * Wrap a resolver so we use module's context instead of app context.
77
+ * Use a middleware if available.
78
+ * Attach metadata to a resolver (we will see if it's helpful, probably in error handling)
79
+ */
80
+ function wrapResolver({ resolver, config, path, middlewareMap, isTypeResolver, isReferenceResolver, isObjectResolver, }) {
81
+ if (isTypeResolver || isReferenceResolver) {
82
+ const wrappedResolver = (root, context, info) => {
83
+ const ctx = {
84
+ root,
85
+ context: isReferenceResolver
86
+ ? context.ɵgetModuleContext(config.id, context)
87
+ : // We mark the context object as possibly undefined,
88
+ // because graphql-jit for some reason doesn't pass it for isTypeOf or resolveType methods
89
+ context === null || context === void 0 ? void 0 : context.ɵgetModuleContext(config.id, context),
90
+ info,
91
+ };
92
+ return resolver(ctx.root, ctx.context, ctx.info);
93
+ };
94
+ writeResolverMetadata(wrappedResolver, config);
95
+ return wrappedResolver;
96
+ }
97
+ if (isObjectResolver) {
98
+ const wrappedResolver = (root, fields, context, info) => {
99
+ const moduleContext = context.ɵgetModuleContext(config.id, context);
100
+ return resolver(root, fields, moduleContext, info);
101
+ };
102
+ writeResolverMetadata(wrappedResolver, config);
103
+ return wrappedResolver;
104
+ }
105
+ const middleware = createMiddleware(path, middlewareMap);
106
+ const wrappedResolver = (root, args, context, info) => {
107
+ const ctx = {
108
+ root,
109
+ args,
110
+ context: context.ɵgetModuleContext(config.id, context),
111
+ info,
112
+ };
113
+ return middleware(ctx, () => resolver(ctx.root, ctx.args, ctx.context, ctx.info));
114
+ };
115
+ writeResolverMetadata(wrappedResolver, config);
116
+ return wrappedResolver;
117
+ }
118
+ /**
119
+ * We iterate over every defined resolver and check if it's valid and not duplicated
120
+ */
121
+ function mergeResolvers(config) {
122
+ if (!config.resolvers) {
123
+ return {};
124
+ }
125
+ const resolvers = Array.isArray(config.resolvers)
126
+ ? config.resolvers
127
+ : [config.resolvers];
128
+ const container = {};
129
+ for (const currentResolvers of resolvers) {
130
+ for (const typeName in currentResolvers) {
131
+ if (currentResolvers.hasOwnProperty(typeName)) {
132
+ const value = currentResolvers[typeName];
133
+ if (isNil(value)) {
134
+ continue;
135
+ }
136
+ else if (isScalarResolver(value)) {
137
+ addScalar({ typeName, resolver: value, container, config });
138
+ }
139
+ else if (isEnumResolver(value)) {
140
+ addEnum({ typeName, resolver: value, container, config });
141
+ }
142
+ else if (value && typeof value === 'object') {
143
+ addObject({ typeName, fields: value, container, config });
144
+ }
145
+ else {
146
+ throw new ResolverInvalidError(`Resolver of "${typeName}" is invalid`, useLocation({ dirname: config.dirname, id: config.id }));
147
+ }
148
+ }
149
+ }
150
+ }
151
+ return container;
152
+ }
153
+ function addObject({ typeName, fields, container, config, }) {
154
+ if (!container[typeName]) {
155
+ container[typeName] = {};
156
+ }
157
+ for (const fieldName in fields) {
158
+ if (fields.hasOwnProperty(fieldName)) {
159
+ const resolver = fields[fieldName];
160
+ if (isResolveFn(resolver)) {
161
+ if (container[typeName][fieldName]) {
162
+ throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}"`, useLocation({ dirname: config.dirname, id: config.id }));
163
+ }
164
+ writeResolverMetadata(resolver, config);
165
+ container[typeName][fieldName] = resolver;
166
+ }
167
+ else if (isResolveOptions(resolver)) {
168
+ if (!container[typeName][fieldName]) {
169
+ container[typeName][fieldName] = {};
170
+ }
171
+ // resolve
172
+ if (isDefined(resolver.resolve)) {
173
+ if (container[typeName][fieldName].resolve) {
174
+ throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (resolve method)`, useLocation({ dirname: config.dirname, id: config.id }));
175
+ }
176
+ writeResolverMetadata(resolver.resolve, config);
177
+ container[typeName][fieldName].resolve = resolver.resolve;
178
+ }
179
+ // subscribe
180
+ if (isDefined(resolver.subscribe)) {
181
+ if (container[typeName][fieldName].subscribe) {
182
+ throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (subscribe method)`, useLocation({ dirname: config.dirname, id: config.id }));
183
+ }
184
+ writeResolverMetadata(resolver.subscribe, config);
185
+ container[typeName][fieldName].subscribe = resolver.subscribe;
186
+ }
187
+ // extensions
188
+ if (isDefined(resolver.extensions)) {
189
+ if (container[typeName][fieldName].extensions) {
190
+ throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (extensions object)`, useLocation({ dirname: config.dirname, id: config.id }));
191
+ }
192
+ writeResolverMetadata(resolver.extensions, config);
193
+ container[typeName][fieldName].extensions = resolver.extensions;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ function addScalar({ typeName, resolver, container, config, }) {
200
+ if (container[typeName]) {
201
+ throw new ResolverDuplicatedError(`Duplicated resolver of scalar "${typeName}"`, useLocation({ dirname: config.dirname, id: config.id }));
202
+ }
203
+ writeResolverMetadata(resolver.parseLiteral, config);
204
+ writeResolverMetadata(resolver.parseValue, config);
205
+ writeResolverMetadata(resolver.serialize, config);
206
+ container[typeName] = resolver;
207
+ }
208
+ function addEnum({ typeName, resolver, container, config, }) {
209
+ if (!container[typeName]) {
210
+ container[typeName] = {};
211
+ }
212
+ for (const key in resolver) {
213
+ if (resolver.hasOwnProperty(key)) {
214
+ const value = resolver[key];
215
+ if (container[typeName][key]) {
216
+ throw new ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${key}" enum value`, useLocation({ dirname: config.dirname, id: config.id }));
217
+ }
218
+ container[typeName][key] = value;
219
+ }
220
+ }
221
+ }
222
+ /**
223
+ * Helps to make sure a resolver has a corresponding type/field definition.
224
+ * We don't want to pass resolve function that are not related to the module.
225
+ */
226
+ function ensureImplements(metadata) {
227
+ return {
228
+ type(name, field) {
229
+ var _a, _b;
230
+ const type = []
231
+ .concat((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[name], (_b = metadata.extends) === null || _b === void 0 ? void 0 : _b[name])
232
+ .filter(isDefined);
233
+ if (type === null || type === void 0 ? void 0 : type.includes(field)) {
234
+ return true;
235
+ }
236
+ const id = `"${name}.${field}"`;
237
+ throw new ExtraResolverError(`Resolver of "${id}" type cannot be implemented`, `${id} is not defined`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
238
+ },
239
+ scalar(name) {
240
+ var _a;
241
+ if ((((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a.__scalars) || []).includes(name)) {
242
+ return true;
243
+ }
244
+ throw new ExtraResolverError(`Resolver of "${name}" scalar cannot be implemented`, `${name} is not defined`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
245
+ },
246
+ };
247
+ }
248
+ function writeResolverMetadata(resolver, config) {
249
+ if (!resolver) {
250
+ return;
251
+ }
252
+ resolver[resolverMetadataProp] = {
253
+ moduleId: config.id,
254
+ };
255
+ }
256
+ export function readResolverMetadata(resolver) {
257
+ return resolver[resolverMetadataProp];
258
+ }
259
+ /**
260
+ * In order to use middlewares on fields
261
+ * that are defined in SDL but have no implemented resolvers,
262
+ * we would have to recreate GraphQLSchema and wrap resolve functions.
263
+ *
264
+ * Since we can't access GraphQLSchema on a module level
265
+ * and recreating GraphQLSchema seems unreasonable,
266
+ * we can create default resolvers instead.
267
+ *
268
+ * @example
269
+ *
270
+ * gql`
271
+ * type Query {
272
+ * me: User!
273
+ * }
274
+ *
275
+ * type User {
276
+ * name: String!
277
+ * }
278
+ * `
279
+ *
280
+ * The resolver of `Query.me` is implemented and resolver of `User.name` is not.
281
+ * In case where a middleware wants to intercept the resolver of `User.name`,
282
+ * we use a default field resolver from `graphql` package
283
+ * and put it next to other defined resolvers.
284
+ *
285
+ * This way our current logic of wrapping resolvers and running
286
+ * middleware functions stays untouched.
287
+ */
288
+ function addDefaultResolvers(resolvers, middlewareMap, config) {
289
+ const container = resolvers;
290
+ const sdl = Array.isArray(config.typeDefs)
291
+ ? concatAST(config.typeDefs)
292
+ : config.typeDefs;
293
+ function hasMiddleware(typeName, fieldName) {
294
+ var _a, _b, _c, _d, _e, _f;
295
+ return ((((_b = (_a = middlewareMap['*']) === null || _a === void 0 ? void 0 : _a['*']) === null || _b === void 0 ? void 0 : _b.length) ||
296
+ ((_d = (_c = middlewareMap[typeName]) === null || _c === void 0 ? void 0 : _c['*']) === null || _d === void 0 ? void 0 : _d.length) ||
297
+ ((_f = (_e = middlewareMap[typeName]) === null || _e === void 0 ? void 0 : _e[fieldName]) === null || _f === void 0 ? void 0 : _f.length)) > 0);
298
+ }
299
+ sdl.definitions.forEach((definition) => {
300
+ if (definition.kind === Kind.OBJECT_TYPE_DEFINITION ||
301
+ definition.kind === Kind.OBJECT_TYPE_EXTENSION) {
302
+ // Right now we only support Object type
303
+ if (definition.fields) {
304
+ const typeName = definition.name.value;
305
+ definition.fields.forEach((field) => {
306
+ var _a;
307
+ const fieldName = field.name.value;
308
+ if (!((_a = container[typeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) &&
309
+ hasMiddleware(typeName, fieldName)) {
310
+ if (!container[typeName]) {
311
+ container[typeName] = {};
312
+ }
313
+ container[typeName][fieldName] = defaultFieldResolver;
314
+ }
315
+ });
316
+ }
317
+ }
318
+ });
319
+ return container;
320
+ }
321
+ //
322
+ // Resolver helpers
323
+ //
324
+ function isResolveFn(value) {
325
+ return typeof value === 'function';
326
+ }
327
+ function isResolveOptions(value) {
328
+ return (isDefined(value.resolve) ||
329
+ isDefined(value.subscribe) ||
330
+ isDefined(value.extensions));
331
+ }
332
+ function isScalarResolver(obj) {
333
+ return obj instanceof GraphQLScalarType;
334
+ }
335
+ function isEnumResolver(obj) {
336
+ return Object.values(obj).every(isPrimitive);
337
+ }
@@ -0,0 +1,18 @@
1
+ import { InjectionToken } from '../di';
2
+ /**
3
+ * @api
4
+ * `MODULE_ID` is an InjectionToken representing module's ID
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { MODULE_ID, Inject, Injectable } from 'graphql-modules';
9
+ *
10
+ * (A)Injectable()
11
+ * export class Data {
12
+ * constructor((A)Inject(MODULE_ID) moduleId: string) {
13
+ * console.log(`Data used in ${moduleId} module`)
14
+ * }
15
+ * }
16
+ * ```
17
+ */
18
+ export const MODULE_ID = new InjectionToken('module-id');
@@ -0,0 +1,21 @@
1
+ import { Kind } from 'graphql';
2
+ import { NonDocumentNodeError, useLocation } from '../shared/errors';
3
+ /**
4
+ * Create a list of DocumentNode objects based on Module's config.
5
+ * Add a location, so we get richer errors.
6
+ */
7
+ export function createTypeDefs(config) {
8
+ const typeDefs = Array.isArray(config.typeDefs)
9
+ ? config.typeDefs
10
+ : [config.typeDefs];
11
+ ensureDocumentNode(config, typeDefs);
12
+ return typeDefs;
13
+ }
14
+ function ensureDocumentNode(config, typeDefs) {
15
+ function ensureEach(doc, i) {
16
+ if ((doc === null || doc === void 0 ? void 0 : doc.kind) !== Kind.DOCUMENT) {
17
+ throw new NonDocumentNodeError(`Expected parsed document but received ${typeof doc} at index ${i} in typeDefs list`, useLocation(config));
18
+ }
19
+ }
20
+ typeDefs.forEach(ensureEach);
21
+ }
File without changes
File without changes
@@ -0,0 +1,69 @@
1
+ export class ModuleNonUniqueIdError extends ExtendableBuiltin(Error) {
2
+ constructor(message, ...rest) {
3
+ super(composeMessage(message, ...rest));
4
+ this.name = this.constructor.name;
5
+ this.message = composeMessage(message, ...rest);
6
+ }
7
+ }
8
+ export class ModuleDuplicatedError extends ExtendableBuiltin(Error) {
9
+ constructor(message, ...rest) {
10
+ super(composeMessage(message, ...rest));
11
+ this.name = this.constructor.name;
12
+ this.message = composeMessage(message, ...rest);
13
+ }
14
+ }
15
+ export class ExtraResolverError extends ExtendableBuiltin(Error) {
16
+ constructor(message, ...rest) {
17
+ super(composeMessage(message, ...rest));
18
+ this.name = this.constructor.name;
19
+ this.message = composeMessage(message, ...rest);
20
+ }
21
+ }
22
+ export class ExtraMiddlewareError extends ExtendableBuiltin(Error) {
23
+ constructor(message, ...rest) {
24
+ super(composeMessage(message, ...rest));
25
+ this.name = this.constructor.name;
26
+ this.message = composeMessage(message, ...rest);
27
+ }
28
+ }
29
+ export class ResolverDuplicatedError extends ExtendableBuiltin(Error) {
30
+ constructor(message, ...rest) {
31
+ super(composeMessage(message, ...rest));
32
+ this.name = this.constructor.name;
33
+ this.message = composeMessage(message, ...rest);
34
+ }
35
+ }
36
+ export class ResolverInvalidError extends ExtendableBuiltin(Error) {
37
+ constructor(message, ...rest) {
38
+ super(composeMessage(message, ...rest));
39
+ this.name = this.constructor.name;
40
+ this.message = composeMessage(message, ...rest);
41
+ }
42
+ }
43
+ export class NonDocumentNodeError extends ExtendableBuiltin(Error) {
44
+ constructor(message, ...rest) {
45
+ super(composeMessage(message, ...rest));
46
+ this.name = this.constructor.name;
47
+ this.message = composeMessage(message, ...rest);
48
+ }
49
+ }
50
+ // helpers
51
+ export function useLocation({ dirname, id }) {
52
+ return dirname
53
+ ? `Module "${id}" located at ${dirname}`
54
+ : [
55
+ `Module "${id}"`,
56
+ `Hint: pass __dirname to "dirname" option of your modules to get more insightful errors`,
57
+ ].join('\n');
58
+ }
59
+ export function ExtendableBuiltin(cls) {
60
+ function ExtendableBuiltin() {
61
+ cls.apply(this, arguments);
62
+ }
63
+ ExtendableBuiltin.prototype = Object.create(cls.prototype);
64
+ Object.setPrototypeOf(ExtendableBuiltin, cls);
65
+ return ExtendableBuiltin;
66
+ }
67
+ export function composeMessage(...lines) {
68
+ return lines.join('\n');
69
+ }
@@ -0,0 +1,9 @@
1
+ import { parse, Kind } from 'graphql';
2
+ export function gql(literals) {
3
+ const result = typeof literals === 'string' ? literals : literals[0];
4
+ const parsed = parse(result);
5
+ if (!parsed || parsed.kind !== Kind.DOCUMENT) {
6
+ throw new Error('Not a valid GraphQL document.');
7
+ }
8
+ return parsed;
9
+ }
@@ -0,0 +1,103 @@
1
+ import { mergeDeepWith } from 'ramda';
2
+ import { isDefined } from './utils';
3
+ import { ExtraMiddlewareError, useLocation } from './errors';
4
+ export function compose(middleware) {
5
+ if (!Array.isArray(middleware)) {
6
+ throw new TypeError('Middleware stack must be an array!');
7
+ }
8
+ for (const fn of middleware) {
9
+ if (typeof fn !== 'function') {
10
+ throw new TypeError('Middleware must be composed of functions!');
11
+ }
12
+ }
13
+ return function composed(context, next) {
14
+ // last called middleware
15
+ let index = -1;
16
+ function dispatch(i) {
17
+ if (i <= index) {
18
+ return Promise.reject(new Error('next() called multiple times'));
19
+ }
20
+ index = i;
21
+ const fn = i === middleware.length ? next : middleware[i];
22
+ if (!fn) {
23
+ return Promise.resolve();
24
+ }
25
+ try {
26
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
27
+ }
28
+ catch (err) {
29
+ return Promise.reject(err);
30
+ }
31
+ }
32
+ return dispatch(0);
33
+ };
34
+ }
35
+ export function createMiddleware(path, middlewareMap) {
36
+ const middlewares = middlewareMap ? pickMiddlewares(path, middlewareMap) : [];
37
+ return compose(middlewares);
38
+ }
39
+ export function mergeMiddlewareMaps(app, mod) {
40
+ const merge = (left, right) => {
41
+ return mergeDeepWith((l, r) => {
42
+ if (Array.isArray(l)) {
43
+ return l.concat(r || []);
44
+ }
45
+ return merge(l, r);
46
+ }, left, right);
47
+ };
48
+ return merge(app, mod);
49
+ }
50
+ function pickMiddlewares(path, middlewareMap) {
51
+ var _a;
52
+ const middlewares = [];
53
+ const [type, field] = path;
54
+ if ((_a = middlewareMap['*']) === null || _a === void 0 ? void 0 : _a['*']) {
55
+ middlewares.push(...middlewareMap['*']['*']);
56
+ }
57
+ const typeMap = middlewareMap[type];
58
+ if (typeMap) {
59
+ if (typeMap['*']) {
60
+ middlewares.push(...typeMap['*']);
61
+ }
62
+ if (field && typeMap[field]) {
63
+ middlewares.push(...typeMap[field]);
64
+ }
65
+ }
66
+ return middlewares.filter(isDefined);
67
+ }
68
+ export function validateMiddlewareMap(middlewareMap, metadata) {
69
+ const exists = checkExistence(metadata);
70
+ for (const typeName in middlewareMap.types) {
71
+ if (middlewareMap.types.hasOwnProperty(typeName)) {
72
+ const typeMiddlewareMap = middlewareMap[typeName];
73
+ if (!exists.type(typeName)) {
74
+ throw new ExtraMiddlewareError(`Cannot apply a middleware to non existing "${typeName}" type`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
75
+ }
76
+ for (const fieldName in typeMiddlewareMap[typeName]) {
77
+ if (typeMiddlewareMap[typeName].hasOwnProperty(fieldName)) {
78
+ if (!exists.field(typeName, fieldName)) {
79
+ throw new ExtraMiddlewareError(`Cannot apply a middleware to non existing "${typeName}.${fieldName}" type.field`, useLocation({ dirname: metadata.dirname, id: metadata.id }));
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ /**
87
+ * Helps to make sure a middleware has a corresponding type/field definition.
88
+ * We don't want to pass a module-level middlewares that are not related to the module.
89
+ * Not because it's dangerous but to prevent unused middlewares.
90
+ */
91
+ function checkExistence(metadata) {
92
+ return {
93
+ type(name) {
94
+ var _a, _b;
95
+ return isDefined(((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[name]) || ((_b = metadata.extends) === null || _b === void 0 ? void 0 : _b[name]));
96
+ },
97
+ field(type, name) {
98
+ var _a, _b, _c, _d;
99
+ return isDefined(((_b = (_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[type]) === null || _b === void 0 ? void 0 : _b.includes(name)) ||
100
+ ((_d = (_c = metadata.extends) === null || _c === void 0 ? void 0 : _c[type]) === null || _d === void 0 ? void 0 : _d.includes(name)));
101
+ },
102
+ };
103
+ }
File without changes
@@ -0,0 +1,101 @@
1
+ import { GraphQLSchema } from 'graphql';
2
+ export function flatten(arr) {
3
+ return Array.prototype.concat(...arr);
4
+ }
5
+ export function isDefined(val) {
6
+ return !isNil(val);
7
+ }
8
+ export function isNil(val) {
9
+ return val === null || typeof val === 'undefined';
10
+ }
11
+ export function isObject(val) {
12
+ return Object.prototype.toString.call(val) === '[object Object]';
13
+ }
14
+ export function isPrimitive(val) {
15
+ return ['number', 'string', 'boolean', 'symbol', 'bigint'].includes(typeof val);
16
+ }
17
+ export function isAsyncIterable(obj) {
18
+ return obj && typeof obj[Symbol.asyncIterator] === 'function';
19
+ }
20
+ export function tapAsyncIterator(iterable, doneCallback) {
21
+ const iteratorMethod = iterable[Symbol.asyncIterator];
22
+ const iterator = iteratorMethod.call(iterable);
23
+ function mapResult(result) {
24
+ if (result.done) {
25
+ doneCallback();
26
+ }
27
+ return result;
28
+ }
29
+ return {
30
+ async next() {
31
+ try {
32
+ let result = await iterator.next();
33
+ return mapResult(result);
34
+ }
35
+ catch (error) {
36
+ doneCallback();
37
+ throw error;
38
+ }
39
+ },
40
+ async return(value) {
41
+ try {
42
+ const result = await iterator.return(value);
43
+ return mapResult(result);
44
+ }
45
+ catch (error) {
46
+ doneCallback();
47
+ throw error;
48
+ }
49
+ },
50
+ throw(error) {
51
+ doneCallback();
52
+ return iterator.throw(error);
53
+ },
54
+ [Symbol.asyncIterator]() {
55
+ return this;
56
+ },
57
+ };
58
+ }
59
+ export function once(cb) {
60
+ let called = false;
61
+ return () => {
62
+ if (!called) {
63
+ called = true;
64
+ cb();
65
+ }
66
+ };
67
+ }
68
+ export function share(factory) {
69
+ let cached = null;
70
+ return (arg) => {
71
+ if (!cached) {
72
+ cached = factory(arg);
73
+ }
74
+ return cached;
75
+ };
76
+ }
77
+ export function uniqueId(isNotUsed) {
78
+ let id;
79
+ while (!isNotUsed((id = Math.random().toString(16).substr(2)))) { }
80
+ return id;
81
+ }
82
+ export function isNotSchema(obj) {
83
+ return obj instanceof GraphQLSchema === false;
84
+ }
85
+ export function merge(source, target) {
86
+ const result = {
87
+ ...source,
88
+ ...target,
89
+ };
90
+ function attachSymbols(obj) {
91
+ const symbols = Object.getOwnPropertySymbols(obj);
92
+ for (const symbol of symbols) {
93
+ result[symbol] = obj[symbol];
94
+ }
95
+ }
96
+ if (source) {
97
+ attachSymbols(source);
98
+ }
99
+ attachSymbols(target);
100
+ return result;
101
+ }
@@ -0,0 +1,6 @@
1
+ export function provideEmpty(token) {
2
+ return {
3
+ provide: token,
4
+ useValue: {},
5
+ };
6
+ }
@@ -0,0 +1,7 @@
1
+ export function execute(app, inputs, options) {
2
+ const executor = app.createExecution(options);
3
+ return executor({
4
+ schema: app.schema,
5
+ ...inputs,
6
+ });
7
+ }