graphql-modules 3.1.2-alpha-20260121023952-c6236f99446644c787494ddb1a9a973180bab70e → 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 +29 -9
- 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
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.moduleFactory = moduleFactory;
|
|
4
|
+
const metadata_1 = require("./metadata");
|
|
5
|
+
const resolvers_1 = require("./resolvers");
|
|
6
|
+
const type_defs_1 = require("./type-defs");
|
|
7
|
+
const tokens_1 = require("./tokens");
|
|
8
|
+
const di_1 = require("../di");
|
|
9
|
+
const resolution_1 = require("./../di/resolution");
|
|
10
|
+
function lazy(getter) {
|
|
11
|
+
let called = false;
|
|
12
|
+
let computedValue;
|
|
13
|
+
return {
|
|
14
|
+
get value() {
|
|
15
|
+
if (!called) {
|
|
16
|
+
called = true;
|
|
17
|
+
computedValue = getter();
|
|
18
|
+
}
|
|
19
|
+
return computedValue;
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function moduleFactory(config) {
|
|
24
|
+
const typeDefs = (0, type_defs_1.createTypeDefs)(config);
|
|
25
|
+
const metadata = (0, metadata_1.metadataFactory)(typeDefs, config);
|
|
26
|
+
const providers = lazy(() => typeof config.providers === 'function'
|
|
27
|
+
? config.providers()
|
|
28
|
+
: config.providers);
|
|
29
|
+
// Filter providers and keep them this way
|
|
30
|
+
// so we don't do this filtering multiple times.
|
|
31
|
+
// Providers don't change over time, so it's safe to do it.
|
|
32
|
+
const operationProviders = lazy(() => di_1.ReflectiveInjector.resolve((0, di_1.onlyOperationProviders)(providers.value)));
|
|
33
|
+
const singletonProviders = lazy(() => di_1.ReflectiveInjector.resolve((0, di_1.onlySingletonProviders)(providers.value)));
|
|
34
|
+
const mod = {
|
|
35
|
+
id: config.id,
|
|
36
|
+
config,
|
|
37
|
+
metadata,
|
|
38
|
+
typeDefs,
|
|
39
|
+
// Factory is called once on application creation,
|
|
40
|
+
// before we even handle GraphQL Operation
|
|
41
|
+
factory(app) {
|
|
42
|
+
const resolvedModule = mod;
|
|
43
|
+
resolvedModule.singletonProviders = singletonProviders.value;
|
|
44
|
+
resolvedModule.operationProviders = operationProviders.value;
|
|
45
|
+
// Create a module-level Singleton injector
|
|
46
|
+
const injector = di_1.ReflectiveInjector.createFromResolved({
|
|
47
|
+
name: `Module "${config.id}" (Singleton Scope)`,
|
|
48
|
+
providers: resolvedModule.singletonProviders.concat((0, resolution_1.resolveProviders)([
|
|
49
|
+
{
|
|
50
|
+
// with module's id, useful in Logging and stuff
|
|
51
|
+
provide: tokens_1.MODULE_ID,
|
|
52
|
+
useValue: config.id,
|
|
53
|
+
},
|
|
54
|
+
])),
|
|
55
|
+
parent: app.injector,
|
|
56
|
+
});
|
|
57
|
+
// We attach injector property to existing `mod` object
|
|
58
|
+
// because we want to keep references
|
|
59
|
+
// that are later on used in testing utils
|
|
60
|
+
resolvedModule.injector = injector;
|
|
61
|
+
// Create resolvers object based on module's config
|
|
62
|
+
// It involves wrapping a resolver with middlewares
|
|
63
|
+
// and other things like validation
|
|
64
|
+
resolvedModule.resolvers = (0, resolvers_1.createResolvers)(config, metadata, {
|
|
65
|
+
middlewareMap: app.middlewares,
|
|
66
|
+
});
|
|
67
|
+
return resolvedModule;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return mod;
|
|
71
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.metadataFactory = metadataFactory;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
function metadataFactory(typeDefs, config) {
|
|
6
|
+
const implemented = {};
|
|
7
|
+
const extended = {};
|
|
8
|
+
function collectObjectDefinition(node) {
|
|
9
|
+
if (!implemented[node.name.value]) {
|
|
10
|
+
implemented[node.name.value] = [];
|
|
11
|
+
}
|
|
12
|
+
if (node.fields && node.fields.length > 0) {
|
|
13
|
+
implemented[node.name.value].push(...node.fields.map((field) => field.name.value));
|
|
14
|
+
}
|
|
15
|
+
if (node.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
16
|
+
implemented[node.name.value].push('__isTypeOf');
|
|
17
|
+
}
|
|
18
|
+
if (node.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION) {
|
|
19
|
+
implemented[node.name.value].push('__resolveReference');
|
|
20
|
+
implemented[node.name.value].push('__resolveObject');
|
|
21
|
+
}
|
|
22
|
+
if (node.kind === graphql_1.Kind.INTERFACE_TYPE_DEFINITION) {
|
|
23
|
+
implemented[node.name.value].push('__resolveType');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function collectObjectExtension(node) {
|
|
27
|
+
if (node.fields) {
|
|
28
|
+
if (!extended[node.name.value]) {
|
|
29
|
+
extended[node.name.value] = [];
|
|
30
|
+
}
|
|
31
|
+
node.fields.forEach((field) => {
|
|
32
|
+
extended[node.name.value].push(field.name.value);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const doc of typeDefs) {
|
|
37
|
+
(0, graphql_1.visit)(doc, {
|
|
38
|
+
// Object
|
|
39
|
+
ObjectTypeDefinition(node) {
|
|
40
|
+
collectObjectDefinition(node);
|
|
41
|
+
},
|
|
42
|
+
ObjectTypeExtension(node) {
|
|
43
|
+
collectObjectExtension(node);
|
|
44
|
+
},
|
|
45
|
+
// Interface
|
|
46
|
+
InterfaceTypeDefinition(node) {
|
|
47
|
+
collectObjectDefinition(node);
|
|
48
|
+
},
|
|
49
|
+
InterfaceTypeExtension(node) {
|
|
50
|
+
collectObjectExtension(node);
|
|
51
|
+
},
|
|
52
|
+
// Union
|
|
53
|
+
UnionTypeDefinition(node) {
|
|
54
|
+
if (!implemented[node.name.value]) {
|
|
55
|
+
implemented[node.name.value] = [];
|
|
56
|
+
}
|
|
57
|
+
if (node.types) {
|
|
58
|
+
implemented[node.name.value].push(...node.types.map((type) => type.name.value));
|
|
59
|
+
}
|
|
60
|
+
implemented[node.name.value].push('__resolveType');
|
|
61
|
+
},
|
|
62
|
+
UnionTypeExtension(node) {
|
|
63
|
+
if (node.types) {
|
|
64
|
+
if (!extended[node.name.value]) {
|
|
65
|
+
extended[node.name.value] = [];
|
|
66
|
+
}
|
|
67
|
+
extended[node.name.value].push(...node.types.map((type) => type.name.value));
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
// Input
|
|
71
|
+
InputObjectTypeDefinition(node) {
|
|
72
|
+
collectObjectDefinition(node);
|
|
73
|
+
},
|
|
74
|
+
InputObjectTypeExtension(node) {
|
|
75
|
+
collectObjectExtension(node);
|
|
76
|
+
},
|
|
77
|
+
// Enum
|
|
78
|
+
EnumTypeDefinition(node) {
|
|
79
|
+
if (node.values) {
|
|
80
|
+
if (!implemented[node.name.value]) {
|
|
81
|
+
implemented[node.name.value] = [];
|
|
82
|
+
}
|
|
83
|
+
implemented[node.name.value].push(...node.values.map((value) => value.name.value));
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
EnumTypeExtension(node) {
|
|
87
|
+
if (node.values) {
|
|
88
|
+
if (!extended[node.name.value]) {
|
|
89
|
+
extended[node.name.value] = [];
|
|
90
|
+
}
|
|
91
|
+
extended[node.name.value].push(...node.values.map((value) => value.name.value));
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
// Scalar
|
|
95
|
+
ScalarTypeDefinition(node) {
|
|
96
|
+
if (!implemented.__scalars) {
|
|
97
|
+
implemented.__scalars = [];
|
|
98
|
+
}
|
|
99
|
+
implemented.__scalars.push(node.name.value);
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
id: config.id,
|
|
105
|
+
typeDefs,
|
|
106
|
+
implements: implemented,
|
|
107
|
+
extends: extended,
|
|
108
|
+
dirname: config.dirname,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createModule = createModule;
|
|
4
|
+
const factory_1 = require("./factory");
|
|
5
|
+
/**
|
|
6
|
+
* @api
|
|
7
|
+
* Creates a Module, an element used by Application. Accepts `ModuleConfig`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createModule, gql } from 'graphql-modules';
|
|
13
|
+
*
|
|
14
|
+
* export const usersModule = createModule({
|
|
15
|
+
* id: 'users',
|
|
16
|
+
* typeDefs: gql`
|
|
17
|
+
* // GraphQL SDL
|
|
18
|
+
* `,
|
|
19
|
+
* resolvers: {
|
|
20
|
+
* // ...
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function createModule(config) {
|
|
26
|
+
return (0, factory_1.moduleFactory)(config);
|
|
27
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createResolvers = createResolvers;
|
|
4
|
+
exports.readResolverMetadata = readResolverMetadata;
|
|
5
|
+
const graphql_1 = require("graphql");
|
|
6
|
+
const errors_1 = require("./../shared/errors");
|
|
7
|
+
const utils_1 = require("../shared/utils");
|
|
8
|
+
const middleware_1 = require("../shared/middleware");
|
|
9
|
+
const resolverMetadataProp = Symbol('metadata');
|
|
10
|
+
function createResolvers(config, metadata, app) {
|
|
11
|
+
const ensure = ensureImplements(metadata);
|
|
12
|
+
const normalizedModuleMiddlewareMap = config.middlewares || {};
|
|
13
|
+
const middlewareMap = (0, middleware_1.mergeMiddlewareMaps)(app.middlewareMap, normalizedModuleMiddlewareMap);
|
|
14
|
+
(0, middleware_1.validateMiddlewareMap)(normalizedModuleMiddlewareMap, metadata);
|
|
15
|
+
const resolvers = addDefaultResolvers(mergeResolvers(config), middlewareMap, config);
|
|
16
|
+
// Wrap resolvers
|
|
17
|
+
for (const typeName in resolvers) {
|
|
18
|
+
if (resolvers.hasOwnProperty(typeName)) {
|
|
19
|
+
const obj = resolvers[typeName];
|
|
20
|
+
if (isScalarResolver(obj)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
else if (isEnumResolver(obj)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
else if (obj && typeof obj === 'object') {
|
|
27
|
+
for (const fieldName in obj) {
|
|
28
|
+
if (obj.hasOwnProperty(fieldName)) {
|
|
29
|
+
ensure.type(typeName, fieldName);
|
|
30
|
+
const path = [typeName, fieldName];
|
|
31
|
+
// function
|
|
32
|
+
if (isResolveFn(obj[fieldName])) {
|
|
33
|
+
const resolver = wrapResolver({
|
|
34
|
+
config,
|
|
35
|
+
resolver: obj[fieldName],
|
|
36
|
+
middlewareMap,
|
|
37
|
+
path,
|
|
38
|
+
isTypeResolver: fieldName === '__isTypeOf' || fieldName === '__resolveType',
|
|
39
|
+
isReferenceResolver: fieldName === '__resolveReference',
|
|
40
|
+
isObjectResolver: fieldName === '__resolveObject',
|
|
41
|
+
});
|
|
42
|
+
resolvers[typeName][fieldName] = resolver;
|
|
43
|
+
}
|
|
44
|
+
else if (isResolveOptions(obj[fieldName])) {
|
|
45
|
+
// { resolve }
|
|
46
|
+
if ((0, utils_1.isDefined)(obj[fieldName].resolve)) {
|
|
47
|
+
const resolver = wrapResolver({
|
|
48
|
+
config,
|
|
49
|
+
resolver: obj[fieldName].resolve,
|
|
50
|
+
middlewareMap,
|
|
51
|
+
path,
|
|
52
|
+
});
|
|
53
|
+
resolvers[typeName][fieldName].resolve = resolver;
|
|
54
|
+
}
|
|
55
|
+
// { subscribe }
|
|
56
|
+
if ((0, utils_1.isDefined)(obj[fieldName].subscribe)) {
|
|
57
|
+
const resolver = wrapResolver({
|
|
58
|
+
config,
|
|
59
|
+
resolver: obj[fieldName].subscribe,
|
|
60
|
+
middlewareMap,
|
|
61
|
+
path,
|
|
62
|
+
});
|
|
63
|
+
resolvers[typeName][fieldName].subscribe = resolver;
|
|
64
|
+
}
|
|
65
|
+
if ((0, utils_1.isDefined)(obj[fieldName].extensions)) {
|
|
66
|
+
// Do NOT add a resolve if one is not specified, it will cause
|
|
67
|
+
// change in behavior in systems like `grafast`
|
|
68
|
+
resolvers[typeName][fieldName].extensions =
|
|
69
|
+
obj[fieldName].extensions;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return resolvers;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Wrap a resolver so we use module's context instead of app context.
|
|
81
|
+
* Use a middleware if available.
|
|
82
|
+
* Attach metadata to a resolver (we will see if it's helpful, probably in error handling)
|
|
83
|
+
*/
|
|
84
|
+
function wrapResolver({ resolver, config, path, middlewareMap, isTypeResolver, isReferenceResolver, isObjectResolver, }) {
|
|
85
|
+
if (isTypeResolver || isReferenceResolver) {
|
|
86
|
+
const wrappedResolver = (root, context, info) => {
|
|
87
|
+
const ctx = {
|
|
88
|
+
root,
|
|
89
|
+
context: isReferenceResolver
|
|
90
|
+
? context.ɵgetModuleContext(config.id, context)
|
|
91
|
+
: // We mark the context object as possibly undefined,
|
|
92
|
+
// because graphql-jit for some reason doesn't pass it for isTypeOf or resolveType methods
|
|
93
|
+
context === null || context === void 0 ? void 0 : context.ɵgetModuleContext(config.id, context),
|
|
94
|
+
info,
|
|
95
|
+
};
|
|
96
|
+
return resolver(ctx.root, ctx.context, ctx.info);
|
|
97
|
+
};
|
|
98
|
+
writeResolverMetadata(wrappedResolver, config);
|
|
99
|
+
return wrappedResolver;
|
|
100
|
+
}
|
|
101
|
+
if (isObjectResolver) {
|
|
102
|
+
const wrappedResolver = (root, fields, context, info) => {
|
|
103
|
+
const moduleContext = context.ɵgetModuleContext(config.id, context);
|
|
104
|
+
return resolver(root, fields, moduleContext, info);
|
|
105
|
+
};
|
|
106
|
+
writeResolverMetadata(wrappedResolver, config);
|
|
107
|
+
return wrappedResolver;
|
|
108
|
+
}
|
|
109
|
+
const middleware = (0, middleware_1.createMiddleware)(path, middlewareMap);
|
|
110
|
+
const wrappedResolver = (root, args, context, info) => {
|
|
111
|
+
const ctx = {
|
|
112
|
+
root,
|
|
113
|
+
args,
|
|
114
|
+
context: context.ɵgetModuleContext(config.id, context),
|
|
115
|
+
info,
|
|
116
|
+
};
|
|
117
|
+
return middleware(ctx, () => resolver(ctx.root, ctx.args, ctx.context, ctx.info));
|
|
118
|
+
};
|
|
119
|
+
writeResolverMetadata(wrappedResolver, config);
|
|
120
|
+
return wrappedResolver;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* We iterate over every defined resolver and check if it's valid and not duplicated
|
|
124
|
+
*/
|
|
125
|
+
function mergeResolvers(config) {
|
|
126
|
+
if (!config.resolvers) {
|
|
127
|
+
return {};
|
|
128
|
+
}
|
|
129
|
+
const resolvers = Array.isArray(config.resolvers)
|
|
130
|
+
? config.resolvers
|
|
131
|
+
: [config.resolvers];
|
|
132
|
+
const container = {};
|
|
133
|
+
for (const currentResolvers of resolvers) {
|
|
134
|
+
for (const typeName in currentResolvers) {
|
|
135
|
+
if (currentResolvers.hasOwnProperty(typeName)) {
|
|
136
|
+
const value = currentResolvers[typeName];
|
|
137
|
+
if ((0, utils_1.isNil)(value)) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
else if (isScalarResolver(value)) {
|
|
141
|
+
addScalar({ typeName, resolver: value, container, config });
|
|
142
|
+
}
|
|
143
|
+
else if (isEnumResolver(value)) {
|
|
144
|
+
addEnum({ typeName, resolver: value, container, config });
|
|
145
|
+
}
|
|
146
|
+
else if (value && typeof value === 'object') {
|
|
147
|
+
addObject({ typeName, fields: value, container, config });
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
throw new errors_1.ResolverInvalidError(`Resolver of "${typeName}" is invalid`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return container;
|
|
156
|
+
}
|
|
157
|
+
function addObject({ typeName, fields, container, config, }) {
|
|
158
|
+
if (!container[typeName]) {
|
|
159
|
+
container[typeName] = {};
|
|
160
|
+
}
|
|
161
|
+
for (const fieldName in fields) {
|
|
162
|
+
if (fields.hasOwnProperty(fieldName)) {
|
|
163
|
+
const resolver = fields[fieldName];
|
|
164
|
+
if (isResolveFn(resolver)) {
|
|
165
|
+
if (container[typeName][fieldName]) {
|
|
166
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}"`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
167
|
+
}
|
|
168
|
+
writeResolverMetadata(resolver, config);
|
|
169
|
+
container[typeName][fieldName] = resolver;
|
|
170
|
+
}
|
|
171
|
+
else if (isResolveOptions(resolver)) {
|
|
172
|
+
if (!container[typeName][fieldName]) {
|
|
173
|
+
container[typeName][fieldName] = {};
|
|
174
|
+
}
|
|
175
|
+
// resolve
|
|
176
|
+
if ((0, utils_1.isDefined)(resolver.resolve)) {
|
|
177
|
+
if (container[typeName][fieldName].resolve) {
|
|
178
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (resolve method)`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
179
|
+
}
|
|
180
|
+
writeResolverMetadata(resolver.resolve, config);
|
|
181
|
+
container[typeName][fieldName].resolve = resolver.resolve;
|
|
182
|
+
}
|
|
183
|
+
// subscribe
|
|
184
|
+
if ((0, utils_1.isDefined)(resolver.subscribe)) {
|
|
185
|
+
if (container[typeName][fieldName].subscribe) {
|
|
186
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (subscribe method)`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
187
|
+
}
|
|
188
|
+
writeResolverMetadata(resolver.subscribe, config);
|
|
189
|
+
container[typeName][fieldName].subscribe = resolver.subscribe;
|
|
190
|
+
}
|
|
191
|
+
// extensions
|
|
192
|
+
if ((0, utils_1.isDefined)(resolver.extensions)) {
|
|
193
|
+
if (container[typeName][fieldName].extensions) {
|
|
194
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${fieldName}" (extensions object)`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
195
|
+
}
|
|
196
|
+
writeResolverMetadata(resolver.extensions, config);
|
|
197
|
+
container[typeName][fieldName].extensions = resolver.extensions;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function addScalar({ typeName, resolver, container, config, }) {
|
|
204
|
+
if (container[typeName]) {
|
|
205
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of scalar "${typeName}"`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
206
|
+
}
|
|
207
|
+
writeResolverMetadata(resolver.parseLiteral, config);
|
|
208
|
+
writeResolverMetadata(resolver.parseValue, config);
|
|
209
|
+
writeResolverMetadata(resolver.serialize, config);
|
|
210
|
+
container[typeName] = resolver;
|
|
211
|
+
}
|
|
212
|
+
function addEnum({ typeName, resolver, container, config, }) {
|
|
213
|
+
if (!container[typeName]) {
|
|
214
|
+
container[typeName] = {};
|
|
215
|
+
}
|
|
216
|
+
for (const key in resolver) {
|
|
217
|
+
if (resolver.hasOwnProperty(key)) {
|
|
218
|
+
const value = resolver[key];
|
|
219
|
+
if (container[typeName][key]) {
|
|
220
|
+
throw new errors_1.ResolverDuplicatedError(`Duplicated resolver of "${typeName}.${key}" enum value`, (0, errors_1.useLocation)({ dirname: config.dirname, id: config.id }));
|
|
221
|
+
}
|
|
222
|
+
container[typeName][key] = value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Helps to make sure a resolver has a corresponding type/field definition.
|
|
228
|
+
* We don't want to pass resolve function that are not related to the module.
|
|
229
|
+
*/
|
|
230
|
+
function ensureImplements(metadata) {
|
|
231
|
+
return {
|
|
232
|
+
type(name, field) {
|
|
233
|
+
var _a, _b;
|
|
234
|
+
const type = []
|
|
235
|
+
.concat((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a[name], (_b = metadata.extends) === null || _b === void 0 ? void 0 : _b[name])
|
|
236
|
+
.filter(utils_1.isDefined);
|
|
237
|
+
if (type === null || type === void 0 ? void 0 : type.includes(field)) {
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
const id = `"${name}.${field}"`;
|
|
241
|
+
throw new errors_1.ExtraResolverError(`Resolver of "${id}" type cannot be implemented`, `${id} is not defined`, (0, errors_1.useLocation)({ dirname: metadata.dirname, id: metadata.id }));
|
|
242
|
+
},
|
|
243
|
+
scalar(name) {
|
|
244
|
+
var _a;
|
|
245
|
+
if ((((_a = metadata.implements) === null || _a === void 0 ? void 0 : _a.__scalars) || []).includes(name)) {
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
throw new errors_1.ExtraResolverError(`Resolver of "${name}" scalar cannot be implemented`, `${name} is not defined`, (0, errors_1.useLocation)({ dirname: metadata.dirname, id: metadata.id }));
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function writeResolverMetadata(resolver, config) {
|
|
253
|
+
if (!resolver) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
resolver[resolverMetadataProp] = {
|
|
257
|
+
moduleId: config.id,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function readResolverMetadata(resolver) {
|
|
261
|
+
return resolver[resolverMetadataProp];
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* In order to use middlewares on fields
|
|
265
|
+
* that are defined in SDL but have no implemented resolvers,
|
|
266
|
+
* we would have to recreate GraphQLSchema and wrap resolve functions.
|
|
267
|
+
*
|
|
268
|
+
* Since we can't access GraphQLSchema on a module level
|
|
269
|
+
* and recreating GraphQLSchema seems unreasonable,
|
|
270
|
+
* we can create default resolvers instead.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
*
|
|
274
|
+
* gql`
|
|
275
|
+
* type Query {
|
|
276
|
+
* me: User!
|
|
277
|
+
* }
|
|
278
|
+
*
|
|
279
|
+
* type User {
|
|
280
|
+
* name: String!
|
|
281
|
+
* }
|
|
282
|
+
* `
|
|
283
|
+
*
|
|
284
|
+
* The resolver of `Query.me` is implemented and resolver of `User.name` is not.
|
|
285
|
+
* In case where a middleware wants to intercept the resolver of `User.name`,
|
|
286
|
+
* we use a default field resolver from `graphql` package
|
|
287
|
+
* and put it next to other defined resolvers.
|
|
288
|
+
*
|
|
289
|
+
* This way our current logic of wrapping resolvers and running
|
|
290
|
+
* middleware functions stays untouched.
|
|
291
|
+
*/
|
|
292
|
+
function addDefaultResolvers(resolvers, middlewareMap, config) {
|
|
293
|
+
const container = resolvers;
|
|
294
|
+
const sdl = Array.isArray(config.typeDefs)
|
|
295
|
+
? (0, graphql_1.concatAST)(config.typeDefs)
|
|
296
|
+
: config.typeDefs;
|
|
297
|
+
function hasMiddleware(typeName, fieldName) {
|
|
298
|
+
var _a, _b, _c, _d, _e, _f;
|
|
299
|
+
return ((((_b = (_a = middlewareMap['*']) === null || _a === void 0 ? void 0 : _a['*']) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
300
|
+
((_d = (_c = middlewareMap[typeName]) === null || _c === void 0 ? void 0 : _c['*']) === null || _d === void 0 ? void 0 : _d.length) ||
|
|
301
|
+
((_f = (_e = middlewareMap[typeName]) === null || _e === void 0 ? void 0 : _e[fieldName]) === null || _f === void 0 ? void 0 : _f.length)) > 0);
|
|
302
|
+
}
|
|
303
|
+
sdl.definitions.forEach((definition) => {
|
|
304
|
+
if (definition.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
|
|
305
|
+
definition.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION) {
|
|
306
|
+
// Right now we only support Object type
|
|
307
|
+
if (definition.fields) {
|
|
308
|
+
const typeName = definition.name.value;
|
|
309
|
+
definition.fields.forEach((field) => {
|
|
310
|
+
var _a;
|
|
311
|
+
const fieldName = field.name.value;
|
|
312
|
+
if (!((_a = container[typeName]) === null || _a === void 0 ? void 0 : _a[fieldName]) &&
|
|
313
|
+
hasMiddleware(typeName, fieldName)) {
|
|
314
|
+
if (!container[typeName]) {
|
|
315
|
+
container[typeName] = {};
|
|
316
|
+
}
|
|
317
|
+
container[typeName][fieldName] = graphql_1.defaultFieldResolver;
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
return container;
|
|
324
|
+
}
|
|
325
|
+
//
|
|
326
|
+
// Resolver helpers
|
|
327
|
+
//
|
|
328
|
+
function isResolveFn(value) {
|
|
329
|
+
return typeof value === 'function';
|
|
330
|
+
}
|
|
331
|
+
function isResolveOptions(value) {
|
|
332
|
+
return ((0, utils_1.isDefined)(value.resolve) ||
|
|
333
|
+
(0, utils_1.isDefined)(value.subscribe) ||
|
|
334
|
+
(0, utils_1.isDefined)(value.extensions));
|
|
335
|
+
}
|
|
336
|
+
function isScalarResolver(obj) {
|
|
337
|
+
return obj instanceof graphql_1.GraphQLScalarType;
|
|
338
|
+
}
|
|
339
|
+
function isEnumResolver(obj) {
|
|
340
|
+
return Object.values(obj).every(utils_1.isPrimitive);
|
|
341
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MODULE_ID = void 0;
|
|
4
|
+
const di_1 = require("../di");
|
|
5
|
+
/**
|
|
6
|
+
* @api
|
|
7
|
+
* `MODULE_ID` is an InjectionToken representing module's ID
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { MODULE_ID, Inject, Injectable } from 'graphql-modules';
|
|
12
|
+
*
|
|
13
|
+
* (A)Injectable()
|
|
14
|
+
* export class Data {
|
|
15
|
+
* constructor((A)Inject(MODULE_ID) moduleId: string) {
|
|
16
|
+
* console.log(`Data used in ${moduleId} module`)
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
exports.MODULE_ID = new di_1.InjectionToken('module-id');
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTypeDefs = createTypeDefs;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const errors_1 = require("../shared/errors");
|
|
6
|
+
/**
|
|
7
|
+
* Create a list of DocumentNode objects based on Module's config.
|
|
8
|
+
* Add a location, so we get richer errors.
|
|
9
|
+
*/
|
|
10
|
+
function createTypeDefs(config) {
|
|
11
|
+
const typeDefs = Array.isArray(config.typeDefs)
|
|
12
|
+
? config.typeDefs
|
|
13
|
+
: [config.typeDefs];
|
|
14
|
+
ensureDocumentNode(config, typeDefs);
|
|
15
|
+
return typeDefs;
|
|
16
|
+
}
|
|
17
|
+
function ensureDocumentNode(config, typeDefs) {
|
|
18
|
+
function ensureEach(doc, i) {
|
|
19
|
+
if ((doc === null || doc === void 0 ? void 0 : doc.kind) !== graphql_1.Kind.DOCUMENT) {
|
|
20
|
+
throw new errors_1.NonDocumentNodeError(`Expected parsed document but received ${typeof doc} at index ${i} in typeDefs list`, (0, errors_1.useLocation)(config));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
typeDefs.forEach(ensureEach);
|
|
24
|
+
}
|
|
File without changes
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
package/cjs/shared/di.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NonDocumentNodeError = exports.ResolverInvalidError = exports.ResolverDuplicatedError = exports.ExtraMiddlewareError = exports.ExtraResolverError = exports.ModuleDuplicatedError = exports.ModuleNonUniqueIdError = void 0;
|
|
4
|
+
exports.useLocation = useLocation;
|
|
5
|
+
exports.ExtendableBuiltin = ExtendableBuiltin;
|
|
6
|
+
exports.composeMessage = composeMessage;
|
|
7
|
+
class ModuleNonUniqueIdError extends ExtendableBuiltin(Error) {
|
|
8
|
+
constructor(message, ...rest) {
|
|
9
|
+
super(composeMessage(message, ...rest));
|
|
10
|
+
this.name = this.constructor.name;
|
|
11
|
+
this.message = composeMessage(message, ...rest);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.ModuleNonUniqueIdError = ModuleNonUniqueIdError;
|
|
15
|
+
class ModuleDuplicatedError 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
|
+
exports.ModuleDuplicatedError = ModuleDuplicatedError;
|
|
23
|
+
class ExtraResolverError extends ExtendableBuiltin(Error) {
|
|
24
|
+
constructor(message, ...rest) {
|
|
25
|
+
super(composeMessage(message, ...rest));
|
|
26
|
+
this.name = this.constructor.name;
|
|
27
|
+
this.message = composeMessage(message, ...rest);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.ExtraResolverError = ExtraResolverError;
|
|
31
|
+
class ExtraMiddlewareError extends ExtendableBuiltin(Error) {
|
|
32
|
+
constructor(message, ...rest) {
|
|
33
|
+
super(composeMessage(message, ...rest));
|
|
34
|
+
this.name = this.constructor.name;
|
|
35
|
+
this.message = composeMessage(message, ...rest);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.ExtraMiddlewareError = ExtraMiddlewareError;
|
|
39
|
+
class ResolverDuplicatedError extends ExtendableBuiltin(Error) {
|
|
40
|
+
constructor(message, ...rest) {
|
|
41
|
+
super(composeMessage(message, ...rest));
|
|
42
|
+
this.name = this.constructor.name;
|
|
43
|
+
this.message = composeMessage(message, ...rest);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.ResolverDuplicatedError = ResolverDuplicatedError;
|
|
47
|
+
class ResolverInvalidError extends ExtendableBuiltin(Error) {
|
|
48
|
+
constructor(message, ...rest) {
|
|
49
|
+
super(composeMessage(message, ...rest));
|
|
50
|
+
this.name = this.constructor.name;
|
|
51
|
+
this.message = composeMessage(message, ...rest);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.ResolverInvalidError = ResolverInvalidError;
|
|
55
|
+
class NonDocumentNodeError extends ExtendableBuiltin(Error) {
|
|
56
|
+
constructor(message, ...rest) {
|
|
57
|
+
super(composeMessage(message, ...rest));
|
|
58
|
+
this.name = this.constructor.name;
|
|
59
|
+
this.message = composeMessage(message, ...rest);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.NonDocumentNodeError = NonDocumentNodeError;
|
|
63
|
+
// helpers
|
|
64
|
+
function useLocation({ dirname, id }) {
|
|
65
|
+
return dirname
|
|
66
|
+
? `Module "${id}" located at ${dirname}`
|
|
67
|
+
: [
|
|
68
|
+
`Module "${id}"`,
|
|
69
|
+
`Hint: pass __dirname to "dirname" option of your modules to get more insightful errors`,
|
|
70
|
+
].join('\n');
|
|
71
|
+
}
|
|
72
|
+
function ExtendableBuiltin(cls) {
|
|
73
|
+
function ExtendableBuiltin() {
|
|
74
|
+
cls.apply(this, arguments);
|
|
75
|
+
}
|
|
76
|
+
ExtendableBuiltin.prototype = Object.create(cls.prototype);
|
|
77
|
+
Object.setPrototypeOf(ExtendableBuiltin, cls);
|
|
78
|
+
return ExtendableBuiltin;
|
|
79
|
+
}
|
|
80
|
+
function composeMessage(...lines) {
|
|
81
|
+
return lines.join('\n');
|
|
82
|
+
}
|