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.
Files changed (161) 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/di/decorators.js +78 -0
  11. package/cjs/di/errors.js +87 -0
  12. package/cjs/di/forward-ref.js +26 -0
  13. package/cjs/di/index.js +19 -0
  14. package/cjs/di/injector.js +173 -0
  15. package/cjs/di/metadata.js +22 -0
  16. package/cjs/di/providers.js +60 -0
  17. package/cjs/di/registry.js +44 -0
  18. package/cjs/di/resolution.js +166 -0
  19. package/cjs/di/utils.js +44 -0
  20. package/cjs/index.js +31 -0
  21. package/cjs/module/factory.js +71 -0
  22. package/cjs/module/metadata.js +110 -0
  23. package/cjs/module/module.js +27 -0
  24. package/cjs/module/resolvers.js +341 -0
  25. package/cjs/module/tokens.js +21 -0
  26. package/cjs/module/type-defs.js +24 -0
  27. package/cjs/module/types.js +0 -0
  28. package/cjs/package.json +1 -0
  29. package/cjs/shared/di.js +0 -0
  30. package/cjs/shared/errors.js +82 -0
  31. package/cjs/shared/gql.js +12 -0
  32. package/cjs/shared/middleware.js +109 -0
  33. package/cjs/shared/types.js +0 -0
  34. package/cjs/shared/utils.js +115 -0
  35. package/cjs/testing/di.js +9 -0
  36. package/cjs/testing/graphql.js +10 -0
  37. package/cjs/testing/index.js +17 -0
  38. package/cjs/testing/test-application.js +65 -0
  39. package/cjs/testing/test-injector.js +22 -0
  40. package/cjs/testing/test-module.js +270 -0
  41. package/esm/application/apollo.js +77 -0
  42. package/esm/application/application.js +146 -0
  43. package/esm/application/context.js +140 -0
  44. package/esm/application/di.js +42 -0
  45. package/esm/application/execution.js +39 -0
  46. package/esm/application/operation-controller.js +13 -0
  47. package/esm/application/subscription.js +51 -0
  48. package/esm/application/tokens.js +17 -0
  49. package/esm/application/types.js +0 -0
  50. package/esm/di/decorators.js +72 -0
  51. package/esm/di/errors.js +79 -0
  52. package/esm/di/forward-ref.js +22 -0
  53. package/esm/di/index.js +4 -0
  54. package/esm/di/injector.js +168 -0
  55. package/esm/di/metadata.js +17 -0
  56. package/esm/di/providers.js +50 -0
  57. package/esm/di/registry.js +40 -0
  58. package/esm/di/resolution.js +159 -0
  59. package/esm/di/utils.js +36 -0
  60. package/esm/index.js +16 -0
  61. package/esm/module/factory.js +68 -0
  62. package/esm/module/metadata.js +107 -0
  63. package/esm/module/module.js +24 -0
  64. package/esm/module/resolvers.js +337 -0
  65. package/esm/module/tokens.js +18 -0
  66. package/esm/module/type-defs.js +21 -0
  67. package/esm/module/types.js +0 -0
  68. package/esm/shared/di.js +0 -0
  69. package/esm/shared/errors.js +69 -0
  70. package/esm/shared/gql.js +9 -0
  71. package/esm/shared/middleware.js +103 -0
  72. package/esm/shared/types.js +0 -0
  73. package/esm/shared/utils.js +101 -0
  74. package/esm/testing/di.js +6 -0
  75. package/esm/testing/graphql.js +7 -0
  76. package/esm/testing/index.js +14 -0
  77. package/esm/testing/test-application.js +62 -0
  78. package/esm/testing/test-injector.js +18 -0
  79. package/esm/testing/test-module.js +266 -0
  80. package/package.json +30 -10
  81. package/typings/application/apollo.d.ts +22 -0
  82. package/typings/application/application.d.ts +32 -0
  83. package/typings/application/context.d.ts +24 -0
  84. package/typings/application/di.d.ts +22 -0
  85. package/typings/application/execution.d.ts +8 -0
  86. package/typings/application/operation-controller.d.ts +5 -0
  87. package/typings/application/subscription.d.ts +8 -0
  88. package/typings/application/tokens.d.ts +17 -0
  89. package/typings/application/types.d.ts +130 -0
  90. package/typings/di/decorators.d.ts +11 -0
  91. package/typings/di/errors.d.ts +16 -0
  92. package/typings/di/forward-ref.d.ts +7 -0
  93. package/typings/di/index.d.ts +5 -0
  94. package/typings/di/injector.d.ts +50 -0
  95. package/typings/di/metadata.d.ts +12 -0
  96. package/typings/di/providers.d.ts +44 -0
  97. package/typings/di/registry.d.ts +11 -0
  98. package/typings/di/resolution.d.ts +63 -0
  99. package/typings/di/utils.d.ts +8 -0
  100. package/typings/index.d.ts +13 -0
  101. package/typings/module/factory.d.ts +16 -0
  102. package/typings/module/metadata.d.ts +12 -0
  103. package/typings/module/module.d.ts +22 -0
  104. package/typings/module/resolvers.d.ts +13 -0
  105. package/typings/module/tokens.d.ts +18 -0
  106. package/typings/module/type-defs.d.ts +7 -0
  107. package/typings/module/types.d.ts +51 -0
  108. package/typings/shared/di.d.ts +3 -0
  109. package/typings/shared/errors.d.ts +36 -0
  110. package/typings/shared/gql.d.ts +2 -0
  111. package/typings/shared/middleware.d.ts +21 -0
  112. package/typings/shared/types.d.ts +22 -0
  113. package/typings/shared/utils.d.ts +12 -0
  114. package/typings/testing/di.d.ts +2 -0
  115. package/typings/testing/graphql.d.ts +14 -0
  116. package/typings/testing/index.d.ts +14 -0
  117. package/typings/testing/test-application.d.ts +2 -0
  118. package/typings/testing/test-injector.d.ts +4 -0
  119. package/typings/testing/test-module.d.ts +10 -0
  120. package/LICENSE.md +0 -21
  121. package/index.js +0 -2359
  122. package/index.mjs +0 -2344
  123. /package/{application/apollo.d.ts → typings/application/apollo.d.cts} +0 -0
  124. /package/{application/application.d.ts → typings/application/application.d.cts} +0 -0
  125. /package/{application/context.d.ts → typings/application/context.d.cts} +0 -0
  126. /package/{application/di.d.ts → typings/application/di.d.cts} +0 -0
  127. /package/{application/execution.d.ts → typings/application/execution.d.cts} +0 -0
  128. /package/{application/operation-controller.d.ts → typings/application/operation-controller.d.cts} +0 -0
  129. /package/{application/subscription.d.ts → typings/application/subscription.d.cts} +0 -0
  130. /package/{application/tokens.d.ts → typings/application/tokens.d.cts} +0 -0
  131. /package/{application/types.d.ts → typings/application/types.d.cts} +0 -0
  132. /package/{di/decorators.d.ts → typings/di/decorators.d.cts} +0 -0
  133. /package/{di/errors.d.ts → typings/di/errors.d.cts} +0 -0
  134. /package/{di/forward-ref.d.ts → typings/di/forward-ref.d.cts} +0 -0
  135. /package/{di/index.d.ts → typings/di/index.d.cts} +0 -0
  136. /package/{di/injector.d.ts → typings/di/injector.d.cts} +0 -0
  137. /package/{di/metadata.d.ts → typings/di/metadata.d.cts} +0 -0
  138. /package/{di/providers.d.ts → typings/di/providers.d.cts} +0 -0
  139. /package/{di/registry.d.ts → typings/di/registry.d.cts} +0 -0
  140. /package/{di/resolution.d.ts → typings/di/resolution.d.cts} +0 -0
  141. /package/{di/utils.d.ts → typings/di/utils.d.cts} +0 -0
  142. /package/{index.d.ts → typings/index.d.cts} +0 -0
  143. /package/{module/factory.d.ts → typings/module/factory.d.cts} +0 -0
  144. /package/{module/metadata.d.ts → typings/module/metadata.d.cts} +0 -0
  145. /package/{module/module.d.ts → typings/module/module.d.cts} +0 -0
  146. /package/{module/resolvers.d.ts → typings/module/resolvers.d.cts} +0 -0
  147. /package/{module/tokens.d.ts → typings/module/tokens.d.cts} +0 -0
  148. /package/{module/type-defs.d.ts → typings/module/type-defs.d.cts} +0 -0
  149. /package/{module/types.d.ts → typings/module/types.d.cts} +0 -0
  150. /package/{shared/di.d.ts → typings/shared/di.d.cts} +0 -0
  151. /package/{shared/errors.d.ts → typings/shared/errors.d.cts} +0 -0
  152. /package/{shared/gql.d.ts → typings/shared/gql.d.cts} +0 -0
  153. /package/{shared/middleware.d.ts → typings/shared/middleware.d.cts} +0 -0
  154. /package/{shared/types.d.ts → typings/shared/types.d.cts} +0 -0
  155. /package/{shared/utils.d.ts → typings/shared/utils.d.cts} +0 -0
  156. /package/{testing/di.d.ts → typings/testing/di.d.cts} +0 -0
  157. /package/{testing/graphql.d.ts → typings/testing/graphql.d.cts} +0 -0
  158. /package/{testing/index.d.ts → typings/testing/index.d.cts} +0 -0
  159. /package/{testing/test-application.d.ts → typings/testing/test-application.d.cts} +0 -0
  160. /package/{testing/test-injector.d.ts → typings/testing/test-injector.d.cts} +0 -0
  161. /package/{testing/test-module.d.ts → typings/testing/test-module.d.cts} +0 -0
