@open-mercato/cli 0.8.1-develop.7206.1.45a3cee87f → 0.8.1-develop.7215.1.60786cf836

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 (84) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/agentic/guides/module-facts.json +140 -140
  3. package/dist/agentic/guides/module-facts.v2.json +140 -140
  4. package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
  5. package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
  6. package/dist/agentic/guides/modules/api_docs/index.md +1 -1
  7. package/dist/agentic/guides/modules/api_keys/index.md +1 -1
  8. package/dist/agentic/guides/modules/attachments/index.md +1 -1
  9. package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
  10. package/dist/agentic/guides/modules/auth/index.md +1 -1
  11. package/dist/agentic/guides/modules/business_rules/index.md +1 -1
  12. package/dist/agentic/guides/modules/catalog/index.md +1 -1
  13. package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
  14. package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
  15. package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
  16. package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
  17. package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
  18. package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
  19. package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
  20. package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
  21. package/dist/agentic/guides/modules/checkout/index.md +1 -1
  22. package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
  23. package/dist/agentic/guides/modules/configs/index.md +1 -1
  24. package/dist/agentic/guides/modules/content/index.md +1 -1
  25. package/dist/agentic/guides/modules/currencies/index.md +1 -1
  26. package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
  27. package/dist/agentic/guides/modules/customers/index.md +1 -1
  28. package/dist/agentic/guides/modules/dashboards/index.md +1 -1
  29. package/dist/agentic/guides/modules/data_sync/index.md +1 -1
  30. package/dist/agentic/guides/modules/design_system/index.md +1 -1
  31. package/dist/agentic/guides/modules/devices/index.md +1 -1
  32. package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
  33. package/dist/agentic/guides/modules/directory/index.md +1 -1
  34. package/dist/agentic/guides/modules/documents/index.md +1 -1
  35. package/dist/agentic/guides/modules/entities/index.md +1 -1
  36. package/dist/agentic/guides/modules/eudr/index.md +1 -1
  37. package/dist/agentic/guides/modules/events/index.md +1 -1
  38. package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
  39. package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
  40. package/dist/agentic/guides/modules/generators/index.md +1 -1
  41. package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
  42. package/dist/agentic/guides/modules/integrations/index.md +1 -1
  43. package/dist/agentic/guides/modules/messages/index.md +1 -1
  44. package/dist/agentic/guides/modules/notifications/index.md +1 -1
  45. package/dist/agentic/guides/modules/onboarding/index.md +1 -1
  46. package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
  47. package/dist/agentic/guides/modules/perspectives/index.md +1 -1
  48. package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
  49. package/dist/agentic/guides/modules/planner/index.md +1 -1
  50. package/dist/agentic/guides/modules/portal/index.md +1 -1
  51. package/dist/agentic/guides/modules/progress/index.md +1 -1
  52. package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
  53. package/dist/agentic/guides/modules/query_index/index.md +1 -1
  54. package/dist/agentic/guides/modules/record_locks/index.md +1 -1
  55. package/dist/agentic/guides/modules/resources/index.md +1 -1
  56. package/dist/agentic/guides/modules/sales/index.md +1 -1
  57. package/dist/agentic/guides/modules/scheduler/index.md +1 -1
  58. package/dist/agentic/guides/modules/search/index.md +1 -1
  59. package/dist/agentic/guides/modules/security/index.md +1 -1
  60. package/dist/agentic/guides/modules/seeds/index.md +1 -1
  61. package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
  62. package/dist/agentic/guides/modules/sso/index.md +1 -1
  63. package/dist/agentic/guides/modules/staff/index.md +1 -1
  64. package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
  65. package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
  66. package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
  67. package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
  68. package/dist/agentic/guides/modules/tillio/index.md +1 -1
  69. package/dist/agentic/guides/modules/translations/index.md +1 -1
  70. package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
  71. package/dist/agentic/guides/modules/webhooks/index.md +1 -1
  72. package/dist/agentic/guides/modules/wms/index.md +1 -1
  73. package/dist/agentic/guides/modules/workflows/index.md +1 -1
  74. package/dist/agentic/guides/reference-module-facts.json +1 -1
  75. package/dist/agentic/guides/upstream/manifest.json +1 -1
  76. package/dist/lib/generators/module-extension-facts.js +11 -2
  77. package/dist/lib/generators/module-extension-facts.js.map +2 -2
  78. package/dist/mercato.js +1 -1
  79. package/dist/mercato.js.map +2 -2
  80. package/package.json +6 -6
  81. package/src/__tests__/mercato.test.ts +79 -0
  82. package/src/lib/generators/__tests__/module-extension-facts.test.ts +35 -0
  83. package/src/lib/generators/module-extension-facts.ts +18 -2
  84. package/src/mercato.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.8.1-develop.7206.1.45a3cee87f",
