@open-mercato/core 0.6.1-develop.3276.1.1fcd145078 → 0.6.1-develop.3278.1.a4d26475e4

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 (212) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/domain_mapping/index.js +31 -0
  3. package/dist/generated/entities/domain_mapping/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +2 -1
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +16 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/salesUi.js +18 -17
  9. package/dist/helpers/integration/salesUi.js.map +2 -2
  10. package/dist/modules/customer_accounts/acl.js +2 -1
  11. package/dist/modules/customer_accounts/acl.js.map +2 -2
  12. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js +110 -0
  13. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js.map +7 -0
  14. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js +114 -0
  15. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js.map +7 -0
  16. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +271 -0
  17. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +7 -0
  18. package/dist/modules/customer_accounts/api/domain-check.js +70 -0
  19. package/dist/modules/customer_accounts/api/domain-check.js.map +7 -0
  20. package/dist/modules/customer_accounts/api/domain-resolve/all.js +128 -0
  21. package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +7 -0
  22. package/dist/modules/customer_accounts/api/domain-resolve.js +84 -0
  23. package/dist/modules/customer_accounts/api/domain-resolve.js.map +7 -0
  24. package/dist/modules/customer_accounts/api/login.js +14 -3
  25. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  26. package/dist/modules/customer_accounts/api/magic-link/request.js +14 -3
  27. package/dist/modules/customer_accounts/api/magic-link/request.js.map +2 -2
  28. package/dist/modules/customer_accounts/api/password/reset-request.js +14 -3
  29. package/dist/modules/customer_accounts/api/password/reset-request.js.map +2 -2
  30. package/dist/modules/customer_accounts/api/signup.js +32 -5
  31. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  32. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js +48 -0
  33. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js.map +7 -0
  34. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +43 -0
  35. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +7 -0
  36. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js +53 -0
  37. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js.map +7 -0
  38. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js +69 -0
  39. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js.map +7 -0
  40. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js +31 -0
  41. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js.map +7 -0
  42. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js +147 -0
  43. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js.map +7 -0
  44. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js +39 -0
  45. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js.map +7 -0
  46. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js +60 -0
  47. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js.map +7 -0
  48. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js +11 -0
  49. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js.map +7 -0
  50. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js +1 -0
  51. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js.map +7 -0
  52. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +361 -0
  53. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +7 -0
  54. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js +28 -0
  55. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js.map +7 -0
  56. package/dist/modules/customer_accounts/data/enrichers.js +78 -12
  57. package/dist/modules/customer_accounts/data/enrichers.js.map +2 -2
  58. package/dist/modules/customer_accounts/data/entities.js +85 -2
  59. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  60. package/dist/modules/customer_accounts/data/guards.js +130 -0
  61. package/dist/modules/customer_accounts/data/guards.js.map +7 -0
  62. package/dist/modules/customer_accounts/data/validators.js +19 -0
  63. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  64. package/dist/modules/customer_accounts/di.js +23 -1
  65. package/dist/modules/customer_accounts/di.js.map +2 -2
  66. package/dist/modules/customer_accounts/events.js +9 -2
  67. package/dist/modules/customer_accounts/events.js.map +2 -2
  68. package/dist/modules/customer_accounts/lib/customerAuthServer.js +27 -7
  69. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  70. package/dist/modules/customer_accounts/lib/customerUrl.js +48 -0
  71. package/dist/modules/customer_accounts/lib/customerUrl.js.map +7 -0
  72. package/dist/modules/customer_accounts/lib/hostname.js +55 -0
  73. package/dist/modules/customer_accounts/lib/hostname.js.map +7 -0
  74. package/dist/modules/customer_accounts/lib/platformDomains.js +7 -0
  75. package/dist/modules/customer_accounts/lib/platformDomains.js.map +7 -0
  76. package/dist/modules/customer_accounts/lib/proxyRanges.js +71 -0
  77. package/dist/modules/customer_accounts/lib/proxyRanges.js.map +7 -0
  78. package/dist/modules/customer_accounts/lib/rateLimiter.js +7 -0
  79. package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
  80. package/dist/modules/customer_accounts/lib/resolveTenantContext.js +63 -0
  81. package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +7 -0
  82. package/dist/modules/customer_accounts/lib/secretCompare.js +13 -0
  83. package/dist/modules/customer_accounts/lib/secretCompare.js.map +7 -0
  84. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js +37 -0
  85. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js.map +7 -0
  86. package/dist/modules/customer_accounts/notifications.client.js +76 -0
  87. package/dist/modules/customer_accounts/notifications.client.js.map +2 -2
  88. package/dist/modules/customer_accounts/notifications.js +76 -0
  89. package/dist/modules/customer_accounts/notifications.js.map +2 -2
  90. package/dist/modules/customer_accounts/services/domainMappingService.js +497 -0
  91. package/dist/modules/customer_accounts/services/domainMappingService.js.map +7 -0
  92. package/dist/modules/customer_accounts/setup.js +48 -1
  93. package/dist/modules/customer_accounts/setup.js.map +2 -2
  94. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js +29 -0
  95. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js.map +7 -0
  96. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js +29 -0
  97. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js.map +7 -0
  98. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js +30 -0
  99. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js.map +7 -0
  100. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js +31 -0
  101. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js.map +7 -0
  102. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js +29 -0
  103. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js.map +7 -0
  104. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js +67 -0
  105. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js.map +7 -0
  106. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js +34 -0
  107. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js.map +7 -0
  108. package/dist/modules/customers/api/companies/route.js +4 -9
  109. package/dist/modules/customers/api/companies/route.js.map +2 -2
  110. package/dist/modules/customers/api/deals/route.js +4 -9
  111. package/dist/modules/customers/api/deals/route.js.map +2 -2
  112. package/dist/modules/customers/api/people/route.js +4 -9
  113. package/dist/modules/customers/api/people/route.js.map +2 -2
  114. package/dist/modules/customers/api/utils.js +0 -12
  115. package/dist/modules/customers/api/utils.js.map +2 -2
  116. package/dist/modules/customers/backend/customers/companies/page.js +361 -284
  117. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  118. package/dist/modules/customers/backend/customers/deals/page.js +378 -473
  119. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  120. package/dist/modules/customers/backend/customers/people/page.js +368 -286
  121. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  122. package/dist/modules/customers/components/detail/assignableStaff.js +15 -1
  123. package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
  124. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +188 -36
  125. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
  126. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js +2 -2
  127. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js.map +2 -2
  128. package/dist/modules/customers/widgets/injection-table.js +6 -0
  129. package/dist/modules/customers/widgets/injection-table.js.map +2 -2
  130. package/dist/modules/perspectives/services/perspectiveService.js +16 -2
  131. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  132. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +1 -0
  133. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  134. package/dist/modules/query_index/lib/engine.js +31 -8
  135. package/dist/modules/query_index/lib/engine.js.map +2 -2
  136. package/generated/entities/domain_mapping/index.ts +14 -0
  137. package/generated/entities.ids.generated.ts +2 -1
  138. package/generated/entity-fields-registry.ts +16 -0
  139. package/package.json +5 -5
  140. package/src/helpers/integration/salesUi.ts +27 -23
  141. package/src/modules/customer_accounts/acl.ts +1 -0
  142. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.ts +119 -0
  143. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.ts +123 -0
  144. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +303 -0
  145. package/src/modules/customer_accounts/api/domain-check.ts +83 -0
  146. package/src/modules/customer_accounts/api/domain-resolve/all.ts +139 -0
  147. package/src/modules/customer_accounts/api/domain-resolve.ts +91 -0
  148. package/src/modules/customer_accounts/api/login.ts +14 -3
  149. package/src/modules/customer_accounts/api/magic-link/request.ts +14 -3
  150. package/src/modules/customer_accounts/api/password/reset-request.ts +15 -3
  151. package/src/modules/customer_accounts/api/signup.ts +36 -5
  152. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.tsx +70 -0
  153. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +66 -0
  154. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.tsx +78 -0
  155. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.tsx +90 -0
  156. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.tsx +43 -0
  157. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.tsx +178 -0
  158. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.tsx +56 -0
  159. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.tsx +69 -0
  160. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.ts +10 -0
  161. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.ts +31 -0
  162. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.ts +26 -0
  163. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +411 -0
  164. package/src/modules/customer_accounts/data/enrichers.ts +95 -12
  165. package/src/modules/customer_accounts/data/entities.ts +80 -1
  166. package/src/modules/customer_accounts/data/guards.ts +155 -0
  167. package/src/modules/customer_accounts/data/validators.ts +26 -0
  168. package/src/modules/customer_accounts/di.ts +35 -1
  169. package/src/modules/customer_accounts/events.ts +8 -1
  170. package/src/modules/customer_accounts/i18n/de.json +78 -0
  171. package/src/modules/customer_accounts/i18n/en.json +78 -0
  172. package/src/modules/customer_accounts/i18n/es.json +78 -0
  173. package/src/modules/customer_accounts/i18n/pl.json +78 -0
  174. package/src/modules/customer_accounts/lib/customerAuthServer.ts +44 -8
  175. package/src/modules/customer_accounts/lib/customerUrl.ts +72 -0
  176. package/src/modules/customer_accounts/lib/hostname.ts +76 -0
  177. package/src/modules/customer_accounts/lib/platformDomains.ts +14 -0
  178. package/src/modules/customer_accounts/lib/proxyRanges.ts +85 -0
  179. package/src/modules/customer_accounts/lib/rateLimiter.ts +10 -0
  180. package/src/modules/customer_accounts/lib/resolveTenantContext.ts +96 -0
  181. package/src/modules/customer_accounts/lib/secretCompare.ts +20 -0
  182. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +341 -0
  183. package/src/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.ts +38 -0
  184. package/src/modules/customer_accounts/notifications.client.ts +76 -0
  185. package/src/modules/customer_accounts/notifications.ts +76 -0
  186. package/src/modules/customer_accounts/services/domainMappingService.ts +632 -0
  187. package/src/modules/customer_accounts/setup.ts +81 -1
  188. package/src/modules/customer_accounts/subscribers/invalidateDomainCache.ts +35 -0
  189. package/src/modules/customer_accounts/subscribers/notifyDomainActivated.ts +32 -0
  190. package/src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts +33 -0
  191. package/src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts +34 -0
  192. package/src/modules/customer_accounts/subscribers/notifyDomainVerified.ts +32 -0
  193. package/src/modules/customer_accounts/workers/domainTlsRetryWorker.ts +84 -0
  194. package/src/modules/customer_accounts/workers/domainVerificationWorker.ts +45 -0
  195. package/src/modules/customers/api/companies/route.ts +4 -9
  196. package/src/modules/customers/api/deals/route.ts +4 -9
  197. package/src/modules/customers/api/people/route.ts +4 -9
  198. package/src/modules/customers/api/utils.ts +0 -14
  199. package/src/modules/customers/backend/customers/companies/page.tsx +321 -237
  200. package/src/modules/customers/backend/customers/deals/page.tsx +321 -455
  201. package/src/modules/customers/backend/customers/people/page.tsx +331 -240
  202. package/src/modules/customers/components/detail/assignableStaff.ts +21 -0
  203. package/src/modules/customers/i18n/de.json +31 -0
  204. package/src/modules/customers/i18n/en.json +31 -0
  205. package/src/modules/customers/i18n/es.json +31 -0
  206. package/src/modules/customers/i18n/pl.json +31 -0
  207. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +197 -40
  208. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.ts +13 -7
  209. package/src/modules/customers/widgets/injection-table.ts +6 -0
  210. package/src/modules/perspectives/services/perspectiveService.ts +30 -2
  211. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +1 -0
  212. package/src/modules/query_index/lib/engine.ts +46 -8