@@ -0,0 +1,107 @@
1
+ import { visit, Kind, } from 'graphql';
2
+ export function metadataFactory(typeDefs, config) {
3
+ const implemented = {};
4
+ const extended = {};
5
+ function collectObjectDefinition(node) {
6
+ if (!implemented[node.name.value]) {
7
+ implemented[node.name.value] = [];
8
+ }
9
+ if (node.fields && node.fields.length > 0) {
10
+ implemented[node.name.value].push(...node.fields.map((field) => field.name.value));
11
+ }
12
+ if (node.kind === Kind.OBJECT_TYPE_DEFINITION) {
13
+ implemented[node.name.value].push('__isTypeOf');
14
+ }
15
+ if (node.kind === Kind.OBJECT_TYPE_DEFINITION) {
16
+ implemented[node.name.value].push('__resolveReference');
17
+ implemented[node.name.value].push('__resolveObject');
18
+ }
19
+ if (node.kind === Kind.INTERFACE_TYPE_DEFINITION) {
20
+ implemented[node.name.value].push('__resolveType');
21
+ }
22
+ }
23
+ function collectObjectExtension(node) {
24
+ if (node.fields) {
25
+ if (!extended[node.name.value]) {
26
+ extended[node.name.value] = [];
27
+ }
28
+ node.fields.forEach((field) => {
29
+ extended[node.name.value].push(field.name.value);
30
+ });
31
+ }
32
+ }
33
+ for (const doc of typeDefs) {
34
+ visit(doc, {
35
+ // Object
36
+ ObjectTypeDefinition(node) {
37
+ collectObjectDefinition(node);
38
+ },
39
+ ObjectTypeExtension(node) {
40
+ collectObjectExtension(node);
41
+ },
42
+ // Interface
43
+ InterfaceTypeDefinition(node) {
44
+ collectObjectDefinition(node);
45
+ },
46
+ InterfaceTypeExtension(node) {
47
+ collectObjectExtension(node);
48
+ },
49
+ // Union
50
+ UnionTypeDefinition(node) {
51
+ if (!implemented[node.name.value]) {
52
+ implemented[node.name.value] = [];
53
+ }
54
+ if (node.types) {
55
+ implemented[node.name.value].push(...node.types.map((type) => type.name.value));
56
+ }
57
+ implemented[node.name.value].push('__resolveType');
58
+ },
59
+ UnionTypeExtension(node) {
60
+ if (node.types) {
61
+ if (!extended[node.name.value]) {
62
+ extended[node.name.value] = [];
63
+ }
64
+ extended[node.name.value].push(...node.types.map((type) => type.name.value));
65
+ }
66
+ },
67
+ // Input
68
+ InputObjectTypeDefinition(node) {
69
+ collectObjectDefinition(node);
70
+ },
71
+ InputObjectTypeExtension(node) {
72
+ collectObjectExtension(node);
73
+ },
74
+ // Enum
75
+ EnumTypeDefinition(node) {
76
+ if (node.values) {
77
+ if (!implemented[node.name.value]) {
78
+ implemented[node.name.value] = [];
79
+ }
80
+ implemented[node.name.value].push(...node.values.map((value) => value.name.value));
81
+ }
82
+ },
83
+ EnumTypeExtension(node) {
84
+ if (node.values) {
85
+ if (!extended[node.name.value]) {
86
+ extended[node.name.value] = [];
87
+ }
88
+ extended[node.name.value].push(...node.values.map((value) => value.name.value));
89
+ }
90
+ },
91
+ // Scalar
92
+ ScalarTypeDefinition(node) {
93
+ if (!implemented.__scalars) {
94
+ implemented.__scalars = [];
95
+ }
96
+ implemented.__scalars.push(node.name.value);
97
+ },
98
+ });
99
+ }
100
+ return {
101
+ id: config.id,
102
+ typeDefs,
103
+ implements: implemented,
104
+ extends: extended,
105
+ dirname: config.dirname,
106
+ };
107
+ }
@@ -0,0 +1,24 @@
1
+ import { moduleFactory } from './factory';
2
+ /**
3
+ * @api
4
+ * Creates a Module, an element used by Application. Accepts `ModuleConfig`.
5
+ *
6
+ * @example
7
+ *
8
+ * ```typescript
9
+ * import { createModule, gql } from 'graphql-modules';
10
+ *
11
+ * export const usersModule = createModule({
12
+ * id: 'users',
13
+ * typeDefs: gql`
14
+ * // GraphQL SDL
15
+ * `,
16
+ * resolvers: {
17
+ * // ...
18
+ * }
19
+ * });
20
+ * ```
21
+ */
22
+ export function createModule(config) {
23
+ return moduleFactory(config);
24
+ }
@@ -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
+ }