@open-mercato/cli 0.8.1-develop.7207.1.901ef7e47a → 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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/agentic/guides/module-facts.json +140 -140
- package/dist/agentic/guides/module-facts.v2.json +140 -140
- package/dist/agentic/guides/modules/agent_orchestrator/index.md +1 -1
- package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
- package/dist/agentic/guides/modules/api_docs/index.md +1 -1
- package/dist/agentic/guides/modules/api_keys/index.md +1 -1
- package/dist/agentic/guides/modules/attachments/index.md +1 -1
- package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
- package/dist/agentic/guides/modules/auth/index.md +1 -1
- package/dist/agentic/guides/modules/business_rules/index.md +1 -1
- package/dist/agentic/guides/modules/catalog/index.md +1 -1
- package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
- package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
- package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
- package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
- package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
- package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
- package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
- package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
- package/dist/agentic/guides/modules/checkout/index.md +1 -1
- package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
- package/dist/agentic/guides/modules/configs/index.md +1 -1
- package/dist/agentic/guides/modules/content/index.md +1 -1
- package/dist/agentic/guides/modules/currencies/index.md +1 -1
- package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
- package/dist/agentic/guides/modules/customers/index.md +1 -1
- package/dist/agentic/guides/modules/dashboards/index.md +1 -1
- package/dist/agentic/guides/modules/data_sync/index.md +1 -1
- package/dist/agentic/guides/modules/design_system/index.md +1 -1
- package/dist/agentic/guides/modules/devices/index.md +1 -1
- package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
- package/dist/agentic/guides/modules/directory/index.md +1 -1
- package/dist/agentic/guides/modules/documents/index.md +1 -1
- package/dist/agentic/guides/modules/entities/index.md +1 -1
- package/dist/agentic/guides/modules/eudr/index.md +1 -1
- package/dist/agentic/guides/modules/events/index.md +1 -1
- package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
- package/dist/agentic/guides/modules/generators/index.md +1 -1
- package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
- package/dist/agentic/guides/modules/integrations/index.md +1 -1
- package/dist/agentic/guides/modules/messages/index.md +1 -1
- package/dist/agentic/guides/modules/notifications/index.md +1 -1
- package/dist/agentic/guides/modules/onboarding/index.md +1 -1
- package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
- package/dist/agentic/guides/modules/perspectives/index.md +1 -1
- package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
- package/dist/agentic/guides/modules/planner/index.md +1 -1
- package/dist/agentic/guides/modules/portal/index.md +1 -1
- package/dist/agentic/guides/modules/progress/index.md +1 -1
- package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
- package/dist/agentic/guides/modules/query_index/index.md +1 -1
- package/dist/agentic/guides/modules/record_locks/index.md +1 -1
- package/dist/agentic/guides/modules/resources/index.md +1 -1
- package/dist/agentic/guides/modules/sales/index.md +1 -1
- package/dist/agentic/guides/modules/scheduler/index.md +1 -1
- package/dist/agentic/guides/modules/search/index.md +1 -1
- package/dist/agentic/guides/modules/security/index.md +1 -1
- package/dist/agentic/guides/modules/seeds/index.md +1 -1
- package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
- package/dist/agentic/guides/modules/sso/index.md +1 -1
- package/dist/agentic/guides/modules/staff/index.md +1 -1
- package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
- package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
- package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
- package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
- package/dist/agentic/guides/modules/tillio/index.md +1 -1
- package/dist/agentic/guides/modules/translations/index.md +1 -1
- package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
- package/dist/agentic/guides/modules/webhooks/index.md +1 -1
- package/dist/agentic/guides/modules/wms/index.md +1 -1
- package/dist/agentic/guides/modules/workflows/index.md +1 -1
- package/dist/agentic/guides/reference-module-facts.json +1 -1
- package/dist/agentic/guides/upstream/manifest.json +1 -1
- package/dist/lib/generators/module-extension-facts.js +11 -2
- package/dist/lib/generators/module-extension-facts.js.map +2 -2
- package/dist/mercato.js +1 -1
- package/dist/mercato.js.map +2 -2
- package/package.json +6 -6
- package/src/__tests__/mercato.test.ts +79 -0
- package/src/lib/generators/__tests__/module-extension-facts.test.ts +35 -0
- package/src/lib/generators/module-extension-facts.ts +18 -2
- 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.
|
|
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.
|
|
64
|
-
"@open-mercato/shared": "0.8.1-develop.
|
|
65
|
-
"@open-mercato/telemetry": "0.8.1-develop.
|
|
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.
|
|
76
|
+
"@open-mercato/shared": "0.8.1-develop.7215.1.60786cf836"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
|
-
"@open-mercato/shared": "0.8.1-develop.
|
|
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 =
|
|
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:
|
|
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 =
|
|
1492
|
+
const allModules = getCliModules()
|
|
1493
1493
|
|
|
1494
1494
|
const modulesToSeed = moduleFilter
|
|
1495
1495
|
? allModules.filter((mod) => mod.id === moduleFilter)
|