@open-mercato/core 0.8.1-develop.7207.1.901ef7e47a → 0.8.1-develop.7218.1.9f22882799

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.
Files changed (62) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +6 -2
  3. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  4. package/dist/modules/catalog/backend/catalog/products/create/page.js +7 -3
  5. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  6. package/dist/modules/catalog/components/products/ProductUomSection.js +11 -22
  7. package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
  8. package/dist/modules/catalog/components/products/productForm.js +26 -1
  9. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  10. package/dist/modules/configs/lib/upgrade-actions.js +1 -0
  11. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  12. package/dist/modules/configs/services/upgradeActionsService.js +9 -2
  13. package/dist/modules/configs/services/upgradeActionsService.js.map +2 -2
  14. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +1 -4
  15. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +2 -2
  16. package/dist/modules/customers/components/calendar/CalendarToolbar.js +3 -0
  17. package/dist/modules/customers/components/calendar/CalendarToolbar.js.map +2 -2
  18. package/dist/modules/customers/components/calendar/editor/RepeatField.js +1 -3
  19. package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +2 -2
  20. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +1 -5
  21. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +2 -2
  22. package/dist/modules/customers/components/calendar/editor/inputs.js.map +2 -2
  23. package/dist/modules/entities/lib/definition-scope-where.js +18 -0
  24. package/dist/modules/entities/lib/definition-scope-where.js.map +7 -0
  25. package/dist/modules/entities/lib/definition-scope.js +2 -8
  26. package/dist/modules/entities/lib/definition-scope.js.map +2 -2
  27. package/dist/modules/entities/lib/helpers.js +6 -32
  28. package/dist/modules/entities/lib/helpers.js.map +2 -2
  29. package/dist/modules/entities/lib/scoped-field-defs.js +5 -10
  30. package/dist/modules/entities/lib/scoped-field-defs.js.map +2 -2
  31. package/dist/modules/query_index/lib/batch.js +2 -2
  32. package/dist/modules/query_index/lib/batch.js.map +2 -2
  33. package/dist/modules/query_index/lib/document.js +7 -1
  34. package/dist/modules/query_index/lib/document.js.map +2 -2
  35. package/dist/modules/query_index/lib/engine.js.map +1 -1
  36. package/dist/modules/query_index/lib/indexer.js +9 -2
  37. package/dist/modules/query_index/lib/indexer.js.map +2 -2
  38. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  39. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js +15 -1
  40. package/dist/modules/wms/components/backend/AdjustInventoryDialog.js.map +2 -2
  41. package/package.json +7 -7
  42. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +6 -2
  43. package/src/modules/catalog/backend/catalog/products/create/page.tsx +7 -6
  44. package/src/modules/catalog/components/products/ProductUomSection.tsx +11 -31
  45. package/src/modules/catalog/components/products/productForm.ts +53 -0
  46. package/src/modules/configs/lib/upgrade-actions.ts +7 -0
  47. package/src/modules/configs/services/upgradeActionsService.ts +17 -2
  48. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +1 -4
  49. package/src/modules/customers/components/calendar/CalendarToolbar.tsx +3 -0
  50. package/src/modules/customers/components/calendar/editor/RepeatField.tsx +0 -3
  51. package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +1 -7
  52. package/src/modules/customers/components/calendar/editor/inputs.tsx +0 -1
  53. package/src/modules/entities/lib/definition-scope-where.ts +27 -0
  54. package/src/modules/entities/lib/definition-scope.ts +2 -10
  55. package/src/modules/entities/lib/helpers.ts +6 -35
  56. package/src/modules/entities/lib/scoped-field-defs.ts +6 -15
  57. package/src/modules/query_index/lib/batch.ts +8 -2
  58. package/src/modules/query_index/lib/document.ts +28 -0
  59. package/src/modules/query_index/lib/engine.ts +4 -4
  60. package/src/modules/query_index/lib/indexer.ts +15 -2
  61. package/src/modules/query_index/lib/search-tokens.ts +31 -0
  62. package/src/modules/wms/components/backend/AdjustInventoryDialog.tsx +21 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/document.ts"],
