@open-mercato/cli 0.10.1-develop.7803.1.e99e862b4e → 0.10.1-develop.7807.1.9b2b8953e9

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 (93) hide show
  1. package/dist/agentic/guides/module-facts.json +162 -162
  2. package/dist/agentic/guides/module-facts.v2.json +162 -162
  3. package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
  4. package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
  5. package/dist/agentic/guides/modules/api_docs/index.md +1 -1
  6. package/dist/agentic/guides/modules/api_keys/index.md +1 -1
  7. package/dist/agentic/guides/modules/attachments/index.md +1 -1
  8. package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
  9. package/dist/agentic/guides/modules/auth/index.md +1 -1
  10. package/dist/agentic/guides/modules/availability/index.md +1 -1
  11. package/dist/agentic/guides/modules/business_rules/index.md +1 -1
  12. package/dist/agentic/guides/modules/carrier_inpost/index.md +1 -1
  13. package/dist/agentic/guides/modules/cart/index.md +1 -1
  14. package/dist/agentic/guides/modules/catalog/index.md +1 -1
  15. package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
  16. package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
  17. package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
  18. package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
  19. package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
  20. package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
  21. package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
  22. package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
  23. package/dist/agentic/guides/modules/channel_smtp/index.md +1 -1
  24. package/dist/agentic/guides/modules/checkout/index.md +1 -1
  25. package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
  26. package/dist/agentic/guides/modules/configs/index.md +1 -1
  27. package/dist/agentic/guides/modules/content/index.md +1 -1
  28. package/dist/agentic/guides/modules/currencies/index.md +1 -1
  29. package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
  30. package/dist/agentic/guides/modules/customer_groups/index.md +1 -1
  31. package/dist/agentic/guides/modules/customers/index.md +1 -1
  32. package/dist/agentic/guides/modules/dashboards/index.md +1 -1
  33. package/dist/agentic/guides/modules/data_sync/index.md +1 -1
  34. package/dist/agentic/guides/modules/design_system/index.md +1 -1
  35. package/dist/agentic/guides/modules/devices/index.md +1 -1
  36. package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
  37. package/dist/agentic/guides/modules/directory/index.md +1 -1
  38. package/dist/agentic/guides/modules/documents/index.md +1 -1
  39. package/dist/agentic/guides/modules/ecommerce/index.md +1 -1
  40. package/dist/agentic/guides/modules/entities/index.md +1 -1
  41. package/dist/agentic/guides/modules/eudr/index.md +1 -1
  42. package/dist/agentic/guides/modules/events/index.md +1 -1
  43. package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
  44. package/dist/agentic/guides/modules/forms/index.md +1 -1
  45. package/dist/agentic/guides/modules/gateway_autopay/index.md +1 -1
  46. package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
  47. package/dist/agentic/guides/modules/gateway_tpay/index.md +1 -1
  48. package/dist/agentic/guides/modules/generators/index.md +1 -1
  49. package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
  50. package/dist/agentic/guides/modules/integrations/index.md +1 -1
  51. package/dist/agentic/guides/modules/messages/index.md +1 -1
  52. package/dist/agentic/guides/modules/notifications/index.md +1 -1
  53. package/dist/agentic/guides/modules/onboarding/index.md +1 -1
  54. package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
  55. package/dist/agentic/guides/modules/perspectives/index.md +1 -1
  56. package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
  57. package/dist/agentic/guides/modules/planner/index.md +1 -1
  58. package/dist/agentic/guides/modules/portal/index.md +1 -1
  59. package/dist/agentic/guides/modules/progress/index.md +1 -1
  60. package/dist/agentic/guides/modules/promotions/index.md +1 -1
  61. package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
  62. package/dist/agentic/guides/modules/query_index/index.md +1 -1
  63. package/dist/agentic/guides/modules/record_locks/index.md +1 -1
  64. package/dist/agentic/guides/modules/resources/index.md +1 -1
  65. package/dist/agentic/guides/modules/sales/index.md +1 -1
  66. package/dist/agentic/guides/modules/scheduler/index.md +1 -1
  67. package/dist/agentic/guides/modules/search/index.md +1 -1
  68. package/dist/agentic/guides/modules/security/index.md +1 -1
  69. package/dist/agentic/guides/modules/seeds/index.md +1 -1
  70. package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
  71. package/dist/agentic/guides/modules/sso/index.md +1 -1
  72. package/dist/agentic/guides/modules/staff/index.md +1 -1
  73. package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
  74. package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
  75. package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
  76. package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
  77. package/dist/agentic/guides/modules/telemetry/index.md +1 -1
  78. package/dist/agentic/guides/modules/tillio/index.md +1 -1
  79. package/dist/agentic/guides/modules/translations/index.md +1 -1
  80. package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
  81. package/dist/agentic/guides/modules/webhooks/index.md +1 -1
  82. package/dist/agentic/guides/modules/wms/index.md +1 -1
  83. package/dist/agentic/guides/modules/workflows/index.md +1 -1
  84. package/dist/agentic/guides/reference-module-facts.json +1 -1
  85. package/dist/agentic/guides/upstream/manifest.json +1 -1
  86. package/dist/lib/module-search-index.js +7 -3
  87. package/dist/lib/module-search-index.js.map +2 -2
  88. package/dist/lib/module-search.js +62 -3
  89. package/dist/lib/module-search.js.map +2 -2
  90. package/package.json +7 -7
  91. package/src/lib/__tests__/module-search.test.ts +111 -0
  92. package/src/lib/module-search-index.ts +7 -3
  93. package/src/lib/module-search.ts +65 -4
@@ -1,5 +1,5 @@
1
1
  # staff — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/staff
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # storage_s3 — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/storage-s3 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/storage-s3 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/storage-s3/src/modules/storage_s3
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # sync_akeneo — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/sync-akeneo 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/sync-akeneo 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/sync-akeneo/src/modules/sync_akeneo
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # sync_excel — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/sync_excel
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # system_status_overlays — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/enterprise 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/enterprise 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/enterprise/src/modules/system_status_overlays
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # telemetry — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/telemetry 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/telemetry 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/telemetry/src/modules/telemetry
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # tillio — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/tillio 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/tillio 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/tillio/src/modules/tillio
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # translations — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/translations
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # warranty_claims — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/warranty_claims
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # webhooks — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/webhooks 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/webhooks 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/webhooks/src/modules/webhooks
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # wms — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/wms
4
4
 
5
5
  ## Sections
@@ -1,5 +1,5 @@
1
1
  # workflows — module facts (generated, do not edit)
2
- <!-- generated from @open-mercato/core 0.10.1-develop.7803.1.e99e862b4e; core 0.10.1-develop.7803.1.e99e862b4e — R1 staleness stamp -->
2
+ <!-- generated from @open-mercato/core 0.10.1-develop.7807.1.9b2b8953e9; core 0.10.1-develop.7807.1.9b2b8953e9 — R1 staleness stamp -->
3
3
  Source root: node_modules/@open-mercato/core/src/modules/workflows
4
4
 
5
5
  ## Sections