3
+ "version": "0.8.1-develop.7215.1.60786cf836",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -60,9 +60,9 @@
60
60
  "@mikro-orm/decorators": "^7.1.14",
61
61
  "@mikro-orm/migrations": "^7.1.14",
62
62
  "@mikro-orm/postgresql": "^7.1.14",
63
- "@open-mercato/queue": "0.8.1-develop.7206.1.45a3cee87f",
64
- "@open-mercato/shared": "0.8.1-develop.7206.1.45a3cee87f",
65
- "@open-mercato/telemetry": "0.8.1-develop.7206.1.45a3cee87f",
63
+ "@open-mercato/queue": "0.8.1-develop.7215.1.60786cf836",
64
+ "@open-mercato/shared": "0.8.1-develop.7215.1.60786cf836",
65
+ "@open-mercato/telemetry": "0.8.1-develop.7215.1.60786cf836",
66
66
  "cross-spawn": "^7.0.6",
67
67
  "pg": "8.23.0",
68
68
  "semver": "^7.8.5",
@@ -73,10 +73,10 @@
73
73
  "typescript-js": "npm:typescript@6.0.3"
74
74
  },
75
75
  "peerDependencies": {
76
- "@open-mercato/shared": "0.8.1-develop.7206.1.45a3cee87f"
76
+ "@open-mercato/shared": "0.8.1-develop.7215.1.60786cf836"
77
77
  },
78
78
  "devDependencies": {
79
- "@open-mercato/shared": "0.8.1-develop.7206.1.45a3cee87f",
79
+ "@open-mercato/shared": "0.8.1-develop.7215.1.60786cf836",
80
80
  "@types/jest": "^30.0.0",
81
81
  "jest": "^30.4.2",
82
82
  "ts-jest": "^29.4.12"
@@ -531,6 +531,85 @@ describe('init command failure output', () => {
531
531
  })
532
532
  })
533
533
 
