@magek/core 0.0.1
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/dist/authorizer.d.ts +7 -0
- package/dist/authorizer.js +35 -0
- package/dist/command-dispatcher.d.ts +8 -0
- package/dist/command-dispatcher.js +55 -0
- package/dist/core-concepts/data-migration/entities/data-migration-entity.d.ts +12 -0
- package/dist/core-concepts/data-migration/entities/data-migration-entity.js +37 -0
- package/dist/core-concepts/data-migration/events/data-migration-finished.d.ts +7 -0
- package/dist/core-concepts/data-migration/events/data-migration-finished.js +13 -0
- package/dist/core-concepts/data-migration/events/data-migration-started.d.ts +7 -0
- package/dist/core-concepts/data-migration/events/data-migration-started.js +13 -0
- package/dist/core-concepts/data-migration/events/entity-migrated.d.ts +9 -0
- package/dist/core-concepts/data-migration/events/entity-migrated.js +15 -0
- package/dist/core-concepts/touch-entity/events/entity-touched.d.ts +7 -0
- package/dist/core-concepts/touch-entity/events/entity-touched.js +13 -0
- package/dist/data-migrations.d.ts +8 -0
- package/dist/data-migrations.js +73 -0
- package/dist/decorators/command.d.ts +19 -0
- package/dist/decorators/command.js +47 -0
- package/dist/decorators/data-migration.d.ts +9 -0
- package/dist/decorators/data-migration.js +25 -0
- package/dist/decorators/entity.d.ts +32 -0
- package/dist/decorators/entity.js +100 -0
- package/dist/decorators/event-handler.d.ts +3 -0
- package/dist/decorators/event-handler.js +18 -0
- package/dist/decorators/event.d.ts +8 -0
- package/dist/decorators/event.js +22 -0
- package/dist/decorators/field-metadata-reader.d.ts +6 -0
- package/dist/decorators/field-metadata-reader.js +221 -0
- package/dist/decorators/global-error-handler.d.ts +2 -0
- package/dist/decorators/global-error-handler.js +15 -0
- package/dist/decorators/global-event-handler.d.ts +3 -0
- package/dist/decorators/global-event-handler.js +9 -0
- package/dist/decorators/health-sensor.d.ts +14 -0
- package/dist/decorators/health-sensor.js +38 -0
- package/dist/decorators/index.d.ts +16 -0
- package/dist/decorators/index.js +19 -0
- package/dist/decorators/metadata.d.ts +13 -0
- package/dist/decorators/metadata.js +55 -0
- package/dist/decorators/non-exposed.d.ts +2 -0
- package/dist/decorators/non-exposed.js +24 -0
- package/dist/decorators/notification.d.ts +35 -0
- package/dist/decorators/notification.js +94 -0
- package/dist/decorators/projects.d.ts +32 -0
- package/dist/decorators/projects.js +87 -0
- package/dist/decorators/query.d.ts +2 -0
- package/dist/decorators/query.js +25 -0
- package/dist/decorators/read-model.d.ts +39 -0
- package/dist/decorators/read-model.js +129 -0
- package/dist/decorators/role.d.ts +6 -0
- package/dist/decorators/role.js +15 -0
- package/dist/decorators/scheduled-command.d.ts +9 -0
- package/dist/decorators/scheduled-command.js +25 -0
- package/dist/decorators/schema-migration.d.ts +36 -0
- package/dist/decorators/schema-migration.js +146 -0
- package/dist/decorators/sequenced-by.d.ts +28 -0
- package/dist/decorators/sequenced-by.js +79 -0
- package/dist/decorators/stage3-utils.d.ts +6 -0
- package/dist/decorators/stage3-utils.js +25 -0
- package/dist/delete-event-dispatcher.d.ts +4 -0
- package/dist/delete-event-dispatcher.js +23 -0
- package/dist/event-dispatcher.d.ts +9 -0
- package/dist/event-dispatcher.js +37 -0
- package/dist/event-processor.d.ts +15 -0
- package/dist/event-processor.js +125 -0
- package/dist/event-search.d.ts +2 -0
- package/dist/event-search.js +26 -0
- package/dist/event-stream-consumer.d.ts +7 -0
- package/dist/event-stream-consumer.js +36 -0
- package/dist/event-stream-producer.d.ts +7 -0
- package/dist/event-stream-producer.js +30 -0
- package/dist/events-reader.d.ts +11 -0
- package/dist/events-reader.js +63 -0
- package/dist/global-error-dispatcher.d.ts +16 -0
- package/dist/global-error-dispatcher.js +109 -0
- package/dist/graphql-dispatcher.d.ts +16 -0
- package/dist/graphql-dispatcher.js +195 -0
- package/dist/importer.d.ts +14 -0
- package/dist/importer.js +49 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +100 -0
- package/dist/injectable/index.d.ts +21 -0
- package/dist/injectable/index.js +2 -0
- package/dist/instrumentation/decorator/trace.d.ts +13 -0
- package/dist/instrumentation/decorator/trace.js +116 -0
- package/dist/instrumentation/index.d.ts +2 -0
- package/dist/instrumentation/index.js +5 -0
- package/dist/instrumentation/trace-notifier.d.ts +3 -0
- package/dist/instrumentation/trace-notifier.js +26 -0
- package/dist/magek.d.ts +42 -0
- package/dist/magek.js +158 -0
- package/dist/query-dispatcher.d.ts +8 -0
- package/dist/query-dispatcher.js +47 -0
- package/dist/read-model-schema-migrator.d.ts +14 -0
- package/dist/read-model-schema-migrator.js +80 -0
- package/dist/read-models-reader.d.ts +31 -0
- package/dist/read-models-reader.js +196 -0
- package/dist/register-handler.d.ts +11 -0
- package/dist/register-handler.js +95 -0
- package/dist/rocket-dispatcher.d.ts +6 -0
- package/dist/rocket-dispatcher.js +21 -0
- package/dist/scheduled-command-dispatcher.d.ts +12 -0
- package/dist/scheduled-command-dispatcher.js +54 -0
- package/dist/schema-migrator.d.ts +12 -0
- package/dist/schema-migrator.js +71 -0
- package/dist/sensor/health/health-indicators/database-events-health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/database-events-health-indicator.js +26 -0
- package/dist/sensor/health/health-indicators/database-health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/database-health-indicator.js +29 -0
- package/dist/sensor/health/health-indicators/database-read-models-health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/database-read-models-health-indicator.js +26 -0
- package/dist/sensor/health/health-indicators/default-health-indicators.d.ts +5 -0
- package/dist/sensor/health/health-indicators/default-health-indicators.js +39 -0
- package/dist/sensor/health/health-indicators/function-health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/function-health-indicator.js +30 -0
- package/dist/sensor/health/health-indicators/health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/health-indicator.js +30 -0
- package/dist/sensor/health/health-indicators/index.d.ts +3 -0
- package/dist/sensor/health/health-indicators/index.js +6 -0
- package/dist/sensor/health/health-indicators/os-info.d.ts +14 -0
- package/dist/sensor/health/health-indicators/os-info.js +38 -0
- package/dist/sensor/health/health-indicators/rockets-health-indicator.d.ts +5 -0
- package/dist/sensor/health/health-indicators/rockets-health-indicator.js +57 -0
- package/dist/sensor/health/health-indicators/version.d.ts +2 -0
- package/dist/sensor/health/health-indicators/version.js +24 -0
- package/dist/sensor/health/health-service.d.ts +22 -0
- package/dist/sensor/health/health-service.js +117 -0
- package/dist/sensor/health/health-utils.d.ts +7 -0
- package/dist/sensor/health/health-utils.js +53 -0
- package/dist/sensor/health/index.d.ts +3 -0
- package/dist/sensor/health/index.js +6 -0
- package/dist/sensor/index.d.ts +1 -0
- package/dist/sensor/index.js +4 -0
- package/dist/services/event-store.d.ts +27 -0
- package/dist/services/event-store.js +260 -0
- package/dist/services/filter-helpers.d.ts +3 -0
- package/dist/services/filter-helpers.js +19 -0
- package/dist/services/graphql/common.d.ts +26 -0
- package/dist/services/graphql/common.js +53 -0
- package/dist/services/graphql/graphql-generator.d.ts +46 -0
- package/dist/services/graphql/graphql-generator.js +269 -0
- package/dist/services/graphql/graphql-mutation-generator.d.ts +12 -0
- package/dist/services/graphql/graphql-mutation-generator.js +25 -0
- package/dist/services/graphql/graphql-query-generator.d.ts +22 -0
- package/dist/services/graphql/graphql-query-generator.js +39 -0
- package/dist/services/graphql/graphql-subcriptions-generator.d.ts +17 -0
- package/dist/services/graphql/graphql-subcriptions-generator.js +60 -0
- package/dist/services/graphql/graphql-type-informer.d.ts +23 -0
- package/dist/services/graphql/graphql-type-informer.js +160 -0
- package/dist/services/graphql/query-generators/graphql-query-by-keys-generator.d.ts +14 -0
- package/dist/services/graphql/query-generators/graphql-query-by-keys-generator.js +48 -0
- package/dist/services/graphql/query-generators/graphql-query-events-generator.d.ts +11 -0
- package/dist/services/graphql/query-generators/graphql-query-events-generator.js +68 -0
- package/dist/services/graphql/query-generators/graphql-query-filters-generator.d.ts +14 -0
- package/dist/services/graphql/query-generators/graphql-query-filters-generator.js +31 -0
- package/dist/services/graphql/query-generators/graphql-query-generator.d.ts +12 -0
- package/dist/services/graphql/query-generators/graphql-query-generator.js +17 -0
- package/dist/services/graphql/query-generators/graphql-query-listed-generator.d.ts +16 -0
- package/dist/services/graphql/query-generators/graphql-query-listed-generator.js +65 -0
- package/dist/services/graphql/query-helpers/graphql-handled-fields-generator.d.ts +15 -0
- package/dist/services/graphql/query-helpers/graphql-handled-fields-generator.js +65 -0
- package/dist/services/graphql/query-helpers/graphql-query-filter-arguments-builder.d.ts +13 -0
- package/dist/services/graphql/query-helpers/graphql-query-filter-arguments-builder.js +169 -0
- package/dist/services/graphql/query-helpers/graphql-query-filter-fields-builder.d.ts +11 -0
- package/dist/services/graphql/query-helpers/graphql-query-filter-fields-builder.js +28 -0
- package/dist/services/graphql/query-helpers/graphql-query-sort-builder.d.ts +12 -0
- package/dist/services/graphql/query-helpers/graphql-query-sort-builder.js +61 -0
- package/dist/services/graphql/websocket-protocol/graphql-websocket-protocol.d.ts +20 -0
- package/dist/services/graphql/websocket-protocol/graphql-websocket-protocol.js +127 -0
- package/dist/services/pub-sub/noop-read-model-pub-sub.d.ts +5 -0
- package/dist/services/pub-sub/noop-read-model-pub-sub.js +10 -0
- package/dist/services/pub-sub/read-model-pub-sub.d.ts +9 -0
- package/dist/services/pub-sub/read-model-pub-sub.js +112 -0
- package/dist/services/raw-events-parser.d.ts +5 -0
- package/dist/services/raw-events-parser.js +44 -0
- package/dist/services/read-model-searcher.d.ts +2 -0
- package/dist/services/read-model-searcher.js +11 -0
- package/dist/services/read-model-store.d.ts +41 -0
- package/dist/services/read-model-store.js +295 -0
- package/dist/services/token-verifiers/index.d.ts +4 -0
- package/dist/services/token-verifiers/index.js +7 -0
- package/dist/services/token-verifiers/jwks-uri-token-verifier.d.ts +21 -0
- package/dist/services/token-verifiers/jwks-uri-token-verifier.js +23 -0
- package/dist/services/token-verifiers/public-key-token-verifier.d.ts +13 -0
- package/dist/services/token-verifiers/public-key-token-verifier.js +19 -0
- package/dist/services/token-verifiers/role-based-token-verifier.d.ts +8 -0
- package/dist/services/token-verifiers/role-based-token-verifier.js +35 -0
- package/dist/services/token-verifiers/utilities.d.ts +31 -0
- package/dist/services/token-verifiers/utilities.js +70 -0
- package/dist/subscribers-notifier.d.ts +14 -0
- package/dist/subscribers-notifier.js +109 -0
- package/dist/token-verifier.d.ts +11 -0
- package/dist/token-verifier.js +46 -0
- package/dist/touch-entity-handler.d.ts +4 -0
- package/dist/touch-entity-handler.js +16 -0
- package/package.json +71 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLGenerator = void 0;
|
|
4
|
+
const common_1 = require("@magek/common");
|
|
5
|
+
const graphql_1 = require("graphql");
|
|
6
|
+
const inflected_1 = require("inflected");
|
|
7
|
+
const command_dispatcher_1 = require("../../command-dispatcher");
|
|
8
|
+
const events_reader_1 = require("../../events-reader");
|
|
9
|
+
const read_models_reader_1 = require("../../read-models-reader");
|
|
10
|
+
const graphql_mutation_generator_1 = require("./graphql-mutation-generator");
|
|
11
|
+
const graphql_query_generator_1 = require("./graphql-query-generator");
|
|
12
|
+
const graphql_subcriptions_generator_1 = require("./graphql-subcriptions-generator");
|
|
13
|
+
const graphql_type_informer_1 = require("./graphql-type-informer");
|
|
14
|
+
const query_dispatcher_1 = require("../../query-dispatcher");
|
|
15
|
+
class GraphQLGenerator {
|
|
16
|
+
static generateSchema(config) {
|
|
17
|
+
const logger = (0, common_1.getLogger)(config, 'GraphQLGenerator#generateSchema');
|
|
18
|
+
if (!this.schema) {
|
|
19
|
+
logger.debug('Generating GraphQL schema...');
|
|
20
|
+
this.commandsDispatcher = new command_dispatcher_1.MagekCommandDispatcher(config);
|
|
21
|
+
this.queriesDispatcher = new query_dispatcher_1.MagekQueryDispatcher(config);
|
|
22
|
+
this.readModelsReader = new read_models_reader_1.MagekReadModelsReader(config);
|
|
23
|
+
this.eventsReader = new events_reader_1.MagekEventsReader(config);
|
|
24
|
+
const typeInformer = new graphql_type_informer_1.GraphQLTypeInformer(logger);
|
|
25
|
+
const generatedFiltersByTypeName = {};
|
|
26
|
+
const queryGenerator = new graphql_query_generator_1.GraphQLQueryGenerator(config, Object.values(config.readModels).map((m) => m.class), config.queryHandlers, typeInformer, this.readModelByIDResolverBuilder.bind(this, config), this.queriesResolverBuilder.bind(this), this.readModelResolverBuilder.bind(this), this.eventResolver.bind(this), generatedFiltersByTypeName);
|
|
27
|
+
const mutationGenerator = new graphql_mutation_generator_1.GraphQLMutationGenerator(config.commandHandlers, typeInformer, this.commandResolverBuilder.bind(this), config);
|
|
28
|
+
const subscriptionGenerator = new graphql_subcriptions_generator_1.GraphQLSubscriptionGenerator(Object.values(config.readModels).map((m) => m.class), typeInformer, this.subscriptionByIDResolverBuilder.bind(this, config), this.subscriptionResolverBuilder.bind(this, config), generatedFiltersByTypeName, config);
|
|
29
|
+
this.schema = new graphql_1.GraphQLSchema({
|
|
30
|
+
query: queryGenerator.generate(),
|
|
31
|
+
mutation: mutationGenerator.generate(),
|
|
32
|
+
subscription: subscriptionGenerator.generate(),
|
|
33
|
+
});
|
|
34
|
+
logger.debug('GraphQL schema generated');
|
|
35
|
+
}
|
|
36
|
+
return this.schema;
|
|
37
|
+
}
|
|
38
|
+
static readModelResolverBuilder(readModelClass) {
|
|
39
|
+
return (parent, args, context, info) => {
|
|
40
|
+
let isPaginated = false;
|
|
41
|
+
const fields = this.getFields(info);
|
|
42
|
+
let select = fields.length > 0 ? fields : undefined;
|
|
43
|
+
if ((info === null || info === void 0 ? void 0 : info.fieldName) === `List${(0, inflected_1.pluralize)(readModelClass.name)}`) {
|
|
44
|
+
isPaginated = true;
|
|
45
|
+
if (select) {
|
|
46
|
+
// In paginated queries, the `items[].` field needs to be removed from the select fields before querying the database
|
|
47
|
+
select = select
|
|
48
|
+
.map((field) => {
|
|
49
|
+
return field.split('.').slice(1).join('.');
|
|
50
|
+
})
|
|
51
|
+
.filter((str) => str.trim().length > 0);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const readModelEnvelope = toReadModelRequestEnvelope(readModelClass, args, context, isPaginated, select);
|
|
55
|
+
return this.readModelsReader.search(readModelEnvelope);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
static readModelByIDResolverBuilder(config, readModelClass) {
|
|
59
|
+
const sequenceKeyName = config.readModelSequenceKeys[readModelClass.name];
|
|
60
|
+
return async (parent, args, context) => {
|
|
61
|
+
const readModelRequestEnvelope = this.toReadModelByIdRequestEnvelope(readModelClass, args, context, sequenceKeyName);
|
|
62
|
+
return await this.readModelsReader.findById(readModelRequestEnvelope);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
static eventResolver(parent, args, context) {
|
|
66
|
+
const eventsRequestEnvelope = toEventSearchRequest(args, context);
|
|
67
|
+
return this.eventsReader.fetch(eventsRequestEnvelope);
|
|
68
|
+
}
|
|
69
|
+
static commandResolverBuilder(commandClass) {
|
|
70
|
+
return async (parent, args, context) => {
|
|
71
|
+
const commandEnvelope = toEnvelope(commandClass.name, args.input, context);
|
|
72
|
+
const result = await this.commandsDispatcher.dispatchCommand(commandEnvelope, context);
|
|
73
|
+
// It could be that the command didn't return anything
|
|
74
|
+
// so in that case we return `true`, as GraphQL doesn't have a `null` type
|
|
75
|
+
return result !== null && result !== void 0 ? result : true;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
static queriesResolverBuilder(queryClass) {
|
|
79
|
+
return async (parent, args, context) => {
|
|
80
|
+
const queryEnvelope = toEnvelope(queryClass.name, args.input, context);
|
|
81
|
+
return await this.queriesDispatcher.dispatchQuery(queryEnvelope, context);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
static subscriptionByIDResolverBuilder(config, readModelClass) {
|
|
85
|
+
return async (parent, args, context, info) => {
|
|
86
|
+
const filterArgs = { filter: { id: { eq: args.id } } };
|
|
87
|
+
return this.subscriptionResolverBuilder(config, readModelClass)(parent, filterArgs, context, info);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
static subscriptionResolverBuilder(config, readModelClass) {
|
|
91
|
+
return async (parent, args, context) => {
|
|
92
|
+
if (!context.connectionID) {
|
|
93
|
+
throw new Error('Missing "connectionID". It is required for subscriptions');
|
|
94
|
+
}
|
|
95
|
+
const readModelRequestEnvelope = toReadModelRequestEnvelope(readModelClass, args, context);
|
|
96
|
+
if (context.storeSubscriptions) {
|
|
97
|
+
await this.readModelsReader.subscribe(context.connectionID, readModelRequestEnvelope, context.operation);
|
|
98
|
+
}
|
|
99
|
+
return context.pubSub.asyncIterator(readModelRequestEnvelope, config);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
static toReadModelByIdRequestEnvelope(readModelClass, args, context, sequenceKeyName) {
|
|
103
|
+
const key = sequenceKeyName
|
|
104
|
+
? {
|
|
105
|
+
id: args.id,
|
|
106
|
+
sequenceKey: {
|
|
107
|
+
name: sequenceKeyName,
|
|
108
|
+
value: args[sequenceKeyName],
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
: { id: args.id };
|
|
112
|
+
return {
|
|
113
|
+
currentUser: context.user,
|
|
114
|
+
requestID: context.requestID,
|
|
115
|
+
class: readModelClass,
|
|
116
|
+
className: readModelClass.name,
|
|
117
|
+
key,
|
|
118
|
+
version: 1, // TODO: How to pass the version through GraphQL?
|
|
119
|
+
filters: {},
|
|
120
|
+
sortBy: {},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Extracts the fields from a GraphQLResolveInfo object. This object is part of a GraphQL request and the goal is to
|
|
125
|
+
* identify the fields in the request. For example, for the following GraphQL query request:
|
|
126
|
+
*
|
|
127
|
+
* ```graphql
|
|
128
|
+
* query {
|
|
129
|
+
* CartReadModel {
|
|
130
|
+
* id
|
|
131
|
+
* cartItems {
|
|
132
|
+
* id
|
|
133
|
+
* quantity
|
|
134
|
+
* }
|
|
135
|
+
* }
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* it will return the following list of fields: `['id', 'cartItems[].id', 'cartItems[].quantity']`
|
|
140
|
+
*
|
|
141
|
+
* @param {GraphQLResolveInfo} info - The GraphQLResolveInfo object.
|
|
142
|
+
* @returns {string[]} - The extracted fields.
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
static getFields(info) {
|
|
146
|
+
let fields = [];
|
|
147
|
+
/**
|
|
148
|
+
* Checks if a type is a list.
|
|
149
|
+
* @param {any} type - The type to check.
|
|
150
|
+
* @returns {boolean} - True if the type is a list, false otherwise.
|
|
151
|
+
*/
|
|
152
|
+
const isList = (type) => {
|
|
153
|
+
if (type instanceof graphql_1.GraphQLNonNull) {
|
|
154
|
+
return type.ofType instanceof graphql_1.GraphQLList;
|
|
155
|
+
}
|
|
156
|
+
return type instanceof graphql_1.GraphQLList;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Extracts fields from a selection set.
|
|
160
|
+
* @param {SelectionSetNode} selectionSet - The selection set.
|
|
161
|
+
* @param {string[]} path - The current path.
|
|
162
|
+
* @param {GraphQLObjectType | any} parentType - The parent type.
|
|
163
|
+
* @param {Map<string, FragmentDefinitionNode>} fragments - The fragment definitions.
|
|
164
|
+
* @returns {string[]} - The extracted fields.
|
|
165
|
+
*/
|
|
166
|
+
const extractFields = (selectionSet, path = [], parentType, fragments) => {
|
|
167
|
+
let subFields = [];
|
|
168
|
+
if (selectionSet && selectionSet.selections) {
|
|
169
|
+
selectionSet.selections.forEach((selection) => {
|
|
170
|
+
if (selection.kind === graphql_1.Kind.FIELD) {
|
|
171
|
+
const fieldName = selection.name.value;
|
|
172
|
+
const field = parentType.getFields()[fieldName];
|
|
173
|
+
if (!field) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const fieldType = (0, graphql_1.getNamedType)(field.type);
|
|
177
|
+
const currentPath = [...path, fieldName];
|
|
178
|
+
if (isList(field.type)) {
|
|
179
|
+
const elementType = (0, graphql_1.getNamedType)(field.type.ofType);
|
|
180
|
+
if ((0, graphql_1.isObjectType)(elementType)) {
|
|
181
|
+
currentPath[currentPath.length - 1] += '[]';
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (!selection.selectionSet) {
|
|
185
|
+
subFields.push(currentPath.join('.'));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const nextParentType = (0, graphql_1.isObjectType)(fieldType) ? fieldType : parentType;
|
|
189
|
+
subFields = subFields.concat(extractFields(selection.selectionSet, currentPath, nextParentType, fragments));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else if (selection.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
193
|
+
const fragmentName = selection.name.value;
|
|
194
|
+
const fragment = fragments.get(fragmentName);
|
|
195
|
+
if (fragment) {
|
|
196
|
+
subFields = subFields.concat(extractFields(fragment.selectionSet, path, parentType, fragments));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (selection.kind === graphql_1.Kind.INLINE_FRAGMENT) {
|
|
200
|
+
const inlineFragmentType = selection.typeCondition
|
|
201
|
+
? info.schema.getType(selection.typeCondition.name.value)
|
|
202
|
+
: parentType;
|
|
203
|
+
if ((0, graphql_1.isObjectType)(inlineFragmentType)) {
|
|
204
|
+
subFields = subFields.concat(extractFields(selection.selectionSet, path, inlineFragmentType, fragments));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return subFields;
|
|
210
|
+
};
|
|
211
|
+
// Collect all fragment definitions
|
|
212
|
+
const fragments = new Map();
|
|
213
|
+
info.fragments &&
|
|
214
|
+
Object.keys(info.fragments).forEach((fragmentName) => {
|
|
215
|
+
fragments.set(fragmentName, info.fragments[fragmentName]);
|
|
216
|
+
});
|
|
217
|
+
info.fieldNodes.forEach((fieldNode) => {
|
|
218
|
+
const firstField = fieldNode.name.value;
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
const firstFieldType = info.schema.getQueryType().getFields()[firstField].type;
|
|
221
|
+
const rootType = (0, graphql_1.getNamedType)(firstFieldType);
|
|
222
|
+
if (fieldNode.selectionSet) {
|
|
223
|
+
fields = fields.concat(extractFields(fieldNode.selectionSet, [], rootType, fragments));
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
return fields;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
exports.GraphQLGenerator = GraphQLGenerator;
|
|
230
|
+
function toReadModelRequestEnvelope(readModelClass, args, context, paginatedVersion = false, select) {
|
|
231
|
+
var _a, _b;
|
|
232
|
+
return {
|
|
233
|
+
requestID: context.requestID,
|
|
234
|
+
currentUser: context.user,
|
|
235
|
+
class: readModelClass,
|
|
236
|
+
className: readModelClass.name,
|
|
237
|
+
filters: (_a = args.filter) !== null && _a !== void 0 ? _a : {},
|
|
238
|
+
sortBy: (_b = args.sortBy) !== null && _b !== void 0 ? _b : {},
|
|
239
|
+
limit: args.limit,
|
|
240
|
+
afterCursor: args.afterCursor,
|
|
241
|
+
paginatedVersion,
|
|
242
|
+
version: 1, // TODO: How to pass the version through GraphQL?
|
|
243
|
+
select,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function toEventSearchRequest(args, context) {
|
|
247
|
+
return {
|
|
248
|
+
requestID: context.requestID,
|
|
249
|
+
currentUser: context.user,
|
|
250
|
+
parameters: args,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function toEnvelope(typeName, value, context) {
|
|
254
|
+
var _a, _b;
|
|
255
|
+
return {
|
|
256
|
+
requestID: context.requestID,
|
|
257
|
+
currentUser: context.user,
|
|
258
|
+
typeName: typeName,
|
|
259
|
+
value,
|
|
260
|
+
version: 1, // TODO: How to pass the version through GraphQL?
|
|
261
|
+
context: {
|
|
262
|
+
request: {
|
|
263
|
+
body: (_a = context.context) === null || _a === void 0 ? void 0 : _a.request.body,
|
|
264
|
+
headers: (_b = context.context) === null || _b === void 0 ? void 0 : _b.request.headers,
|
|
265
|
+
},
|
|
266
|
+
rawContext: context,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ResolverBuilder, TargetTypesMap } from './common';
|
|
2
|
+
import { GraphQLTypeInformer } from './graphql-type-informer';
|
|
3
|
+
import { GraphQLObjectType } from 'graphql';
|
|
4
|
+
import { MagekConfig } from '@magek/common';
|
|
5
|
+
export declare class GraphQLMutationGenerator {
|
|
6
|
+
private readonly targetTypes;
|
|
7
|
+
private readonly typeInformer;
|
|
8
|
+
private readonly mutationResolver;
|
|
9
|
+
private readonly config;
|
|
10
|
+
constructor(targetTypes: TargetTypesMap, typeInformer: GraphQLTypeInformer, mutationResolver: ResolverBuilder, config: MagekConfig);
|
|
11
|
+
generate(): GraphQLObjectType | undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLMutationGenerator = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const graphql_handled_fields_generator_1 = require("./query-helpers/graphql-handled-fields-generator");
|
|
6
|
+
class GraphQLMutationGenerator {
|
|
7
|
+
constructor(targetTypes, typeInformer, mutationResolver, config) {
|
|
8
|
+
this.targetTypes = targetTypes;
|
|
9
|
+
this.typeInformer = typeInformer;
|
|
10
|
+
this.mutationResolver = mutationResolver;
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
generate() {
|
|
14
|
+
const graphqlGenerateHandledFields = new graphql_handled_fields_generator_1.GraphQLHandledFieldsGenerator(this.targetTypes, this.typeInformer, this.mutationResolver, this.config);
|
|
15
|
+
const mutations = graphqlGenerateHandledFields.generateFields();
|
|
16
|
+
if (Object.keys(mutations).length === 0) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
return new graphql_1.GraphQLObjectType({
|
|
20
|
+
name: 'Mutation',
|
|
21
|
+
fields: mutations,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.GraphQLMutationGenerator = GraphQLMutationGenerator;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AnyClass, MagekConfig } from '@magek/common';
|
|
2
|
+
import { GraphQLFieldResolver, GraphQLInputObjectType, GraphQLObjectType } from 'graphql';
|
|
3
|
+
import { GraphQLResolverContext, ResolverBuilder, TargetTypesMap } from './common';
|
|
4
|
+
import { GraphQLTypeInformer } from './graphql-type-informer';
|
|
5
|
+
export declare class GraphQLQueryGenerator {
|
|
6
|
+
protected readonly config: MagekConfig;
|
|
7
|
+
protected readonly readModels: AnyClass[];
|
|
8
|
+
protected readonly targetTypes: TargetTypesMap;
|
|
9
|
+
protected readonly typeInformer: GraphQLTypeInformer;
|
|
10
|
+
protected readonly byIDResolverBuilder: ResolverBuilder;
|
|
11
|
+
protected readonly queryResolverBuilder: ResolverBuilder;
|
|
12
|
+
protected readonly filterResolverBuilder: ResolverBuilder;
|
|
13
|
+
protected readonly eventsResolver: GraphQLFieldResolver<unknown, GraphQLResolverContext, any>;
|
|
14
|
+
protected generatedFiltersByTypeName: Record<string, GraphQLInputObjectType>;
|
|
15
|
+
private graphqlQueryByKeysGenerator;
|
|
16
|
+
private graphqlQueryGenerator;
|
|
17
|
+
private graphqlQueryFiltersGenerator;
|
|
18
|
+
private graphqlQueryListedGenerator;
|
|
19
|
+
private graphqlQueryEventsGenerator;
|
|
20
|
+
constructor(config: MagekConfig, readModels: AnyClass[], targetTypes: TargetTypesMap, typeInformer: GraphQLTypeInformer, byIDResolverBuilder: ResolverBuilder, queryResolverBuilder: ResolverBuilder, filterResolverBuilder: ResolverBuilder, eventsResolver: GraphQLFieldResolver<unknown, GraphQLResolverContext, any>, generatedFiltersByTypeName?: Record<string, GraphQLInputObjectType>);
|
|
21
|
+
generate(): GraphQLObjectType;
|
|
22
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLQueryGenerator = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const graphql_query_events_generator_1 = require("./query-generators/graphql-query-events-generator");
|
|
6
|
+
const graphql_query_by_keys_generator_1 = require("./query-generators/graphql-query-by-keys-generator");
|
|
7
|
+
const graphql_query_filters_generator_1 = require("./query-generators/graphql-query-filters-generator");
|
|
8
|
+
const graphql_query_listed_generator_1 = require("./query-generators/graphql-query-listed-generator");
|
|
9
|
+
const graphql_query_generator_1 = require("./query-generators/graphql-query-generator");
|
|
10
|
+
class GraphQLQueryGenerator {
|
|
11
|
+
constructor(config, readModels, targetTypes, typeInformer, byIDResolverBuilder, queryResolverBuilder, filterResolverBuilder, eventsResolver, generatedFiltersByTypeName = {}) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.readModels = readModels;
|
|
14
|
+
this.targetTypes = targetTypes;
|
|
15
|
+
this.typeInformer = typeInformer;
|
|
16
|
+
this.byIDResolverBuilder = byIDResolverBuilder;
|
|
17
|
+
this.queryResolverBuilder = queryResolverBuilder;
|
|
18
|
+
this.filterResolverBuilder = filterResolverBuilder;
|
|
19
|
+
this.eventsResolver = eventsResolver;
|
|
20
|
+
this.generatedFiltersByTypeName = generatedFiltersByTypeName;
|
|
21
|
+
this.graphqlQueryByKeysGenerator = new graphql_query_by_keys_generator_1.GraphqlQueryByKeysGenerator(config, readModels, typeInformer, byIDResolverBuilder);
|
|
22
|
+
this.graphqlQueryGenerator = new graphql_query_generator_1.GraphqlQueryGenerator(targetTypes, typeInformer, queryResolverBuilder, config);
|
|
23
|
+
this.graphqlQueryFiltersGenerator = new graphql_query_filters_generator_1.GraphqlQueryFiltersGenerator(readModels, typeInformer, filterResolverBuilder, generatedFiltersByTypeName, config);
|
|
24
|
+
this.graphqlQueryListedGenerator = new graphql_query_listed_generator_1.GraphqlQueryListedGenerator(readModels, typeInformer, filterResolverBuilder, generatedFiltersByTypeName, config);
|
|
25
|
+
this.graphqlQueryEventsGenerator = new graphql_query_events_generator_1.GraphqlQueryEventsGenerator(config, byIDResolverBuilder, eventsResolver);
|
|
26
|
+
}
|
|
27
|
+
generate() {
|
|
28
|
+
const byIDQueries = this.graphqlQueryByKeysGenerator.generateByKeysQueries();
|
|
29
|
+
const queries = this.graphqlQueryGenerator.generateQueries();
|
|
30
|
+
const filterQueries = this.graphqlQueryFiltersGenerator.generateFilterQueries();
|
|
31
|
+
const listedQueries = this.graphqlQueryListedGenerator.generateListedQueries();
|
|
32
|
+
const eventQueries = this.graphqlQueryEventsGenerator.generateEventQueries();
|
|
33
|
+
return new graphql_1.GraphQLObjectType({
|
|
34
|
+
name: 'Query',
|
|
35
|
+
fields: { ...byIDQueries, ...filterQueries, ...listedQueries, ...eventQueries, ...queries },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.GraphQLQueryGenerator = GraphQLQueryGenerator;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GraphQLInputObjectType, GraphQLObjectType } from 'graphql';
|
|
2
|
+
import { ResolverBuilder } from './common';
|
|
3
|
+
import { GraphQLTypeInformer } from './graphql-type-informer';
|
|
4
|
+
import { AnyClass, MagekConfig } from '@magek/common';
|
|
5
|
+
export declare class GraphQLSubscriptionGenerator {
|
|
6
|
+
private readonly readModels;
|
|
7
|
+
private readonly typeInformer;
|
|
8
|
+
private readonly byIDResolverBuilder;
|
|
9
|
+
private readonly filterResolverBuilder;
|
|
10
|
+
protected generatedFiltersByTypeName: Record<string, GraphQLInputObjectType>;
|
|
11
|
+
private readonly config;
|
|
12
|
+
private graphqlQueryFilterFieldsBuilder;
|
|
13
|
+
constructor(readModels: AnyClass[], typeInformer: GraphQLTypeInformer, byIDResolverBuilder: ResolverBuilder, filterResolverBuilder: ResolverBuilder, generatedFiltersByTypeName: Record<string, GraphQLInputObjectType> | undefined, config: MagekConfig);
|
|
14
|
+
generate(): GraphQLObjectType | undefined;
|
|
15
|
+
private generateByIDSubscriptions;
|
|
16
|
+
private generateFilterSubscriptions;
|
|
17
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLSubscriptionGenerator = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const inflected = require("inflected");
|
|
6
|
+
const graphql_query_filter_fields_builder_1 = require("./query-helpers/graphql-query-filter-fields-builder");
|
|
7
|
+
class GraphQLSubscriptionGenerator {
|
|
8
|
+
constructor(readModels, typeInformer, byIDResolverBuilder, filterResolverBuilder, generatedFiltersByTypeName = {}, config) {
|
|
9
|
+
this.readModels = readModels;
|
|
10
|
+
this.typeInformer = typeInformer;
|
|
11
|
+
this.byIDResolverBuilder = byIDResolverBuilder;
|
|
12
|
+
this.filterResolverBuilder = filterResolverBuilder;
|
|
13
|
+
this.generatedFiltersByTypeName = generatedFiltersByTypeName;
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.graphqlQueryFilterFieldsBuilder = new graphql_query_filter_fields_builder_1.GraphqlQueryFilterFieldsBuilder(typeInformer, generatedFiltersByTypeName, config);
|
|
16
|
+
}
|
|
17
|
+
generate() {
|
|
18
|
+
const byIDSubscriptions = this.generateByIDSubscriptions();
|
|
19
|
+
const filterSubscriptions = this.generateFilterSubscriptions();
|
|
20
|
+
const fields = { ...byIDSubscriptions, ...filterSubscriptions };
|
|
21
|
+
if (Object.keys(fields).length === 0) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return new graphql_1.GraphQLObjectType({
|
|
25
|
+
name: 'Subscription',
|
|
26
|
+
fields: fields,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
generateByIDSubscriptions() {
|
|
30
|
+
const subscriptions = {};
|
|
31
|
+
for (const readModel of this.readModels) {
|
|
32
|
+
const excludeProps = this.config.nonExposedGraphQLMetadataKey[readModel.name];
|
|
33
|
+
const graphQLType = this.typeInformer.generateGraphQLTypeForClass(readModel, excludeProps);
|
|
34
|
+
subscriptions[readModel.name] = {
|
|
35
|
+
type: graphQLType,
|
|
36
|
+
args: {
|
|
37
|
+
id: { type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID) },
|
|
38
|
+
},
|
|
39
|
+
resolve: (source) => source,
|
|
40
|
+
subscribe: this.byIDResolverBuilder(readModel),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return subscriptions;
|
|
44
|
+
}
|
|
45
|
+
generateFilterSubscriptions() {
|
|
46
|
+
const subscriptions = {};
|
|
47
|
+
for (const readModel of this.readModels) {
|
|
48
|
+
const excludeProps = this.config.nonExposedGraphQLMetadataKey[readModel.name];
|
|
49
|
+
const graphQLType = this.typeInformer.generateGraphQLTypeForClass(readModel, excludeProps);
|
|
50
|
+
subscriptions[inflected.pluralize(readModel.name)] = {
|
|
51
|
+
type: graphQLType,
|
|
52
|
+
args: this.graphqlQueryFilterFieldsBuilder.generateFilterQueriesFields(`${readModel.name}Subscription`, readModel, excludeProps),
|
|
53
|
+
resolve: (source) => source,
|
|
54
|
+
subscribe: this.filterResolverBuilder(readModel),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return subscriptions;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.GraphQLSubscriptionGenerator = GraphQLSubscriptionGenerator;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { GraphQLInputType, GraphQLOutputType, GraphQLType } from 'graphql';
|
|
2
|
+
import { Logger, ClassType, TypeMetadata } from '@magek/common';
|
|
3
|
+
export declare class GraphQLTypeInformer {
|
|
4
|
+
private logger;
|
|
5
|
+
private graphQLTypes;
|
|
6
|
+
constructor(logger: Logger);
|
|
7
|
+
generateGraphQLTypeForClass(type: ClassType, excludeProps: Array<string>, inputType: true): GraphQLInputType;
|
|
8
|
+
generateGraphQLTypeForClass(type: ClassType, excludeProps: Array<string>, inputType?: false): GraphQLOutputType;
|
|
9
|
+
generateGraphQLTypeForClass(type: ClassType, excludeProps: Array<string>, inputType: boolean): GraphQLType;
|
|
10
|
+
getOrCreateGraphQLType(typeMetadata: TypeMetadata, inputType: true): GraphQLInputType;
|
|
11
|
+
getOrCreateGraphQLType(typeMetadata: TypeMetadata, inputType?: false): GraphQLOutputType;
|
|
12
|
+
getOrCreateGraphQLType(typeMetadata: TypeMetadata, inputType: boolean): GraphQLType;
|
|
13
|
+
private getGraphQLName;
|
|
14
|
+
private createGraphQLType;
|
|
15
|
+
private validateUnionClasses;
|
|
16
|
+
private getUnionClasses;
|
|
17
|
+
private createEnumType;
|
|
18
|
+
private createArrayType;
|
|
19
|
+
private getOrCreateObjectType;
|
|
20
|
+
private createObjectType;
|
|
21
|
+
private getOrCreateObjectTypeForUnion;
|
|
22
|
+
private createOutputObjectType;
|
|
23
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLTypeInformer = void 0;
|
|
4
|
+
const metadata_1 = require("./../../decorators/metadata");
|
|
5
|
+
const graphql_1 = require("graphql");
|
|
6
|
+
const graphql_scalars_1 = require("graphql-scalars");
|
|
7
|
+
const common_1 = require("./common");
|
|
8
|
+
class GraphQLTypeInformer {
|
|
9
|
+
constructor(logger) {
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
this.graphQLTypes = {};
|
|
12
|
+
}
|
|
13
|
+
generateGraphQLTypeForClass(type, excludeProps, inputType = false) {
|
|
14
|
+
this.logger.debug(`Generate GraphQL ${inputType ? 'input' : 'output'} type for class ${type.name}`);
|
|
15
|
+
const metadata = (0, metadata_1.getClassMetadata)(type);
|
|
16
|
+
return this.getOrCreateObjectType(metadata, inputType, excludeProps);
|
|
17
|
+
}
|
|
18
|
+
getOrCreateGraphQLType(typeMetadata, inputType = false) {
|
|
19
|
+
if (typeMetadata.typeName === 'Promise') {
|
|
20
|
+
return this.getOrCreateGraphQLType(typeMetadata.parameters[0], inputType);
|
|
21
|
+
}
|
|
22
|
+
const name = this.getGraphQLName(typeMetadata, inputType);
|
|
23
|
+
// Check if GraphQL type already exists and reuse
|
|
24
|
+
if (name && this.graphQLTypes[name]) {
|
|
25
|
+
this.logger.debug(`Found existing GraphQL ${inputType ? 'input' : 'output'} type for name ${name}`);
|
|
26
|
+
return typeMetadata.isNullable ? this.graphQLTypes[name] : new graphql_1.GraphQLNonNull(this.graphQLTypes[name]);
|
|
27
|
+
}
|
|
28
|
+
// Create new GraphQL type from metadata
|
|
29
|
+
const createdGraphQLType = this.createGraphQLType(typeMetadata, inputType);
|
|
30
|
+
// Store created GraphQL type to reuse
|
|
31
|
+
if (name)
|
|
32
|
+
this.graphQLTypes[name] = createdGraphQLType;
|
|
33
|
+
return typeMetadata.isNullable ? createdGraphQLType : new graphql_1.GraphQLNonNull(createdGraphQLType);
|
|
34
|
+
}
|
|
35
|
+
getGraphQLName(typeMetadata, inputType) {
|
|
36
|
+
if (typeMetadata.name === 'UUID' || typeMetadata.name === 'Date') {
|
|
37
|
+
// UUID is a class but should result in a scalar which doesn't need a separate input type
|
|
38
|
+
// Date is an interface which has no `type`, so we need to use `name` instead
|
|
39
|
+
return typeMetadata.name;
|
|
40
|
+
}
|
|
41
|
+
if (typeMetadata.typeGroup === 'Array' || typeMetadata.typeGroup === 'ReadonlyArray') {
|
|
42
|
+
return this.getGraphQLName(typeMetadata.parameters[0], inputType) + 'List' + (inputType ? 'Input' : '');
|
|
43
|
+
}
|
|
44
|
+
if (typeMetadata.typeName && typeMetadata.typeGroup === 'Class') {
|
|
45
|
+
return typeMetadata.typeName + (inputType ? 'Input' : '');
|
|
46
|
+
}
|
|
47
|
+
if (typeMetadata.typeGroup === 'Union')
|
|
48
|
+
return typeMetadata.name;
|
|
49
|
+
return typeMetadata.typeName || null;
|
|
50
|
+
}
|
|
51
|
+
createGraphQLType(typeMetadata, inputType) {
|
|
52
|
+
this.logger.debug(`Creating GraphQL ${inputType ? 'input' : 'output'} type for type ${typeMetadata.name}`);
|
|
53
|
+
const { name, typeGroup } = typeMetadata;
|
|
54
|
+
if (name === 'Date')
|
|
55
|
+
return common_1.DateScalar;
|
|
56
|
+
if (name === 'UUID')
|
|
57
|
+
return graphql_1.GraphQLID;
|
|
58
|
+
if (typeGroup === 'String')
|
|
59
|
+
return graphql_1.GraphQLString;
|
|
60
|
+
if (typeGroup === 'Number')
|
|
61
|
+
return graphql_1.GraphQLFloat;
|
|
62
|
+
if (typeGroup === 'Boolean')
|
|
63
|
+
return graphql_1.GraphQLBoolean;
|
|
64
|
+
if (typeGroup === 'Enum')
|
|
65
|
+
return this.createEnumType(typeMetadata);
|
|
66
|
+
if (typeGroup === 'Array' || typeGroup === 'ReadonlyArray')
|
|
67
|
+
return this.createArrayType(typeMetadata, inputType);
|
|
68
|
+
if (typeGroup === 'Class' && typeMetadata.type && !(0, common_1.isExternalType)(typeMetadata)) {
|
|
69
|
+
const metadata = (0, metadata_1.getClassMetadata)(typeMetadata.type);
|
|
70
|
+
return this.createObjectType(metadata, inputType);
|
|
71
|
+
}
|
|
72
|
+
if (typeMetadata.typeGroup === 'Union' &&
|
|
73
|
+
!(0, common_1.isExternalType)(typeMetadata) &&
|
|
74
|
+
!inputType &&
|
|
75
|
+
this.validateUnionClasses(typeMetadata.parameters)) {
|
|
76
|
+
const graphQLUnionClasses = this.getUnionClasses(typeMetadata);
|
|
77
|
+
return new graphql_1.GraphQLUnionType({
|
|
78
|
+
name: typeMetadata.name,
|
|
79
|
+
types: graphQLUnionClasses,
|
|
80
|
+
resolveType(obj) {
|
|
81
|
+
return obj.constructor.name;
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return graphql_scalars_1.GraphQLJSON;
|
|
86
|
+
}
|
|
87
|
+
validateUnionClasses(params) {
|
|
88
|
+
return params.every((typeMetadata) => typeMetadata.typeGroup === 'Class' && typeMetadata.type && !(0, common_1.isExternalType)(typeMetadata));
|
|
89
|
+
}
|
|
90
|
+
getUnionClasses(typeMetadata) {
|
|
91
|
+
return typeMetadata.parameters.map((param) => {
|
|
92
|
+
if (param.typeGroup === 'Class' && param.type && !(0, common_1.isExternalType)(typeMetadata)) {
|
|
93
|
+
const metadata = (0, metadata_1.getClassMetadata)(param.type);
|
|
94
|
+
return this.getOrCreateObjectTypeForUnion(metadata);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
throw new Error(`Union type ${typeMetadata.name} can only contain classes`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
createEnumType(typeMetadata) {
|
|
102
|
+
return new graphql_1.GraphQLEnumType({
|
|
103
|
+
name: typeMetadata.name,
|
|
104
|
+
values: typeMetadata.parameters.reduce((obj, el) => ({ ...obj, [el.name]: {} }), {}),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
createArrayType(typeMetadata, inputType) {
|
|
108
|
+
const param = typeMetadata.parameters[0];
|
|
109
|
+
const GraphQLPropType = this.getOrCreateGraphQLType(param, inputType);
|
|
110
|
+
return new graphql_1.GraphQLList(GraphQLPropType);
|
|
111
|
+
}
|
|
112
|
+
getOrCreateObjectType(classMetadata, inputType, excludeProps) {
|
|
113
|
+
const typeName = classMetadata.name + (inputType ? 'Input' : '');
|
|
114
|
+
if (typeName && this.graphQLTypes[typeName])
|
|
115
|
+
return this.graphQLTypes[typeName];
|
|
116
|
+
const createdGraphQLType = this.createObjectType(classMetadata, inputType, excludeProps);
|
|
117
|
+
if (typeName)
|
|
118
|
+
this.graphQLTypes[typeName] = createdGraphQLType;
|
|
119
|
+
return createdGraphQLType;
|
|
120
|
+
}
|
|
121
|
+
createObjectType(classMetadata, inputType, excludeProps) {
|
|
122
|
+
const finalFields = (0, common_1.nonExcludedFields)(classMetadata.fields, excludeProps);
|
|
123
|
+
if (inputType) {
|
|
124
|
+
return new graphql_1.GraphQLInputObjectType({
|
|
125
|
+
name: classMetadata.name + 'Input',
|
|
126
|
+
fields: finalFields === null || finalFields === void 0 ? void 0 : finalFields.reduce((obj, prop) => {
|
|
127
|
+
this.logger.debug(`Get or create GraphQL input type for property ${prop.name}`);
|
|
128
|
+
return {
|
|
129
|
+
...obj,
|
|
130
|
+
[prop.name]: { type: this.getOrCreateGraphQLType(prop.typeInfo, inputType) },
|
|
131
|
+
};
|
|
132
|
+
}, {}),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return this.createOutputObjectType(classMetadata, excludeProps);
|
|
136
|
+
}
|
|
137
|
+
getOrCreateObjectTypeForUnion(classMetadata, excludeProps) {
|
|
138
|
+
const typeName = classMetadata.name;
|
|
139
|
+
if (typeName && this.graphQLTypes[typeName])
|
|
140
|
+
return this.graphQLTypes[typeName];
|
|
141
|
+
const createdGraphQLType = this.createOutputObjectType(classMetadata, excludeProps);
|
|
142
|
+
if (typeName)
|
|
143
|
+
this.graphQLTypes[typeName] = createdGraphQLType;
|
|
144
|
+
return createdGraphQLType;
|
|
145
|
+
}
|
|
146
|
+
createOutputObjectType(classMetadata, excludeProps) {
|
|
147
|
+
const finalFields = (0, common_1.nonExcludedFields)(classMetadata.fields, excludeProps);
|
|
148
|
+
return new graphql_1.GraphQLObjectType({
|
|
149
|
+
name: classMetadata.name,
|
|
150
|
+
fields: finalFields === null || finalFields === void 0 ? void 0 : finalFields.reduce((obj, prop) => {
|
|
151
|
+
this.logger.debug(`Get or create GraphQL output type for property ${prop.name}`);
|
|
152
|
+
return {
|
|
153
|
+
...obj,
|
|
154
|
+
[prop.name]: { type: this.getOrCreateGraphQLType(prop.typeInfo, false) },
|
|
155
|
+
};
|
|
156
|
+
}, {}),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.GraphQLTypeInformer = GraphQLTypeInformer;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GraphQLFieldConfigMap } from 'graphql';
|
|
2
|
+
import { GraphQLResolverContext, ResolverBuilder } from '../common';
|
|
3
|
+
import { AnyClass, MagekConfig } from '@magek/common';
|
|
4
|
+
import { GraphQLTypeInformer } from '../graphql-type-informer';
|
|
5
|
+
export declare class GraphqlQueryByKeysGenerator {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly readModels;
|
|
8
|
+
private readonly typeInformer;
|
|
9
|
+
private readonly byIDResolverBuilder;
|
|
10
|
+
constructor(config: MagekConfig, readModels: AnyClass[], typeInformer: GraphQLTypeInformer, byIDResolverBuilder: ResolverBuilder);
|
|
11
|
+
generateByKeysQueries(): GraphQLFieldConfigMap<unknown, GraphQLResolverContext>;
|
|
12
|
+
private generateByIdQuery;
|
|
13
|
+
private generateByIdAndSequenceKeyQuery;
|
|
14
|
+
}
|