@@ -1185,7 +1185,7 @@
1185
1185
  "facts": {
1186
1186
  "title": "Example Module",
1187
1187
  "description": "Demonstrates pages, APIs, entities and DI.",
1188
- "coreVersion": "0.10.1-develop.7803.1.e99e862b4e",
1188
+ "coreVersion": "0.10.1-develop.7807.1.9b2b8953e9",
1189
1189
  "sourcePackage": null,
1190
1190
  "sourceVersion": null,
1191
1191
  "sourceRoot": "src/modules/example",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generator": "@open-mercato/cli@0.10.1-develop.7803.1.e99e862b4e",
3
+ "generator": "@open-mercato/cli@0.10.1-develop.7807.1.9b2b8953e9",
4
4
  "files": {
5
5
  "AGENTS.md": "b27342ee5f61e805ba52703fdb7ec822b030490f734b4d80f48dfd1e05fa4cf5",
6
6
  "BACKWARD_COMPATIBILITY.md": "e4b53767506d7ff4628c6cc7e38956792b32eb606749f8f4ba3f67dd2c9e86da"
@@ -173,7 +173,7 @@ const absolute = (site, page) => /^https?:\/\//.test(page) ? page : `${site}${pa
173
173
  function latestLine(lines) {
174
174
  return lines.find((line) => line.source === "latest") ?? null;
175
175
  }
176
- const SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
176
+ const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
177
177
  function resolveLine(omVersion, lines) {
178
178
  const found = (line2) => line2 ? { line: line2.key, version: line2.version, note: null } : { line: null, version: null, note: null };
179
179
  const raw = (omVersion ?? "").trim();
@@ -181,14 +181,18 @@ function resolveLine(omVersion, lines) {
181
181
  const byKey = lines.find((line2) => line2.key === raw);
182
182
  if (byKey) return found(byKey);
183
183
  const version = raw.replace(/^(?:v|=|\^|~|>=)\s*/, "");
184
+ const semver = SEMVER.exec(version);
185
+ const lineKey = /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
186
+ if (!semver && !lineKey || semver?.[4]?.split(".").some((part) => /^0\d+$/.test(part))) {
187
+ return { line: null, version: null, note: "Unknown Open Mercato version." };
188
+ }
184
189
  const exact = lines.find((line2) => line2.version === version);
185
190
  if (exact) return found(exact);
186
- const semver = SEMVER.exec(version);
187
191
  if (semver && semver[4] && /(^|[.-])develop([.-]|$)/.test(semver[4])) {
188
192
  const next = lines.find((line2) => line2.source === "develop");
189
193
  if (next) return found(next);
190
194
  }
191
- const majorMinor = /^(\d+)\.(\d+)(?:\.\d+)?(?:-[0-9A-Za-z.-]+)?$/.exec(version);
195
+ const majorMinor = semver ?? lineKey;
192
196
  if (!majorMinor) return { line: null, version: null, note: "Unknown Open Mercato version." };
193
197
  const key = `${Number(majorMinor[1])}.${Number(majorMinor[2])}`;
194
198
  const line = lines.find((candidate) => candidate.key === key);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/module-search-index.ts"],
4
- "sourcesContent": ["// Ranking and lookups behind `mercato module search|info`, kept identical to the Open Mercato Modules catalog\n// (https://modules.openmercato.com, `lib/core/search.ts` and `lib/core/refs.ts`): same MiniSearch options, tokenizer,\n// stop words, boosts and built-in rules, so the CLI, the catalog site and its MCP server rank the same way.\n// `__tests__/module-search.test.ts` holds this file to the catalog's own output on a fixture built from real data.\nimport MiniSearch, { type Options, type SearchResult } from 'minisearch'\nimport { satisfies } from 'semver'\n\nexport type CellStatus = string\nexport type OriginType = 'official' | 'community' | '3rd-party'\nexport type EntryKind = 'module' | 'provider' | 'library' | 'tool'\nexport type LicenseKind = 'osi' | 'proprietary' | 'enterprise' | 'unknown'\nexport type ReceiptSource = 'ci' | 'preview'\n\nexport type AgentPolicy = {\n decision: 'allow' | 'ask' | 'refuse'\n reasons: { code: string; text: string }[]\n until?: string\n consentText?: string\n}\n\nexport type CatalogLine = {\n key: string\n version: string\n source: 'latest' | 'previous' | 'develop'\n}\n\nexport type AnatomyLists = {\n aclFeatures?: string[]\n eventsEmitted?: string[]\n eventsConsumed?: string[]\n env?: string[]\n hosts?: string[]\n tables?: string[]\n publicRoutes?: string[]\n credentials?: { key: string; type?: string; required?: boolean }[]\n}\n\nexport type AnatomySummary = {\n version: string\n counts?: Record<string, number | null>\n lists?: AnatomyLists\n callout?: string | null\n}\n\nexport type CellSummary = { status: CellStatus; at: string | null; moduleVersion?: string | null }\n\nexport type BuiltFor = { range: string | null; kind: string; lines: string[]; ranges?: Record<string, string> }\n\nexport type CatalogEntry = {\n locator: string\n path: string\n npm: string | null\n title: string\n summary: string\n whenToUse: string\n type: OriginType\n kind: EntryKind\n category: string\n tags: string[]\n providers: { name: string; label: string }[]\n moduleIds: string[]\n /** What the package needs; an adapter's catalog libraries among them join its `yarn add` (`peerLibrarySpecs`). */\n requires?: { raw: string; resolvesTo?: string | null }[]\n renamedFrom: string[]\n status: string\n listed: boolean\n featured: boolean\n license: { spdx: string | null; kind: LicenseKind; mismatch?: boolean }\n version: {\n latest: string | null\n preview: string | null\n installableFrom: string | null\n gitRef: string | null\n recommended: Record<string, string | null>\n }\n compat: {\n lines: Record<string, CellSummary>\n verifiedOn: string[]\n builtFor?: BuiltFor\n inPresets?: string[]\n inEmptyPreset?: string[]\n ships?: Record<string, string>\n isolation?: Record<string, { status: CellStatus; moduleVersion: string | null }>\n }\n anatomy: AnatomySummary | null\n signals?: {\n supplyChain?: { status: string; reasons: string[] }\n hygiene?: { status: string; failing: string[] }\n anatomy?: string\n }\n tier: 'listed' | 'verified' | null\n quality: unknown\n agentPolicy: Record<string, AgentPolicy>\n install: { cli: string; cmm?: string; needsAllowThirdParty?: boolean; moduleFlag: string | null }\n links: { page: string; md: string; json?: string; npm?: string | null; repo?: string | null }\n _meta?: Record<string, unknown>\n}\n\nexport type CatalogIndex = {\n schemaVersion: 1\n generatedAt: string\n dataVersion: string\n site: string\n lines: CatalogLine[]\n entries: CatalogEntry[]\n dataAsOf?: { source?: ReceiptSource | null }\n builtIn?: { coreVersion: string; count: number; href: string }\n}\n\nexport type BuiltInModule = {\n id: string\n title: string\n description: string\n category: string\n requires?: string[]\n inPresets?: string[]\n inEmptyPreset?: string[]\n anatomy: AnatomySummary | null\n install: string\n page: string\n}\n\nexport type BuiltInIndex = {\n schemaVersion: 1\n coreVersion: string\n generatedAt: string\n modules: BuiltInModule[]\n}\n\nexport type ModuleCard = {\n locator: string\n path: string\n title: string\n summary: string\n whenToUse: string\n type: OriginType\n kind: EntryKind\n category: string\n license: { spdx: string | null; kind: LicenseKind }\n tier: 'listed' | 'verified' | null\n omQuality: boolean\n verifiedOn: string[]\n line: string | null\n status: CellStatus | null\n agentPolicy: AgentPolicy | null\n installableFrom: string | null\n install: string\n matchedOn: string[]\n card: string\n presetNote?: string\n installEmptyPreset?: string | null\n}\n\nexport type BuiltInCard = {\n id: string\n title: string\n description: string\n category: string\n enabled: boolean | null\n install: string\n page: string\n matchedOn: string[]\n presetNote: string | null\n}\n\nexport type SearchModulesInput = {\n query?: string\n omVersion?: string\n category?: string\n type?: OriginType[]\n kind?: (EntryKind | 'built-in')[]\n verifiedOnly?: boolean\n verifiedModulesOnly?: boolean\n includeBuiltIn?: boolean\n includeExamples?: boolean\n emits?: string\n consumes?: string\n provider?: string\n limit?: number\n}\n\nexport type SearchModulesOutput = {\n results: ModuleCard[]\n builtIn: BuiltInCard[]\n total: number\n line: string | null\n dataVersion: string\n generatedAt: string\n receiptSource?: ReceiptSource | null\n didYouMean?: string\n}\n\nexport const SEARCH_BOOST = {\n title: 3,\n npm: 3,\n summary: 2,\n whenToUse: 2,\n providers: 2,\n tags: 1.5,\n aliases: 1.5,\n renamedFrom: 1,\n category: 1,\n anatomy: 1,\n} as const\ntype SearchField = keyof typeof SEARCH_BOOST\nconst SEARCH_FIELDS = Object.keys(SEARCH_BOOST) as SearchField[]\n\nexport const ALIASES_META_KEY = 'com.openmercato.modules/aliases'\nexport const INSTALLABLE_META_KEY = 'com.openmercato.modules/installable'\nexport const BUILTIN_MAX = 5\nexport const BUILTIN_RATIO = 0.5\nexport const BOOST_VERIFIED = 0.15\nexport const BOOST_OFFICIAL = 0.1\nexport const MIN_AND_RESULTS = 3\n/** An OR hit that matched no query word as typed and scores below this share of the best hit is dropped. */\nexport const WEAK_HIT_RATIO = 0.2\nexport const SEARCH_MAX_LIMIT = 20\nexport const SEARCH_DEFAULTS = { verifiedOnly: false, includeBuiltIn: true, includeExamples: false, limit: 10 } as const\nexport const CORE_PACKAGE = '@open-mercato/core'\nexport const ENTERPRISE_PACKAGE = '@open-mercato/enterprise'\nexport const ENTERPRISE_ENABLE_STEP = 'echo OM_ENABLE_ENTERPRISE_MODULES=true >> .env'\nexport const PREVIEW_LINE =\n \"Receipts: Preview run in Docker on the maintainer's machine, not CI. The first nightly CI run replaces it.\"\nconst VERDICT_STATES: ReadonlySet<CellStatus> = new Set(['verified', 'broken', 'harness-red', 'infra-error'])\n\nconst STOPWORDS = new Set([\n 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from', 'i', 'in', 'into', 'is', 'it', 'its', 'me',\n 'module', 'modules', 'my', 'of', 'on', 'or', 'our', 'that', 'the', 'this', 'to', 'via', 'we', 'with', 'you', 'your',\n 'can', 'do', 'does', 'how', 'need', 'needs', 'use', 'used', 'uses', 'want', 'wants', 'what', 'when', 'which',\n])\n\nexport function tokenize(text: string): string[] {\n const lower = text.toLowerCase()\n const tokens = lower.split(/[^a-z0-9*]+/).filter((token) => token !== '')\n for (const match of lower.matchAll(/[a-z0-9]+(?:[._-][a-z0-9*]+)+/g)) tokens.push(match[0])\n return tokens\n}\n\nexport function processTerm(term: string): string | null {\n return term.length < 2 || STOPWORDS.has(term) ? null : term\n}\n\nexport type SearchDoc = {\n id: string\n group: 'module' | 'builtin'\n title: string\n npm: string\n summary: string\n whenToUse: string\n providers: string\n tags: string\n aliases: string\n renamedFrom: string\n category: string\n anatomy: string\n}\n\nconst SEARCH_OPTIONS: Options<SearchDoc> = {\n idField: 'id',\n fields: SEARCH_FIELDS,\n storeFields: ['group'],\n tokenize,\n processTerm,\n searchOptions: { prefix: true, fuzzy: 0.2, boost: { ...SEARCH_BOOST } },\n}\n\nexport type AnatomyIds = {\n event: string[]\n emits: string[]\n consumes: string[]\n entity: string[]\n permission: string[]\n env: string[]\n host: string[]\n setting: string[]\n module: string[]\n}\n\nexport type ModuleMeta = {\n entry: CatalogEntry\n example: boolean\n omQuality: boolean\n ids: AnatomyIds\n}\n\nexport type BuiltInMeta = {\n module: BuiltInModule\n ids: AnatomyIds\n}\n\nexport type CatalogSearcher = {\n miniSearch: MiniSearch<SearchDoc>\n index: CatalogIndex\n builtIn: BuiltInIndex | null\n site: string\n modules: Map<string, ModuleMeta>\n builtInModules: Map<string, BuiltInMeta>\n}\n\nfunction anatomyIds(anatomy: AnatomySummary | null | undefined, moduleIds: readonly string[]): AnatomyIds {\n const lists = anatomy?.lists\n return {\n event: [...new Set([...(lists?.eventsEmitted ?? []), ...(lists?.eventsConsumed ?? [])])],\n emits: [...(lists?.eventsEmitted ?? [])],\n consumes: [...(lists?.eventsConsumed ?? [])],\n entity: lists?.tables ?? [],\n permission: lists?.aclFeatures ?? [],\n env: lists?.env ?? [],\n host: lists?.hosts ?? [],\n setting: (lists?.credentials ?? []).map((credential) => credential.key),\n module: [...moduleIds],\n }\n}\n\nconst anatomyText = (ids: AnatomyIds) =>\n [...ids.module, ...ids.entity, ...ids.event, ...ids.permission, ...ids.setting, ...ids.env, ...ids.host].join(' ')\n\nfunction aliasesOf(entry: CatalogEntry): string[] {\n const value = entry._meta?.[ALIASES_META_KEY]\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []\n}\n\nfunction moduleDoc(entry: CatalogEntry, ids: AnatomyIds): SearchDoc {\n return {\n id: entry.locator,\n group: 'module',\n title: entry.title,\n npm: [entry.npm ?? entry.locator.replace(/^github:/, ''), entry.path].join(' '),\n summary: entry.summary,\n whenToUse: entry.whenToUse,\n providers: entry.providers.map((provider) => `${provider.name} ${provider.label}`).join(' '),\n tags: entry.tags.join(' '),\n aliases: aliasesOf(entry).join(' '),\n renamedFrom: entry.renamedFrom.map((locator) => locator.replace(/^(npm|github):/, '')).join(' '),\n category: entry.category,\n anatomy: anatomyText(ids),\n }\n}\n\nfunction builtInDoc(coreModule: BuiltInModule, ids: AnatomyIds): SearchDoc {\n return {\n id: `core:${coreModule.id}`,\n group: 'builtin',\n title: coreModule.title,\n npm: coreModule.id,\n summary: coreModule.description,\n whenToUse: '',\n providers: '',\n tags: '',\n aliases: '',\n renamedFrom: '',\n category: coreModule.category,\n anatomy: anatomyText(ids),\n }\n}\n\nexport function createCatalogSearcher(index: CatalogIndex, builtIn: BuiltInIndex | null): CatalogSearcher {\n const miniSearch = new MiniSearch<SearchDoc>(SEARCH_OPTIONS)\n const modules = new Map<string, ModuleMeta>()\n const builtInModules = new Map<string, BuiltInMeta>()\n const docs: SearchDoc[] = []\n for (const entry of index.entries.filter((candidate) => candidate.listed)) {\n const ids = anatomyIds(entry.anatomy, entry.moduleIds)\n modules.set(entry.locator, {\n entry,\n ids,\n example: entry.tags.includes('example'),\n omQuality: entry.quality !== null && entry.quality !== undefined,\n })\n docs.push(moduleDoc(entry, ids))\n }\n for (const coreModule of builtIn?.modules ?? []) {\n const ids = anatomyIds(coreModule.anatomy, [coreModule.id])\n builtInModules.set(coreModule.id, { module: coreModule, ids })\n docs.push(builtInDoc(coreModule, ids))\n }\n miniSearch.addAll(docs)\n const loaded = MiniSearch.loadJS<SearchDoc>(miniSearch.toJSON(), SEARCH_OPTIONS)\n return { miniSearch: loaded, index, builtIn, site: index.site.replace(/\\/+$/, ''), modules, builtInModules }\n}\n\nconst absolute = (site: string, page: string) => (/^https?:\\/\\//.test(page) ? page : `${site}${page}`)\n\nexport function latestLine(lines: readonly CatalogLine[]): CatalogLine | null {\n return lines.find((line) => line.source === 'latest') ?? null\n}\n\nconst SEMVER = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/\n\nexport function resolveLine(\n omVersion: string | null | undefined,\n lines: readonly CatalogLine[],\n): { line: string | null; version: string | null; note: string | null } {\n const found = (line: CatalogLine | null) =>\n line ? { line: line.key, version: line.version, note: null } : { line: null, version: null, note: null }\n const raw = (omVersion ?? '').trim()\n if (raw === '') return found(latestLine(lines))\n const byKey = lines.find((line) => line.key === raw)\n if (byKey) return found(byKey)\n const version = raw.replace(/^(?:v|=|\\^|~|>=)\\s*/, '')\n const exact = lines.find((line) => line.version === version)\n if (exact) return found(exact)\n const semver = SEMVER.exec(version)\n if (semver && semver[4] && /(^|[.-])develop([.-]|$)/.test(semver[4])) {\n const next = lines.find((line) => line.source === 'develop')\n if (next) return found(next)\n }\n const majorMinor = /^(\\d+)\\.(\\d+)(?:\\.\\d+)?(?:-[0-9A-Za-z.-]+)?$/.exec(version)\n if (!majorMinor) return { line: null, version: null, note: 'Unknown Open Mercato version.' }\n const key = `${Number(majorMinor[1])}.${Number(majorMinor[2])}`\n const line = lines.find((candidate) => candidate.key === key)\n if (line) return found(line)\n return { line: null, version: null, note: `Line ${key} is not tested by the catalog.` }\n}\n\nfunction matchedOn(\n match: SearchResult['match'],\n meta: { providers?: readonly { name: string; label: string }[]; tags?: readonly string[]; ids: AnatomyIds; category?: string },\n queryTerms: readonly string[] = [],\n): string[] {\n const chips: string[] = []\n const add = (chip: string) => {\n if (!chips.includes(chip)) chips.push(chip)\n }\n const has = (id: string, term: string) => tokenize(id).includes(term)\n const order: SearchField[] = ['title', 'npm', 'aliases', 'renamedFrom', 'providers', 'anatomy', 'summary', 'whenToUse', 'tags', 'category']\n const typed = new Set(queryTerms)\n const fieldsByTerm = Object.entries(match).sort(\n (left, right) => Number(typed.has(right[0])) - Number(typed.has(left[0])) || right[0].length - left[0].length,\n )\n for (const field of order) {\n for (const [term, fields] of fieldsByTerm) {\n if (!fields.includes(field)) continue\n if (field === 'title' || field === 'npm' || field === 'aliases' || field === 'renamedFrom') add('name')\n else if (field === 'summary' || field === 'whenToUse') add('summary')\n else if (field === 'tags') {\n const tag = meta.tags?.find((candidate) => has(candidate, term))\n add(tag ? `tag ${tag}` : 'summary')\n } else if (field === 'category' && meta.category) add(`category ${meta.category}`)\n else if (field === 'providers') {\n const provider = meta.providers?.find((candidate) => has(candidate.name, term) || has(candidate.label, term))\n add(provider ? `provider ${provider.label}` : 'provider')\n } else if (field === 'anatomy') anatomyChips(meta.ids, fieldsByTerm, has).forEach(add)\n }\n }\n return chips.slice(0, 5)\n}\n\nfunction anatomyChips(\n ids: AnatomyIds,\n fieldsByTerm: readonly (readonly [string, readonly string[]])[],\n has: (id: string, term: string) => boolean,\n): string[] {\n const kinds: (keyof AnatomyIds)[] = ['event', 'entity', 'permission', 'env', 'setting', 'host', 'module']\n const terms = fieldsByTerm.filter(([, fields]) => fields.includes('anatomy')).map(([term]) => term)\n const left = new Set(terms)\n const chips: string[] = []\n while (left.size > 0) {\n let best: { chip: string; covers: string[]; exact: boolean; first: number } | null = null\n for (const kind of kinds)\n for (const id of ids[kind]) {\n const covers = terms.filter((term) => left.has(term) && (id === term || has(id, term)))\n if (covers.length === 0) continue\n const exact = covers.includes(id)\n const first = terms.indexOf(covers[0] as string)\n const better =\n !best ||\n covers.length > best.covers.length ||\n (covers.length === best.covers.length && (exact && !best.exact ? true : exact === best.exact && first < best.first))\n if (better) best = { chip: `${kind} ${id}`, covers, exact, first }\n }\n if (!best) break\n chips.push(best.chip)\n for (const term of best.covers) left.delete(term)\n }\n return chips\n}\n\nconst STABLE_VERSION = /^\\d+\\.\\d+\\.\\d+$/\n\nfunction satisfiesRange(version: string, range: string): boolean {\n try {\n return satisfies(version, range, { includePrerelease: true })\n } catch {\n return false\n }\n}\n\nexport function lineVersion(entry: CatalogEntry, line: string | null): string | null {\n return (line !== null ? entry.compat.ships?.[line] : undefined) ?? installVersion(entry, line)\n}\n\n/** A cell whose receipt judged another version than the one a fresh app gets on the line is no verdict on that line. */\nfunction judgedCell(entry: CatalogEntry, line: string): CellSummary | null {\n const cell = entry.compat.lines[line] ?? null\n if (!cell || cell.moduleVersion === null || cell.moduleVersion === undefined || !VERDICT_STATES.has(cell.status)) return cell\n const installs = lineVersion(entry, line)\n return installs === null || cell.moduleVersion === installs ? cell : null\n}\n\nexport function statusOn(entry: CatalogEntry, line: string): CellStatus {\n if (entry.version.recommended[line]) return 'verified'\n return judgedCell(entry, line)?.status ?? 'untested'\n}\n\nfunction installableOn(entry: CatalogEntry, line: string | null): string | null | undefined {\n if (line === null) return undefined\n const map = entry._meta?.[INSTALLABLE_META_KEY]\n if (!map || typeof map !== 'object') return undefined\n const value = (map as Record<string, unknown>)[line]\n return typeof value === 'string' ? value : value === null ? null : undefined\n}\n\nexport function installVersion(entry: CatalogEntry, line: string | null): string | null {\n return (\n (line !== null ? entry.version.recommended[line] : null) ??\n installableOn(entry, line) ??\n entry.version.latest ??\n entry.version.preview ??\n null\n )\n}\n\nfunction declaredRangeOf(entry: CatalogEntry, version: string): string | null {\n const builtFor = entry.compat.builtFor\n if (!builtFor || builtFor.kind === 'missing' || builtFor.kind === 'star') return null\n if (builtFor.ranges) {\n for (const [line, range] of Object.entries(builtFor.ranges)) if (lineVersion(entry, line) === version) return range\n return null\n }\n const lines = new Set([...Object.keys(entry.compat.lines), ...Object.keys(entry.compat.ships ?? {})])\n return [...lines].some((line) => lineVersion(entry, line) === version) ? builtFor.range : null\n}\n\n/**\n * The version an app from the empty preset installs: the one a new app ships where the install version broke in\n * isolation there, or where its declared peers reject the version that line ships.\n */\nexport function emptyPresetVersion(entry: CatalogEntry, line: string | null): string | null {\n const version = installVersion(entry, line)\n if (line === null || !version) return version\n const ships = entry.compat.ships?.[line]\n if (!ships || ships === version) return version\n const isolation = entry.compat.isolation?.[line]\n if (isolation?.moduleVersion === version) return isolation.status === 'broken' ? ships : version\n const range = declaredRangeOf(entry, version)\n return STABLE_VERSION.test(ships) && range !== null && !satisfiesRange(ships, range) ? ships : version\n}\n\nexport function builtInEnableCommand(id: string): string {\n return `yarn mercato module enable ${CORE_PACKAGE} --module ${id}`\n}\n\n/** A provider without a module of its own: an adapter `yarn add` adds and `yarn generate` registers. */\nexport const isAdapter = (entry: Pick<CatalogEntry, 'kind' | 'moduleIds'>): boolean =>\n entry.kind === 'provider' && entry.moduleIds.length === 0\n\n/** Finds a catalog entry by locator (`npm:<name>`). */\nexport type PeerLookup = (locator: string) => CatalogEntry | null | undefined\n\n/**\n * The catalog libraries an adapter peers on, as `name@version` for its `yarn add` (catalog `peerLibrarySpecs`). An\n * @open-mercato peer of an @open-mercato adapter comes from the same release and takes the adapter's version; any\n * other peer takes its own install version on the line. Empty for every other kind.\n */\nexport function peerLibrarySpecs(\n entry: CatalogEntry,\n version: string | null,\n line: string | null,\n find: PeerLookup | undefined,\n): string[] {\n if (!find || !entry.npm || !isAdapter(entry)) return []\n const specs: string[] = []\n for (const requirement of entry.requires ?? []) {\n const peer = requirement.resolvesTo?.startsWith('npm:') ? find(requirement.resolvesTo) : null\n if (!peer?.npm || peer.kind !== 'library' || peer.npm === entry.npm) continue\n const sameRelease = Boolean(version) && peer.npm.startsWith('@open-mercato/') && entry.npm.startsWith('@open-mercato/')\n const peerVersion = sameRelease ? version : installVersion(peer, line)\n const spec = peerVersion ? `${peer.npm}@${peerVersion}` : peer.npm\n if (!specs.includes(spec)) specs.push(spec)\n }\n return specs\n}\n\nfunction packageCommand(entry: CatalogEntry, spec: string, peers: readonly string[] = []): string | null {\n if (entry.kind === 'tool') return entry.tags.includes('cli') ? `npx ${spec}` : `yarn add ${spec}`\n if (isAdapter(entry)) return `yarn add ${[...peers, spec].join(' ')}`\n return entry.kind === 'library' ? `yarn add ${spec}` : null\n}\n\nfunction inPreset(entry: CatalogEntry, enabled: readonly { id: string; from: string }[] | null): boolean {\n if (!enabled || !entry.npm || entry.moduleIds.length === 0) return false\n return entry.moduleIds.every((id) => enabled.some((item) => item.id === id && item.from === entry.npm))\n}\n\nfunction installCli(\n entry: CatalogEntry,\n line: string | null,\n preset: readonly { id: string; from: string }[] | null,\n version: string | null = installVersion(entry, line),\n find?: PeerLookup,\n): string {\n if (entry.npm === null) {\n const repo = entry.locator.replace(/^github:/, '')\n const ref = entry.version.gitRef ? ` --ref ${entry.version.gitRef}` : ''\n return `npx create-mercato-module install ${repo}${ref}`\n }\n const spec = version ? `${entry.npm}@${version}` : entry.npm\n const own = packageCommand(entry, spec, peerLibrarySpecs(entry, version, line, find))\n if (own) return own\n if (inPreset(entry, preset)) return `yarn add ${spec}`\n const moduleFlag = entry.install.moduleFlag ?? null\n if (entry.npm === ENTERPRISE_PACKAGE && !moduleFlag) return `${ENTERPRISE_ENABLE_STEP} && yarn generate`\n const thirdParty = entry.npm.startsWith('@open-mercato/') ? '' : ' --allow-third-party'\n if (!moduleFlag && entry.moduleIds.length > 1) {\n return entry.moduleIds.map((id) => `yarn mercato module add ${spec}${thirdParty} --module ${id}`).join(' && ')\n }\n return `yarn mercato module add ${spec}${thirdParty}${moduleFlag ? ` --module ${moduleFlag}` : ''}`\n}\n\n/** The command of an app that does not register the package yet (an app from the empty preset) on a line. */\nexport function installCommand(\n entry: CatalogEntry,\n line: string | null,\n latest: string | null,\n find?: PeerLookup,\n): string {\n if (line === null || line === latest) return entry.install.cli\n const both = entry.npm !== null && (entry.compat.inEmptyPreset ?? []).includes(line)\n const version = (entry.compat.inPresets ?? []).includes(line)\n ? emptyPresetVersion(entry, line)\n : installVersion(entry, line)\n const npm = entry.npm\n return installCli(entry, line, both && npm ? entry.moduleIds.map((id) => ({ id, from: npm })) : null, version, find)\n}\n\nfunction listAnd(items: readonly string[]): string {\n return items.length <= 1 ? (items[0] ?? '') : `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n}\n\nconst EMPTY_PRESET_LEAD = 'In an app from the empty preset:'\n\nfunction presetInstallText(moduleIds: readonly string[]): string {\n return `Nothing to install: a new app already registers ${moduleIds.length ? listAnd(moduleIds) : 'it'} in src/modules.ts.`\n}\n\nexport function newAppInstallText(moduleIds: readonly string[], emptyCommand: string | null): string {\n return emptyCommand ? `${presetInstallText(moduleIds)} ${EMPTY_PRESET_LEAD} ${emptyCommand}` : presetInstallText(moduleIds)\n}\n\n/**\n * Where a new app (classic preset) of the line already registers the package, `install` is that sentence, `presetNote`\n * the whole install sentence and `installEmptyPreset` the command of an app from the empty preset (null when that\n * preset registers it too). Elsewhere `install` is the command.\n */\nexport function installFields(\n entry: CatalogEntry,\n line: string | null,\n latest: string | null,\n find?: PeerLookup,\n): Pick<ModuleCard, 'install' | 'presetNote' | 'installEmptyPreset'> {\n const command = installCommand(entry, line, latest, find)\n if (line === null || !(entry.compat.inPresets ?? []).includes(line)) return { install: command }\n const empty = (entry.compat.inEmptyPreset ?? []).includes(line) ? null : command\n return {\n install: presetInstallText(entry.moduleIds),\n presetNote: newAppInstallText(entry.moduleIds, empty),\n installEmptyPreset: empty,\n }\n}\n\n/** What a new app (classic preset) of the line has of a built-in module; null when a new app has it off. */\nexport function builtInPresetText(coreModule: BuiltInModule, line: string | null): string | null {\n if (!line || !coreModule.inPresets?.includes(line)) return null\n const on = `On in a new app on ${line}: nothing to enable.`\n if (coreModule.inEmptyPreset?.includes(line)) return on\n return `${on} ${EMPTY_PRESET_LEAD} ${coreModule.install || builtInEnableCommand(coreModule.id)}`\n}\n\n/** The `get_module` warnings of a built-in module. */\nexport function builtInNotes(coreModule: BuiltInModule, line: string | null): string[] {\n const text = builtInPresetText(coreModule, line)\n if (text) return [`Built into Open Mercato core as ${coreModule.id}.`, text]\n return [`Built into Open Mercato core as ${coreModule.id}. Enable it: ${builtInEnableCommand(coreModule.id)}`]\n}\n\n/** Order without a query: OM Quality, Verified, Listed, then featured, receipt freshness on the line, title. */\nfunction relevanceCompare(line: string | null) {\n const level = (meta: ModuleMeta) =>\n meta.omQuality ? 0 : meta.entry.tier === 'verified' ? 1 : meta.entry.tier === 'listed' ? 2 : 3\n const fresh = (meta: ModuleMeta) => {\n const at = line ? judgedCell(meta.entry, line)?.at : null\n return at ? Date.parse(at) : 0\n }\n return (left: ModuleMeta, right: ModuleMeta) =>\n level(left) - level(right) ||\n Number(right.entry.featured) - Number(left.entry.featured) ||\n fresh(right) - fresh(left) ||\n left.entry.title.localeCompare(right.entry.title)\n}\n\n/** The query with one swap of two adjacent letters undone in one word (`stirpe` -> `stripe`); at most 60 variants. */\nexport function swapVariants(query: string): string[] {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n if (words.length > 6) return []\n const variants: string[] = []\n words.forEach((word, wordIndex) => {\n if (word.length < 3 || word.length > 24 || !/^[a-z0-9]+$/.test(word) || processTerm(word) === null) return\n for (let index = 0; index < word.length - 1; index++) {\n if (word[index] === word[index + 1]) continue\n const swapped = `${word.slice(0, index)}${word[index + 1]}${word[index]}${word.slice(index + 2)}`\n variants.push([...words.slice(0, wordIndex), swapped, ...words.slice(wordIndex + 1)].join(' '))\n }\n })\n return [...new Set(variants)].slice(0, 60)\n}\n\nexport type RankedModule = { meta: ModuleMeta; matchedOn: string[] }\n\nexport type RankedSearch = {\n line: string | null\n latest: string | null\n modules: RankedModule[]\n builtIn: BuiltInCard[]\n didYouMean: string | null\n}\n\ntype Hits = {\n modules: { meta: ModuleMeta; result: SearchResult }[]\n builtIns: { meta: BuiltInMeta; result: SearchResult }[]\n}\n\n/**\n * `search_modules` ranking (tools@1): AND first, then OR with weak hits cut, then one swapped pair of letters. Without\n * a query (blank, or only stop words next to a filter) the filters alone pick the modules, in relevance order.\n */\nexport function rankModules(searcher: CatalogSearcher, rawInput: SearchModulesInput): RankedSearch {\n const input = {\n ...rawInput,\n query: rawInput.query ?? '',\n verifiedOnly: rawInput.verifiedOnly ?? SEARCH_DEFAULTS.verifiedOnly,\n includeBuiltIn: rawInput.includeBuiltIn ?? SEARCH_DEFAULTS.includeBuiltIn,\n includeExamples: rawInput.includeExamples ?? SEARCH_DEFAULTS.includeExamples,\n }\n const lines = searcher.index.lines\n const latest = latestLine(lines)?.key ?? null\n const line = input.omVersion ? resolveLine(input.omVersion, lines).line : latest\n const boostDocument = (id: unknown) => {\n const meta = searcher.modules.get(String(id))\n if (!meta) return 1\n const verified = line !== null && statusOn(meta.entry, line) === 'verified' ? 1 : 0\n return 1 + BOOST_VERIFIED * verified + BOOST_OFFICIAL * (meta.entry.type === 'official' ? 1 : 0)\n }\n const wantKinds = input.kind\n const provider = input.provider?.toLowerCase()\n const providerMatches = (item: { name: string; label: string }) => item.name === provider || item.label.toLowerCase() === provider\n const moduleOk = (meta: ModuleMeta) => {\n const entry = meta.entry\n return (\n entry.listed &&\n (input.includeExamples || !meta.example) &&\n (!input.category || entry.category === input.category) &&\n (!input.type || input.type.includes(entry.type)) &&\n (!wantKinds || wantKinds.includes(entry.kind)) &&\n (!input.verifiedOnly || (line !== null && statusOn(entry, line) === 'verified')) &&\n (!input.verifiedModulesOnly || entry.kind !== 'module' || (line !== null && Boolean(entry.version.recommended[line]))) &&\n (!input.emits || meta.ids.emits.includes(input.emits)) &&\n (!input.consumes || meta.ids.consumes.includes(input.consumes)) &&\n (!provider || entry.providers.some(providerMatches))\n )\n }\n const builtInOk = (meta: BuiltInMeta) =>\n input.includeBuiltIn &&\n (!wantKinds || wantKinds.includes('built-in')) &&\n (!input.type || input.type.includes('official')) &&\n (!input.category || meta.module.category === input.category) &&\n !input.provider &&\n !input.verifiedOnly &&\n (!input.emits || meta.ids.emits.includes(input.emits)) &&\n (!input.consumes || meta.ids.consumes.includes(input.consumes))\n const builtInCard = (meta: BuiltInMeta, chips: string[]): BuiltInCard => ({\n id: meta.module.id,\n title: meta.module.title,\n description: meta.module.description,\n category: meta.module.category,\n enabled: null,\n install: meta.module.install || builtInEnableCommand(meta.module.id),\n page: absolute(searcher.site, meta.module.page),\n matchedOn: chips,\n presetNote: builtInPresetText(meta.module, line),\n })\n\n const filtered = Boolean(\n input.category || input.emits || input.consumes || input.provider || input.type || wantKinds || input.verifiedOnly,\n )\n const words = tokenize(input.query).some((term) => processTerm(term) !== null)\n if (input.query.trim() === '' || (filtered && !words)) {\n const filterChips = (category: string, providers: readonly { name: string; label: string }[]): string[] => [\n ...(input.emits ? [`event ${input.emits}`] : []),\n ...(input.consumes && input.consumes !== input.emits ? [`event ${input.consumes}`] : []),\n ...(provider ? providers.filter(providerMatches).slice(0, 1).map((item) => `provider ${item.label}`) : []),\n ...(input.category ? [`category ${category}`] : []),\n ]\n const modules = [...searcher.modules.values()].filter(moduleOk).sort(relevanceCompare(line))\n const narrowed = Boolean(input.category || input.emits || input.consumes || wantKinds)\n const builtIns = narrowed\n ? [...searcher.builtInModules.values()].filter(builtInOk).sort((left, right) => left.module.title.localeCompare(right.module.title))\n : []\n return {\n line,\n latest,\n modules: modules.map((meta) => ({ meta, matchedOn: filterChips(meta.entry.category, meta.entry.providers) })),\n builtIn: builtIns.slice(0, BUILTIN_MAX).map((meta) => builtInCard(meta, filterChips(meta.module.category, []))),\n didYouMean: null,\n }\n }\n\n const run = (combineWith: 'AND' | 'OR', query: string = input.query): Hits => {\n const hits = searcher.miniSearch.search(query, {\n combineWith,\n prefix: true,\n fuzzy: 0.2,\n boost: { ...SEARCH_BOOST },\n boostDocument,\n })\n const modules: Hits['modules'] = []\n const builtIns: Hits['builtIns'] = []\n for (const result of hits) {\n const id = String(result.id)\n if (result['group'] === 'builtin') {\n const meta = searcher.builtInModules.get(id.replace(/^core:/, ''))\n if (meta && builtInOk(meta)) builtIns.push({ meta, result })\n } else {\n const meta = searcher.modules.get(id)\n if (meta && moduleOk(meta)) modules.push({ meta, result })\n }\n }\n return { modules, builtIns }\n }\n const none = (hits: Hits) => hits.modules.length === 0 && hits.builtIns.length === 0\n const topOf = (hits: Hits) => Math.max(hits.modules[0]?.result.score ?? 0, hits.builtIns[0]?.result.score ?? 0)\n const typed = new Set(tokenize(input.query).filter((term) => processTerm(term) !== null))\n const strong = <T extends { result: SearchResult }>(hits: readonly T[], top: number): T[] =>\n hits.filter((hit) => hit.result.score >= WEAK_HIT_RATIO * top || Object.keys(hit.result.match).some((term) => typed.has(term)))\n let found = run('AND')\n let didYouMean: string | null = null\n if (none(found)) {\n const orHits = run('OR')\n const top = topOf(orHits)\n found = { modules: strong(orHits.modules, top), builtIns: strong(orHits.builtIns, top) }\n if (none(found)) {\n let best: { variant: string; hits: Hits; top: number } | null = null\n for (const variant of swapVariants(input.query)) {\n const hits = run('AND', variant)\n const top = topOf(hits)\n if (!none(hits) && (!best || top > best.top)) best = { variant, hits, top }\n }\n if (best) {\n found = best.hits\n didYouMean = best.variant\n }\n }\n } else if (found.modules.length < MIN_AND_RESULTS && tokenize(input.query).filter((term) => processTerm(term)).length > 1) {\n const orHits = run('OR')\n const top = Math.max(topOf(found), topOf(orHits))\n const seen = new Set(found.modules.map((hit) => hit.meta.entry.locator))\n found = {\n modules: [...found.modules, ...strong(orHits.modules, top).filter((hit) => !seen.has(hit.meta.entry.locator))],\n builtIns: found.builtIns,\n }\n }\n\n const best = found.modules[0]?.result.score ?? 0\n const query = (didYouMean ?? input.query).trim().toLowerCase()\n const builtIn = found.builtIns\n .filter(\n ({ meta, result }) =>\n result.score >= BUILTIN_RATIO * best ||\n meta.module.title.toLowerCase() === query ||\n meta.module.id === query.replace(/[\\s-]+/g, '_'),\n )\n .slice(0, BUILTIN_MAX)\n .map(({ meta, result }) => builtInCard(meta, matchedOn(result.match, { ids: meta.ids }, result.queryTerms)))\n const modules = found.modules.map(({ meta, result }) => ({\n meta,\n matchedOn: matchedOn(\n result.match,\n { providers: meta.entry.providers, tags: meta.entry.tags, ids: meta.ids, category: meta.entry.category },\n result.queryTerms,\n ),\n }))\n return { line, latest, modules, builtIn, didYouMean }\n}\n\nexport function toModuleCard(searcher: CatalogSearcher, hit: RankedModule, line: string | null, latest: string | null): ModuleCard {\n const entry = hit.meta.entry\n return {\n locator: entry.locator,\n path: entry.path,\n title: entry.title,\n summary: entry.summary,\n whenToUse: entry.whenToUse,\n type: entry.type,\n kind: entry.kind,\n category: entry.category,\n license: { spdx: entry.license.spdx, kind: entry.license.kind },\n tier: entry.tier,\n omQuality: hit.meta.omQuality,\n verifiedOn: entry.compat.verifiedOn,\n line,\n status: line ? statusOn(entry, line) : null,\n agentPolicy: line ? (entry.agentPolicy[line] ?? null) : null,\n installableFrom: entry.version.installableFrom,\n ...installFields(entry, line, latest, peerLookup(searcher)),\n matchedOn: hit.matchedOn,\n card: absolute(searcher.site, entry.links.page),\n }\n}\n\n/** The listed entries of the search index, where the catalog looks up an adapter's peer libraries. */\nexport function peerLookup(searcher: CatalogSearcher): PeerLookup {\n return (locator) => searcher.modules.get(locator)?.entry\n}\n\nexport function receiptSourceOf(searcher: CatalogSearcher): ReceiptSource | null {\n const source = searcher.index.dataAsOf?.source\n return source === 'ci' || source === 'preview' ? source : null\n}\n\nexport function searchModules(searcher: CatalogSearcher, input: SearchModulesInput): SearchModulesOutput {\n const limit = Math.min(SEARCH_MAX_LIMIT, Math.max(1, Math.floor(input.limit ?? SEARCH_DEFAULTS.limit)))\n const ranked = rankModules(searcher, input)\n return {\n results: ranked.modules.slice(0, limit).map((hit) => toModuleCard(searcher, hit, ranked.line, ranked.latest)),\n builtIn: ranked.builtIn,\n total: ranked.modules.length,\n line: ranked.line,\n dataVersion: searcher.index.dataVersion,\n generatedAt: searcher.index.generatedAt,\n receiptSource: receiptSourceOf(searcher),\n ...(ranked.didYouMean ? { didYouMean: ranked.didYouMean } : {}),\n }\n}\n\nexport function stripVersion(ref: string): { name: string; version: string | null } {\n const match = /^(.+?)@(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(ref.trim())\n return match ? { name: match[1] as string, version: match[2] as string } : { name: ref.trim(), version: null }\n}\n\nexport type ResolvedRef =\n | { kind: 'entry'; entry: CatalogEntry; candidates: string[] }\n | { kind: 'builtin'; builtIn: BuiltInModule; candidates: string[] }\n | { kind: 'none'; candidates: string[] }\n\nconst normalizeRef = (value: string) => value.trim().toLowerCase()\nconst rankEntry = (entry: CatalogEntry) => (entry.type === 'official' ? 0 : 2) + (entry.tier === 'verified' ? 0 : 1)\n\nexport function resolveRef(ref: string, entries: readonly CatalogEntry[], builtIn: readonly BuiltInModule[]): ResolvedRef {\n const wanted = normalizeRef(stripVersion(ref).name)\n const direct = entries.find(\n (entry) =>\n normalizeRef(entry.locator) === wanted ||\n (entry.npm !== null && normalizeRef(entry.npm) === wanted) ||\n normalizeRef(entry.path) === wanted ||\n normalizeRef(`/m/${entry.path}`) === wanted ||\n entry.renamedFrom.some((previous) => normalizeRef(previous) === wanted || normalizeRef(previous) === `npm:${wanted}`),\n )\n if (direct) return { kind: 'entry', entry: direct, candidates: [] }\n const githubPath = wanted.startsWith('github:')\n ? `github/${wanted.slice(7)}`\n : wanted.replace(/^https:\\/\\/github\\.com\\//, 'github/')\n const github = entries.find((entry) => normalizeRef(entry.path) === githubPath)\n if (github) return { kind: 'entry', entry: github, candidates: [] }\n\n const id = wanted.replace(/^core:/, '')\n const byId = entries.filter((entry) => entry.moduleIds.includes(id)).sort((left, right) => rankEntry(left) - rankEntry(right))\n const core = builtIn.find((coreModule) => coreModule.id === id)\n if (core) return { kind: 'builtin', builtIn: core, candidates: byId.map((entry) => entry.locator).slice(0, 10) }\n if (byId.length === 1) return { kind: 'entry', entry: byId[0] as CatalogEntry, candidates: [] }\n if (byId.length > 1) return { kind: 'none', candidates: byId.map((entry) => entry.locator).slice(0, 10) }\n\n const loose = entries\n .filter(\n (entry) =>\n wanted.length >= 3 &&\n (normalizeRef(entry.locator).includes(wanted) || entry.moduleIds.some((moduleId) => moduleId.includes(wanted.replace(/-/g, '_')))),\n )\n .sort((left, right) => rankEntry(left) - rankEntry(right))\n return { kind: 'none', candidates: loose.map((entry) => entry.locator).slice(0, 10) }\n}\n\nconst clip = (text: string, max = 200) => (text.length > max ? `${text.slice(0, max - 3)}...` : text)\n\nexport function entryWarnings(\n entry: CatalogEntry,\n today: string,\n line: string | null,\n receiptSource: ReceiptSource | null = null,\n): string[] {\n const warnings: string[] = []\n if (!entry.listed) warnings.push(`Not listed: ${(line ? entry.agentPolicy[line] : null)?.reasons[0]?.text ?? 'see the card.'}`)\n if (entry.status !== 'active') warnings.push(`Status: ${entry.status}.`)\n if (entry.version.installableFrom && entry.version.installableFrom > today)\n warnings.push(\n `${entry.version.latest ?? 'The newest release'} is installable from ${entry.version.installableFrom} (Yarn age gate).`,\n )\n if (entry.license.mismatch) warnings.push('License sources disagree. See the card.')\n const supplyChain = entry.signals?.supplyChain\n if (supplyChain && supplyChain.status !== 'ok')\n warnings.push(`Supply chain ${supplyChain.status}: ${supplyChain.reasons.join('; ') || 'see the card'}.`)\n const hygiene = entry.signals?.hygiene\n if (hygiene && hygiene.status !== 'ok') warnings.push(`Hygiene ${hygiene.status}: ${hygiene.failing.join(', ') || 'see the card'}.`)\n if (entry.signals?.anatomy === 'hidden') warnings.push('Anatomy is not published for this entry.')\n return [...(receiptSource === 'preview' ? [PREVIEW_LINE] : []), ...warnings.map((warning) => clip(warning))].slice(0, 10)\n}\n\nexport function unknownModuleMessage(ref: string, candidates: readonly string[]): string {\n return candidates.length > 0\n ? `Unknown module \"${ref.slice(0, 80)}\". Did you mean: ${candidates.join(', ')}?`\n : `Unknown module \"${ref.slice(0, 80)}\".`\n}\n\nexport function builtInWarnings(coreModule: BuiltInModule, line: string | null): string[] {\n return builtInNotes(coreModule, line).map((note) => clip(note))\n}\n\nexport function sharedModuleIdWarning(id: string, count: number): string {\n return clip(`Module ID ${id} is provided by ${count} entries. Pick one of the candidates.`)\n}\n\nexport function cardUrl(searcher: CatalogSearcher, page: string): string {\n return absolute(searcher.site, page)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Ranking and lookups behind `mercato module search|info`, kept identical to the Open Mercato Modules catalog\n// (https://modules.openmercato.com, `lib/core/search.ts` and `lib/core/refs.ts`): same MiniSearch options, tokenizer,\n// stop words, boosts and built-in rules, so the CLI, the catalog site and its MCP server rank the same way.\n// `__tests__/module-search.test.ts` holds this file to the catalog's own output on a fixture built from real data.\nimport MiniSearch, { type Options, type SearchResult } from 'minisearch'\nimport { satisfies } from 'semver'\n\nexport type CellStatus = string\nexport type OriginType = 'official' | 'community' | '3rd-party'\nexport type EntryKind = 'module' | 'provider' | 'library' | 'tool'\nexport type LicenseKind = 'osi' | 'proprietary' | 'enterprise' | 'unknown'\nexport type ReceiptSource = 'ci' | 'preview'\n\nexport type AgentPolicy = {\n decision: 'allow' | 'ask' | 'refuse'\n reasons: { code: string; text: string }[]\n until?: string\n consentText?: string\n}\n\nexport type CatalogLine = {\n key: string\n version: string\n source: 'latest' | 'previous' | 'develop'\n}\n\nexport type AnatomyLists = {\n aclFeatures?: string[]\n eventsEmitted?: string[]\n eventsConsumed?: string[]\n env?: string[]\n hosts?: string[]\n tables?: string[]\n publicRoutes?: string[]\n credentials?: { key: string; type?: string; required?: boolean }[]\n}\n\nexport type AnatomySummary = {\n version: string\n counts?: Record<string, number | null>\n lists?: AnatomyLists\n callout?: string | null\n}\n\nexport type CellSummary = { status: CellStatus; at: string | null; moduleVersion?: string | null }\n\nexport type BuiltFor = { range: string | null; kind: string; lines: string[]; ranges?: Record<string, string> }\n\nexport type CatalogEntry = {\n locator: string\n path: string\n npm: string | null\n title: string\n summary: string\n whenToUse: string\n type: OriginType\n kind: EntryKind\n category: string\n tags: string[]\n providers: { name: string; label: string }[]\n moduleIds: string[]\n /** What the package needs; an adapter's catalog libraries among them join its `yarn add` (`peerLibrarySpecs`). */\n requires?: { raw: string; resolvesTo?: string | null }[]\n renamedFrom: string[]\n status: string\n listed: boolean\n featured: boolean\n license: { spdx: string | null; kind: LicenseKind; mismatch?: boolean }\n version: {\n latest: string | null\n preview: string | null\n installableFrom: string | null\n gitRef: string | null\n recommended: Record<string, string | null>\n }\n compat: {\n lines: Record<string, CellSummary>\n verifiedOn: string[]\n builtFor?: BuiltFor\n inPresets?: string[]\n inEmptyPreset?: string[]\n ships?: Record<string, string>\n isolation?: Record<string, { status: CellStatus; moduleVersion: string | null }>\n }\n anatomy: AnatomySummary | null\n signals?: {\n supplyChain?: { status: string; reasons: string[] }\n hygiene?: { status: string; failing: string[] }\n anatomy?: string\n }\n tier: 'listed' | 'verified' | null\n quality: unknown\n agentPolicy: Record<string, AgentPolicy>\n install: { cli: string; cmm?: string; needsAllowThirdParty?: boolean; moduleFlag: string | null }\n links: { page: string; md: string; json?: string; npm?: string | null; repo?: string | null }\n _meta?: Record<string, unknown>\n}\n\nexport type CatalogIndex = {\n schemaVersion: 1\n generatedAt: string\n dataVersion: string\n site: string\n lines: CatalogLine[]\n entries: CatalogEntry[]\n dataAsOf?: { source?: ReceiptSource | null }\n builtIn?: { coreVersion: string; count: number; href: string }\n}\n\nexport type BuiltInModule = {\n id: string\n title: string\n description: string\n category: string\n requires?: string[]\n inPresets?: string[]\n inEmptyPreset?: string[]\n anatomy: AnatomySummary | null\n install: string\n page: string\n}\n\nexport type BuiltInIndex = {\n schemaVersion: 1\n coreVersion: string\n generatedAt: string\n modules: BuiltInModule[]\n}\n\nexport type ModuleCard = {\n locator: string\n path: string\n title: string\n summary: string\n whenToUse: string\n type: OriginType\n kind: EntryKind\n category: string\n license: { spdx: string | null; kind: LicenseKind }\n tier: 'listed' | 'verified' | null\n omQuality: boolean\n verifiedOn: string[]\n line: string | null\n status: CellStatus | null\n agentPolicy: AgentPolicy | null\n installableFrom: string | null\n install: string\n matchedOn: string[]\n card: string\n presetNote?: string\n installEmptyPreset?: string | null\n}\n\nexport type BuiltInCard = {\n id: string\n title: string\n description: string\n category: string\n enabled: boolean | null\n install: string\n page: string\n matchedOn: string[]\n presetNote: string | null\n}\n\nexport type SearchModulesInput = {\n query?: string\n omVersion?: string\n category?: string\n type?: OriginType[]\n kind?: (EntryKind | 'built-in')[]\n verifiedOnly?: boolean\n verifiedModulesOnly?: boolean\n includeBuiltIn?: boolean\n includeExamples?: boolean\n emits?: string\n consumes?: string\n provider?: string\n limit?: number\n}\n\nexport type SearchModulesOutput = {\n results: ModuleCard[]\n builtIn: BuiltInCard[]\n total: number\n line: string | null\n dataVersion: string\n generatedAt: string\n receiptSource?: ReceiptSource | null\n didYouMean?: string\n}\n\nexport const SEARCH_BOOST = {\n title: 3,\n npm: 3,\n summary: 2,\n whenToUse: 2,\n providers: 2,\n tags: 1.5,\n aliases: 1.5,\n renamedFrom: 1,\n category: 1,\n anatomy: 1,\n} as const\ntype SearchField = keyof typeof SEARCH_BOOST\nconst SEARCH_FIELDS = Object.keys(SEARCH_BOOST) as SearchField[]\n\nexport const ALIASES_META_KEY = 'com.openmercato.modules/aliases'\nexport const INSTALLABLE_META_KEY = 'com.openmercato.modules/installable'\nexport const BUILTIN_MAX = 5\nexport const BUILTIN_RATIO = 0.5\nexport const BOOST_VERIFIED = 0.15\nexport const BOOST_OFFICIAL = 0.1\nexport const MIN_AND_RESULTS = 3\n/** An OR hit that matched no query word as typed and scores below this share of the best hit is dropped. */\nexport const WEAK_HIT_RATIO = 0.2\nexport const SEARCH_MAX_LIMIT = 20\nexport const SEARCH_DEFAULTS = { verifiedOnly: false, includeBuiltIn: true, includeExamples: false, limit: 10 } as const\nexport const CORE_PACKAGE = '@open-mercato/core'\nexport const ENTERPRISE_PACKAGE = '@open-mercato/enterprise'\nexport const ENTERPRISE_ENABLE_STEP = 'echo OM_ENABLE_ENTERPRISE_MODULES=true >> .env'\nexport const PREVIEW_LINE =\n \"Receipts: Preview run in Docker on the maintainer's machine, not CI. The first nightly CI run replaces it.\"\nconst VERDICT_STATES: ReadonlySet<CellStatus> = new Set(['verified', 'broken', 'harness-red', 'infra-error'])\n\nconst STOPWORDS = new Set([\n 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from', 'i', 'in', 'into', 'is', 'it', 'its', 'me',\n 'module', 'modules', 'my', 'of', 'on', 'or', 'our', 'that', 'the', 'this', 'to', 'via', 'we', 'with', 'you', 'your',\n 'can', 'do', 'does', 'how', 'need', 'needs', 'use', 'used', 'uses', 'want', 'wants', 'what', 'when', 'which',\n])\n\nexport function tokenize(text: string): string[] {\n const lower = text.toLowerCase()\n const tokens = lower.split(/[^a-z0-9*]+/).filter((token) => token !== '')\n for (const match of lower.matchAll(/[a-z0-9]+(?:[._-][a-z0-9*]+)+/g)) tokens.push(match[0])\n return tokens\n}\n\nexport function processTerm(term: string): string | null {\n return term.length < 2 || STOPWORDS.has(term) ? null : term\n}\n\nexport type SearchDoc = {\n id: string\n group: 'module' | 'builtin'\n title: string\n npm: string\n summary: string\n whenToUse: string\n providers: string\n tags: string\n aliases: string\n renamedFrom: string\n category: string\n anatomy: string\n}\n\nconst SEARCH_OPTIONS: Options<SearchDoc> = {\n idField: 'id',\n fields: SEARCH_FIELDS,\n storeFields: ['group'],\n tokenize,\n processTerm,\n searchOptions: { prefix: true, fuzzy: 0.2, boost: { ...SEARCH_BOOST } },\n}\n\nexport type AnatomyIds = {\n event: string[]\n emits: string[]\n consumes: string[]\n entity: string[]\n permission: string[]\n env: string[]\n host: string[]\n setting: string[]\n module: string[]\n}\n\nexport type ModuleMeta = {\n entry: CatalogEntry\n example: boolean\n omQuality: boolean\n ids: AnatomyIds\n}\n\nexport type BuiltInMeta = {\n module: BuiltInModule\n ids: AnatomyIds\n}\n\nexport type CatalogSearcher = {\n miniSearch: MiniSearch<SearchDoc>\n index: CatalogIndex\n builtIn: BuiltInIndex | null\n site: string\n modules: Map<string, ModuleMeta>\n builtInModules: Map<string, BuiltInMeta>\n}\n\nfunction anatomyIds(anatomy: AnatomySummary | null | undefined, moduleIds: readonly string[]): AnatomyIds {\n const lists = anatomy?.lists\n return {\n event: [...new Set([...(lists?.eventsEmitted ?? []), ...(lists?.eventsConsumed ?? [])])],\n emits: [...(lists?.eventsEmitted ?? [])],\n consumes: [...(lists?.eventsConsumed ?? [])],\n entity: lists?.tables ?? [],\n permission: lists?.aclFeatures ?? [],\n env: lists?.env ?? [],\n host: lists?.hosts ?? [],\n setting: (lists?.credentials ?? []).map((credential) => credential.key),\n module: [...moduleIds],\n }\n}\n\nconst anatomyText = (ids: AnatomyIds) =>\n [...ids.module, ...ids.entity, ...ids.event, ...ids.permission, ...ids.setting, ...ids.env, ...ids.host].join(' ')\n\nfunction aliasesOf(entry: CatalogEntry): string[] {\n const value = entry._meta?.[ALIASES_META_KEY]\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []\n}\n\nfunction moduleDoc(entry: CatalogEntry, ids: AnatomyIds): SearchDoc {\n return {\n id: entry.locator,\n group: 'module',\n title: entry.title,\n npm: [entry.npm ?? entry.locator.replace(/^github:/, ''), entry.path].join(' '),\n summary: entry.summary,\n whenToUse: entry.whenToUse,\n providers: entry.providers.map((provider) => `${provider.name} ${provider.label}`).join(' '),\n tags: entry.tags.join(' '),\n aliases: aliasesOf(entry).join(' '),\n renamedFrom: entry.renamedFrom.map((locator) => locator.replace(/^(npm|github):/, '')).join(' '),\n category: entry.category,\n anatomy: anatomyText(ids),\n }\n}\n\nfunction builtInDoc(coreModule: BuiltInModule, ids: AnatomyIds): SearchDoc {\n return {\n id: `core:${coreModule.id}`,\n group: 'builtin',\n title: coreModule.title,\n npm: coreModule.id,\n summary: coreModule.description,\n whenToUse: '',\n providers: '',\n tags: '',\n aliases: '',\n renamedFrom: '',\n category: coreModule.category,\n anatomy: anatomyText(ids),\n }\n}\n\nexport function createCatalogSearcher(index: CatalogIndex, builtIn: BuiltInIndex | null): CatalogSearcher {\n const miniSearch = new MiniSearch<SearchDoc>(SEARCH_OPTIONS)\n const modules = new Map<string, ModuleMeta>()\n const builtInModules = new Map<string, BuiltInMeta>()\n const docs: SearchDoc[] = []\n for (const entry of index.entries.filter((candidate) => candidate.listed)) {\n const ids = anatomyIds(entry.anatomy, entry.moduleIds)\n modules.set(entry.locator, {\n entry,\n ids,\n example: entry.tags.includes('example'),\n omQuality: entry.quality !== null && entry.quality !== undefined,\n })\n docs.push(moduleDoc(entry, ids))\n }\n for (const coreModule of builtIn?.modules ?? []) {\n const ids = anatomyIds(coreModule.anatomy, [coreModule.id])\n builtInModules.set(coreModule.id, { module: coreModule, ids })\n docs.push(builtInDoc(coreModule, ids))\n }\n miniSearch.addAll(docs)\n const loaded = MiniSearch.loadJS<SearchDoc>(miniSearch.toJSON(), SEARCH_OPTIONS)\n return { miniSearch: loaded, index, builtIn, site: index.site.replace(/\\/+$/, ''), modules, builtInModules }\n}\n\nconst absolute = (site: string, page: string) => (/^https?:\\/\\//.test(page) ? page : `${site}${page}`)\n\nexport function latestLine(lines: readonly CatalogLine[]): CatalogLine | null {\n return lines.find((line) => line.source === 'latest') ?? null\n}\n\nconst SEMVER = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/\n\nexport function resolveLine(\n omVersion: string | null | undefined,\n lines: readonly CatalogLine[],\n): { line: string | null; version: string | null; note: string | null } {\n const found = (line: CatalogLine | null) =>\n line ? { line: line.key, version: line.version, note: null } : { line: null, version: null, note: null }\n const raw = (omVersion ?? '').trim()\n if (raw === '') return found(latestLine(lines))\n const byKey = lines.find((line) => line.key === raw)\n if (byKey) return found(byKey)\n const version = raw.replace(/^(?:v|=|\\^|~|>=)\\s*/, '')\n const semver = SEMVER.exec(version)\n const lineKey = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/.exec(version)\n if ((!semver && !lineKey) || semver?.[4]?.split('.').some((part) => /^0\\d+$/.test(part))) {\n return { line: null, version: null, note: 'Unknown Open Mercato version.' }\n }\n const exact = lines.find((line) => line.version === version)\n if (exact) return found(exact)\n if (semver && semver[4] && /(^|[.-])develop([.-]|$)/.test(semver[4])) {\n const next = lines.find((line) => line.source === 'develop')\n if (next) return found(next)\n }\n const majorMinor = semver ?? lineKey\n if (!majorMinor) return { line: null, version: null, note: 'Unknown Open Mercato version.' }\n const key = `${Number(majorMinor[1])}.${Number(majorMinor[2])}`\n const line = lines.find((candidate) => candidate.key === key)\n if (line) return found(line)\n return { line: null, version: null, note: `Line ${key} is not tested by the catalog.` }\n}\n\nfunction matchedOn(\n match: SearchResult['match'],\n meta: { providers?: readonly { name: string; label: string }[]; tags?: readonly string[]; ids: AnatomyIds; category?: string },\n queryTerms: readonly string[] = [],\n): string[] {\n const chips: string[] = []\n const add = (chip: string) => {\n if (!chips.includes(chip)) chips.push(chip)\n }\n const has = (id: string, term: string) => tokenize(id).includes(term)\n const order: SearchField[] = ['title', 'npm', 'aliases', 'renamedFrom', 'providers', 'anatomy', 'summary', 'whenToUse', 'tags', 'category']\n const typed = new Set(queryTerms)\n const fieldsByTerm = Object.entries(match).sort(\n (left, right) => Number(typed.has(right[0])) - Number(typed.has(left[0])) || right[0].length - left[0].length,\n )\n for (const field of order) {\n for (const [term, fields] of fieldsByTerm) {\n if (!fields.includes(field)) continue\n if (field === 'title' || field === 'npm' || field === 'aliases' || field === 'renamedFrom') add('name')\n else if (field === 'summary' || field === 'whenToUse') add('summary')\n else if (field === 'tags') {\n const tag = meta.tags?.find((candidate) => has(candidate, term))\n add(tag ? `tag ${tag}` : 'summary')\n } else if (field === 'category' && meta.category) add(`category ${meta.category}`)\n else if (field === 'providers') {\n const provider = meta.providers?.find((candidate) => has(candidate.name, term) || has(candidate.label, term))\n add(provider ? `provider ${provider.label}` : 'provider')\n } else if (field === 'anatomy') anatomyChips(meta.ids, fieldsByTerm, has).forEach(add)\n }\n }\n return chips.slice(0, 5)\n}\n\nfunction anatomyChips(\n ids: AnatomyIds,\n fieldsByTerm: readonly (readonly [string, readonly string[]])[],\n has: (id: string, term: string) => boolean,\n): string[] {\n const kinds: (keyof AnatomyIds)[] = ['event', 'entity', 'permission', 'env', 'setting', 'host', 'module']\n const terms = fieldsByTerm.filter(([, fields]) => fields.includes('anatomy')).map(([term]) => term)\n const left = new Set(terms)\n const chips: string[] = []\n while (left.size > 0) {\n let best: { chip: string; covers: string[]; exact: boolean; first: number } | null = null\n for (const kind of kinds)\n for (const id of ids[kind]) {\n const covers = terms.filter((term) => left.has(term) && (id === term || has(id, term)))\n if (covers.length === 0) continue\n const exact = covers.includes(id)\n const first = terms.indexOf(covers[0] as string)\n const better =\n !best ||\n covers.length > best.covers.length ||\n (covers.length === best.covers.length && (exact && !best.exact ? true : exact === best.exact && first < best.first))\n if (better) best = { chip: `${kind} ${id}`, covers, exact, first }\n }\n if (!best) break\n chips.push(best.chip)\n for (const term of best.covers) left.delete(term)\n }\n return chips\n}\n\nconst STABLE_VERSION = /^\\d+\\.\\d+\\.\\d+$/\n\nfunction satisfiesRange(version: string, range: string): boolean {\n try {\n return satisfies(version, range, { includePrerelease: true })\n } catch {\n return false\n }\n}\n\nexport function lineVersion(entry: CatalogEntry, line: string | null): string | null {\n return (line !== null ? entry.compat.ships?.[line] : undefined) ?? installVersion(entry, line)\n}\n\n/** A cell whose receipt judged another version than the one a fresh app gets on the line is no verdict on that line. */\nfunction judgedCell(entry: CatalogEntry, line: string): CellSummary | null {\n const cell = entry.compat.lines[line] ?? null\n if (!cell || cell.moduleVersion === null || cell.moduleVersion === undefined || !VERDICT_STATES.has(cell.status)) return cell\n const installs = lineVersion(entry, line)\n return installs === null || cell.moduleVersion === installs ? cell : null\n}\n\nexport function statusOn(entry: CatalogEntry, line: string): CellStatus {\n if (entry.version.recommended[line]) return 'verified'\n return judgedCell(entry, line)?.status ?? 'untested'\n}\n\nfunction installableOn(entry: CatalogEntry, line: string | null): string | null | undefined {\n if (line === null) return undefined\n const map = entry._meta?.[INSTALLABLE_META_KEY]\n if (!map || typeof map !== 'object') return undefined\n const value = (map as Record<string, unknown>)[line]\n return typeof value === 'string' ? value : value === null ? null : undefined\n}\n\nexport function installVersion(entry: CatalogEntry, line: string | null): string | null {\n return (\n (line !== null ? entry.version.recommended[line] : null) ??\n installableOn(entry, line) ??\n entry.version.latest ??\n entry.version.preview ??\n null\n )\n}\n\nfunction declaredRangeOf(entry: CatalogEntry, version: string): string | null {\n const builtFor = entry.compat.builtFor\n if (!builtFor || builtFor.kind === 'missing' || builtFor.kind === 'star') return null\n if (builtFor.ranges) {\n for (const [line, range] of Object.entries(builtFor.ranges)) if (lineVersion(entry, line) === version) return range\n return null\n }\n const lines = new Set([...Object.keys(entry.compat.lines), ...Object.keys(entry.compat.ships ?? {})])\n return [...lines].some((line) => lineVersion(entry, line) === version) ? builtFor.range : null\n}\n\n/**\n * The version an app from the empty preset installs: the one a new app ships where the install version broke in\n * isolation there, or where its declared peers reject the version that line ships.\n */\nexport function emptyPresetVersion(entry: CatalogEntry, line: string | null): string | null {\n const version = installVersion(entry, line)\n if (line === null || !version) return version\n const ships = entry.compat.ships?.[line]\n if (!ships || ships === version) return version\n const isolation = entry.compat.isolation?.[line]\n if (isolation?.moduleVersion === version) return isolation.status === 'broken' ? ships : version\n const range = declaredRangeOf(entry, version)\n return STABLE_VERSION.test(ships) && range !== null && !satisfiesRange(ships, range) ? ships : version\n}\n\nexport function builtInEnableCommand(id: string): string {\n return `yarn mercato module enable ${CORE_PACKAGE} --module ${id}`\n}\n\n/** A provider without a module of its own: an adapter `yarn add` adds and `yarn generate` registers. */\nexport const isAdapter = (entry: Pick<CatalogEntry, 'kind' | 'moduleIds'>): boolean =>\n entry.kind === 'provider' && entry.moduleIds.length === 0\n\n/** Finds a catalog entry by locator (`npm:<name>`). */\nexport type PeerLookup = (locator: string) => CatalogEntry | null | undefined\n\n/**\n * The catalog libraries an adapter peers on, as `name@version` for its `yarn add` (catalog `peerLibrarySpecs`). An\n * @open-mercato peer of an @open-mercato adapter comes from the same release and takes the adapter's version; any\n * other peer takes its own install version on the line. Empty for every other kind.\n */\nexport function peerLibrarySpecs(\n entry: CatalogEntry,\n version: string | null,\n line: string | null,\n find: PeerLookup | undefined,\n): string[] {\n if (!find || !entry.npm || !isAdapter(entry)) return []\n const specs: string[] = []\n for (const requirement of entry.requires ?? []) {\n const peer = requirement.resolvesTo?.startsWith('npm:') ? find(requirement.resolvesTo) : null\n if (!peer?.npm || peer.kind !== 'library' || peer.npm === entry.npm) continue\n const sameRelease = Boolean(version) && peer.npm.startsWith('@open-mercato/') && entry.npm.startsWith('@open-mercato/')\n const peerVersion = sameRelease ? version : installVersion(peer, line)\n const spec = peerVersion ? `${peer.npm}@${peerVersion}` : peer.npm\n if (!specs.includes(spec)) specs.push(spec)\n }\n return specs\n}\n\nfunction packageCommand(entry: CatalogEntry, spec: string, peers: readonly string[] = []): string | null {\n if (entry.kind === 'tool') return entry.tags.includes('cli') ? `npx ${spec}` : `yarn add ${spec}`\n if (isAdapter(entry)) return `yarn add ${[...peers, spec].join(' ')}`\n return entry.kind === 'library' ? `yarn add ${spec}` : null\n}\n\nfunction inPreset(entry: CatalogEntry, enabled: readonly { id: string; from: string }[] | null): boolean {\n if (!enabled || !entry.npm || entry.moduleIds.length === 0) return false\n return entry.moduleIds.every((id) => enabled.some((item) => item.id === id && item.from === entry.npm))\n}\n\nfunction installCli(\n entry: CatalogEntry,\n line: string | null,\n preset: readonly { id: string; from: string }[] | null,\n version: string | null = installVersion(entry, line),\n find?: PeerLookup,\n): string {\n if (entry.npm === null) {\n const repo = entry.locator.replace(/^github:/, '')\n const ref = entry.version.gitRef ? ` --ref ${entry.version.gitRef}` : ''\n return `npx create-mercato-module install ${repo}${ref}`\n }\n const spec = version ? `${entry.npm}@${version}` : entry.npm\n const own = packageCommand(entry, spec, peerLibrarySpecs(entry, version, line, find))\n if (own) return own\n if (inPreset(entry, preset)) return `yarn add ${spec}`\n const moduleFlag = entry.install.moduleFlag ?? null\n if (entry.npm === ENTERPRISE_PACKAGE && !moduleFlag) return `${ENTERPRISE_ENABLE_STEP} && yarn generate`\n const thirdParty = entry.npm.startsWith('@open-mercato/') ? '' : ' --allow-third-party'\n if (!moduleFlag && entry.moduleIds.length > 1) {\n return entry.moduleIds.map((id) => `yarn mercato module add ${spec}${thirdParty} --module ${id}`).join(' && ')\n }\n return `yarn mercato module add ${spec}${thirdParty}${moduleFlag ? ` --module ${moduleFlag}` : ''}`\n}\n\n/** The command of an app that does not register the package yet (an app from the empty preset) on a line. */\nexport function installCommand(\n entry: CatalogEntry,\n line: string | null,\n latest: string | null,\n find?: PeerLookup,\n): string {\n if (line === null || line === latest) return entry.install.cli\n const both = entry.npm !== null && (entry.compat.inEmptyPreset ?? []).includes(line)\n const version = (entry.compat.inPresets ?? []).includes(line)\n ? emptyPresetVersion(entry, line)\n : installVersion(entry, line)\n const npm = entry.npm\n return installCli(entry, line, both && npm ? entry.moduleIds.map((id) => ({ id, from: npm })) : null, version, find)\n}\n\nfunction listAnd(items: readonly string[]): string {\n return items.length <= 1 ? (items[0] ?? '') : `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n}\n\nconst EMPTY_PRESET_LEAD = 'In an app from the empty preset:'\n\nfunction presetInstallText(moduleIds: readonly string[]): string {\n return `Nothing to install: a new app already registers ${moduleIds.length ? listAnd(moduleIds) : 'it'} in src/modules.ts.`\n}\n\nexport function newAppInstallText(moduleIds: readonly string[], emptyCommand: string | null): string {\n return emptyCommand ? `${presetInstallText(moduleIds)} ${EMPTY_PRESET_LEAD} ${emptyCommand}` : presetInstallText(moduleIds)\n}\n\n/**\n * Where a new app (classic preset) of the line already registers the package, `install` is that sentence, `presetNote`\n * the whole install sentence and `installEmptyPreset` the command of an app from the empty preset (null when that\n * preset registers it too). Elsewhere `install` is the command.\n */\nexport function installFields(\n entry: CatalogEntry,\n line: string | null,\n latest: string | null,\n find?: PeerLookup,\n): Pick<ModuleCard, 'install' | 'presetNote' | 'installEmptyPreset'> {\n const command = installCommand(entry, line, latest, find)\n if (line === null || !(entry.compat.inPresets ?? []).includes(line)) return { install: command }\n const empty = (entry.compat.inEmptyPreset ?? []).includes(line) ? null : command\n return {\n install: presetInstallText(entry.moduleIds),\n presetNote: newAppInstallText(entry.moduleIds, empty),\n installEmptyPreset: empty,\n }\n}\n\n/** What a new app (classic preset) of the line has of a built-in module; null when a new app has it off. */\nexport function builtInPresetText(coreModule: BuiltInModule, line: string | null): string | null {\n if (!line || !coreModule.inPresets?.includes(line)) return null\n const on = `On in a new app on ${line}: nothing to enable.`\n if (coreModule.inEmptyPreset?.includes(line)) return on\n return `${on} ${EMPTY_PRESET_LEAD} ${coreModule.install || builtInEnableCommand(coreModule.id)}`\n}\n\n/** The `get_module` warnings of a built-in module. */\nexport function builtInNotes(coreModule: BuiltInModule, line: string | null): string[] {\n const text = builtInPresetText(coreModule, line)\n if (text) return [`Built into Open Mercato core as ${coreModule.id}.`, text]\n return [`Built into Open Mercato core as ${coreModule.id}. Enable it: ${builtInEnableCommand(coreModule.id)}`]\n}\n\n/** Order without a query: OM Quality, Verified, Listed, then featured, receipt freshness on the line, title. */\nfunction relevanceCompare(line: string | null) {\n const level = (meta: ModuleMeta) =>\n meta.omQuality ? 0 : meta.entry.tier === 'verified' ? 1 : meta.entry.tier === 'listed' ? 2 : 3\n const fresh = (meta: ModuleMeta) => {\n const at = line ? judgedCell(meta.entry, line)?.at : null\n return at ? Date.parse(at) : 0\n }\n return (left: ModuleMeta, right: ModuleMeta) =>\n level(left) - level(right) ||\n Number(right.entry.featured) - Number(left.entry.featured) ||\n fresh(right) - fresh(left) ||\n left.entry.title.localeCompare(right.entry.title)\n}\n\n/** The query with one swap of two adjacent letters undone in one word (`stirpe` -> `stripe`); at most 60 variants. */\nexport function swapVariants(query: string): string[] {\n const words = query.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n if (words.length > 6) return []\n const variants: string[] = []\n words.forEach((word, wordIndex) => {\n if (word.length < 3 || word.length > 24 || !/^[a-z0-9]+$/.test(word) || processTerm(word) === null) return\n for (let index = 0; index < word.length - 1; index++) {\n if (word[index] === word[index + 1]) continue\n const swapped = `${word.slice(0, index)}${word[index + 1]}${word[index]}${word.slice(index + 2)}`\n variants.push([...words.slice(0, wordIndex), swapped, ...words.slice(wordIndex + 1)].join(' '))\n }\n })\n return [...new Set(variants)].slice(0, 60)\n}\n\nexport type RankedModule = { meta: ModuleMeta; matchedOn: string[] }\n\nexport type RankedSearch = {\n line: string | null\n latest: string | null\n modules: RankedModule[]\n builtIn: BuiltInCard[]\n didYouMean: string | null\n}\n\ntype Hits = {\n modules: { meta: ModuleMeta; result: SearchResult }[]\n builtIns: { meta: BuiltInMeta; result: SearchResult }[]\n}\n\n/**\n * `search_modules` ranking (tools@1): AND first, then OR with weak hits cut, then one swapped pair of letters. Without\n * a query (blank, or only stop words next to a filter) the filters alone pick the modules, in relevance order.\n */\nexport function rankModules(searcher: CatalogSearcher, rawInput: SearchModulesInput): RankedSearch {\n const input = {\n ...rawInput,\n query: rawInput.query ?? '',\n verifiedOnly: rawInput.verifiedOnly ?? SEARCH_DEFAULTS.verifiedOnly,\n includeBuiltIn: rawInput.includeBuiltIn ?? SEARCH_DEFAULTS.includeBuiltIn,\n includeExamples: rawInput.includeExamples ?? SEARCH_DEFAULTS.includeExamples,\n }\n const lines = searcher.index.lines\n const latest = latestLine(lines)?.key ?? null\n const line = input.omVersion ? resolveLine(input.omVersion, lines).line : latest\n const boostDocument = (id: unknown) => {\n const meta = searcher.modules.get(String(id))\n if (!meta) return 1\n const verified = line !== null && statusOn(meta.entry, line) === 'verified' ? 1 : 0\n return 1 + BOOST_VERIFIED * verified + BOOST_OFFICIAL * (meta.entry.type === 'official' ? 1 : 0)\n }\n const wantKinds = input.kind\n const provider = input.provider?.toLowerCase()\n const providerMatches = (item: { name: string; label: string }) => item.name === provider || item.label.toLowerCase() === provider\n const moduleOk = (meta: ModuleMeta) => {\n const entry = meta.entry\n return (\n entry.listed &&\n (input.includeExamples || !meta.example) &&\n (!input.category || entry.category === input.category) &&\n (!input.type || input.type.includes(entry.type)) &&\n (!wantKinds || wantKinds.includes(entry.kind)) &&\n (!input.verifiedOnly || (line !== null && statusOn(entry, line) === 'verified')) &&\n (!input.verifiedModulesOnly || entry.kind !== 'module' || (line !== null && Boolean(entry.version.recommended[line]))) &&\n (!input.emits || meta.ids.emits.includes(input.emits)) &&\n (!input.consumes || meta.ids.consumes.includes(input.consumes)) &&\n (!provider || entry.providers.some(providerMatches))\n )\n }\n const builtInOk = (meta: BuiltInMeta) =>\n input.includeBuiltIn &&\n (!wantKinds || wantKinds.includes('built-in')) &&\n (!input.type || input.type.includes('official')) &&\n (!input.category || meta.module.category === input.category) &&\n !input.provider &&\n !input.verifiedOnly &&\n (!input.emits || meta.ids.emits.includes(input.emits)) &&\n (!input.consumes || meta.ids.consumes.includes(input.consumes))\n const builtInCard = (meta: BuiltInMeta, chips: string[]): BuiltInCard => ({\n id: meta.module.id,\n title: meta.module.title,\n description: meta.module.description,\n category: meta.module.category,\n enabled: null,\n install: meta.module.install || builtInEnableCommand(meta.module.id),\n page: absolute(searcher.site, meta.module.page),\n matchedOn: chips,\n presetNote: builtInPresetText(meta.module, line),\n })\n\n const filtered = Boolean(\n input.category || input.emits || input.consumes || input.provider || input.type || wantKinds || input.verifiedOnly,\n )\n const words = tokenize(input.query).some((term) => processTerm(term) !== null)\n if (input.query.trim() === '' || (filtered && !words)) {\n const filterChips = (category: string, providers: readonly { name: string; label: string }[]): string[] => [\n ...(input.emits ? [`event ${input.emits}`] : []),\n ...(input.consumes && input.consumes !== input.emits ? [`event ${input.consumes}`] : []),\n ...(provider ? providers.filter(providerMatches).slice(0, 1).map((item) => `provider ${item.label}`) : []),\n ...(input.category ? [`category ${category}`] : []),\n ]\n const modules = [...searcher.modules.values()].filter(moduleOk).sort(relevanceCompare(line))\n const narrowed = Boolean(input.category || input.emits || input.consumes || wantKinds)\n const builtIns = narrowed\n ? [...searcher.builtInModules.values()].filter(builtInOk).sort((left, right) => left.module.title.localeCompare(right.module.title))\n : []\n return {\n line,\n latest,\n modules: modules.map((meta) => ({ meta, matchedOn: filterChips(meta.entry.category, meta.entry.providers) })),\n builtIn: builtIns.slice(0, BUILTIN_MAX).map((meta) => builtInCard(meta, filterChips(meta.module.category, []))),\n didYouMean: null,\n }\n }\n\n const run = (combineWith: 'AND' | 'OR', query: string = input.query): Hits => {\n const hits = searcher.miniSearch.search(query, {\n combineWith,\n prefix: true,\n fuzzy: 0.2,\n boost: { ...SEARCH_BOOST },\n boostDocument,\n })\n const modules: Hits['modules'] = []\n const builtIns: Hits['builtIns'] = []\n for (const result of hits) {\n const id = String(result.id)\n if (result['group'] === 'builtin') {\n const meta = searcher.builtInModules.get(id.replace(/^core:/, ''))\n if (meta && builtInOk(meta)) builtIns.push({ meta, result })\n } else {\n const meta = searcher.modules.get(id)\n if (meta && moduleOk(meta)) modules.push({ meta, result })\n }\n }\n return { modules, builtIns }\n }\n const none = (hits: Hits) => hits.modules.length === 0 && hits.builtIns.length === 0\n const topOf = (hits: Hits) => Math.max(hits.modules[0]?.result.score ?? 0, hits.builtIns[0]?.result.score ?? 0)\n const typed = new Set(tokenize(input.query).filter((term) => processTerm(term) !== null))\n const strong = <T extends { result: SearchResult }>(hits: readonly T[], top: number): T[] =>\n hits.filter((hit) => hit.result.score >= WEAK_HIT_RATIO * top || Object.keys(hit.result.match).some((term) => typed.has(term)))\n let found = run('AND')\n let didYouMean: string | null = null\n if (none(found)) {\n const orHits = run('OR')\n const top = topOf(orHits)\n found = { modules: strong(orHits.modules, top), builtIns: strong(orHits.builtIns, top) }\n if (none(found)) {\n let best: { variant: string; hits: Hits; top: number } | null = null\n for (const variant of swapVariants(input.query)) {\n const hits = run('AND', variant)\n const top = topOf(hits)\n if (!none(hits) && (!best || top > best.top)) best = { variant, hits, top }\n }\n if (best) {\n found = best.hits\n didYouMean = best.variant\n }\n }\n } else if (found.modules.length < MIN_AND_RESULTS && tokenize(input.query).filter((term) => processTerm(term)).length > 1) {\n const orHits = run('OR')\n const top = Math.max(topOf(found), topOf(orHits))\n const seen = new Set(found.modules.map((hit) => hit.meta.entry.locator))\n found = {\n modules: [...found.modules, ...strong(orHits.modules, top).filter((hit) => !seen.has(hit.meta.entry.locator))],\n builtIns: found.builtIns,\n }\n }\n\n const best = found.modules[0]?.result.score ?? 0\n const query = (didYouMean ?? input.query).trim().toLowerCase()\n const builtIn = found.builtIns\n .filter(\n ({ meta, result }) =>\n result.score >= BUILTIN_RATIO * best ||\n meta.module.title.toLowerCase() === query ||\n meta.module.id === query.replace(/[\\s-]+/g, '_'),\n )\n .slice(0, BUILTIN_MAX)\n .map(({ meta, result }) => builtInCard(meta, matchedOn(result.match, { ids: meta.ids }, result.queryTerms)))\n const modules = found.modules.map(({ meta, result }) => ({\n meta,\n matchedOn: matchedOn(\n result.match,\n { providers: meta.entry.providers, tags: meta.entry.tags, ids: meta.ids, category: meta.entry.category },\n result.queryTerms,\n ),\n }))\n return { line, latest, modules, builtIn, didYouMean }\n}\n\nexport function toModuleCard(searcher: CatalogSearcher, hit: RankedModule, line: string | null, latest: string | null): ModuleCard {\n const entry = hit.meta.entry\n return {\n locator: entry.locator,\n path: entry.path,\n title: entry.title,\n summary: entry.summary,\n whenToUse: entry.whenToUse,\n type: entry.type,\n kind: entry.kind,\n category: entry.category,\n license: { spdx: entry.license.spdx, kind: entry.license.kind },\n tier: entry.tier,\n omQuality: hit.meta.omQuality,\n verifiedOn: entry.compat.verifiedOn,\n line,\n status: line ? statusOn(entry, line) : null,\n agentPolicy: line ? (entry.agentPolicy[line] ?? null) : null,\n installableFrom: entry.version.installableFrom,\n ...installFields(entry, line, latest, peerLookup(searcher)),\n matchedOn: hit.matchedOn,\n card: absolute(searcher.site, entry.links.page),\n }\n}\n\n/** The listed entries of the search index, where the catalog looks up an adapter's peer libraries. */\nexport function peerLookup(searcher: CatalogSearcher): PeerLookup {\n return (locator) => searcher.modules.get(locator)?.entry\n}\n\nexport function receiptSourceOf(searcher: CatalogSearcher): ReceiptSource | null {\n const source = searcher.index.dataAsOf?.source\n return source === 'ci' || source === 'preview' ? source : null\n}\n\nexport function searchModules(searcher: CatalogSearcher, input: SearchModulesInput): SearchModulesOutput {\n const limit = Math.min(SEARCH_MAX_LIMIT, Math.max(1, Math.floor(input.limit ?? SEARCH_DEFAULTS.limit)))\n const ranked = rankModules(searcher, input)\n return {\n results: ranked.modules.slice(0, limit).map((hit) => toModuleCard(searcher, hit, ranked.line, ranked.latest)),\n builtIn: ranked.builtIn,\n total: ranked.modules.length,\n line: ranked.line,\n dataVersion: searcher.index.dataVersion,\n generatedAt: searcher.index.generatedAt,\n receiptSource: receiptSourceOf(searcher),\n ...(ranked.didYouMean ? { didYouMean: ranked.didYouMean } : {}),\n }\n}\n\nexport function stripVersion(ref: string): { name: string; version: string | null } {\n const match = /^(.+?)@(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(ref.trim())\n return match ? { name: match[1] as string, version: match[2] as string } : { name: ref.trim(), version: null }\n}\n\nexport type ResolvedRef =\n | { kind: 'entry'; entry: CatalogEntry; candidates: string[] }\n | { kind: 'builtin'; builtIn: BuiltInModule; candidates: string[] }\n | { kind: 'none'; candidates: string[] }\n\nconst normalizeRef = (value: string) => value.trim().toLowerCase()\nconst rankEntry = (entry: CatalogEntry) => (entry.type === 'official' ? 0 : 2) + (entry.tier === 'verified' ? 0 : 1)\n\nexport function resolveRef(ref: string, entries: readonly CatalogEntry[], builtIn: readonly BuiltInModule[]): ResolvedRef {\n const wanted = normalizeRef(stripVersion(ref).name)\n const direct = entries.find(\n (entry) =>\n normalizeRef(entry.locator) === wanted ||\n (entry.npm !== null && normalizeRef(entry.npm) === wanted) ||\n normalizeRef(entry.path) === wanted ||\n normalizeRef(`/m/${entry.path}`) === wanted ||\n entry.renamedFrom.some((previous) => normalizeRef(previous) === wanted || normalizeRef(previous) === `npm:${wanted}`),\n )\n if (direct) return { kind: 'entry', entry: direct, candidates: [] }\n const githubPath = wanted.startsWith('github:')\n ? `github/${wanted.slice(7)}`\n : wanted.replace(/^https:\\/\\/github\\.com\\//, 'github/')\n const github = entries.find((entry) => normalizeRef(entry.path) === githubPath)\n if (github) return { kind: 'entry', entry: github, candidates: [] }\n\n const id = wanted.replace(/^core:/, '')\n const byId = entries.filter((entry) => entry.moduleIds.includes(id)).sort((left, right) => rankEntry(left) - rankEntry(right))\n const core = builtIn.find((coreModule) => coreModule.id === id)\n if (core) return { kind: 'builtin', builtIn: core, candidates: byId.map((entry) => entry.locator).slice(0, 10) }\n if (byId.length === 1) return { kind: 'entry', entry: byId[0] as CatalogEntry, candidates: [] }\n if (byId.length > 1) return { kind: 'none', candidates: byId.map((entry) => entry.locator).slice(0, 10) }\n\n const loose = entries\n .filter(\n (entry) =>\n wanted.length >= 3 &&\n (normalizeRef(entry.locator).includes(wanted) || entry.moduleIds.some((moduleId) => moduleId.includes(wanted.replace(/-/g, '_')))),\n )\n .sort((left, right) => rankEntry(left) - rankEntry(right))\n return { kind: 'none', candidates: loose.map((entry) => entry.locator).slice(0, 10) }\n}\n\nconst clip = (text: string, max = 200) => (text.length > max ? `${text.slice(0, max - 3)}...` : text)\n\nexport function entryWarnings(\n entry: CatalogEntry,\n today: string,\n line: string | null,\n receiptSource: ReceiptSource | null = null,\n): string[] {\n const warnings: string[] = []\n if (!entry.listed) warnings.push(`Not listed: ${(line ? entry.agentPolicy[line] : null)?.reasons[0]?.text ?? 'see the card.'}`)\n if (entry.status !== 'active') warnings.push(`Status: ${entry.status}.`)\n if (entry.version.installableFrom && entry.version.installableFrom > today)\n warnings.push(\n `${entry.version.latest ?? 'The newest release'} is installable from ${entry.version.installableFrom} (Yarn age gate).`,\n )\n if (entry.license.mismatch) warnings.push('License sources disagree. See the card.')\n const supplyChain = entry.signals?.supplyChain\n if (supplyChain && supplyChain.status !== 'ok')\n warnings.push(`Supply chain ${supplyChain.status}: ${supplyChain.reasons.join('; ') || 'see the card'}.`)\n const hygiene = entry.signals?.hygiene\n if (hygiene && hygiene.status !== 'ok') warnings.push(`Hygiene ${hygiene.status}: ${hygiene.failing.join(', ') || 'see the card'}.`)\n if (entry.signals?.anatomy === 'hidden') warnings.push('Anatomy is not published for this entry.')\n return [...(receiptSource === 'preview' ? [PREVIEW_LINE] : []), ...warnings.map((warning) => clip(warning))].slice(0, 10)\n}\n\nexport function unknownModuleMessage(ref: string, candidates: readonly string[]): string {\n return candidates.length > 0\n ? `Unknown module \"${ref.slice(0, 80)}\". Did you mean: ${candidates.join(', ')}?`\n : `Unknown module \"${ref.slice(0, 80)}\".`\n}\n\nexport function builtInWarnings(coreModule: BuiltInModule, line: string | null): string[] {\n return builtInNotes(coreModule, line).map((note) => clip(note))\n}\n\nexport function sharedModuleIdWarning(id: string, count: number): string {\n return clip(`Module ID ${id} is provided by ${count} entries. Pick one of the candidates.`)\n}\n\nexport function cardUrl(searcher: CatalogSearcher, page: string): string {\n return absolute(searcher.site, page)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["line", "modules", "query", "best", "top"]
7
7
  }
@@ -29,6 +29,7 @@ import {
29
29
  import { parseModuleInfoArgs, parseModuleSearchArgs } from "./module-search-args.js";
30
30
  const DEFAULT_MODULES_INDEX_URL = "https://modules.openmercato.com/modules.json";
31
31
  const MODULES_SITE_URL = "https://modules.openmercato.com";
32
+ const MODULE_INDEX_MAX_BYTES = 10 * 1024 * 1024;
32
33
  const MODULE_INDEX_TIMEOUT_MS = 4e3;
33
34
  const MODULE_INDEX_TTL_MS = 10 * 60 * 1e3;
34
35
  const MODULE_INDEX_CACHE_FILE = path.join(".mercato", "cache", "modules-index.json");
@@ -156,10 +157,59 @@ function writeCache(file, cache) {
156
157
  return;
157
158
  }
158
159
  }
160
+ function validateIndexUrl(value) {
161
+ const url = new URL(value);
162
+ const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
163
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && local)) {
164
+ throw new Error("[internal] Module index URL must use HTTPS except on loopback hosts");
165
+ }
166
+ }
159
167
  async function fetchOnce(fetchImpl, url, etag, timeoutMs) {
160
168
  const headers = { accept: "application/json" };
161
169
  if (etag) headers["if-none-match"] = etag;
162
- return fetchImpl(url, { headers, signal: AbortSignal.timeout(timeoutMs) });
170
+ const signal = AbortSignal.timeout(timeoutMs);
171
+ let target = url;
172
+ for (let redirects = 0; redirects <= 5; redirects += 1) {
173
+ validateIndexUrl(target);
174
+ const response = await fetchImpl(target, { headers, signal, redirect: "manual" });
175
+ if (![301, 302, 303, 307, 308].includes(response.status)) return response;
176
+ await response.body?.cancel();
177
+ const location = response.headers.get("location");
178
+ if (!location || redirects === 5) throw new Error("[internal] Invalid or excessive module index redirects");
179
+ target = new URL(location, target).toString();
180
+ }
181
+ throw new Error("[internal] Excessive module index redirects");
182
+ }
183
+ async function readBoundedJson(response) {
184
+ const tooLarge = () => new Error(`[internal] Module index exceeds ${MODULE_INDEX_MAX_BYTES} bytes`);
185
+ const length = Number(response.headers.get("content-length"));
186
+ if (length > MODULE_INDEX_MAX_BYTES) {
187
+ await response.body?.cancel();
188
+ throw tooLarge();
189
+ }
190
+ if (!response.body) {
191
+ const value = await response.json();
192
+ if (Buffer.byteLength(JSON.stringify(value) ?? "") > MODULE_INDEX_MAX_BYTES) throw tooLarge();
193
+ return value;
194
+ }
195
+ const reader = response.body.getReader();
196
+ const chunks = [];
197
+ let bytes = 0;
198
+ try {
199
+ while (true) {
200
+ const chunk = await reader.read();
201
+ if (chunk.done) break;
202
+ bytes += chunk.value.byteLength;
203
+ if (bytes > MODULE_INDEX_MAX_BYTES) {
204
+ await reader.cancel();
205
+ throw tooLarge();
206
+ }
207
+ chunks.push(chunk.value);
208
+ }
209
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
210
+ } finally {
211
+ reader.releaseLock();
212
+ }
163
213
  }
164
214
  async function fetchWithRetry(fetchImpl, url, etag, timeoutMs) {
165
215
  let lastError = null;
@@ -167,6 +217,7 @@ async function fetchWithRetry(fetchImpl, url, etag, timeoutMs) {
167
217
  try {
168
218
  const response = await fetchOnce(fetchImpl, url, etag, timeoutMs);
169
219
  if (response.status >= 500) {
220
+ await response.body?.cancel();
170
221
  lastError = new Error(`${url} answered ${response.status}`);
171
222
  continue;
172
223
  }
@@ -181,7 +232,7 @@ async function fetchJson(fetchImpl, url, etag, timeoutMs, parse) {
181
232
  const response = await fetchWithRetry(fetchImpl, url, etag, timeoutMs);
182
233
  if (response.status === 304) return { notModified: true };
183
234
  if (!response.ok) throw new Error(`${url} answered ${response.status}`);
184
- const value = parse(await response.json());
235
+ const value = parse(await readBoundedJson(response));
185
236
  if (value === null) throw new Error(`${url} is not a module index this CLI understands`);
186
237
  return { notModified: false, value, etag: response.headers.get("etag") };
187
238
  }
@@ -194,7 +245,14 @@ function searcherOf(index, builtIn) {
194
245
  }
195
246
  async function loadIndex(options) {
196
247
  const url = options.url ?? DEFAULT_MODULES_INDEX_URL;
197
- const builtInUrl = options.builtInUrl ?? defaultBuiltInUrl(url);
248
+ let builtInUrl;
249
+ try {
250
+ validateIndexUrl(url);
251
+ builtInUrl = options.builtInUrl ?? defaultBuiltInUrl(url);
252
+ validateIndexUrl(builtInUrl);
253
+ } catch (error) {
254
+ throw new ModuleIndexUnavailableError(error instanceof Error ? error.message : String(error));
255
+ }
198
256
  const timeoutMs = options.timeoutMs ?? MODULE_INDEX_TIMEOUT_MS;
199
257
  const ttlMs = options.ttlMs ?? MODULE_INDEX_TTL_MS;
200
258
  const fetchImpl = options.fetchImpl ?? ((input, init) => fetch(input, init));
@@ -646,6 +704,7 @@ export {
646
704
  DEFAULT_MODULES_INDEX_URL,
647
705
  MODULES_SITE_URL,
648
706
  MODULE_INDEX_CACHE_FILE,
707
+ MODULE_INDEX_MAX_BYTES,
649
708
  MODULE_INDEX_TIMEOUT_MS,
650
709
  MODULE_INDEX_TTL_MS,
651
710
  MODULE_INDEX_UNAVAILABLE_EXIT_CODE,