534
+ describe('seed:defaults command', () => {
535
+ const originalDatabaseUrl = process.env.DATABASE_URL
536
+
537
+ beforeEach(() => {
538
+ jest.restoreAllMocks()
539
+ jest.resetModules()
540
+ process.env.DATABASE_URL = 'postgres://postgres:secret@127.0.0.1:5432/open_mercato'
541
+ })
542
+
543
+ afterEach(() => {
544
+ jest.dontMock('../lib/resolver')
545
+ jest.dontMock('@open-mercato/shared/lib/bootstrap/dynamicLoader')
546
+ jest.dontMock('@open-mercato/shared/lib/di/container')
547
+ jest.dontMock('@open-mercato/core/modules/directory/data/entities')
548
+ jest.dontMock('@open-mercato/core/modules/auth/lib/setup-app')
549
+ jest.resetModules()
550
+ })
551
+
552
+ afterAll(() => {
553
+ process.env.DATABASE_URL = originalDatabaseUrl
554
+ })
555
+
556
+ it('honors an overrides.setup.seedDefaults: false entry instead of seeding from the raw bootstrap array', async () => {
557
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
558
+ const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
559
+
560
+ const { applyModuleOverridesFromEnabledModules } = await import('@open-mercato/shared/modules/overrides')
561
+ applyModuleOverridesFromEnabledModules([
562
+ { id: 'workflows', overrides: { setup: { seedDefaults: false } } },
563
+ ])
564
+
565
+ const workflowsSeedDefaults = jest.fn().mockResolvedValue(undefined)
566
+ const catalogSeedDefaults = jest.fn().mockResolvedValue(undefined)
567
+
568
+ jest.doMock('../lib/resolver', () => ({
569
+ createResolver: () => ({
570
+ getAppDir: () => '/tmp/test-app',
571
+ }),
572
+ }))
573
+ jest.doMock('@open-mercato/shared/lib/bootstrap/dynamicLoader', () => ({
574
+ bootstrapFromAppRoot: jest.fn().mockResolvedValue({
575
+ modules: [
576
+ { id: 'workflows', setup: { seedDefaults: workflowsSeedDefaults } },
577
+ { id: 'catalog', setup: { seedDefaults: catalogSeedDefaults } },
578
+ ],
579
+ }),
580
+ }))
581
+ jest.doMock('@open-mercato/shared/lib/di/container', () => ({
582
+ createRequestContainer: jest.fn().mockResolvedValue({
583
+ resolve: jest.fn().mockReturnValue({
584
+ find: jest.fn().mockResolvedValue([{ id: 'org-1', tenant: { id: 'tenant-1' } }]),
585
+ }),
586
+ }),
587
+ }))
588
+ jest.doMock(
589
+ '@open-mercato/core/modules/directory/data/entities',
590
+ () => ({ Organization: class Organization {} }),
591
+ { virtual: true },
592
+ )
593
+ jest.doMock(
594
+ '@open-mercato/core/modules/auth/lib/setup-app',
595
+ () => ({ ensureCustomRoleAcls: jest.fn().mockResolvedValue(undefined) }),
596
+ { virtual: true },
597
+ )
598
+
599
+ const mercato = await import('../mercato')
600
+ const exitCode = await mercato.run(['node', 'mercato', 'seed:defaults'])
601
+
602
+ expect(exitCode).toBe(0)
603
+ expect(workflowsSeedDefaults).not.toHaveBeenCalled()
604
+ expect(catalogSeedDefaults).toHaveBeenCalledWith(
605
+ expect.objectContaining({ tenantId: 'tenant-1', organizationId: 'org-1' }),
606
+ )
607
+
608
+ consoleErrorSpy.mockRestore()
609
+ consoleLogSpy.mockRestore()
610
+ })
611
+ })
612
+
534
613
  describe('generate post-step structural invalidation', () => {
535
614
  beforeEach(() => {
536
615
  jest.restoreAllMocks()
@@ -76,6 +76,41 @@ describe('module extension facts', () => {
76
76
  expect(hostOrder).toEqual([...hostOrder].sort((left, right) => left.localeCompare(right)))
77
77
  })
78
78
 
79
+ it('captures extra mount points from an array-form host source, keeping the first entry as the primary path', () => {
80
+ write(moduleRoot, 'extension-points.ts', `
81
+ import { defineModuleExtensionPoints, dataTableExtensionHost, crudFormExtensionHost } from 'x'
82
+ export const extensionPoints = defineModuleExtensionPoints({
83
+ moduleId: 'alpha',
84
+ hosts: {
85
+ records: dataTableExtensionHost({ tableId: 'alpha.records.list', source: ['Records.tsx', 'Extra.tsx'] }),
86
+ editor: crudFormExtensionHost({ entityId: 'alpha.record', source: 'Edit.tsx' }),
87
+ },
88
+ })
89
+ `)
90
+ write(moduleRoot, 'Records.tsx', 'export const tableId = extensionPoints.hosts.records.tableId')
91
+ write(moduleRoot, 'Extra.tsx', 'export const extra = true')
92
+ write(moduleRoot, 'Edit.tsx', 'export const entityId = extensionPoints.hosts.editor.entityId')
93
+
94
+ const facts = extractModuleExtensionFacts({
95
+ moduleId: 'alpha',
96
+ moduleRoot,
97
+ sourceRoot: 'node_modules/pkg/src/modules/alpha',
98
+ entities: [],
99
+ events: [],
100
+ apiRoutes: [],
101
+ searchEntities: [],
102
+ })
103
+
104
+ const header = facts.hosts.find((host) => host.id === 'data-table:alpha.records.list:header')
105
+ expect(header?.bound).toBe(true)
106
+ expect(header?.source).toMatchObject({ kind: 'declaration', symbol: 'extensionPoints.hosts.records' })
107
+ expect(header?.additionalSources).toEqual(['Extra.tsx'])
108
+
109
+ const editorFields = facts.hosts.find((host) => host.id === 'crud-form:alpha.record:fields')
110
+ expect(editorFields?.bound).toBe(true)
111
+ expect(editorFields?.additionalSources).toBeUndefined()
112
+ })
113
+
79
114
  it('extracts outgoing mechanisms with kind-specific contracts and correlates targets', () => {
80
115
  write(moduleRoot, 'extension-points.ts', `
81
116
  import { defineModuleExtensionPoints, dataTableExtensionHost } from 'x'
@@ -439,6 +439,20 @@ function stringValue(value: StaticValue | undefined): string | undefined {
439
439
  return typeof value === 'string' ? value : undefined
440
440
  }
441
441
 
442
+ /**
443
+ * Normalizes a `source` declaration (single string or array of strings) into
444
+ * an ordered list. The first entry stays the authoritative provenance path;
445
+ * any remaining entries are additional mount points.
446
+ */
447
+ function sourceEntries(value: StaticValue | undefined): string[] {
448
+ if (typeof value === 'string') return [value]
449
+ return strings(value)
450
+ }
451
+
452
+ function primarySource(value: StaticValue | undefined): string | undefined {
453
+ return sourceEntries(value)[0]
454
+ }
455
+
442
456
  function numberValue(value: StaticValue | undefined): number | undefined {
443
457
  if (typeof value === 'number') return value
444
458
  if (typeof value === 'string' && /^\d+$/.test(value)) return Number(value)
@@ -560,7 +574,7 @@ function hasDeclarationBinding(
560
574
  hostKey: string,
561
575
  declaration: StaticObject,
562
576
  ): boolean {
563
- const relativeSource = stringValue(declaration.source)
577
+ const relativeSource = primarySource(declaration.source)
564
578
  if (!relativeSource) return false
565
579
  const bindingFile = sourceFile(path.join(moduleRoot, relativeSource))
566
580
  if (!bindingFile) return false
@@ -588,6 +602,7 @@ function baseHost(options: {
588
602
  const { declaration } = options
589
603
  const aliases = strings(declaration.aliases)
590
604
  const fallbacks = strings(declaration.fallbacks)
605
+ const additionalSources = sourceEntries(declaration.source).slice(1)
591
606
  const fact: ModuleExtensionHostFact = {
592
607
  key: options.key,
593
608
  id: options.id,
@@ -611,6 +626,7 @@ function baseHost(options: {
611
626
  if (activation) fact.activation = activation
612
627
  if (aliases.length > 0) fact.aliases = aliases
613
628
  if (fallbacks.length > 0) fact.fallbacks = fallbacks
629
+ if (additionalSources.length > 0) fact.additionalSources = additionalSources
614
630
  return fact
615
631
  }
616
632
 
@@ -645,7 +661,7 @@ function extractDeclaredHosts(options: ExtractModuleExtensionFactsOptions): {
645
661
  unresolved.push({
646
662
  key: `${options.moduleId}.${hostKey}`,
647
663
  source: {
648
- path: stringValue(host.source) ?? portablePath(options.moduleRoot, options.sourceRoot, filePath),
664
+ path: primarySource(host.source) ?? portablePath(options.moduleRoot, options.sourceRoot, filePath),
649
665
  symbol: `extensionPoints.hosts.${hostKey}`,
650
666
  },
651
667
  reason: 'unbound-declaration',
package/src/mercato.ts CHANGED
@@ -1489,7 +1489,7 @@ export async function run(argv = process.argv) {
1489
1489
  const resolver = createResolver()
1490
1490
  const data = await bootstrapFromAppRoot(resolver.getAppDir())
1491
1491
  registerCliModules(data.modules)
1492
- const allModules = data.modules
1492
+ const allModules = getCliModules()
1493
1493
 
1494
1494
  const modulesToSeed = moduleFilter
1495
1495
  ? allModules.filter((mod) => mod.id === moduleFilter)