4
- "sourcesContent": ["import {\n isSearchFieldBlocklisted,\n resolveSearchConfig,\n type SearchConfig,\n} from '@open-mercato/shared/lib/search/config'\n\nexport type IndexDocumentScope = {\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport type IndexCustomFieldValue = {\n key: string\n value: unknown\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport const AGGREGATE_SEARCH_FIELD = 'search_text'\n\n/**\n * Controls which fields may contribute text to the `search_text` aggregate.\n *\n * Both properties are optional so existing callers keep working unchanged: an\n * omitted `config` is resolved from the environment, and an omitted `entityType`\n * means only the global blocklist entries apply.\n */\nexport type AggregateSearchOptions = {\n entityType?: string | null\n config?: SearchConfig\n}\n\nfunction normalizeScopeValue(value: string | null | undefined): string | null {\n if (value === undefined || value === null || value === '') return null\n return value\n}\n\nfunction isScopedValueVisible(\n scopeValue: string | null,\n fieldValue: string | null,\n): boolean {\n if (scopeValue === null) return fieldValue === null\n return fieldValue === null || fieldValue === scopeValue\n}\n\nfunction normalizeValue(value: unknown): unknown {\n if (value === undefined) return null\n return value\n}\n\nfunction collectAggregateSearchValues(\n field: string,\n value: unknown,\n entityType: string | null,\n config: SearchConfig,\n): string[] {\n const lower = field.toLowerCase()\n if (\n lower === AGGREGATE_SEARCH_FIELD\n || lower === 'id'\n || lower.endsWith('_id')\n || lower.endsWith('.id')\n || lower.endsWith('_at')\n || ['created_at', 'updated_at', 'deleted_at', 'tenant_id', 'organization_id'].includes(lower)\n ) {\n return []\n }\n\n if (isSearchFieldBlocklisted(field, entityType, config)) return []\n\n if (typeof value === 'string') {\n const trimmed = value.trim()\n return trimmed.length > 0 ? [trimmed] : []\n }\n\n if (Array.isArray(value)) {\n return value\n .filter((entry): entry is string => typeof entry === 'string')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n }\n\n return []\n}\n\nexport function attachAggregateSearchField(\n doc: Record<string, unknown>,\n options: AggregateSearchOptions = {},\n): Record<string, unknown> {\n const config = options.config ?? resolveSearchConfig()\n const entityType = options.entityType ?? null\n const parts: string[] = []\n const seen = new Set<string>()\n\n for (const [field, value] of Object.entries(doc)) {\n const values = collectAggregateSearchValues(field, value, entityType, config)\n for (const entry of values) {\n const key = entry.toLowerCase()\n if (seen.has(key)) continue\n seen.add(key)\n parts.push(entry)\n }\n }\n\n if (parts.length > 0) {\n doc[AGGREGATE_SEARCH_FIELD] = parts.join('\\n')\n }\n\n return doc\n}\n\nexport function buildIndexDocument(\n baseRow: Record<string, unknown>,\n customFieldValues: Iterable<IndexCustomFieldValue> = [],\n scope: IndexDocumentScope = {},\n options: AggregateSearchOptions = {},\n): Record<string, unknown> {\n const doc: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(baseRow)) {\n doc[key] = value\n }\n\n const scopeOrg = normalizeScopeValue(scope.organizationId ?? null)\n const scopeTenant = normalizeScopeValue(scope.tenantId ?? null)\n\n const grouped = new Map<string, unknown[]>()\n for (const field of customFieldValues) {\n const org = normalizeScopeValue(field.organizationId ?? null)\n const tenant = normalizeScopeValue(field.tenantId ?? null)\n\n if (!isScopedValueVisible(scopeOrg, org)) continue\n if (!isScopedValueVisible(scopeTenant, tenant)) continue\n\n const bucketKey = `cf:${field.key}`\n let bucket = grouped.get(bucketKey)\n if (!bucket) {\n bucket = []\n grouped.set(bucketKey, bucket)\n }\n\n const { value } = field\n if (Array.isArray(value)) {\n for (const entry of value) bucket.push(normalizeValue(entry))\n } else {\n bucket.push(normalizeValue(value))\n }\n }\n\n for (const [key, values] of grouped.entries()) {\n if (values.length === 1) {\n doc[key] = values[0]\n } else if (values.length > 1) {\n doc[key] = values\n }\n }\n\n return attachAggregateSearchField(doc, options)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n isSearchFieldBlocklisted,\n resolveSearchConfig,\n type SearchConfig,\n} from '@open-mercato/shared/lib/search/config'\n\nexport type IndexDocumentScope = {\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport type IndexCustomFieldValue = {\n key: string\n value: unknown\n organizationId?: string | null\n tenantId?: string | null\n}\n\nexport const AGGREGATE_SEARCH_FIELD = 'search_text'\n\n/**\n * Controls which fields may contribute text to the `search_text` aggregate.\n *\n * Both properties are optional so existing callers keep working unchanged: an\n * omitted `config` is resolved from the environment, and an omitted `entityType`\n * means only the global blocklist entries apply.\n */\nexport type AggregateSearchOptions = {\n entityType?: string | null\n config?: SearchConfig\n}\n\nfunction normalizeScopeValue(value: string | null | undefined): string | null {\n if (value === undefined || value === null || value === '') return null\n return value\n}\n\nfunction isScopedValueVisible(\n scopeValue: string | null,\n fieldValue: string | null,\n): boolean {\n if (scopeValue === null) return fieldValue === null\n return fieldValue === null || fieldValue === scopeValue\n}\n\nfunction normalizeValue(value: unknown): unknown {\n if (value === undefined) return null\n return value\n}\n\nfunction collectAggregateSearchValues(\n field: string,\n value: unknown,\n entityType: string | null,\n config: SearchConfig,\n): string[] {\n const lower = field.toLowerCase()\n if (\n lower === AGGREGATE_SEARCH_FIELD\n || lower === 'id'\n || lower.endsWith('_id')\n || lower.endsWith('.id')\n || lower.endsWith('_at')\n || ['created_at', 'updated_at', 'deleted_at', 'tenant_id', 'organization_id'].includes(lower)\n ) {\n return []\n }\n\n if (isSearchFieldBlocklisted(field, entityType, config)) return []\n\n if (typeof value === 'string') {\n const trimmed = value.trim()\n return trimmed.length > 0 ? [trimmed] : []\n }\n\n if (Array.isArray(value)) {\n return value\n .filter((entry): entry is string => typeof entry === 'string')\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0)\n }\n\n return []\n}\n\nexport function attachAggregateSearchField(\n doc: Record<string, unknown>,\n options: AggregateSearchOptions = {},\n): Record<string, unknown> {\n const config = options.config ?? resolveSearchConfig()\n const entityType = options.entityType ?? null\n const parts: string[] = []\n const seen = new Set<string>()\n\n for (const [field, value] of Object.entries(doc)) {\n const values = collectAggregateSearchValues(field, value, entityType, config)\n for (const entry of values) {\n const key = entry.toLowerCase()\n if (seen.has(key)) continue\n seen.add(key)\n parts.push(entry)\n }\n }\n\n if (parts.length > 0) {\n doc[AGGREGATE_SEARCH_FIELD] = parts.join('\\n')\n }\n\n return doc\n}\n\n/**\n * Recomputes the aggregate on a shallow copy of `doc`.\n *\n * Search tokens are built from the *decrypted* index document, while the document\n * persisted in `entity_indexes` stays encrypted at rest. The aggregate composed during\n * document build therefore concatenates ciphertext for every field an encryption map\n * covers, and `decryptIndexDocForSearch` cannot repair it because `search_text` is on no\n * map (#5625). Token writers call this on the decrypted document so the aggregate is\n * tokenized from the same plaintext a user actually searches for; the copy keeps the\n * caller's stored document untouched.\n *\n * A pre-existing aggregate is blanked before recomposition rather than deleted: an empty\n * string yields no tokens, but it keeps the key on the document, and\n * `replaceSearchTokensForRecord` scopes its DELETE to the document's own field names. A\n * deleted key would drop `search_text` out of that scope and strand the ciphertext-derived\n * rows with no writer left to remove them.\n */\nexport function rebuildAggregateSearchField(\n doc: Record<string, unknown>,\n options: AggregateSearchOptions = {},\n): Record<string, unknown> {\n const copy = { ...doc }\n // `collectAggregateSearchValues` skips the aggregate's own key, so this blank is\n // overwritten whenever anything survives the blocklist and stays blank otherwise.\n if (AGGREGATE_SEARCH_FIELD in copy) copy[AGGREGATE_SEARCH_FIELD] = ''\n return attachAggregateSearchField(copy, options)\n}\n\nexport function buildIndexDocument(\n baseRow: Record<string, unknown>,\n customFieldValues: Iterable<IndexCustomFieldValue> = [],\n scope: IndexDocumentScope = {},\n options: AggregateSearchOptions = {},\n): Record<string, unknown> {\n const doc: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(baseRow)) {\n doc[key] = value\n }\n\n const scopeOrg = normalizeScopeValue(scope.organizationId ?? null)\n const scopeTenant = normalizeScopeValue(scope.tenantId ?? null)\n\n const grouped = new Map<string, unknown[]>()\n for (const field of customFieldValues) {\n const org = normalizeScopeValue(field.organizationId ?? null)\n const tenant = normalizeScopeValue(field.tenantId ?? null)\n\n if (!isScopedValueVisible(scopeOrg, org)) continue\n if (!isScopedValueVisible(scopeTenant, tenant)) continue\n\n const bucketKey = `cf:${field.key}`\n let bucket = grouped.get(bucketKey)\n if (!bucket) {\n bucket = []\n grouped.set(bucketKey, bucket)\n }\n\n const { value } = field\n if (Array.isArray(value)) {\n for (const entry of value) bucket.push(normalizeValue(entry))\n } else {\n bucket.push(normalizeValue(value))\n }\n }\n\n for (const [key, values] of grouped.entries()) {\n if (values.length === 1) {\n doc[key] = values[0]\n } else if (values.length > 1) {\n doc[key] = values\n }\n }\n\n return attachAggregateSearchField(doc, options)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }