@open-mercato/documents 0.7.1-develop.7195.1.b5efd1d51a → 0.7.1-develop.7200.1.8ba2d93d3f
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/modules/documents/search.js +1 -2
- package/dist/modules/documents/search.js.map +2 -2
- package/package.json +6 -6
- package/src/modules/documents/i18n/de.json +2 -1
- package/src/modules/documents/i18n/en.json +2 -1
- package/src/modules/documents/i18n/es.json +2 -1
- package/src/modules/documents/i18n/ko.json +2 -1
- package/src/modules/documents/i18n/pl.json +2 -1
- package/src/modules/documents/search.ts +0 -1
|
@@ -23,8 +23,7 @@ function buildPresenter(t, ctx) {
|
|
|
23
23
|
// localized document label while the record id is used only for routing.
|
|
24
24
|
title: pickString(ctx.record.title) ?? t("documents.search.badge.document", "Document"),
|
|
25
25
|
subtitle: pickString(ctx.record.folder_name, ctx.record.folderName) ?? void 0,
|
|
26
|
-
icon: "file-text"
|
|
27
|
-
badge: t("documents.search.badge.document", "Document")
|
|
26
|
+
icon: "file-text"
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
async function resolveContentText(ctx) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/modules/documents/search.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n SearchBuildContext,\n SearchIndexSource,\n SearchModuleConfig,\n SearchResultPresenter,\n} from '@open-mercato/shared/modules/search'\nimport type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { DocumentContent } from './data/entities'\nimport { DOCUMENTS_ENTITY_IDS } from './lib/constants'\n\ntype ContainerLike = {\n resolve: (name: string) => unknown\n}\n\nfunction pickString(...values: Array<unknown>): string | null {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed.length > 0) return trimmed\n }\n return null\n}\n\nfunction isContainerLike(value: unknown): value is ContainerLike {\n return typeof value === 'object' && value !== null && 'resolve' in value && typeof value.resolve === 'function'\n}\n\nfunction isEntityManager(value: unknown): value is EntityManager {\n return typeof value === 'object' && value !== null && 'findOne' in value && typeof value.findOne === 'function'\n}\n\nfunction buildPresenter(t: TranslateFn, ctx: SearchBuildContext): SearchResultPresenter {\n return {\n // Search presenters must never surface opaque database identifiers as a\n // user-facing fallback. A missing/decrypted-away title remains a generic,\n // localized document label while the record id is used only for routing.\n title: pickString(ctx.record.title) ?? t('documents.search.badge.document', 'Document'),\n subtitle: pickString(ctx.record.folder_name, ctx.record.folderName) ?? undefined,\n icon: 'file-text',\n
|
|
5
|
-
"mappings": "AAOA,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAEtC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAMrC,SAAS,cAAc,QAAuC;AAC5D,aAAW,SAAS,QAAQ;AAC1B,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,SAAS,EAAG,QAAO;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAwC;AAC/D,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,SAAS,OAAO,MAAM,YAAY;AACvG;AAEA,SAAS,gBAAgB,OAAwC;AAC/D,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,SAAS,OAAO,MAAM,YAAY;AACvG;AAEA,SAAS,eAAe,GAAgB,KAAgD;AACtF,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,OAAO,WAAW,IAAI,OAAO,KAAK,KAAK,EAAE,mCAAmC,UAAU;AAAA,IACtF,UAAU,WAAW,IAAI,OAAO,aAAa,IAAI,OAAO,UAAU,KAAK;AAAA,IACvE,MAAM;AAAA,
|
|
4
|
+
"sourcesContent": ["import type {\n SearchBuildContext,\n SearchIndexSource,\n SearchModuleConfig,\n SearchResultPresenter,\n} from '@open-mercato/shared/modules/search'\nimport type { TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { DocumentContent } from './data/entities'\nimport { DOCUMENTS_ENTITY_IDS } from './lib/constants'\n\ntype ContainerLike = {\n resolve: (name: string) => unknown\n}\n\nfunction pickString(...values: Array<unknown>): string | null {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed.length > 0) return trimmed\n }\n return null\n}\n\nfunction isContainerLike(value: unknown): value is ContainerLike {\n return typeof value === 'object' && value !== null && 'resolve' in value && typeof value.resolve === 'function'\n}\n\nfunction isEntityManager(value: unknown): value is EntityManager {\n return typeof value === 'object' && value !== null && 'findOne' in value && typeof value.findOne === 'function'\n}\n\nfunction buildPresenter(t: TranslateFn, ctx: SearchBuildContext): SearchResultPresenter {\n return {\n // Search presenters must never surface opaque database identifiers as a\n // user-facing fallback. A missing/decrypted-away title remains a generic,\n // localized document label while the record id is used only for routing.\n title: pickString(ctx.record.title) ?? t('documents.search.badge.document', 'Document'),\n subtitle: pickString(ctx.record.folder_name, ctx.record.folderName) ?? undefined,\n icon: 'file-text',\n }\n}\n\nasync function resolveContentText(ctx: SearchBuildContext): Promise<string | null> {\n const direct = pickString(ctx.record.content_text, ctx.record.contentText)\n if (direct) return direct\n if (!isContainerLike(ctx.container) || typeof ctx.record.id !== 'string') return null\n // Both ownership predicates are mandatory. A build context missing either\n // scope value must refuse the read rather than widen it to a documentId-only\n // lookup that would cross tenant/organization boundaries.\n const tenantId = pickString(ctx.tenantId)\n const organizationId = pickString(ctx.organizationId)\n if (!tenantId || !organizationId) return null\n const em = ctx.container.resolve('em')\n if (!isEntityManager(em)) return null\n const content = await findOneWithDecryption(\n em,\n DocumentContent,\n {\n documentId: ctx.record.id,\n deletedAt: null,\n tenantId,\n organizationId,\n },\n { fields: ['contentText'] as const },\n { tenantId, organizationId },\n )\n return pickString(content?.contentText)\n}\n\nasync function buildDocumentSource(ctx: SearchBuildContext): Promise<SearchIndexSource | null> {\n const { t } = await resolveTranslations()\n const title = pickString(ctx.record.title)\n const contentText = await resolveContentText(ctx)\n const text = [title, contentText].filter((value): value is string => Boolean(value))\n if (text.length === 0) return null\n return {\n text,\n presenter: buildPresenter(t, ctx),\n checksumSource: {\n record: ctx.record,\n contentText,\n customFields: ctx.customFields,\n },\n }\n}\n\nexport const searchConfig: SearchModuleConfig = {\n entities: [\n {\n entityId: DOCUMENTS_ENTITY_IDS.document,\n // Global cross-entity search is only feature-gated (search.view) with no per-record ACL\n // filter, so indexing per-document-private title/content here would expose them to any\n // org user holding documents.view \u2014 bypassing per-doc sharing. Disabled for M1; secure\n // per-doc-filtered document search is deferred until the search layer gains a per-record\n // visibility hook. In M1, documents are found via the permission-filtered list route\n // (/api/documents?search=). The reindex calls elsewhere safely no-op while this is off.\n enabled: false,\n priority: 9,\n fieldPolicy: {\n searchable: ['title', 'content_text'],\n excluded: ['yjs_state', 'content_html'],\n },\n buildSource: buildDocumentSource,\n formatResult: async (ctx) => {\n const { t } = await resolveTranslations()\n return buildPresenter(t, ctx)\n },\n resolveUrl: async (ctx) => `/backend/documents/${encodeURIComponent(String(ctx.record.id))}`,\n },\n ],\n}\n\nexport const config = searchConfig\nexport default searchConfig\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAEtC,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAMrC,SAAS,cAAc,QAAuC;AAC5D,aAAW,SAAS,QAAQ;AAC1B,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,SAAS,EAAG,QAAO;AAAA,EACjC;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAwC;AAC/D,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,SAAS,OAAO,MAAM,YAAY;AACvG;AAEA,SAAS,gBAAgB,OAAwC;AAC/D,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,SAAS,OAAO,MAAM,YAAY;AACvG;AAEA,SAAS,eAAe,GAAgB,KAAgD;AACtF,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,OAAO,WAAW,IAAI,OAAO,KAAK,KAAK,EAAE,mCAAmC,UAAU;AAAA,IACtF,UAAU,WAAW,IAAI,OAAO,aAAa,IAAI,OAAO,UAAU,KAAK;AAAA,IACvE,MAAM;AAAA,EACR;AACF;AAEA,eAAe,mBAAmB,KAAiD;AACjF,QAAM,SAAS,WAAW,IAAI,OAAO,cAAc,IAAI,OAAO,WAAW;AACzE,MAAI,OAAQ,QAAO;AACnB,MAAI,CAAC,gBAAgB,IAAI,SAAS,KAAK,OAAO,IAAI,OAAO,OAAO,SAAU,QAAO;AAIjF,QAAM,WAAW,WAAW,IAAI,QAAQ;AACxC,QAAM,iBAAiB,WAAW,IAAI,cAAc;AACpD,MAAI,CAAC,YAAY,CAAC,eAAgB,QAAO;AACzC,QAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,MAAI,CAAC,gBAAgB,EAAE,EAAG,QAAO;AACjC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,MACE,YAAY,IAAI,OAAO;AAAA,MACvB,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAAA,IACA,EAAE,QAAQ,CAAC,aAAa,EAAW;AAAA,IACnC,EAAE,UAAU,eAAe;AAAA,EAC7B;AACA,SAAO,WAAW,SAAS,WAAW;AACxC;AAEA,eAAe,oBAAoB,KAA4D;AAC7F,QAAM,EAAE,EAAE,IAAI,MAAM,oBAAoB;AACxC,QAAM,QAAQ,WAAW,IAAI,OAAO,KAAK;AACzC,QAAM,cAAc,MAAM,mBAAmB,GAAG;AAChD,QAAM,OAAO,CAAC,OAAO,WAAW,EAAE,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC;AACnF,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO;AAAA,IACL;AAAA,IACA,WAAW,eAAe,GAAG,GAAG;AAAA,IAChC,gBAAgB;AAAA,MACd,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,cAAc,IAAI;AAAA,IACpB;AAAA,EACF;AACF;AAEO,MAAM,eAAmC;AAAA,EAC9C,UAAU;AAAA,IACR;AAAA,MACE,UAAU,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAO/B,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA,QACX,YAAY,CAAC,SAAS,cAAc;AAAA,QACpC,UAAU,CAAC,aAAa,cAAc;AAAA,MACxC;AAAA,MACA,aAAa;AAAA,MACb,cAAc,OAAO,QAAQ;AAC3B,cAAM,EAAE,EAAE,IAAI,MAAM,oBAAoB;AACxC,eAAO,eAAe,GAAG,GAAG;AAAA,MAC9B;AAAA,MACA,YAAY,OAAO,QAAQ,sBAAsB,mBAAmB,OAAO,IAAI,OAAO,EAAE,CAAC,CAAC;AAAA,IAC5F;AAAA,EACF;AACF;AAEO,MAAM,SAAS;AACtB,IAAO,iBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/documents",
|
|
3
|
-
"version": "0.7.1-develop.
|
|
3
|
+
"version": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
"@hocuspocus/server": "^4.4.0",
|
|
76
76
|
"@hocuspocus/transformer": "^4.3.0",
|
|
77
77
|
"@mikro-orm/core": "^7.1.14",
|
|
78
|
-
"@open-mercato/events": "0.7.1-develop.
|
|
79
|
-
"@open-mercato/ui": "0.7.1-develop.
|
|
78
|
+
"@open-mercato/events": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
79
|
+
"@open-mercato/ui": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
80
80
|
"@tiptap/core": "^3",
|
|
81
81
|
"@tiptap/extension-bubble-menu": "^3",
|
|
82
82
|
"@tiptap/extension-collaboration": "^3.27.3",
|
|
@@ -113,13 +113,13 @@
|
|
|
113
113
|
},
|
|
114
114
|
"peerDependencies": {
|
|
115
115
|
"@mikro-orm/postgresql": "^7.0.14",
|
|
116
|
-
"@open-mercato/shared": "0.7.1-develop.
|
|
116
|
+
"@open-mercato/shared": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
117
117
|
"react": "^19.0.0",
|
|
118
118
|
"react-dom": "^19.0.0"
|
|
119
119
|
},
|
|
120
120
|
"devDependencies": {
|
|
121
|
-
"@open-mercato/core": "0.7.1-develop.
|
|
122
|
-
"@open-mercato/shared": "0.7.1-develop.
|
|
121
|
+
"@open-mercato/core": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
122
|
+
"@open-mercato/shared": "0.7.1-develop.7200.1.8ba2d93d3f",
|
|
123
123
|
"@types/jest": "^30.0.0",
|
|
124
124
|
"@types/pg": "^8.23.1",
|
|
125
125
|
"@types/react": "^19.2.18",
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"documents.versions.snapshot.defaultLabel": "Momentaufnahme",
|
|
519
519
|
"documents.versions.snapshot.labelPlaceholder": "Bezeichnung (optional)",
|
|
520
520
|
"documents.versions.snapshotTooLarge": "Diese Version ist zu groß, um sicher verarbeitet zu werden.",
|
|
521
|
-
"documents.versions.title": "Versionsverlauf"
|
|
521
|
+
"documents.versions.title": "Versionsverlauf",
|
|
522
|
+
"search.entityType.documents.document": "Dokument"
|
|
522
523
|
}
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"documents.versions.snapshot.defaultLabel": "Snapshot",
|
|
519
519
|
"documents.versions.snapshot.labelPlaceholder": "Label (optional)",
|
|
520
520
|
"documents.versions.snapshotTooLarge": "This version is too large to process safely.",
|
|
521
|
-
"documents.versions.title": "Version history"
|
|
521
|
+
"documents.versions.title": "Version history",
|
|
522
|
+
"search.entityType.documents.document": "Document"
|
|
522
523
|
}
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"documents.versions.snapshot.defaultLabel": "Instantánea",
|
|
519
519
|
"documents.versions.snapshot.labelPlaceholder": "Etiqueta (opcional)",
|
|
520
520
|
"documents.versions.snapshotTooLarge": "Esta versión es demasiado grande para procesarla de forma segura.",
|
|
521
|
-
"documents.versions.title": "Historial de versiones"
|
|
521
|
+
"documents.versions.title": "Historial de versiones",
|
|
522
|
+
"search.entityType.documents.document": "Documento"
|
|
522
523
|
}
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"documents.versions.snapshot.defaultLabel": "스냅샷",
|
|
519
519
|
"documents.versions.snapshot.labelPlaceholder": "라벨 (선택 사항)",
|
|
520
520
|
"documents.versions.snapshotTooLarge": "이 버전은 너무 커서 안전하게 처리할 수 없습니다.",
|
|
521
|
-
"documents.versions.title": "버전 기록"
|
|
521
|
+
"documents.versions.title": "버전 기록",
|
|
522
|
+
"search.entityType.documents.document": "문서"
|
|
522
523
|
}
|
|
@@ -518,5 +518,6 @@
|
|
|
518
518
|
"documents.versions.snapshot.defaultLabel": "Migawka",
|
|
519
519
|
"documents.versions.snapshot.labelPlaceholder": "Etykieta (opcjonalnie)",
|
|
520
520
|
"documents.versions.snapshotTooLarge": "Ta wersja jest zbyt duża, aby można ją było bezpiecznie przetworzyć.",
|
|
521
|
-
"documents.versions.title": "Historia wersji"
|
|
521
|
+
"documents.versions.title": "Historia wersji",
|
|
522
|
+
"search.entityType.documents.document": "Dokument"
|
|
522
523
|
}
|
|
@@ -40,7 +40,6 @@ function buildPresenter(t: TranslateFn, ctx: SearchBuildContext): SearchResultPr
|
|
|
40
40
|
title: pickString(ctx.record.title) ?? t('documents.search.badge.document', 'Document'),
|
|
41
41
|
subtitle: pickString(ctx.record.folder_name, ctx.record.folderName) ?? undefined,
|
|
42
42
|
icon: 'file-text',
|
|
43
|
-
badge: t('documents.search.badge.document', 'Document'),
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
|