@comet/cms-api 9.0.0-beta.3 → 9.0.0-beta.4
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/lib/blocks/tipTap/createTipTapRichTextBlock.d.ts +44 -0
- package/lib/blocks/tipTap/createTipTapRichTextBlock.d.ts.map +1 -0
- package/lib/blocks/tipTap/createTipTapRichTextBlock.js +346 -0
- package/lib/blocks/tipTap/createTipTapRichTextBlock.js.map +1 -0
- package/lib/blocks/tipTap/extensions/BlockStyleHeading.d.ts +2 -0
- package/lib/blocks/tipTap/extensions/BlockStyleHeading.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/BlockStyleHeading.js +18 -0
- package/lib/blocks/tipTap/extensions/BlockStyleHeading.js.map +1 -0
- package/lib/blocks/tipTap/extensions/BlockStyleParagraph.d.ts +2 -0
- package/lib/blocks/tipTap/extensions/BlockStyleParagraph.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/BlockStyleParagraph.js +18 -0
- package/lib/blocks/tipTap/extensions/BlockStyleParagraph.js.map +1 -0
- package/lib/blocks/tipTap/extensions/CmsLink.d.ts +3 -0
- package/lib/blocks/tipTap/extensions/CmsLink.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/CmsLink.js +22 -0
- package/lib/blocks/tipTap/extensions/CmsLink.js.map +1 -0
- package/lib/blocks/tipTap/extensions/InlineStyleMark.d.ts +3 -0
- package/lib/blocks/tipTap/extensions/InlineStyleMark.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/InlineStyleMark.js +24 -0
- package/lib/blocks/tipTap/extensions/InlineStyleMark.js.map +1 -0
- package/lib/blocks/tipTap/extensions/NonBreakingSpace.d.ts +3 -0
- package/lib/blocks/tipTap/extensions/NonBreakingSpace.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/NonBreakingSpace.js +18 -0
- package/lib/blocks/tipTap/extensions/NonBreakingSpace.js.map +1 -0
- package/lib/blocks/tipTap/extensions/SoftHyphen.d.ts +3 -0
- package/lib/blocks/tipTap/extensions/SoftHyphen.d.ts.map +1 -0
- package/lib/blocks/tipTap/extensions/SoftHyphen.js +18 -0
- package/lib/blocks/tipTap/extensions/SoftHyphen.js.map +1 -0
- package/lib/common/enum/core-permission.enum.d.ts +2 -1
- package/lib/common/enum/core-permission.enum.d.ts.map +1 -1
- package/lib/common/enum/core-permission.enum.js +1 -0
- package/lib/common/enum/core-permission.enum.js.map +1 -1
- package/lib/dam/files/dto/file.args.d.ts +1 -0
- package/lib/dam/files/dto/file.args.d.ts.map +1 -1
- package/lib/dam/files/dto/file.args.js +6 -0
- package/lib/dam/files/dto/file.args.js.map +1 -1
- package/lib/dam/files/files.resolver.d.ts.map +1 -1
- package/lib/dam/files/files.resolver.js +18 -0
- package/lib/dam/files/files.resolver.js.map +1 -1
- package/lib/dam/files/files.service.d.ts.map +1 -1
- package/lib/dam/files/files.service.js +6 -0
- package/lib/dam/files/files.service.js.map +1 -1
- package/lib/dependencies/dependencies.service.d.ts +3 -1
- package/lib/dependencies/dependencies.service.d.ts.map +1 -1
- package/lib/dependencies/dependencies.service.js +9 -3
- package/lib/dependencies/dependencies.service.js.map +1 -1
- package/lib/entity-info/entity-info.decorator.d.ts +1 -0
- package/lib/entity-info/entity-info.decorator.d.ts.map +1 -1
- package/lib/entity-info/entity-info.decorator.js.map +1 -1
- package/lib/entity-info/entity-info.object.d.ts.map +1 -1
- package/lib/entity-info/entity-info.object.js +2 -0
- package/lib/entity-info/entity-info.object.js.map +1 -1
- package/lib/entity-info/entity-info.service.d.ts +0 -5
- package/lib/entity-info/entity-info.service.d.ts.map +1 -1
- package/lib/entity-info/entity-info.service.js +28 -75
- package/lib/entity-info/entity-info.service.js.map +1 -1
- package/lib/entity-info/resolve-field-to-sql.d.ts +7 -0
- package/lib/entity-info/resolve-field-to-sql.d.ts.map +1 -0
- package/lib/entity-info/resolve-field-to-sql.js +47 -0
- package/lib/entity-info/resolve-field-to-sql.js.map +1 -0
- package/lib/full-text-search/dto/paginated-entity-info.d.ts +5 -0
- package/lib/full-text-search/dto/paginated-entity-info.d.ts.map +1 -0
- package/lib/full-text-search/dto/paginated-entity-info.js +19 -0
- package/lib/full-text-search/dto/paginated-entity-info.js.map +1 -0
- package/lib/full-text-search/entities/entity-info-full-text.object.d.ts +6 -0
- package/lib/full-text-search/entities/entity-info-full-text.object.d.ts.map +1 -0
- package/lib/full-text-search/entities/entity-info-full-text.object.js +35 -0
- package/lib/full-text-search/entities/entity-info-full-text.object.js.map +1 -0
- package/lib/full-text-search/full-text-search.module.d.ts +4 -0
- package/lib/full-text-search/full-text-search.module.d.ts.map +1 -0
- package/lib/full-text-search/full-text-search.module.js +27 -0
- package/lib/full-text-search/full-text-search.module.js.map +1 -0
- package/lib/full-text-search/full-text-search.resolver.d.ts +8 -0
- package/lib/full-text-search/full-text-search.resolver.d.ts.map +1 -0
- package/lib/full-text-search/full-text-search.resolver.js +61 -0
- package/lib/full-text-search/full-text-search.resolver.js.map +1 -0
- package/lib/full-text-search/full-text-search.service.d.ts +12 -0
- package/lib/full-text-search/full-text-search.service.d.ts.map +1 -0
- package/lib/full-text-search/full-text-search.service.js +79 -0
- package/lib/full-text-search/full-text-search.service.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -5
- package/lib/index.js.map +1 -1
- package/lib/mailer/mailer.module.d.ts +8 -0
- package/lib/mailer/mailer.module.d.ts.map +1 -1
- package/lib/mailer/mailer.module.js.map +1 -1
- package/lib/mikro-orm/helper/entity-to-mikro-orm-full-text.d.ts +4 -0
- package/lib/mikro-orm/helper/entity-to-mikro-orm-full-text.d.ts.map +1 -0
- package/lib/mikro-orm/helper/entity-to-mikro-orm-full-text.js +21 -0
- package/lib/mikro-orm/helper/entity-to-mikro-orm-full-text.js.map +1 -0
- package/lib/translation/azure-ai-translator.resolver.d.ts +2 -0
- package/lib/translation/azure-ai-translator.resolver.d.ts.map +1 -1
- package/lib/translation/azure-ai-translator.resolver.js +37 -0
- package/lib/translation/azure-ai-translator.resolver.js.map +1 -1
- package/lib/translation/dto/azure-ai-translation-batch.input.d.ts +5 -0
- package/lib/translation/dto/azure-ai-translation-batch.input.d.ts.map +1 -0
- package/lib/translation/dto/azure-ai-translation-batch.input.js +33 -0
- package/lib/translation/dto/azure-ai-translation-batch.input.js.map +1 -0
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +39 -32
|
@@ -16,100 +16,53 @@ const common_1 = require("@nestjs/common");
|
|
|
16
16
|
const discover_service_1 = require("../dependencies/discover.service");
|
|
17
17
|
const entity_info_decorator_1 = require("./entity-info.decorator");
|
|
18
18
|
const entity_info_object_1 = require("./entity-info.object");
|
|
19
|
+
const resolve_field_to_sql_1 = require("./resolve-field-to-sql");
|
|
19
20
|
let EntityInfoService = EntityInfoService_1 = class EntityInfoService {
|
|
20
21
|
constructor(discoverService, entityManager) {
|
|
21
22
|
this.discoverService = discoverService;
|
|
22
23
|
this.entityManager = entityManager;
|
|
23
24
|
this.logger = new common_1.Logger(EntityInfoService_1.name);
|
|
24
25
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Resolves a field path (e.g., "title" or "manufacturer.name") to a SQL expression.
|
|
27
|
-
* Supports direct fields, embeddables, and n-level deep ManyToOne/OneToOne relations using subqueries.
|
|
28
|
-
*/
|
|
29
|
-
resolveFieldToSql(fieldPath, metadata, tableName) {
|
|
30
|
-
const parts = fieldPath.split(".");
|
|
31
|
-
// Direct field - find the actual column name
|
|
32
|
-
if (parts.length === 1) {
|
|
33
|
-
const fieldProp = metadata.props.find((p) => p.name === parts[0]);
|
|
34
|
-
if (!fieldProp) {
|
|
35
|
-
throw new Error(`Field "${parts[0]}" not found in entity "${metadata.className}"`);
|
|
36
|
-
}
|
|
37
|
-
return `"${tableName}"."${fieldProp.fieldNames[0]}"`;
|
|
38
|
-
}
|
|
39
|
-
// Relation path - resolve first relation and recurse for the rest
|
|
40
|
-
const [relationName, ...remainingParts] = parts;
|
|
41
|
-
// Find the relation property in metadata
|
|
42
|
-
const relationProp = metadata.props.find((p) => p.name === relationName);
|
|
43
|
-
if (!relationProp) {
|
|
44
|
-
throw new Error(`Relation "${relationName}" not found in entity "${metadata.className}"`);
|
|
45
|
-
}
|
|
46
|
-
// Handle embedded properties - fields are columns on the same table
|
|
47
|
-
if (relationProp.kind === "embedded") {
|
|
48
|
-
let currentProp = relationProp;
|
|
49
|
-
let currentName = relationName;
|
|
50
|
-
for (const part of remainingParts) {
|
|
51
|
-
const childProp = currentProp.embeddedProps?.[part];
|
|
52
|
-
if (!childProp) {
|
|
53
|
-
throw new Error(`Embedded field "${part}" not found in embeddable "${currentName}" of entity "${metadata.className}"`);
|
|
54
|
-
}
|
|
55
|
-
currentName = part;
|
|
56
|
-
currentProp = childProp;
|
|
57
|
-
}
|
|
58
|
-
return `"${tableName}"."${currentProp.fieldNames[0]}"`;
|
|
59
|
-
}
|
|
60
|
-
if (relationProp.kind !== "m:1" && relationProp.kind !== "1:1") {
|
|
61
|
-
throw new Error(`Only ManyToOne, OneToOne relations and embeddables are supported for EntityInfo. "${relationName}" is "${relationProp.kind}"`);
|
|
62
|
-
}
|
|
63
|
-
if (!relationProp.targetMeta) {
|
|
64
|
-
throw new Error(`Relation "${relationName}" has no target metadata`);
|
|
65
|
-
}
|
|
66
|
-
// Get the join column (foreign key) and target table info
|
|
67
|
-
const joinColumn = relationProp.joinColumns[0];
|
|
68
|
-
const targetTableName = relationProp.targetMeta.tableName;
|
|
69
|
-
const targetPrimaryKey = relationProp.targetMeta.primaryKeys[0];
|
|
70
|
-
// Recursively resolve the remaining path in the target entity
|
|
71
|
-
const innerSql = this.resolveFieldToSql(remainingParts.join("."), relationProp.targetMeta, targetTableName);
|
|
72
|
-
return `(SELECT ${innerSql} FROM "${targetTableName}" WHERE "${targetTableName}"."${targetPrimaryKey}" = "${tableName}"."${joinColumn}")`;
|
|
73
|
-
}
|
|
74
26
|
async createEntityInfoView() {
|
|
75
27
|
const indexSelects = [];
|
|
76
28
|
const targetEntities = this.discoverService.discoverTargetEntities();
|
|
77
29
|
for (const targetEntity of targetEntities) {
|
|
78
30
|
const entityInfo = Reflect.getMetadata(entity_info_decorator_1.ENTITY_INFO_METADATA_KEY, targetEntity.entity);
|
|
79
|
-
if (entityInfo) {
|
|
80
|
-
|
|
81
|
-
|
|
31
|
+
if (!entityInfo) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (typeof entityInfo === "string") {
|
|
35
|
+
indexSelects.push(`SELECT sub."name", sub."secondaryInformation", sub."visible", sub."id", sub."entityName" FROM (${entityInfo}) sub`);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const { entityName, metadata } = targetEntity;
|
|
39
|
+
const primary = metadata.primaryKeys[0];
|
|
40
|
+
// Resolve the name field (must not be NULL)
|
|
41
|
+
const nameSql = `COALESCE(${(0, resolve_field_to_sql_1.resolveFieldToSql)(entityInfo.name, metadata, metadata.tableName)}, '')`;
|
|
42
|
+
// Resolve the secondaryInformation field (if provided, can be NULL)
|
|
43
|
+
let secondaryInformationSql = "null";
|
|
44
|
+
if (entityInfo.secondaryInformation) {
|
|
45
|
+
secondaryInformationSql = (0, resolve_field_to_sql_1.resolveFieldToSql)(entityInfo.secondaryInformation, metadata, metadata.tableName);
|
|
82
46
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
secondaryInformationSql = this.resolveFieldToSql(entityInfo.secondaryInformation, metadata, metadata.tableName);
|
|
47
|
+
let visibleSql = "true";
|
|
48
|
+
if (entityInfo.visible) {
|
|
49
|
+
const qb = this.entityManager.createQueryBuilder(targetEntity.entity.name, metadata.tableName);
|
|
50
|
+
const query = qb.select("*").where(entityInfo.visible);
|
|
51
|
+
const sql = query.getFormattedQuery();
|
|
52
|
+
const sqlWhereMatch = sql.match(/^select .*? from .*? where (.*)/);
|
|
53
|
+
if (!sqlWhereMatch) {
|
|
54
|
+
throw new Error(`Could not extract where clause from query: ${sql}`);
|
|
92
55
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const query = qb.select("*").where(entityInfo.visible);
|
|
97
|
-
const sql = query.getFormattedQuery();
|
|
98
|
-
const sqlWhereMatch = sql.match(/^select .*? from .*? where (.*)/);
|
|
99
|
-
if (!sqlWhereMatch) {
|
|
100
|
-
throw new Error(`Could not extract where clause from query: ${sql}`);
|
|
101
|
-
}
|
|
102
|
-
visibleSql = sqlWhereMatch[1];
|
|
103
|
-
}
|
|
104
|
-
const select = `SELECT
|
|
56
|
+
visibleSql = sqlWhereMatch[1];
|
|
57
|
+
}
|
|
58
|
+
const select = `SELECT
|
|
105
59
|
${nameSql} "name",
|
|
106
60
|
${secondaryInformationSql} "secondaryInformation",
|
|
107
61
|
${visibleSql} AS "visible",
|
|
108
62
|
"${metadata.tableName}"."${primary}"::text "id",
|
|
109
63
|
'${entityName}' "entityName"
|
|
110
64
|
FROM "${metadata.tableName}"`;
|
|
111
|
-
|
|
112
|
-
}
|
|
65
|
+
indexSelects.push(select);
|
|
113
66
|
}
|
|
114
67
|
}
|
|
115
68
|
// add all PageTreeNode Documents (Page, Link etc) thru PageTreeNodeDocument (no @EntityInfo needed on Page/Link)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-info.service.js","sourceRoot":"","sources":["../../src/entity-info/entity-info.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"entity-info.service.js","sourceRoot":"","sources":["../../src/entity-info/entity-info.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { EntityMetadata } from "@mikro-orm/postgresql";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a field path (e.g., "title" or "manufacturer.name") to a SQL expression.
|
|
4
|
+
* Supports direct fields, embeddables, and n-level deep ManyToOne/OneToOne relations using subqueries.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveFieldToSql(fieldPath: string, metadata: EntityMetadata, tableName: string): string;
|
|
7
|
+
//# sourceMappingURL=resolve-field-to-sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-field-to-sql.d.ts","sourceRoot":"","sources":["../../src/entity-info/resolve-field-to-sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmDxG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveFieldToSql = resolveFieldToSql;
|
|
4
|
+
/**
|
|
5
|
+
* Resolves a field path (e.g., "title" or "manufacturer.name") to a SQL expression.
|
|
6
|
+
* Supports direct fields, embeddables, and n-level deep ManyToOne/OneToOne relations using subqueries.
|
|
7
|
+
*/
|
|
8
|
+
function resolveFieldToSql(fieldPath, metadata, tableName) {
|
|
9
|
+
const parts = fieldPath.split(".");
|
|
10
|
+
if (parts.length === 1) {
|
|
11
|
+
const fieldProp = metadata.props.find((p) => p.name === parts[0]);
|
|
12
|
+
if (!fieldProp) {
|
|
13
|
+
throw new Error(`Field "${parts[0]}" not found in entity "${metadata.className}"`);
|
|
14
|
+
}
|
|
15
|
+
return `"${tableName}"."${fieldProp.fieldNames[0]}"`;
|
|
16
|
+
}
|
|
17
|
+
const [relationName, ...remainingParts] = parts;
|
|
18
|
+
const relationProp = metadata.props.find((p) => p.name === relationName);
|
|
19
|
+
if (!relationProp) {
|
|
20
|
+
throw new Error(`Relation "${relationName}" not found in entity "${metadata.className}"`);
|
|
21
|
+
}
|
|
22
|
+
if (relationProp.kind === "embedded") {
|
|
23
|
+
let currentProp = relationProp;
|
|
24
|
+
let currentName = relationName;
|
|
25
|
+
for (const part of remainingParts) {
|
|
26
|
+
const childProp = currentProp.embeddedProps?.[part];
|
|
27
|
+
if (!childProp) {
|
|
28
|
+
throw new Error(`Embedded field "${part}" not found in embeddable "${currentName}" of entity "${metadata.className}"`);
|
|
29
|
+
}
|
|
30
|
+
currentName = part;
|
|
31
|
+
currentProp = childProp;
|
|
32
|
+
}
|
|
33
|
+
return `"${tableName}"."${currentProp.fieldNames[0]}"`;
|
|
34
|
+
}
|
|
35
|
+
if (relationProp.kind !== "m:1" && relationProp.kind !== "1:1") {
|
|
36
|
+
throw new Error(`Only ManyToOne, OneToOne relations and embeddables are supported for EntityInfo. "${relationName}" is "${relationProp.kind}"`);
|
|
37
|
+
}
|
|
38
|
+
if (!relationProp.targetMeta) {
|
|
39
|
+
throw new Error(`Relation "${relationName}" has no target metadata`);
|
|
40
|
+
}
|
|
41
|
+
const joinColumn = relationProp.joinColumns[0];
|
|
42
|
+
const targetTableName = relationProp.targetMeta.tableName;
|
|
43
|
+
const targetPrimaryKey = relationProp.targetMeta.primaryKeys[0];
|
|
44
|
+
const innerSql = resolveFieldToSql(remainingParts.join("."), relationProp.targetMeta, targetTableName);
|
|
45
|
+
return `(SELECT ${innerSql} FROM "${targetTableName}" WHERE "${targetTableName}"."${targetPrimaryKey}" = "${tableName}"."${joinColumn}")`;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=resolve-field-to-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-field-to-sql.js","sourceRoot":"","sources":["../../src/entity-info/resolve-field-to-sql.ts"],"names":[],"mappings":";;AAMA,8CAmDC;AAvDD;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,SAAiB,EAAE,QAAwB,EAAE,SAAiB;IAC5F,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,0BAA0B,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;QACvF,CAAC;QAED,OAAO,IAAI,SAAS,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IACzD,CAAC;IAED,MAAM,CAAC,YAAY,EAAE,GAAG,cAAc,CAAC,GAAG,KAAK,CAAC;IAEhD,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IAEzE,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,0BAA0B,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACnC,IAAI,WAAW,GAAG,YAAY,CAAC;QAC/B,IAAI,WAAW,GAAG,YAAY,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,8BAA8B,WAAW,gBAAgB,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;YAC3H,CAAC;YACD,WAAW,GAAG,IAAI,CAAC;YACnB,WAAW,GAAG,SAAS,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,SAAS,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3D,CAAC;IAED,IAAI,YAAY,CAAC,IAAI,KAAK,KAAK,IAAI,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACX,qFAAqF,YAAY,SAAS,YAAY,CAAC,IAAI,GAAG,CACjI,CAAC;IACN,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,0BAA0B,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC;IAC1D,MAAM,gBAAgB,GAAG,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAEvG,OAAO,WAAW,QAAQ,UAAU,eAAe,YAAY,eAAe,MAAM,gBAAgB,QAAQ,SAAS,MAAM,UAAU,IAAI,CAAC;AAC9I,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated-entity-info.d.ts","sourceRoot":"","sources":["../../../src/full-text-search/dto/paginated-entity-info.ts"],"names":[],"mappings":";AAKA,qBACa,mBAAoB,SAAQ,wBAAiD;CAAG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.PaginatedEntityInfo = void 0;
|
|
10
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
11
|
+
const paginated_response_factory_1 = require("../../common/pagination/paginated-response.factory");
|
|
12
|
+
const entity_info_object_1 = require("../../entity-info/entity-info.object");
|
|
13
|
+
let PaginatedEntityInfo = class PaginatedEntityInfo extends paginated_response_factory_1.PaginatedResponseFactory.create(entity_info_object_1.EntityInfoObject) {
|
|
14
|
+
};
|
|
15
|
+
exports.PaginatedEntityInfo = PaginatedEntityInfo;
|
|
16
|
+
exports.PaginatedEntityInfo = PaginatedEntityInfo = __decorate([
|
|
17
|
+
(0, graphql_1.ObjectType)()
|
|
18
|
+
], PaginatedEntityInfo);
|
|
19
|
+
//# sourceMappingURL=paginated-entity-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paginated-entity-info.js","sourceRoot":"","sources":["../../../src/full-text-search/dto/paginated-entity-info.ts"],"names":[],"mappings":";;;;;;;;;AAAA,6CAA6C;AAE7C,mGAA8F;AAC9F,6EAAwE;AAGjE,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,qDAAwB,CAAC,MAAM,CAAC,qCAAgB,CAAC;CAAG,CAAA;AAAhF,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,oBAAU,GAAE;GACA,mBAAmB,CAA6D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-info-full-text.object.d.ts","sourceRoot":"","sources":["../../../src/full-text-search/entities/entity-info-full-text.object.ts"],"names":[],"mappings":"AAMA,qBACa,wBAAwB;IAEjC,EAAE,EAAE,MAAM,CAAC;IAGX,UAAU,EAAE,MAAM,CAAC;IAGnB,QAAQ,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.EntityInfoFullTextObject = void 0;
|
|
13
|
+
const core_1 = require("@mikro-orm/core");
|
|
14
|
+
const postgresql_1 = require("@mikro-orm/postgresql");
|
|
15
|
+
// Note: This file is intentionally not named *.entity.ts to exclude it from MikroORM's CLI migration glob pattern.
|
|
16
|
+
// The "EntityInfoFullText" view is created dynamically at startup by FullTextSearchService, not via migrations.
|
|
17
|
+
let EntityInfoFullTextObject = class EntityInfoFullTextObject {
|
|
18
|
+
};
|
|
19
|
+
exports.EntityInfoFullTextObject = EntityInfoFullTextObject;
|
|
20
|
+
__decorate([
|
|
21
|
+
(0, core_1.PrimaryKey)({ type: "text" }),
|
|
22
|
+
__metadata("design:type", String)
|
|
23
|
+
], EntityInfoFullTextObject.prototype, "id", void 0);
|
|
24
|
+
__decorate([
|
|
25
|
+
(0, core_1.PrimaryKey)({ type: "text" }),
|
|
26
|
+
__metadata("design:type", String)
|
|
27
|
+
], EntityInfoFullTextObject.prototype, "entityName", void 0);
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, core_1.Property)({ type: postgresql_1.FullTextType }),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], EntityInfoFullTextObject.prototype, "fullText", void 0);
|
|
32
|
+
exports.EntityInfoFullTextObject = EntityInfoFullTextObject = __decorate([
|
|
33
|
+
(0, core_1.Entity)({ tableName: "EntityInfoFullText" })
|
|
34
|
+
], EntityInfoFullTextObject);
|
|
35
|
+
//# sourceMappingURL=entity-info-full-text.object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-info-full-text.object.js","sourceRoot":"","sources":["../../../src/full-text-search/entities/entity-info-full-text.object.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0CAA+D;AAC/D,sDAAqD;AAErD,mHAAmH;AACnH,gHAAgH;AAGzG,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;CASpC,CAAA;AATY,4DAAwB;AAEjC;IADC,IAAA,iBAAU,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;oDAClB;AAGX;IADC,IAAA,iBAAU,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;4DACV;AAGnB;IADC,IAAA,eAAQ,EAAC,EAAE,IAAI,EAAE,yBAAY,EAAE,CAAC;;0DAChB;mCARR,wBAAwB;IADpC,IAAA,aAAM,EAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC;GAC/B,wBAAwB,CASpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.module.d.ts","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.module.ts"],"names":[],"mappings":"AAQA,oBAAoB;AACpB,qBAKa,oBAAoB;CAAG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FullTextSearchModule = void 0;
|
|
10
|
+
const nestjs_1 = require("@mikro-orm/nestjs");
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const entity_info_module_1 = require("../entity-info/entity-info.module");
|
|
13
|
+
const entity_info_full_text_object_1 = require("./entities/entity-info-full-text.object");
|
|
14
|
+
const full_text_search_resolver_1 = require("./full-text-search.resolver");
|
|
15
|
+
const full_text_search_service_1 = require("./full-text-search.service");
|
|
16
|
+
/** @experimental */
|
|
17
|
+
let FullTextSearchModule = class FullTextSearchModule {
|
|
18
|
+
};
|
|
19
|
+
exports.FullTextSearchModule = FullTextSearchModule;
|
|
20
|
+
exports.FullTextSearchModule = FullTextSearchModule = __decorate([
|
|
21
|
+
(0, common_1.Module)({
|
|
22
|
+
imports: [entity_info_module_1.EntityInfoModule, nestjs_1.MikroOrmModule.forFeature([entity_info_full_text_object_1.EntityInfoFullTextObject])],
|
|
23
|
+
providers: [full_text_search_service_1.FullTextSearchService, full_text_search_resolver_1.FullTextSearchResolver],
|
|
24
|
+
exports: [full_text_search_service_1.FullTextSearchService],
|
|
25
|
+
})
|
|
26
|
+
], FullTextSearchModule);
|
|
27
|
+
//# sourceMappingURL=full-text-search.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.module.js","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,8CAAmD;AACnD,2CAAwC;AAExC,0EAAqE;AACrE,0FAAmF;AACnF,2EAAqE;AACrE,yEAAmE;AAEnE,oBAAoB;AAMb,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;CAAG,CAAA;AAAvB,oDAAoB;+BAApB,oBAAoB;IALhC,IAAA,eAAM,EAAC;QACJ,OAAO,EAAE,CAAC,qCAAgB,EAAE,uBAAc,CAAC,UAAU,CAAC,CAAC,uDAAwB,CAAC,CAAC,CAAC;QAClF,SAAS,EAAE,CAAC,gDAAqB,EAAE,kDAAsB,CAAC;QAC1D,OAAO,EAAE,CAAC,gDAAqB,CAAC;KACnC,CAAC;GACW,oBAAoB,CAAG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EntityManager } from "@mikro-orm/postgresql";
|
|
2
|
+
import { PaginatedEntityInfo } from "./dto/paginated-entity-info";
|
|
3
|
+
export declare class FullTextSearchResolver {
|
|
4
|
+
private readonly entityManager;
|
|
5
|
+
constructor(entityManager: EntityManager);
|
|
6
|
+
fullTextSearch(search: string, offset: number, limit: number): Promise<PaginatedEntityInfo>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=full-text-search.resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.resolver.d.ts","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAKtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGlE,qBAEa,sBAAsB;IACnB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAGnD,cAAc,CACA,MAAM,EAAE,MAAM,EACwB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACpE,OAAO,CAAC,mBAAmB,CAAC;CA6BlC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.FullTextSearchResolver = void 0;
|
|
16
|
+
const postgresql_1 = require("@mikro-orm/postgresql");
|
|
17
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
18
|
+
const entity_info_object_1 = require("../entity-info/entity-info.object");
|
|
19
|
+
const required_permission_decorator_1 = require("../user-permissions/decorators/required-permission.decorator");
|
|
20
|
+
const paginated_entity_info_1 = require("./dto/paginated-entity-info");
|
|
21
|
+
const entity_info_full_text_object_1 = require("./entities/entity-info-full-text.object");
|
|
22
|
+
let FullTextSearchResolver = class FullTextSearchResolver {
|
|
23
|
+
constructor(entityManager) {
|
|
24
|
+
this.entityManager = entityManager;
|
|
25
|
+
}
|
|
26
|
+
async fullTextSearch(search, offset, limit) {
|
|
27
|
+
const [matches, totalCount] = await this.entityManager.findAndCount(entity_info_full_text_object_1.EntityInfoFullTextObject, { fullText: { $fulltext: search } }, { offset, limit });
|
|
28
|
+
if (matches.length === 0) {
|
|
29
|
+
return new paginated_entity_info_1.PaginatedEntityInfo([], totalCount);
|
|
30
|
+
}
|
|
31
|
+
// Join with EntityInfo view to fetch name, secondaryInformation, visible for the matched rows
|
|
32
|
+
const infos = await this.entityManager.find(entity_info_object_1.EntityInfoObject, {
|
|
33
|
+
$or: matches.map((match) => ({ id: match.id, entityName: match.entityName })),
|
|
34
|
+
});
|
|
35
|
+
const infoByKey = new Map(infos.map((info) => [`${info.entityName}:${info.id}`, info]));
|
|
36
|
+
const results = matches.map((match) => {
|
|
37
|
+
const info = infoByKey.get(`${match.entityName}:${match.id}`);
|
|
38
|
+
if (!info) {
|
|
39
|
+
throw new Error(`EntityInfo not found for ${match.entityName}:${match.id}. This may indicate a data inconsistency where the full-text search index contains an entry without corresponding entity information.`);
|
|
40
|
+
}
|
|
41
|
+
return info;
|
|
42
|
+
});
|
|
43
|
+
return new paginated_entity_info_1.PaginatedEntityInfo(results, totalCount);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.FullTextSearchResolver = FullTextSearchResolver;
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, graphql_1.Query)(() => paginated_entity_info_1.PaginatedEntityInfo),
|
|
49
|
+
__param(0, (0, graphql_1.Args)("search")),
|
|
50
|
+
__param(1, (0, graphql_1.Args)("offset", { type: () => graphql_1.Int, defaultValue: 0 })),
|
|
51
|
+
__param(2, (0, graphql_1.Args)("limit", { type: () => graphql_1.Int, defaultValue: 25 })),
|
|
52
|
+
__metadata("design:type", Function),
|
|
53
|
+
__metadata("design:paramtypes", [String, Number, Number]),
|
|
54
|
+
__metadata("design:returntype", Promise)
|
|
55
|
+
], FullTextSearchResolver.prototype, "fullTextSearch", null);
|
|
56
|
+
exports.FullTextSearchResolver = FullTextSearchResolver = __decorate([
|
|
57
|
+
(0, graphql_1.Resolver)(() => entity_info_object_1.EntityInfoObject),
|
|
58
|
+
(0, required_permission_decorator_1.RequiredPermission)("fullTextSearch", { skipScopeCheck: true }),
|
|
59
|
+
__metadata("design:paramtypes", [postgresql_1.EntityManager])
|
|
60
|
+
], FullTextSearchResolver);
|
|
61
|
+
//# sourceMappingURL=full-text-search.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.resolver.js","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,sDAAsD;AACtD,6CAA6D;AAE7D,0EAAqE;AACrE,gHAAkG;AAClG,uEAAkE;AAClE,0FAAmF;AAI5E,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAC/B,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAGvD,AAAN,KAAK,CAAC,cAAc,CACA,MAAc,EACwB,MAAc,EACd,KAAa;QAEnE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAC/D,uDAAwB,EACxB,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EACnC,EAAE,MAAM,EAAE,KAAK,EAAE,CACpB,CAAC;QAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,2CAAmB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACnD,CAAC;QAED,8FAA8F;QAC9F,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,qCAAgB,EAAE;YAC1D,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;SAChF,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACxF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAClC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,MAAM,IAAI,KAAK,CACX,4BAA4B,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,uIAAuI,CAClM,CAAC;YACN,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,2CAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACxD,CAAC;CACJ,CAAA;AArCY,wDAAsB;AAIzB;IADL,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,2CAAmB,CAAC;IAE5B,WAAA,IAAA,cAAI,EAAC,QAAQ,CAAC,CAAA;IACd,WAAA,IAAA,cAAI,EAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,aAAG,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAA;IACpD,WAAA,IAAA,cAAI,EAAC,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,aAAG,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAA;;;;4DA6BxD;iCApCQ,sBAAsB;IAFlC,IAAA,kBAAQ,EAAC,GAAG,EAAE,CAAC,qCAAgB,CAAC;IAChC,IAAA,kDAAkB,EAAC,gBAAgB,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;qCAEf,0BAAa;GADhD,sBAAsB,CAqClC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EntityManager } from "@mikro-orm/postgresql";
|
|
2
|
+
import { DiscoverService } from "../dependencies/discover.service";
|
|
3
|
+
import { PageTreeFullTextService } from "../page-tree/fullText/page-tree-full-text.service";
|
|
4
|
+
export declare class FullTextSearchService {
|
|
5
|
+
private readonly discoverService;
|
|
6
|
+
private entityManager;
|
|
7
|
+
private readonly pageTreeFullTextService?;
|
|
8
|
+
constructor(discoverService: DiscoverService, entityManager: EntityManager, pageTreeFullTextService?: PageTreeFullTextService | undefined);
|
|
9
|
+
createEntityInfoFullTextView(): Promise<void>;
|
|
10
|
+
dropEntityInfoFullTextView(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=full-text-search.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.service.d.ts","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGjE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAE5F,qBACa,qBAAqB;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,aAAa;IACT,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;gBAFpC,eAAe,EAAE,eAAe,EACzC,aAAa,EAAE,aAAa,EACP,uBAAuB,CAAC,EAAE,uBAAuB,YAAA;IAG5E,4BAA4B,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD7C,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;CAGpD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.FullTextSearchService = void 0;
|
|
16
|
+
const postgresql_1 = require("@mikro-orm/postgresql");
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const discover_service_1 = require("../dependencies/discover.service");
|
|
19
|
+
const entity_info_decorator_1 = require("../entity-info/entity-info.decorator");
|
|
20
|
+
const resolve_field_to_sql_1 = require("../entity-info/resolve-field-to-sql");
|
|
21
|
+
const page_tree_full_text_service_1 = require("../page-tree/fullText/page-tree-full-text.service");
|
|
22
|
+
let FullTextSearchService = class FullTextSearchService {
|
|
23
|
+
constructor(discoverService, entityManager, pageTreeFullTextService) {
|
|
24
|
+
this.discoverService = discoverService;
|
|
25
|
+
this.entityManager = entityManager;
|
|
26
|
+
this.pageTreeFullTextService = pageTreeFullTextService;
|
|
27
|
+
}
|
|
28
|
+
async createEntityInfoFullTextView() {
|
|
29
|
+
const indexSelects = [];
|
|
30
|
+
const targetEntities = this.discoverService.discoverTargetEntities();
|
|
31
|
+
const pageTreeFullText = !!this.pageTreeFullTextService;
|
|
32
|
+
for (const targetEntity of targetEntities) {
|
|
33
|
+
const entityInfo = Reflect.getMetadata(entity_info_decorator_1.ENTITY_INFO_METADATA_KEY, targetEntity.entity);
|
|
34
|
+
if (!entityInfo) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (typeof entityInfo === "string") {
|
|
38
|
+
if (pageTreeFullText && targetEntity.metadata.tableName === "PageTreeNode") {
|
|
39
|
+
indexSelects.push(`SELECT "PageTreeNodeEntityInfo"."id", 'PageTreeNode' AS "entityName", "PageTreeNodeFullText"."fullText"
|
|
40
|
+
FROM "PageTreeNodeEntityInfo"
|
|
41
|
+
INNER JOIN "PageTreeNodeFullText" ON "PageTreeNodeFullText"."pageTreeNodeId" = "PageTreeNodeEntityInfo"."id"::uuid`);
|
|
42
|
+
}
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!entityInfo.fullText) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const { entityName, metadata } = targetEntity;
|
|
49
|
+
const primary = metadata.primaryKeys[0];
|
|
50
|
+
const fullTextSql = (0, resolve_field_to_sql_1.resolveFieldToSql)(entityInfo.fullText, metadata, metadata.tableName);
|
|
51
|
+
indexSelects.push(`SELECT
|
|
52
|
+
"${metadata.tableName}"."${primary}"::text "id",
|
|
53
|
+
'${entityName}' "entityName",
|
|
54
|
+
${fullTextSql} AS "fullText"
|
|
55
|
+
FROM "${metadata.tableName}"`);
|
|
56
|
+
}
|
|
57
|
+
if (indexSelects.length === 0) {
|
|
58
|
+
// Empty placeholder so the view always exists with the expected columns
|
|
59
|
+
indexSelects.push(`SELECT NULL::text AS "id", NULL::text AS "entityName", NULL::tsvector AS "fullText" WHERE false`);
|
|
60
|
+
}
|
|
61
|
+
const viewSql = indexSelects.join("\n UNION ALL \n");
|
|
62
|
+
console.time("creating EntityInfoFullText view");
|
|
63
|
+
await this.entityManager.getConnection().execute(`DROP VIEW IF EXISTS "EntityInfoFullText"`);
|
|
64
|
+
await this.entityManager.getConnection().execute(`CREATE VIEW "EntityInfoFullText" AS ${viewSql}`);
|
|
65
|
+
console.timeEnd("creating EntityInfoFullText view");
|
|
66
|
+
}
|
|
67
|
+
async dropEntityInfoFullTextView() {
|
|
68
|
+
await this.entityManager.getConnection().execute(`DROP VIEW IF EXISTS "EntityInfoFullText"`);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
exports.FullTextSearchService = FullTextSearchService;
|
|
72
|
+
exports.FullTextSearchService = FullTextSearchService = __decorate([
|
|
73
|
+
(0, common_1.Injectable)(),
|
|
74
|
+
__param(2, (0, common_1.Optional)()),
|
|
75
|
+
__metadata("design:paramtypes", [discover_service_1.DiscoverService,
|
|
76
|
+
postgresql_1.EntityManager,
|
|
77
|
+
page_tree_full_text_service_1.PageTreeFullTextService])
|
|
78
|
+
], FullTextSearchService);
|
|
79
|
+
//# sourceMappingURL=full-text-search.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-text-search.service.js","sourceRoot":"","sources":["../../src/full-text-search/full-text-search.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,sDAAiE;AACjE,2CAAsD;AAEtD,uEAAmE;AACnE,gFAA4F;AAC5F,8EAAwE;AACxE,mGAA4F;AAGrF,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAC9B,YACqB,eAAgC,EACzC,aAA4B,EACP,uBAAiD;QAF7D,oBAAe,GAAf,eAAe,CAAiB;QACzC,kBAAa,GAAb,aAAa,CAAe;QACP,4BAAuB,GAAvB,uBAAuB,CAA0B;IAC/E,CAAC;IAEJ,KAAK,CAAC,4BAA4B;QAC9B,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,sBAAsB,EAAE,CAAC;QACrE,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC;QAExD,KAAK,MAAM,YAAY,IAAI,cAAc,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,gDAAwB,EAAE,YAAY,CAAC,MAAM,CAA0B,CAAC;YAC/G,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,SAAS;YACb,CAAC;YAED,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACjC,IAAI,gBAAgB,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,KAAK,cAAc,EAAE,CAAC;oBACzE,YAAY,CAAC,IAAI,CAAC;;2IAEqG,CAAC,CAAC;gBAC7H,CAAC;gBACD,SAAS;YACb,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;gBACvB,SAAS;YACb,CAAC;YAED,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC;YAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAExC,MAAM,WAAW,GAAG,IAAA,wCAAiB,EAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;YAEzF,YAAY,CAAC,IAAI,CAAC;+BACC,QAAQ,CAAC,SAAS,MAAM,OAAO;+BAC/B,UAAU;8BACX,WAAW;gCACT,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC;QAC/C,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,wEAAwE;YACxE,YAAY,CAAC,IAAI,CAAC,iGAAiG,CAAC,CAAC;QACzH,CAAC;QAED,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAErD,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QACjD,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;QAC7F,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,uCAAuC,OAAO,EAAE,CAAC,CAAC;QACnG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,0BAA0B;QAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACjG,CAAC;CACJ,CAAA;AA3DY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKJ,WAAA,IAAA,iBAAQ,GAAE,CAAA;qCAFuB,kCAAe;QAC1B,0BAAa;QACmB,qDAAuB;GAJzE,qBAAqB,CA2DjC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ export { RootBlockDataScalar } from "./blocks/rootBlocks/root-block-data.scalar"
|
|
|
56
56
|
export { RootBlockInputScalar } from "./blocks/rootBlocks/root-block-input.scalar";
|
|
57
57
|
export { blockToMikroOrmFullText, getSearchTextFromBlock, SearchText, WeightedSearchText } from "./blocks/search/get-search-text";
|
|
58
58
|
export { SpaceBlock } from "./blocks/SpaceBlock/SpaceBlock";
|
|
59
|
+
export { createTipTapRichTextBlock, type CreateTipTapRichTextBlockOptions } from "./blocks/tipTap/createTipTapRichTextBlock";
|
|
59
60
|
export { transformToBlockSaveIndex } from "./blocks/transformToBlockSaveIndex/transformToBlockSaveIndex";
|
|
60
61
|
export { VimeoVideoBlock } from "./blocks/vimeo-video.block";
|
|
61
62
|
export { YouTubeVideoBlock } from "./blocks/YouTubeVideoBlock/you-tube-video.block";
|
|
@@ -150,6 +151,7 @@ export { FileUploadInput, FileUploadInterface } from "./file-utils/file-upload.i
|
|
|
150
151
|
export { createFileUploadInputFromUrl, slugifyFilename } from "./file-utils/files.utils";
|
|
151
152
|
export { FocalPoint } from "./file-utils/focal-point.enum";
|
|
152
153
|
export { getCenteredPosition, getMaxDimensionsFromArea, ImageDimensionsAndCoordinates } from "./file-utils/images.util";
|
|
154
|
+
export { FullTextSearchModule } from "./full-text-search/full-text-search.module";
|
|
153
155
|
export { IMGPROXY_CONFIG } from "./imgproxy/imgproxy.constants";
|
|
154
156
|
export { Extension, Gravity, ResizingType } from "./imgproxy/imgproxy.enum";
|
|
155
157
|
export { ImgproxyModule } from "./imgproxy/imgproxy.module";
|
|
@@ -172,6 +174,7 @@ export { MailerLog } from "./mailer/entities/mailer-log.entity";
|
|
|
172
174
|
export { MAILER_SERVICE_CONFIG } from "./mailer/mailer.constants";
|
|
173
175
|
export { MailerModule, MailerModuleConfig } from "./mailer/mailer.module";
|
|
174
176
|
export { MailerService, SendMailParams } from "./mailer/mailer.service";
|
|
177
|
+
export { entityToMikroOrmFullText } from "./mikro-orm/helper/entity-to-mikro-orm-full-text";
|
|
175
178
|
export { createMigrationsList, createOrmConfig, MikroOrmModule, MikroOrmModuleOptions } from "./mikro-orm/mikro-orm.module";
|
|
176
179
|
export { AttachedDocumentLoaderService } from "./page-tree/attached-document-loader.service";
|
|
177
180
|
export { AnchorBlock } from "./page-tree/blocks/anchor.block";
|