@@ -2,7 +2,6 @@ import { createScopedApiHelpers } from "@open-mercato/shared/lib/api/scoped";
2
2
  import { sql } from "kysely";
3
3
  import { resolveSearchConfig } from "@open-mercato/shared/lib/search/config";
4
4
  import { tokenizeText } from "@open-mercato/shared/lib/search/tokenize";
5
- import { deserializeAdvancedFilter } from "@open-mercato/shared/lib/query/advanced-filter";
6
5
  import { SortDir } from "@open-mercato/shared/lib/query/types";
7
6
  const { withScopedPayload, parseScopedCommandInput } = createScopedApiHelpers({
8
7
  messages: {
@@ -175,16 +174,6 @@ function applyEntityIdExclusion(filters, ids) {
175
174
  $nin: Array.from(/* @__PURE__ */ new Set([...currentNotIn, ...uniqueIds]))
176
175
  };
177
176
  }
178
- function consumeAdvancedFilterState(query) {
179
- const state = deserializeAdvancedFilter(query);
180
- if (!state) return null;
181
- for (const key of Object.keys(query)) {
182
- if (key.startsWith("filter[")) {
183
- delete query[key];
184
- }
185
- }
186
- return state;
187
- }
188
177
  async function findMatchingEntityIdsWithQueryEngine({
189
178
  ctx,
190
179
  entityId,
@@ -224,7 +213,6 @@ async function findMatchingEntityIdsWithQueryEngine({
224
213
  export {
225
214
  applyEntityIdExclusion,
226
215
  applyEntityIdRestriction,
227
- consumeAdvancedFilterState,
228
216
  findMatchingEntityIdsBySearchTokens,
229
217
  findMatchingEntityIdsBySearchTokensAcrossSources,
230
218
  findMatchingEntityIdsWithQueryEngine,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/api/utils.ts"],
4
- "sourcesContent": ["import { createScopedApiHelpers } from '@open-mercato/shared/lib/api/scoped'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from 'kysely'\nimport type { CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { QueryCustomFieldSource, QueryJoinEdge, QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { resolveSearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { deserializeAdvancedFilter } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\n\nconst { withScopedPayload, parseScopedCommandInput } = createScopedApiHelpers({\n messages: {\n tenantRequired: { key: 'customers.errors.tenant_required', fallback: 'Tenant context is required' },\n organizationRequired: { key: 'customers.errors.organization_required', fallback: 'Organization context is required' },\n },\n})\n\nconst NO_MATCH_ID = '00000000-0000-0000-0000-000000000000'\n\ntype SearchTokenMatchInput = {\n ctx: CrudCtx\n entityType: string\n fields: string[]\n query: string\n}\n\ntype SearchTokenSource = {\n entityType: string\n fields: string[]\n mapToEntityIds?: {\n table: string\n sourceColumn?: string\n targetColumn: string\n tenantColumn?: string\n organizationColumn?: string\n }\n}\n\nasync function enrichSearchSourcesWithCustomFieldTokens(\n ctx: CrudCtx,\n sources: SearchTokenSource[],\n): Promise<SearchTokenSource[]> {\n const entityTypes = Array.from(\n new Set(\n sources\n .map((source) => source.entityType)\n .filter((value): value is string => typeof value === 'string' && value.length > 0),\n ),\n )\n if (!entityTypes.length) return sources\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n let defsQuery = db\n .selectFrom('custom_field_defs')\n .select(['entity_id', 'key', 'kind'])\n .where('entity_id', 'in', entityTypes)\n .where('is_active', '=', true)\n\n const tenantScope = ctx.auth?.tenantId ?? null\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('tenant_id', '=', tenantScope),\n eb('tenant_id', 'is', null),\n ]))\n\n if (ctx.selectedOrganizationId) {\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('organization_id', '=', ctx.selectedOrganizationId),\n eb('organization_id', 'is', null),\n ]))\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('organization_id', 'in', ctx.organizationIds),\n eb('organization_id', 'is', null),\n ]))\n }\n\n const customFieldKeysByEntity = new Map<string, Set<string>>()\n const rows = await defsQuery.execute()\n for (const row of rows as Array<{ entity_id?: unknown; key?: unknown; kind?: unknown }>) {\n if (row.kind === 'attachment') continue\n const entityType = typeof row.entity_id === 'string' ? row.entity_id : null\n const key = typeof row.key === 'string' ? row.key.trim() : ''\n if (!entityType || !key) continue\n const bucket = customFieldKeysByEntity.get(entityType) ?? new Set<string>()\n bucket.add(`cf:${key}`)\n customFieldKeysByEntity.set(entityType, bucket)\n }\n\n return sources.map((source) => {\n const customFieldKeys = customFieldKeysByEntity.get(source.entityType)\n return {\n ...source,\n fields: Array.from(new Set([\n 'search_text',\n ...source.fields,\n ...(customFieldKeys ? Array.from(customFieldKeys) : []),\n ])),\n }\n })\n}\n\nasync function findSearchTokenEntityIds({\n ctx,\n entityType,\n fields,\n query,\n}: SearchTokenMatchInput): Promise<string[] | null> {\n const trimmed = query.trim()\n if (!trimmed) return null\n\n const tokens = tokenizeText(trimmed, resolveSearchConfig())\n if (!tokens.hashes.length) return []\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n let searchQuery = db\n .selectFrom('search_tokens')\n .select('entity_id')\n .where('entity_type', '=', entityType)\n .where('field', 'in', fields)\n .where('token_hash', 'in', tokens.hashes)\n .groupBy('entity_id')\n .having(sql<boolean>`count(distinct token_hash) >= ${tokens.hashes.length}`)\n\n if (ctx.auth?.tenantId !== undefined) {\n searchQuery = searchQuery.where(sql<boolean>`tenant_id is not distinct from ${ctx.auth?.tenantId ?? null}`)\n }\n if (ctx.selectedOrganizationId) {\n searchQuery = searchQuery.where('organization_id', '=', ctx.selectedOrganizationId)\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n searchQuery = searchQuery.where('organization_id', 'in', ctx.organizationIds)\n }\n\n const rows = await searchQuery.execute() as Array<{ entity_id?: unknown }>\n return rows\n .map((row) => (typeof row.entity_id === 'string' ? row.entity_id : null))\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n}\n\nasync function mapScopedEntityIds({\n ctx,\n ids,\n config,\n}: {\n ctx: CrudCtx\n ids: string[]\n config: NonNullable<SearchTokenSource['mapToEntityIds']>\n}): Promise<string[]> {\n if (!ids.length) return []\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n const sourceColumn = config.sourceColumn ?? 'id'\n const tenantColumn = config.tenantColumn ?? 'tenant_id'\n const organizationColumn = config.organizationColumn ?? 'organization_id'\n\n let mapQuery = db\n .selectFrom(config.table)\n .select(config.targetColumn)\n .where(sourceColumn, 'in', ids)\n\n if (ctx.auth?.tenantId !== undefined) {\n mapQuery = mapQuery.where(sql<boolean>`${sql.ref(tenantColumn)} is not distinct from ${ctx.auth?.tenantId ?? null}`)\n }\n if (ctx.selectedOrganizationId) {\n mapQuery = mapQuery.where(organizationColumn, '=', ctx.selectedOrganizationId)\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n mapQuery = mapQuery.where(organizationColumn, 'in', ctx.organizationIds)\n }\n\n const rows = await mapQuery.execute() as Array<Record<string, unknown>>\n return rows\n .map((row) => {\n const value = row[config.targetColumn]\n return typeof value === 'string' ? value : null\n })\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n}\n\nexport async function findMatchingEntityIdsBySearchTokensAcrossSources({\n ctx,\n sources,\n query,\n}: {\n ctx: CrudCtx\n sources: SearchTokenSource[]\n query: string\n}): Promise<string[] | null> {\n const trimmed = query.trim()\n if (!trimmed) return null\n\n const enrichedSources = await enrichSearchSourcesWithCustomFieldTokens(ctx, sources)\n const matchedIds = new Set<string>()\n for (const source of enrichedSources) {\n const rawIds = await findSearchTokenEntityIds({\n ctx,\n entityType: source.entityType,\n fields: source.fields,\n query: trimmed,\n })\n if (rawIds === null) return null\n const entityIds = source.mapToEntityIds\n ? await mapScopedEntityIds({ ctx, ids: rawIds, config: source.mapToEntityIds })\n : rawIds\n entityIds.forEach((id) => matchedIds.add(id))\n }\n\n return Array.from(matchedIds)\n}\n\nexport async function findMatchingEntityIdsBySearchTokens({\n ctx,\n entityType,\n fields,\n query,\n}: SearchTokenMatchInput): Promise<string[] | null> {\n return findMatchingEntityIdsBySearchTokensAcrossSources({\n ctx,\n query,\n sources: [{ entityType, fields }],\n })\n}\n\nexport function applyEntityIdRestriction(\n filters: Record<string, unknown>,\n ids: string[] | null,\n): void {\n if (ids === null) return\n const currentIdFilter =\n filters.id && typeof filters.id === 'object' && !Array.isArray(filters.id)\n ? (filters.id as { $eq?: unknown; $in?: unknown })\n : null\n const currentEq = typeof currentIdFilter?.$eq === 'string' ? currentIdFilter.$eq : null\n\n if (currentEq) {\n filters.id = ids.includes(currentEq) ? { $eq: currentEq } : { $eq: NO_MATCH_ID }\n return\n }\n\n filters.id = ids.length > 0 ? { $in: ids } : { $eq: NO_MATCH_ID }\n}\n\nexport function applyEntityIdExclusion(\n filters: Record<string, unknown>,\n ids: string[],\n): void {\n const uniqueIds = Array.from(new Set(ids.filter((id) => typeof id === 'string' && id.length > 0)))\n if (!uniqueIds.length) return\n\n const currentIdFilter =\n filters.id && typeof filters.id === 'object' && !Array.isArray(filters.id)\n ? (filters.id as { $eq?: unknown; $in?: unknown; $nin?: unknown })\n : null\n const currentEq = typeof currentIdFilter?.$eq === 'string' ? currentIdFilter.$eq : null\n const currentIn = Array.isArray(currentIdFilter?.$in)\n ? currentIdFilter.$in.filter((value): value is string => typeof value === 'string' && value.length > 0)\n : null\n const currentNotIn = Array.isArray(currentIdFilter?.$nin)\n ? currentIdFilter.$nin.filter((value): value is string => typeof value === 'string' && value.length > 0)\n : []\n\n if (currentEq) {\n filters.id = uniqueIds.includes(currentEq) ? { $eq: NO_MATCH_ID } : { $eq: currentEq }\n return\n }\n\n if (currentIn) {\n const nextIds = currentIn.filter((id) => !uniqueIds.includes(id))\n filters.id = nextIds.length > 0 ? { $in: nextIds } : { $eq: NO_MATCH_ID }\n return\n }\n\n filters.id = {\n ...(currentIdFilter ?? {}),\n $nin: Array.from(new Set([...currentNotIn, ...uniqueIds])),\n }\n}\n\nexport function consumeAdvancedFilterState(query: Record<string, unknown>) {\n const state = deserializeAdvancedFilter(query)\n if (!state) return null\n\n for (const key of Object.keys(query)) {\n if (key.startsWith('filter[')) {\n delete query[key]\n }\n }\n\n return state\n}\n\nexport async function findMatchingEntityIdsWithQueryEngine({\n ctx,\n entityId,\n filters,\n customFieldSources,\n joins,\n}: {\n ctx: CrudCtx\n entityId: EntityId\n filters: Record<string, unknown>\n customFieldSources?: QueryCustomFieldSource[]\n joins?: QueryJoinEdge[]\n}): Promise<string[]> {\n const qe = ctx.container.resolve('queryEngine') as QueryEngine\n const ids = new Set<string>()\n const pageSize = 100\n let page = 1\n let total = 0\n\n do {\n const result = await qe.query(entityId, {\n fields: ['id'],\n filters,\n page: { page, pageSize },\n sort: [{ field: 'id', dir: SortDir.Asc }],\n tenantId: ctx.auth?.tenantId ?? undefined,\n organizationId: ctx.selectedOrganizationId ?? undefined,\n organizationIds: ctx.organizationIds ?? undefined,\n customFieldSources,\n joins,\n })\n\n total = result.total ?? 0\n for (const item of result.items ?? []) {\n const id = item && typeof item === 'object' ? (item as Record<string, unknown>).id : null\n if (typeof id === 'string' && id.length > 0) {\n ids.add(id)\n }\n }\n if (!result.items?.length) break\n page += 1\n } while (ids.size < total)\n\n return Array.from(ids)\n}\n\nexport { withScopedPayload, parseScopedCommandInput }\n"],
5
- "mappings": "AAAA,SAAS,8BAA8B;AAEvC,SAAS,WAAW;AAIpB,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAC7B,SAAS,iCAAiC;AAC1C,SAAS,eAAe;AAExB,MAAM,EAAE,mBAAmB,wBAAwB,IAAI,uBAAuB;AAAA,EAC5E,UAAU;AAAA,IACR,gBAAgB,EAAE,KAAK,oCAAoC,UAAU,6BAA6B;AAAA,IAClG,sBAAsB,EAAE,KAAK,0CAA0C,UAAU,mCAAmC;AAAA,EACtH;AACF,CAAC;AAED,MAAM,cAAc;AAqBpB,eAAe,yCACb,KACA,SAC8B;AAC9B,QAAM,cAAc,MAAM;AAAA,IACxB,IAAI;AAAA,MACF,QACG,IAAI,CAAC,WAAW,OAAO,UAAU,EACjC,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAAA,IACrF;AAAA,EACF;AACA,MAAI,CAAC,YAAY,OAAQ,QAAO;AAEhC,QAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,QAAM,KAAK,GAAG,UAAe;AAC7B,MAAI,YAAY,GACb,WAAW,mBAAmB,EAC9B,OAAO,CAAC,aAAa,OAAO,MAAM,CAAC,EACnC,MAAM,aAAa,MAAM,WAAW,EACpC,MAAM,aAAa,KAAK,IAAI;AAE/B,QAAM,cAAc,IAAI,MAAM,YAAY;AAC1C,cAAY,UAAU,MAAM,CAAC,OAAY,GAAG,GAAG;AAAA,IAC7C,GAAG,aAAa,KAAK,WAAW;AAAA,IAChC,GAAG,aAAa,MAAM,IAAI;AAAA,EAC5B,CAAC,CAAC;AAEF,MAAI,IAAI,wBAAwB;AAC9B,gBAAY,UAAU,MAAM,CAAC,OAAY,GAAG,GAAG;AAAA,MAC7C,GAAG,mBAAmB,KAAK,IAAI,sBAAsB;AAAA,MACrD,GAAG,mBAAmB,MAAM,IAAI;AAAA,IAClC,CAAC,CAAC;AAAA,EACJ,WAAW,MAAM,QAAQ,IAAI,eAAe,KAAK,IAAI,gBAAgB,SAAS,GAAG;AAC/E,gBAAY,UAAU,MAAM,CAAC,OAAY,GAAG,GAAG;AAAA,MAC7C,GAAG,mBAAmB,MAAM,IAAI,eAAe;AAAA,MAC/C,GAAG,mBAAmB,MAAM,IAAI;AAAA,IAClC,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,0BAA0B,oBAAI,IAAyB;AAC7D,QAAM,OAAO,MAAM,UAAU,QAAQ;AACrC,aAAW,OAAO,MAAuE;AACvF,QAAI,IAAI,SAAS,aAAc;AAC/B,UAAM,aAAa,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY;AACvE,UAAM,MAAM,OAAO,IAAI,QAAQ,WAAW,IAAI,IAAI,KAAK,IAAI;AAC3D,QAAI,CAAC,cAAc,CAAC,IAAK;AACzB,UAAM,SAAS,wBAAwB,IAAI,UAAU,KAAK,oBAAI,IAAY;AAC1E,WAAO,IAAI,MAAM,GAAG,EAAE;AACtB,4BAAwB,IAAI,YAAY,MAAM;AAAA,EAChD;AAEA,SAAO,QAAQ,IAAI,CAAC,WAAW;AAC7B,UAAM,kBAAkB,wBAAwB,IAAI,OAAO,UAAU;AACrE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,MAAM,KAAK,oBAAI,IAAI;AAAA,QACzB;AAAA,QACA,GAAG,OAAO;AAAA,QACV,GAAI,kBAAkB,MAAM,KAAK,eAAe,IAAI,CAAC;AAAA,MACvD,CAAC,CAAC;AAAA,IACJ;AAAA,EACF,CAAC;AACH;AAEA,eAAe,yBAAyB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoD;AAClD,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,SAAS,aAAa,SAAS,oBAAoB,CAAC;AAC1D,MAAI,CAAC,OAAO,OAAO,OAAQ,QAAO,CAAC;AAEnC,QAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,QAAM,KAAK,GAAG,UAAe;AAC7B,MAAI,cAAc,GACf,WAAW,eAAe,EAC1B,OAAO,WAAW,EAClB,MAAM,eAAe,KAAK,UAAU,EACpC,MAAM,SAAS,MAAM,MAAM,EAC3B,MAAM,cAAc,MAAM,OAAO,MAAM,EACvC,QAAQ,WAAW,EACnB,OAAO,oCAA6C,OAAO,OAAO,MAAM,EAAE;AAE7E,MAAI,IAAI,MAAM,aAAa,QAAW;AACpC,kBAAc,YAAY,MAAM,qCAA8C,IAAI,MAAM,YAAY,IAAI,EAAE;AAAA,EAC5G;AACA,MAAI,IAAI,wBAAwB;AAC9B,kBAAc,YAAY,MAAM,mBAAmB,KAAK,IAAI,sBAAsB;AAAA,EACpF,WAAW,MAAM,QAAQ,IAAI,eAAe,KAAK,IAAI,gBAAgB,SAAS,GAAG;AAC/E,kBAAc,YAAY,MAAM,mBAAmB,MAAM,IAAI,eAAe;AAAA,EAC9E;AAEA,QAAM,OAAO,MAAM,YAAY,QAAQ;AACvC,SAAO,KACJ,IAAI,CAAC,QAAS,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY,IAAK,EACvE,OAAO,CAAC,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AACzE;AAEA,eAAe,mBAAmB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,MAAI,CAAC,IAAI,OAAQ,QAAO,CAAC;AAEzB,QAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,QAAM,KAAK,GAAG,UAAe;AAC7B,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,qBAAqB,OAAO,sBAAsB;AAExD,MAAI,WAAW,GACZ,WAAW,OAAO,KAAK,EACvB,OAAO,OAAO,YAAY,EAC1B,MAAM,cAAc,MAAM,GAAG;AAEhC,MAAI,IAAI,MAAM,aAAa,QAAW;AACpC,eAAW,SAAS,MAAM,MAAe,IAAI,IAAI,YAAY,CAAC,yBAAyB,IAAI,MAAM,YAAY,IAAI,EAAE;AAAA,EACrH;AACA,MAAI,IAAI,wBAAwB;AAC9B,eAAW,SAAS,MAAM,oBAAoB,KAAK,IAAI,sBAAsB;AAAA,EAC/E,WAAW,MAAM,QAAQ,IAAI,eAAe,KAAK,IAAI,gBAAgB,SAAS,GAAG;AAC/E,eAAW,SAAS,MAAM,oBAAoB,MAAM,IAAI,eAAe;AAAA,EACzE;AAEA,QAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,SAAO,KACJ,IAAI,CAAC,QAAQ;AACZ,UAAM,QAAQ,IAAI,OAAO,YAAY;AACrC,WAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,EAC7C,CAAC,EACA,OAAO,CAAC,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AACzE;AAEA,eAAsB,iDAAiD;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AACF,GAI6B;AAC3B,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,kBAAkB,MAAM,yCAAyC,KAAK,OAAO;AACnF,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,UAAU,iBAAiB;AACpC,UAAM,SAAS,MAAM,yBAAyB;AAAA,MAC5C;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,OAAO;AAAA,IACT,CAAC;AACD,QAAI,WAAW,KAAM,QAAO;AAC5B,UAAM,YAAY,OAAO,iBACrB,MAAM,mBAAmB,EAAE,KAAK,KAAK,QAAQ,QAAQ,OAAO,eAAe,CAAC,IAC5E;AACJ,cAAU,QAAQ,CAAC,OAAO,WAAW,IAAI,EAAE,CAAC;AAAA,EAC9C;AAEA,SAAO,MAAM,KAAK,UAAU;AAC9B;AAEA,eAAsB,oCAAoC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoD;AAClD,SAAO,iDAAiD;AAAA,IACtD;AAAA,IACA;AAAA,IACA,SAAS,CAAC,EAAE,YAAY,OAAO,CAAC;AAAA,EAClC,CAAC;AACH;AAEO,SAAS,yBACd,SACA,KACM;AACN,MAAI,QAAQ,KAAM;AAClB,QAAM,kBACJ,QAAQ,MAAM,OAAO,QAAQ,OAAO,YAAY,CAAC,MAAM,QAAQ,QAAQ,EAAE,IACpE,QAAQ,KACT;AACN,QAAM,YAAY,OAAO,iBAAiB,QAAQ,WAAW,gBAAgB,MAAM;AAEnF,MAAI,WAAW;AACb,YAAQ,KAAK,IAAI,SAAS,SAAS,IAAI,EAAE,KAAK,UAAU,IAAI,EAAE,KAAK,YAAY;AAC/E;AAAA,EACF;AAEA,UAAQ,KAAK,IAAI,SAAS,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,YAAY;AAClE;AAEO,SAAS,uBACd,SACA,KACM;AACN,QAAM,YAAY,MAAM,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,OAAO,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;AACjG,MAAI,CAAC,UAAU,OAAQ;AAEvB,QAAM,kBACJ,QAAQ,MAAM,OAAO,QAAQ,OAAO,YAAY,CAAC,MAAM,QAAQ,QAAQ,EAAE,IACpE,QAAQ,KACT;AACN,QAAM,YAAY,OAAO,iBAAiB,QAAQ,WAAW,gBAAgB,MAAM;AACnF,QAAM,YAAY,MAAM,QAAQ,iBAAiB,GAAG,IAChD,gBAAgB,IAAI,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC,IACpG;AACJ,QAAM,eAAe,MAAM,QAAQ,iBAAiB,IAAI,IACpD,gBAAgB,KAAK,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC,IACrG,CAAC;AAEL,MAAI,WAAW;AACb,YAAQ,KAAK,UAAU,SAAS,SAAS,IAAI,EAAE,KAAK,YAAY,IAAI,EAAE,KAAK,UAAU;AACrF;AAAA,EACF;AAEA,MAAI,WAAW;AACb,UAAM,UAAU,UAAU,OAAO,CAAC,OAAO,CAAC,UAAU,SAAS,EAAE,CAAC;AAChE,YAAQ,KAAK,QAAQ,SAAS,IAAI,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,YAAY;AACxE;AAAA,EACF;AAEA,UAAQ,KAAK;AAAA,IACX,GAAI,mBAAmB,CAAC;AAAA,IACxB,MAAM,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,cAAc,GAAG,SAAS,CAAC,CAAC;AAAA,EAC3D;AACF;AAEO,SAAS,2BAA2B,OAAgC;AACzE,QAAM,QAAQ,0BAA0B,KAAK;AAC7C,MAAI,CAAC,MAAO,QAAO;AAEnB,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,QAAI,IAAI,WAAW,SAAS,GAAG;AAC7B,aAAO,MAAM,GAAG;AAAA,IAClB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,qCAAqC;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMsB;AACpB,QAAM,KAAK,IAAI,UAAU,QAAQ,aAAa;AAC9C,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,WAAW;AACjB,MAAI,OAAO;AACX,MAAI,QAAQ;AAEZ,KAAG;AACD,UAAM,SAAS,MAAM,GAAG,MAAM,UAAU;AAAA,MACtC,QAAQ,CAAC,IAAI;AAAA,MACb;AAAA,MACA,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,MAAM,CAAC,EAAE,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MACxC,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B;AAAA,MAC9C,iBAAiB,IAAI,mBAAmB;AAAA,MACxC;AAAA,MACA;AAAA,IACF,CAAC;AAED,YAAQ,OAAO,SAAS;AACxB,eAAW,QAAQ,OAAO,SAAS,CAAC,GAAG;AACrC,YAAM,KAAK,QAAQ,OAAO,SAAS,WAAY,KAAiC,KAAK;AACrF,UAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GAAG;AAC3C,YAAI,IAAI,EAAE;AAAA,MACZ;AAAA,IACF;AACA,QAAI,CAAC,OAAO,OAAO,OAAQ;AAC3B,YAAQ;AAAA,EACV,SAAS,IAAI,OAAO;AAEpB,SAAO,MAAM,KAAK,GAAG;AACvB;",
4
+ "sourcesContent": ["import { createScopedApiHelpers } from '@open-mercato/shared/lib/api/scoped'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from 'kysely'\nimport type { CrudCtx } from '@open-mercato/shared/lib/crud/factory'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { QueryCustomFieldSource, QueryJoinEdge, QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { resolveSearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\n\nconst { withScopedPayload, parseScopedCommandInput } = createScopedApiHelpers({\n messages: {\n tenantRequired: { key: 'customers.errors.tenant_required', fallback: 'Tenant context is required' },\n organizationRequired: { key: 'customers.errors.organization_required', fallback: 'Organization context is required' },\n },\n})\n\nconst NO_MATCH_ID = '00000000-0000-0000-0000-000000000000'\n\ntype SearchTokenMatchInput = {\n ctx: CrudCtx\n entityType: string\n fields: string[]\n query: string\n}\n\ntype SearchTokenSource = {\n entityType: string\n fields: string[]\n mapToEntityIds?: {\n table: string\n sourceColumn?: string\n targetColumn: string\n tenantColumn?: string\n organizationColumn?: string\n }\n}\n\nasync function enrichSearchSourcesWithCustomFieldTokens(\n ctx: CrudCtx,\n sources: SearchTokenSource[],\n): Promise<SearchTokenSource[]> {\n const entityTypes = Array.from(\n new Set(\n sources\n .map((source) => source.entityType)\n .filter((value): value is string => typeof value === 'string' && value.length > 0),\n ),\n )\n if (!entityTypes.length) return sources\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n let defsQuery = db\n .selectFrom('custom_field_defs')\n .select(['entity_id', 'key', 'kind'])\n .where('entity_id', 'in', entityTypes)\n .where('is_active', '=', true)\n\n const tenantScope = ctx.auth?.tenantId ?? null\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('tenant_id', '=', tenantScope),\n eb('tenant_id', 'is', null),\n ]))\n\n if (ctx.selectedOrganizationId) {\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('organization_id', '=', ctx.selectedOrganizationId),\n eb('organization_id', 'is', null),\n ]))\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n defsQuery = defsQuery.where((eb: any) => eb.or([\n eb('organization_id', 'in', ctx.organizationIds),\n eb('organization_id', 'is', null),\n ]))\n }\n\n const customFieldKeysByEntity = new Map<string, Set<string>>()\n const rows = await defsQuery.execute()\n for (const row of rows as Array<{ entity_id?: unknown; key?: unknown; kind?: unknown }>) {\n if (row.kind === 'attachment') continue\n const entityType = typeof row.entity_id === 'string' ? row.entity_id : null\n const key = typeof row.key === 'string' ? row.key.trim() : ''\n if (!entityType || !key) continue\n const bucket = customFieldKeysByEntity.get(entityType) ?? new Set<string>()\n bucket.add(`cf:${key}`)\n customFieldKeysByEntity.set(entityType, bucket)\n }\n\n return sources.map((source) => {\n const customFieldKeys = customFieldKeysByEntity.get(source.entityType)\n return {\n ...source,\n fields: Array.from(new Set([\n 'search_text',\n ...source.fields,\n ...(customFieldKeys ? Array.from(customFieldKeys) : []),\n ])),\n }\n })\n}\n\nasync function findSearchTokenEntityIds({\n ctx,\n entityType,\n fields,\n query,\n}: SearchTokenMatchInput): Promise<string[] | null> {\n const trimmed = query.trim()\n if (!trimmed) return null\n\n const tokens = tokenizeText(trimmed, resolveSearchConfig())\n if (!tokens.hashes.length) return []\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n let searchQuery = db\n .selectFrom('search_tokens')\n .select('entity_id')\n .where('entity_type', '=', entityType)\n .where('field', 'in', fields)\n .where('token_hash', 'in', tokens.hashes)\n .groupBy('entity_id')\n .having(sql<boolean>`count(distinct token_hash) >= ${tokens.hashes.length}`)\n\n if (ctx.auth?.tenantId !== undefined) {\n searchQuery = searchQuery.where(sql<boolean>`tenant_id is not distinct from ${ctx.auth?.tenantId ?? null}`)\n }\n if (ctx.selectedOrganizationId) {\n searchQuery = searchQuery.where('organization_id', '=', ctx.selectedOrganizationId)\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n searchQuery = searchQuery.where('organization_id', 'in', ctx.organizationIds)\n }\n\n const rows = await searchQuery.execute() as Array<{ entity_id?: unknown }>\n return rows\n .map((row) => (typeof row.entity_id === 'string' ? row.entity_id : null))\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n}\n\nasync function mapScopedEntityIds({\n ctx,\n ids,\n config,\n}: {\n ctx: CrudCtx\n ids: string[]\n config: NonNullable<SearchTokenSource['mapToEntityIds']>\n}): Promise<string[]> {\n if (!ids.length) return []\n\n const em = ctx.container.resolve('em') as EntityManager\n const db = em.getKysely<any>() as any\n const sourceColumn = config.sourceColumn ?? 'id'\n const tenantColumn = config.tenantColumn ?? 'tenant_id'\n const organizationColumn = config.organizationColumn ?? 'organization_id'\n\n let mapQuery = db\n .selectFrom(config.table)\n .select(config.targetColumn)\n .where(sourceColumn, 'in', ids)\n\n if (ctx.auth?.tenantId !== undefined) {\n mapQuery = mapQuery.where(sql<boolean>`${sql.ref(tenantColumn)} is not distinct from ${ctx.auth?.tenantId ?? null}`)\n }\n if (ctx.selectedOrganizationId) {\n mapQuery = mapQuery.where(organizationColumn, '=', ctx.selectedOrganizationId)\n } else if (Array.isArray(ctx.organizationIds) && ctx.organizationIds.length > 0) {\n mapQuery = mapQuery.where(organizationColumn, 'in', ctx.organizationIds)\n }\n\n const rows = await mapQuery.execute() as Array<Record<string, unknown>>\n return rows\n .map((row) => {\n const value = row[config.targetColumn]\n return typeof value === 'string' ? value : null\n })\n .filter((id): id is string => typeof id === 'string' && id.length > 0)\n}\n\nexport async function findMatchingEntityIdsBySearchTokensAcrossSources({\n ctx,\n sources,\n query,\n}: {\n ctx: CrudCtx\n sources: SearchTokenSource[]\n query: string\n}): Promise<string[] | null> {\n const trimmed = query.trim()\n if (!trimmed) return null\n\n const enrichedSources = await enrichSearchSourcesWithCustomFieldTokens(ctx, sources)\n const matchedIds = new Set<string>()\n for (const source of enrichedSources) {\n const rawIds = await findSearchTokenEntityIds({\n ctx,\n entityType: source.entityType,\n fields: source.fields,\n query: trimmed,\n })\n if (rawIds === null) return null\n const entityIds = source.mapToEntityIds\n ? await mapScopedEntityIds({ ctx, ids: rawIds, config: source.mapToEntityIds })\n : rawIds\n entityIds.forEach((id) => matchedIds.add(id))\n }\n\n return Array.from(matchedIds)\n}\n\nexport async function findMatchingEntityIdsBySearchTokens({\n ctx,\n entityType,\n fields,\n query,\n}: SearchTokenMatchInput): Promise<string[] | null> {\n return findMatchingEntityIdsBySearchTokensAcrossSources({\n ctx,\n query,\n sources: [{ entityType, fields }],\n })\n}\n\nexport function applyEntityIdRestriction(\n filters: Record<string, unknown>,\n ids: string[] | null,\n): void {\n if (ids === null) return\n const currentIdFilter =\n filters.id && typeof filters.id === 'object' && !Array.isArray(filters.id)\n ? (filters.id as { $eq?: unknown; $in?: unknown })\n : null\n const currentEq = typeof currentIdFilter?.$eq === 'string' ? currentIdFilter.$eq : null\n\n if (currentEq) {\n filters.id = ids.includes(currentEq) ? { $eq: currentEq } : { $eq: NO_MATCH_ID }\n return\n }\n\n filters.id = ids.length > 0 ? { $in: ids } : { $eq: NO_MATCH_ID }\n}\n\nexport function applyEntityIdExclusion(\n filters: Record<string, unknown>,\n ids: string[],\n): void {\n const uniqueIds = Array.from(new Set(ids.filter((id) => typeof id === 'string' && id.length > 0)))\n if (!uniqueIds.length) return\n\n const currentIdFilter =\n filters.id && typeof filters.id === 'object' && !Array.isArray(filters.id)\n ? (filters.id as { $eq?: unknown; $in?: unknown; $nin?: unknown })\n : null\n const currentEq = typeof currentIdFilter?.$eq === 'string' ? currentIdFilter.$eq : null\n const currentIn = Array.isArray(currentIdFilter?.$in)\n ? currentIdFilter.$in.filter((value): value is string => typeof value === 'string' && value.length > 0)\n : null\n const currentNotIn = Array.isArray(currentIdFilter?.$nin)\n ? currentIdFilter.$nin.filter((value): value is string => typeof value === 'string' && value.length > 0)\n : []\n\n if (currentEq) {\n filters.id = uniqueIds.includes(currentEq) ? { $eq: NO_MATCH_ID } : { $eq: currentEq }\n return\n }\n\n if (currentIn) {\n const nextIds = currentIn.filter((id) => !uniqueIds.includes(id))\n filters.id = nextIds.length > 0 ? { $in: nextIds } : { $eq: NO_MATCH_ID }\n return\n }\n\n filters.id = {\n ...(currentIdFilter ?? {}),\n $nin: Array.from(new Set([...currentNotIn, ...uniqueIds])),\n }\n}\n\nexport async function findMatchingEntityIdsWithQueryEngine({\n ctx,\n entityId,\n filters,\n customFieldSources,\n joins,\n}: {\n ctx: CrudCtx\n entityId: EntityId\n filters: Record<string, unknown>\n customFieldSources?: QueryCustomFieldSource[]\n joins?: QueryJoinEdge[]\n}): Promise<string[]> {\n const qe = ctx.container.resolve('queryEngine') as QueryEngine\n const ids = new Set<string>()\n const pageSize = 100\n let page = 1\n let total = 0\n\n do {\n const result = await qe.query(entityId, {\n fields: ['id'],\n filters,\n page: { page, pageSize },\n sort: [{ field: 'id', dir: SortDir.Asc }],\n tenantId: ctx.auth?.tenantId ?? undefined,\n organizationId: ctx.selectedOrganizationId ?? undefined,\n organizationIds: ctx.organizationIds ?? undefined,\n customFieldSources,\n joins,\n })\n\n total = result.total ?? 0\n for (const item of result.items ?? []) {\n const id = item && typeof item === 'object' ? (item as Record<string, unknown>).id : null\n if (typeof id === 'string' && id.length > 0) {\n ids.add(id)\n }\n }\n if (!result.items?.length) break\n page += 1\n } while (ids.size < total)\n\n return Array.from(ids)\n}\n\nexport { withScopedPayload, parseScopedCommandInput }\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }