@medusajs/search 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/README.md +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +24 -0
- package/dist/initialize/index.d.ts +8 -0
- package/dist/initialize/index.js +17 -0
- package/dist/joiner-config.d.ts +2 -0
- package/dist/joiner-config.js +4 -0
- package/dist/loaders/connection.d.ts +4 -0
- package/dist/loaders/connection.js +41 -0
- package/dist/loaders/container.d.ts +4 -0
- package/dist/loaders/container.js +21 -0
- package/dist/loaders/index.d.ts +2 -0
- package/dist/loaders/index.js +10 -0
- package/dist/migrations/Migration20231019174230.d.ts +4 -0
- package/dist/migrations/Migration20231019174230.js +18 -0
- package/dist/models/catalog-relation.d.ts +15 -0
- package/dist/models/catalog-relation.js +72 -0
- package/dist/models/catalog.d.ts +11 -0
- package/dist/models/catalog.js +55 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.js +18 -0
- package/dist/module-definition.d.ts +2 -0
- package/dist/module-definition.js +15 -0
- package/dist/scripts/bin/run-migration-down.d.ts +3 -0
- package/dist/scripts/bin/run-migration-down.js +32 -0
- package/dist/scripts/bin/run-migration-up.d.ts +3 -0
- package/dist/scripts/bin/run-migration-up.js +32 -0
- package/dist/scripts/bin/run-seed.d.ts +3 -0
- package/dist/scripts/bin/run-seed.js +38 -0
- package/dist/scripts/index.d.ts +2 -0
- package/dist/scripts/index.js +18 -0
- package/dist/scripts/migration-down.d.ts +10 -0
- package/dist/scripts/migration-down.js +52 -0
- package/dist/scripts/migration-up.d.ts +10 -0
- package/dist/scripts/migration-up.js +56 -0
- package/dist/scripts/seed-data/index.d.ts +8 -0
- package/dist/scripts/seed-data/index.js +138 -0
- package/dist/scripts/seed.d.ts +5 -0
- package/dist/scripts/seed.js +65 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/postgres-provider.d.ts +126 -0
- package/dist/services/postgres-provider.js +441 -0
- package/dist/services/search-module-service.d.ts +31 -0
- package/dist/services/search-module-service.js +66 -0
- package/dist/types/index.d.ts +122 -0
- package/dist/types/index.js +7 -0
- package/dist/utils/build-config.d.ts +21 -0
- package/dist/utils/build-config.js +437 -0
- package/dist/utils/create-partitions.d.ts +3 -0
- package/dist/utils/create-partitions.js +27 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/query-builder.d.ts +28 -0
- package/dist/utils/query-builder.js +375 -0
- package/package.json +67 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SchemaObjectRepresentation } from "../types";
|
|
2
|
+
export declare const CustomDirectives: {
|
|
3
|
+
Listeners: {
|
|
4
|
+
configurationPropertyName: string;
|
|
5
|
+
isRequired: boolean;
|
|
6
|
+
name: string;
|
|
7
|
+
directive: string;
|
|
8
|
+
definition: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* This util build an internal representation object from the provided schema.
|
|
13
|
+
* It will resolve all modules, fields, link module representation to build
|
|
14
|
+
* the appropriate representation for the catalog module.
|
|
15
|
+
*
|
|
16
|
+
* This representation will be used to re construct the expected output object from a search
|
|
17
|
+
* but can also be used for anything since the relation tree is available through ref.
|
|
18
|
+
*
|
|
19
|
+
* @param schema
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildSchemaObjectRepresentation(schema: any): [SchemaObjectRepresentation, Record<string, any>];
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildSchemaObjectRepresentation = exports.CustomDirectives = void 0;
|
|
4
|
+
const schema_1 = require("@graphql-tools/schema");
|
|
5
|
+
const modules_sdk_1 = require("@medusajs/modules-sdk");
|
|
6
|
+
const index_1 = require("graphql/index");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
exports.CustomDirectives = {
|
|
9
|
+
Listeners: {
|
|
10
|
+
configurationPropertyName: "listeners",
|
|
11
|
+
isRequired: true,
|
|
12
|
+
name: "Listeners",
|
|
13
|
+
directive: "@Listeners",
|
|
14
|
+
definition: "directive @Listeners (values: [String!]) on OBJECT",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
function makeSchemaExecutable(inputSchema) {
|
|
18
|
+
const { schema: cleanedSchema } = (0, modules_sdk_1.cleanGraphQLSchema)(inputSchema);
|
|
19
|
+
return (0, schema_1.makeExecutableSchema)({ typeDefs: cleanedSchema });
|
|
20
|
+
}
|
|
21
|
+
function retrieveAliasForEntity(entityName, serviceName, aliases) {
|
|
22
|
+
aliases = Array.isArray(aliases) ? aliases : [aliases];
|
|
23
|
+
aliases = aliases.filter(Boolean);
|
|
24
|
+
aliases = aliases
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.map((alias) => {
|
|
27
|
+
const names = Array.isArray(alias?.name) ? alias?.name : [alias?.name];
|
|
28
|
+
return names?.map((name) => ({
|
|
29
|
+
name,
|
|
30
|
+
args: alias?.args,
|
|
31
|
+
}));
|
|
32
|
+
})
|
|
33
|
+
.flat();
|
|
34
|
+
let alias = aliases.find((alias) => {
|
|
35
|
+
const curEntity = alias.args?.entity || alias?.name;
|
|
36
|
+
return curEntity && curEntity.toLowerCase() === entityName.toLowerCase();
|
|
37
|
+
});
|
|
38
|
+
alias = alias?.name;
|
|
39
|
+
return alias;
|
|
40
|
+
}
|
|
41
|
+
function retrieveModuleAndAlias(entityName, moduleJoinerConfigs) {
|
|
42
|
+
let relatedModule;
|
|
43
|
+
let alias;
|
|
44
|
+
for (const moduleJoinerConfig of moduleJoinerConfigs) {
|
|
45
|
+
const moduleSchema = moduleJoinerConfig.schema;
|
|
46
|
+
const moduleAliases = moduleJoinerConfig.alias;
|
|
47
|
+
/**
|
|
48
|
+
* If the entity exist in the module schema, then the current module is the
|
|
49
|
+
* one we are looking for.
|
|
50
|
+
*
|
|
51
|
+
* If the module does not have any schema, then we need to base the search
|
|
52
|
+
* on the provided aliases. in any case, we try to get both
|
|
53
|
+
*/
|
|
54
|
+
if (moduleSchema) {
|
|
55
|
+
const executableSchema = makeSchemaExecutable(moduleSchema);
|
|
56
|
+
const entitiesMap = executableSchema.getTypeMap();
|
|
57
|
+
if (entitiesMap[entityName]) {
|
|
58
|
+
relatedModule = moduleJoinerConfig;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (relatedModule && moduleAliases) {
|
|
62
|
+
alias = retrieveAliasForEntity(entityName, moduleJoinerConfig.serviceName, moduleJoinerConfig.alias);
|
|
63
|
+
}
|
|
64
|
+
if (relatedModule) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!relatedModule) {
|
|
69
|
+
throw new Error(`CatalogModule error, unable to retrieve the module that correspond to the entity ${entityName}. Please add the entity to the module schema or add an alias to the module configuration and the entity it correspond to in the args under the entity property.`);
|
|
70
|
+
}
|
|
71
|
+
if (!alias) {
|
|
72
|
+
throw new Error(`CatalogModule error, the module ${relatedModule?.serviceName} has a schema but does not have any alias for the entity ${entityName}. Please add an alias to the module configuration and the entity it correspond to in the args under the entity property.`);
|
|
73
|
+
}
|
|
74
|
+
return { relatedModule, alias };
|
|
75
|
+
}
|
|
76
|
+
// TODO: rename util
|
|
77
|
+
function retrieveLinkModuleAndAlias({ primaryEntity, primaryModuleConfig, foreignEntity, foreignModuleConfig, moduleJoinerConfigs, }) {
|
|
78
|
+
const linkModulesMetadata = [];
|
|
79
|
+
for (const linkModuleJoinerConfig of moduleJoinerConfigs.filter((config) => config.isLink)) {
|
|
80
|
+
const linkPrimary = linkModuleJoinerConfig.relationships[0];
|
|
81
|
+
const linkForeign = linkModuleJoinerConfig.relationships[1];
|
|
82
|
+
if (linkPrimary.serviceName === primaryModuleConfig.serviceName &&
|
|
83
|
+
linkForeign.serviceName === foreignModuleConfig.serviceName) {
|
|
84
|
+
const primaryEntityLinkableKey = linkPrimary.foreignKey;
|
|
85
|
+
const isTheForeignKeyEntityEqualPrimaryEntity = primaryModuleConfig.linkableKeys?.[primaryEntityLinkableKey] ===
|
|
86
|
+
primaryEntity;
|
|
87
|
+
const foreignEntityLinkableKey = linkForeign.foreignKey;
|
|
88
|
+
const isTheForeignKeyEntityEqualForeignEntity = foreignModuleConfig.linkableKeys?.[foreignEntityLinkableKey] ===
|
|
89
|
+
foreignEntity;
|
|
90
|
+
const linkName = linkModuleJoinerConfig.extends?.find((extend) => {
|
|
91
|
+
return (extend.serviceName === primaryModuleConfig.serviceName &&
|
|
92
|
+
extend.relationship.primaryKey === primaryEntityLinkableKey);
|
|
93
|
+
})?.relationship.serviceName;
|
|
94
|
+
if (!linkName) {
|
|
95
|
+
throw new Error(`CatalogModule error, unable to retrieve the link module name for the services ${primaryModuleConfig.serviceName} - ${foreignModuleConfig.serviceName}. Please be sure that the extend relationship service name is set correctly`);
|
|
96
|
+
}
|
|
97
|
+
if (!linkModuleJoinerConfig.alias?.[0]?.args?.entity) {
|
|
98
|
+
throw new Error(`CatalogModule error, unable to retrieve the link module entity name for the services ${primaryModuleConfig.serviceName} - ${foreignModuleConfig.serviceName}. Please be sure that the link module alias has an entity property in the args.`);
|
|
99
|
+
}
|
|
100
|
+
if (isTheForeignKeyEntityEqualPrimaryEntity &&
|
|
101
|
+
isTheForeignKeyEntityEqualForeignEntity) {
|
|
102
|
+
linkModulesMetadata.push({
|
|
103
|
+
entityName: linkModuleJoinerConfig.alias[0].args.entity,
|
|
104
|
+
alias: linkModuleJoinerConfig.alias[0].name,
|
|
105
|
+
linkModuleConfig: linkModuleJoinerConfig,
|
|
106
|
+
intermediateEntityNames: [],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const intermediateEntityName = foreignModuleConfig.linkableKeys[foreignEntityLinkableKey];
|
|
111
|
+
if (!foreignModuleConfig.schema) {
|
|
112
|
+
throw new Error(`CatalogModule error, unable to retrieve the intermediate entity name for the services ${primaryModuleConfig.serviceName} - ${foreignModuleConfig.serviceName}. Please be sure that the foreign module ${foreignModuleConfig.serviceName} has a schema.`);
|
|
113
|
+
}
|
|
114
|
+
const executableSchema = makeSchemaExecutable(foreignModuleConfig.schema);
|
|
115
|
+
const entitiesMap = executableSchema.getTypeMap();
|
|
116
|
+
let intermediateEntities = [];
|
|
117
|
+
let foundCount = 0;
|
|
118
|
+
const isForeignEntityChildOfIntermediateEntity = (entityName) => {
|
|
119
|
+
for (const entityType of Object.values(entitiesMap)) {
|
|
120
|
+
if (entityType.astNode?.kind === "ObjectTypeDefinition" &&
|
|
121
|
+
entityType.astNode?.fields?.some((field) => {
|
|
122
|
+
return field.type?.type?.name?.value === entityName;
|
|
123
|
+
})) {
|
|
124
|
+
if (entityType.name === intermediateEntityName) {
|
|
125
|
+
++foundCount;
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const test = isForeignEntityChildOfIntermediateEntity(entityType.name);
|
|
130
|
+
if (test) {
|
|
131
|
+
intermediateEntities.push(entityType.name);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
};
|
|
138
|
+
isForeignEntityChildOfIntermediateEntity(foreignEntity);
|
|
139
|
+
if (foundCount !== 1) {
|
|
140
|
+
throw new Error(`CatalogModule error, unable to retrieve the intermediate entities for the services ${primaryModuleConfig.serviceName} - ${foreignModuleConfig.serviceName} between ${foreignEntity} and ${intermediateEntityName}. Multiple paths or no path found. Please check your schema in ${foreignModuleConfig.serviceName}`);
|
|
141
|
+
}
|
|
142
|
+
intermediateEntities.push(intermediateEntityName);
|
|
143
|
+
linkModulesMetadata.push({
|
|
144
|
+
entityName: linkModuleJoinerConfig.alias[0].args.entity,
|
|
145
|
+
alias: linkModuleJoinerConfig.alias[0].name,
|
|
146
|
+
linkModuleConfig: linkModuleJoinerConfig,
|
|
147
|
+
intermediateEntityNames: intermediateEntities,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!linkModulesMetadata.length) {
|
|
153
|
+
throw new Error(`CatalogModule error, unable to retrieve the link module that correspond to the entities ${primaryEntity} - ${foreignEntity}.`);
|
|
154
|
+
}
|
|
155
|
+
return linkModulesMetadata;
|
|
156
|
+
}
|
|
157
|
+
function getObjectRepresentationRef(entityName, { objectRepresentationRef }) {
|
|
158
|
+
return (objectRepresentationRef[entityName] ?? (objectRepresentationRef[entityName] = {
|
|
159
|
+
entity: entityName,
|
|
160
|
+
parents: [],
|
|
161
|
+
alias: "",
|
|
162
|
+
listeners: [],
|
|
163
|
+
moduleConfig: null,
|
|
164
|
+
fields: [],
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
function setCustomDirectives(currentObjectRepresentationRef, directives) {
|
|
168
|
+
for (const customDirectiveConfiguration of Object.values(exports.CustomDirectives)) {
|
|
169
|
+
const directive = directives.find((typeDirective) => typeDirective.name.value === customDirectiveConfiguration.name);
|
|
170
|
+
if (!directive) {
|
|
171
|
+
if (customDirectiveConfiguration.isRequired) {
|
|
172
|
+
throw new Error(`CatalogModule error, the type ${currentObjectRepresentationRef.entity} defined in the schema is missing the ${customDirectiveConfiguration.directive} directive which is required`);
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// Only support array directive value for now
|
|
177
|
+
currentObjectRepresentationRef[customDirectiveConfiguration.configurationPropertyName] = (directive.arguments[0].value?.values ?? []).map((v) => v.value);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function processEntity(entityName, { entitiesMap, moduleJoinerConfigs, objectRepresentationRef, }) {
|
|
181
|
+
/**
|
|
182
|
+
* Get the reference to the object representation for the current entity.
|
|
183
|
+
*/
|
|
184
|
+
const currentObjectRepresentationRef = getObjectRepresentationRef(entityName, {
|
|
185
|
+
objectRepresentationRef,
|
|
186
|
+
});
|
|
187
|
+
/**
|
|
188
|
+
* Retrieve and set the custom directives for the current entity.
|
|
189
|
+
*/
|
|
190
|
+
setCustomDirectives(currentObjectRepresentationRef, entitiesMap[entityName].astNode?.directives ?? []);
|
|
191
|
+
currentObjectRepresentationRef.fields =
|
|
192
|
+
(0, modules_sdk_1.getFieldsAndRelations)(entitiesMap, entityName) ?? [];
|
|
193
|
+
/**
|
|
194
|
+
* Retrieve the module and alias for the current entity.
|
|
195
|
+
*/
|
|
196
|
+
const { relatedModule: currentEntityModule, alias } = retrieveModuleAndAlias(entityName, moduleJoinerConfigs);
|
|
197
|
+
objectRepresentationRef._serviceNameModuleConfigMap[currentEntityModule.serviceName] = currentEntityModule;
|
|
198
|
+
currentObjectRepresentationRef.moduleConfig = currentEntityModule;
|
|
199
|
+
currentObjectRepresentationRef.alias = alias;
|
|
200
|
+
/**
|
|
201
|
+
* Retrieve the parent entities for the current entity.
|
|
202
|
+
*/
|
|
203
|
+
const schemaParentEntity = Object.values(entitiesMap).filter((value) => {
|
|
204
|
+
return (value.astNode &&
|
|
205
|
+
value.astNode.fields?.some((field) => {
|
|
206
|
+
let currentType = field.type;
|
|
207
|
+
while (currentType.type) {
|
|
208
|
+
currentType = currentType.type;
|
|
209
|
+
}
|
|
210
|
+
return currentType.name?.value === entityName;
|
|
211
|
+
}));
|
|
212
|
+
});
|
|
213
|
+
/**
|
|
214
|
+
* If the current entity has parent entities, then we need to process them.
|
|
215
|
+
*/
|
|
216
|
+
if (schemaParentEntity.length) {
|
|
217
|
+
const parentEntityNames = schemaParentEntity.map((parent) => {
|
|
218
|
+
return parent.name;
|
|
219
|
+
});
|
|
220
|
+
for (const parent of parentEntityNames) {
|
|
221
|
+
/**
|
|
222
|
+
* Retrieve the parent entity field in the schema
|
|
223
|
+
*/
|
|
224
|
+
const entityFieldInParent = entitiesMap[parent].astNode?.fields?.find((field) => {
|
|
225
|
+
let currentType = field.type;
|
|
226
|
+
while (currentType.type) {
|
|
227
|
+
currentType = currentType.type;
|
|
228
|
+
}
|
|
229
|
+
return currentType.name?.value === entityName;
|
|
230
|
+
});
|
|
231
|
+
const isEntityListInParent = entityFieldInParent.type.kind === index_1.Kind.LIST_TYPE;
|
|
232
|
+
const entityTargetPropertyNameInParent = entityFieldInParent.name.value;
|
|
233
|
+
/**
|
|
234
|
+
* Retrieve the parent entity object representation reference.
|
|
235
|
+
*/
|
|
236
|
+
const parentObjectRepresentationRef = getObjectRepresentationRef(parent, {
|
|
237
|
+
objectRepresentationRef,
|
|
238
|
+
});
|
|
239
|
+
const parentModuleConfig = parentObjectRepresentationRef.moduleConfig;
|
|
240
|
+
/**
|
|
241
|
+
* If the parent entity and the current entity are part of the same servive then configure the parent and
|
|
242
|
+
* add the parent id as a field to the current entity.
|
|
243
|
+
*/
|
|
244
|
+
if (currentObjectRepresentationRef.moduleConfig.serviceName ===
|
|
245
|
+
parentModuleConfig.serviceName ||
|
|
246
|
+
parentModuleConfig.isLink) {
|
|
247
|
+
currentObjectRepresentationRef.parents.push({
|
|
248
|
+
ref: parentObjectRepresentationRef,
|
|
249
|
+
targetProp: entityTargetPropertyNameInParent,
|
|
250
|
+
isList: isEntityListInParent,
|
|
251
|
+
});
|
|
252
|
+
currentObjectRepresentationRef.fields.push(parentObjectRepresentationRef.alias + ".id");
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
/**
|
|
256
|
+
* If the parent entity and the current entity are not part of the same service then we need to
|
|
257
|
+
* find the link module that join them.
|
|
258
|
+
*/
|
|
259
|
+
const linkModuleMetadatas = retrieveLinkModuleAndAlias({
|
|
260
|
+
primaryEntity: parentObjectRepresentationRef.entity,
|
|
261
|
+
primaryModuleConfig: parentModuleConfig,
|
|
262
|
+
foreignEntity: currentObjectRepresentationRef.entity,
|
|
263
|
+
foreignModuleConfig: currentEntityModule,
|
|
264
|
+
moduleJoinerConfigs,
|
|
265
|
+
});
|
|
266
|
+
for (const linkModuleMetadata of linkModuleMetadatas) {
|
|
267
|
+
const linkObjectRepresentationRef = getObjectRepresentationRef(linkModuleMetadata.entityName, { objectRepresentationRef });
|
|
268
|
+
objectRepresentationRef._serviceNameModuleConfigMap[linkModuleMetadata.linkModuleConfig.serviceName ||
|
|
269
|
+
linkModuleMetadata.entityName] = currentEntityModule;
|
|
270
|
+
/**
|
|
271
|
+
* Add the schema parent entity as a parent to the link module and configure it.
|
|
272
|
+
*/
|
|
273
|
+
linkObjectRepresentationRef.parents = [
|
|
274
|
+
{
|
|
275
|
+
ref: parentObjectRepresentationRef,
|
|
276
|
+
targetProp: linkModuleMetadata.alias,
|
|
277
|
+
},
|
|
278
|
+
];
|
|
279
|
+
linkObjectRepresentationRef.alias = linkModuleMetadata.alias;
|
|
280
|
+
linkObjectRepresentationRef.listeners = [
|
|
281
|
+
`${linkModuleMetadata.entityName}.attached`,
|
|
282
|
+
`${linkModuleMetadata.entityName}.detached`,
|
|
283
|
+
];
|
|
284
|
+
linkObjectRepresentationRef.moduleConfig =
|
|
285
|
+
linkModuleMetadata.linkModuleConfig;
|
|
286
|
+
linkObjectRepresentationRef.fields = [
|
|
287
|
+
...linkModuleMetadata.linkModuleConfig
|
|
288
|
+
.relationships.map((relationship) => [
|
|
289
|
+
parentModuleConfig.serviceName,
|
|
290
|
+
currentEntityModule.serviceName,
|
|
291
|
+
].includes(relationship.serviceName) &&
|
|
292
|
+
relationship.foreignKey)
|
|
293
|
+
.filter((v) => Boolean(v)),
|
|
294
|
+
parentObjectRepresentationRef.alias + ".id",
|
|
295
|
+
];
|
|
296
|
+
/**
|
|
297
|
+
* If the current entity is not the entity that is used to join the link module and the parent entity
|
|
298
|
+
* then we need to add the new entity that join them and then add the link as its parent
|
|
299
|
+
* before setting the new entity as the true parent of the current entity.
|
|
300
|
+
*/
|
|
301
|
+
for (let i = linkModuleMetadata.intermediateEntityNames.length - 1; i >= 0; --i) {
|
|
302
|
+
const intermediateEntityName = linkModuleMetadata.intermediateEntityNames[i];
|
|
303
|
+
const parentIntermediateEntityRef = i === linkModuleMetadata.intermediateEntityNames.length - 1
|
|
304
|
+
? linkObjectRepresentationRef
|
|
305
|
+
: objectRepresentationRef[linkModuleMetadata.intermediateEntityNames[i + 1]];
|
|
306
|
+
const { relatedModule: intermediateEntityModule, alias: intermediateEntityAlias, } = retrieveModuleAndAlias(intermediateEntityName, moduleJoinerConfigs);
|
|
307
|
+
const intermediateEntityObjectRepresentationRef = getObjectRepresentationRef(intermediateEntityName, {
|
|
308
|
+
objectRepresentationRef,
|
|
309
|
+
});
|
|
310
|
+
objectRepresentationRef._serviceNameModuleConfigMap[intermediateEntityModule.serviceName] = intermediateEntityModule;
|
|
311
|
+
intermediateEntityObjectRepresentationRef.parents.push({
|
|
312
|
+
ref: parentIntermediateEntityRef,
|
|
313
|
+
targetProp: intermediateEntityAlias,
|
|
314
|
+
isList: true, // TODO: check if it is a list in retrieveLinkModuleAndAlias and return the intermediate entity names + isList for each
|
|
315
|
+
});
|
|
316
|
+
intermediateEntityObjectRepresentationRef.alias =
|
|
317
|
+
intermediateEntityAlias;
|
|
318
|
+
intermediateEntityObjectRepresentationRef.listeners = [
|
|
319
|
+
intermediateEntityName + ".created",
|
|
320
|
+
intermediateEntityName + ".updated",
|
|
321
|
+
];
|
|
322
|
+
intermediateEntityObjectRepresentationRef.moduleConfig =
|
|
323
|
+
intermediateEntityModule;
|
|
324
|
+
intermediateEntityObjectRepresentationRef.fields = [
|
|
325
|
+
"id",
|
|
326
|
+
linkObjectRepresentationRef.alias + ".id",
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
let currentParentIntermediateRef = linkObjectRepresentationRef;
|
|
330
|
+
if (linkModuleMetadata.intermediateEntityNames.length) {
|
|
331
|
+
currentParentIntermediateRef =
|
|
332
|
+
objectRepresentationRef[linkModuleMetadata.intermediateEntityNames[0]];
|
|
333
|
+
}
|
|
334
|
+
currentObjectRepresentationRef.parents.push({
|
|
335
|
+
ref: currentParentIntermediateRef,
|
|
336
|
+
inSchemaRef: parentObjectRepresentationRef,
|
|
337
|
+
targetProp: entityTargetPropertyNameInParent,
|
|
338
|
+
isList: isEntityListInParent,
|
|
339
|
+
});
|
|
340
|
+
currentObjectRepresentationRef.fields.push(currentParentIntermediateRef.alias + ".id");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Build a special object which will be used to retrieve the correct
|
|
348
|
+
* object representation using path tree
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* {
|
|
352
|
+
* _schemaPropertiesMap: {
|
|
353
|
+
* "product": <ProductRef>
|
|
354
|
+
* "product.variants": <ProductVariantRef>
|
|
355
|
+
* }
|
|
356
|
+
* }
|
|
357
|
+
*/
|
|
358
|
+
function buildAliasMap(objectRepresentation) {
|
|
359
|
+
const aliasMap = {};
|
|
360
|
+
function recursivelyBuildAliasPath(current, alias = "", aliases = []) {
|
|
361
|
+
if (current.parents?.length) {
|
|
362
|
+
for (const parentEntity of current.parents) {
|
|
363
|
+
/**
|
|
364
|
+
* Here we build the alias from child to parent to get it as parent to child
|
|
365
|
+
*/
|
|
366
|
+
const _aliases = recursivelyBuildAliasPath(parentEntity.ref, `${parentEntity.targetProp}${alias ? "." + alias : ""}`).map((alias) => ({ alias: alias.alias }));
|
|
367
|
+
aliases.push(..._aliases);
|
|
368
|
+
/**
|
|
369
|
+
* Now if there is a inSchemaRef it means that we had inferred a link module
|
|
370
|
+
* and we want to get the alias path as it would be in the schema provided
|
|
371
|
+
* and it become the short cut path of the full path above
|
|
372
|
+
*/
|
|
373
|
+
if (parentEntity.inSchemaRef) {
|
|
374
|
+
const shortCutOf = _aliases.map((a) => a.alias)[0];
|
|
375
|
+
const _aliasesShortCut = recursivelyBuildAliasPath(parentEntity.inSchemaRef, `${parentEntity.targetProp}${alias ? "." + alias : ""}`).map((alias_) => {
|
|
376
|
+
return {
|
|
377
|
+
alias: alias_.alias,
|
|
378
|
+
// It has to be the same entry point
|
|
379
|
+
shortCutOf: shortCutOf.split(".")[0] === alias_.alias.split(".")[0]
|
|
380
|
+
? shortCutOf
|
|
381
|
+
: undefined,
|
|
382
|
+
};
|
|
383
|
+
});
|
|
384
|
+
aliases.push(..._aliasesShortCut);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
aliases.push({ alias: current.alias + (alias ? "." + alias : "") });
|
|
389
|
+
return aliases;
|
|
390
|
+
}
|
|
391
|
+
for (const objectRepresentationKey of Object.keys(objectRepresentation).filter((key) => !types_1.schemaObjectRepresentationPropertiesToOmit.includes(key))) {
|
|
392
|
+
const entityRepresentationRef = objectRepresentation[objectRepresentationKey];
|
|
393
|
+
const aliases = recursivelyBuildAliasPath(entityRepresentationRef);
|
|
394
|
+
for (const alias of aliases) {
|
|
395
|
+
aliasMap[alias.alias] = {
|
|
396
|
+
ref: entityRepresentationRef,
|
|
397
|
+
};
|
|
398
|
+
if (alias.shortCutOf) {
|
|
399
|
+
aliasMap[alias.alias]["shortCutOf"] = alias.shortCutOf;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return aliasMap;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* This util build an internal representation object from the provided schema.
|
|
407
|
+
* It will resolve all modules, fields, link module representation to build
|
|
408
|
+
* the appropriate representation for the catalog module.
|
|
409
|
+
*
|
|
410
|
+
* This representation will be used to re construct the expected output object from a search
|
|
411
|
+
* but can also be used for anything since the relation tree is available through ref.
|
|
412
|
+
*
|
|
413
|
+
* @param schema
|
|
414
|
+
*/
|
|
415
|
+
function buildSchemaObjectRepresentation(schema) {
|
|
416
|
+
const moduleJoinerConfigs = modules_sdk_1.MedusaModule.getAllJoinerConfigs();
|
|
417
|
+
const augmentedSchema = exports.CustomDirectives.Listeners.definition + schema;
|
|
418
|
+
const executableSchema = makeSchemaExecutable(augmentedSchema);
|
|
419
|
+
const entitiesMap = executableSchema.getTypeMap();
|
|
420
|
+
const objectRepresentation = {
|
|
421
|
+
_serviceNameModuleConfigMap: {},
|
|
422
|
+
};
|
|
423
|
+
Object.entries(entitiesMap).forEach(([entityName, entityMapValue]) => {
|
|
424
|
+
if (!entityMapValue.astNode) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
processEntity(entityName, {
|
|
428
|
+
entitiesMap,
|
|
429
|
+
moduleJoinerConfigs,
|
|
430
|
+
objectRepresentationRef: objectRepresentation,
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
objectRepresentation._schemaPropertiesMap =
|
|
434
|
+
buildAliasMap(objectRepresentation);
|
|
435
|
+
return [objectRepresentation, entitiesMap];
|
|
436
|
+
}
|
|
437
|
+
exports.buildSchemaObjectRepresentation = buildSchemaObjectRepresentation;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPartitions = void 0;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
async function createPartitions(schemaObjectRepresentation, manager) {
|
|
6
|
+
const activeSchema = manager.config.get("schema")
|
|
7
|
+
? `"${manager.config.get("schema")}".`
|
|
8
|
+
: "";
|
|
9
|
+
const partitions = Object.keys(schemaObjectRepresentation)
|
|
10
|
+
.filter((key) => !types_1.schemaObjectRepresentationPropertiesToOmit.includes(key))
|
|
11
|
+
.map((key) => {
|
|
12
|
+
const cName = key.toLowerCase();
|
|
13
|
+
const part = [];
|
|
14
|
+
part.push(`CREATE TABLE IF NOT EXISTS ${activeSchema}cat_${cName} PARTITION OF ${activeSchema}catalog FOR VALUES IN ('${key}')`);
|
|
15
|
+
for (const parent of schemaObjectRepresentation[key].parents) {
|
|
16
|
+
const pKey = `${parent.ref.entity}-${key}`;
|
|
17
|
+
const pName = `${parent.ref.entity}${key}`.toLowerCase();
|
|
18
|
+
part.push(`CREATE TABLE IF NOT EXISTS ${activeSchema}cat_pivot_${pName} PARTITION OF ${activeSchema}catalog_relation FOR VALUES IN ('${pKey}')`);
|
|
19
|
+
}
|
|
20
|
+
return part;
|
|
21
|
+
})
|
|
22
|
+
.flat();
|
|
23
|
+
partitions.push(`analyse ${activeSchema}catalog`);
|
|
24
|
+
partitions.push(`analyse ${activeSchema}catalog_relation`);
|
|
25
|
+
await manager.execute(partitions.join("; "));
|
|
26
|
+
}
|
|
27
|
+
exports.createPartitions = createPartitions;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./query-builder"), exports);
|
|
18
|
+
__exportStar(require("./create-partitions"), exports);
|
|
19
|
+
__exportStar(require("./build-config"), exports);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { QueryFormat, QueryOptions, SchemaObjectRepresentation } from "../types";
|
|
3
|
+
export declare class QueryBuilder {
|
|
4
|
+
private readonly structure;
|
|
5
|
+
private readonly entityMap;
|
|
6
|
+
private readonly knex;
|
|
7
|
+
private readonly selector;
|
|
8
|
+
private readonly options?;
|
|
9
|
+
private readonly schema;
|
|
10
|
+
constructor(args: {
|
|
11
|
+
schema: SchemaObjectRepresentation;
|
|
12
|
+
entityMap: Record<string, any>;
|
|
13
|
+
knex: Knex;
|
|
14
|
+
selector: QueryFormat;
|
|
15
|
+
options?: QueryOptions;
|
|
16
|
+
});
|
|
17
|
+
private getStructureKeys;
|
|
18
|
+
private getEntity;
|
|
19
|
+
private getGraphQLType;
|
|
20
|
+
private transformValueToType;
|
|
21
|
+
private getPostgresCastType;
|
|
22
|
+
private parseWhere;
|
|
23
|
+
private buildQueryParts;
|
|
24
|
+
private buildSelectParts;
|
|
25
|
+
private transformOrderBy;
|
|
26
|
+
buildQuery(countAllResults?: boolean, returnIdOnly?: boolean): string;
|
|
27
|
+
buildObjectFromResultset(resultSet: Record<string, any>[]): Record<string, any>[];
|
|
28
|
+
}
|