@open-mercato/cli 0.10.1-develop.7903.1.d8ab1c8b0d → 0.10.1-develop.7907.1.28240ddda3
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 +162 -162
- package/dist/agentic/guides/module-facts.v2.json +162 -162
- 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/availability/index.md +1 -1
- package/dist/agentic/guides/modules/business_rules/index.md +1 -1
- package/dist/agentic/guides/modules/carrier_inpost/index.md +1 -1
- package/dist/agentic/guides/modules/cart/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/channel_smtp/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/customer_groups/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/ecommerce/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/forms/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_autopay/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
- package/dist/agentic/guides/modules/gateway_tpay/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/promotions/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/telemetry/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/agentic/shared/AGENTS.md.template +1 -1
- package/dist/agentic/shared/ai/harness/README.md +4 -2
- package/dist/agentic/shared/ai/harness/RELEASE.md +4 -4
- package/dist/agentic/shared/ai/harness/cases.json +75 -0
- package/dist/agentic/shared/ai/harness/cases.schema.json +4 -4
- package/dist/agentic/shared/ai/harness/validators.json +1 -1
- package/dist/agentic/shared/ai/skills/om-find-module/SKILL.md +52 -0
- package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +1 -0
- package/dist/agentic/shared/ai/skills/tiers.json +1 -0
- package/dist/lib/init-existing-database.js +26 -0
- package/dist/lib/init-existing-database.js.map +7 -0
- package/dist/mercato.js +15 -4
- package/dist/mercato.js.map +2 -2
- package/package.json +7 -7
- package/src/__tests__/mercato.test.ts +90 -0
- package/src/lib/__tests__/init-existing-database.test.ts +27 -0
- package/src/lib/init-existing-database.ts +24 -0
- package/src/mercato.ts +15 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/cli",
|
|
3
|
-
"version": "0.10.1-develop.
|
|
3
|
+
"version": "0.10.1-develop.7907.1.28240ddda3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -60,10 +60,10 @@
|
|
|
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/events": "0.10.1-develop.
|
|
64
|
-
"@open-mercato/queue": "0.10.1-develop.
|
|
65
|
-
"@open-mercato/shared": "0.10.1-develop.
|
|
66
|
-
"@open-mercato/telemetry": "0.10.1-develop.
|
|
63
|
+
"@open-mercato/events": "0.10.1-develop.7907.1.28240ddda3",
|
|
64
|
+
"@open-mercato/queue": "0.10.1-develop.7907.1.28240ddda3",
|
|
65
|
+
"@open-mercato/shared": "0.10.1-develop.7907.1.28240ddda3",
|
|
66
|
+
"@open-mercato/telemetry": "0.10.1-develop.7907.1.28240ddda3",
|
|
67
67
|
"cross-spawn": "^7.0.6",
|
|
68
68
|
"minisearch": "7.2.0",
|
|
69
69
|
"pg": "8.23.0",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"typescript-js": "npm:typescript@6.0.3"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@open-mercato/shared": "0.10.1-develop.
|
|
78
|
+
"@open-mercato/shared": "0.10.1-develop.7907.1.28240ddda3"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@open-mercato/shared": "0.10.1-develop.
|
|
81
|
+
"@open-mercato/shared": "0.10.1-develop.7907.1.28240ddda3",
|
|
82
82
|
"@types/jest": "^30.0.0",
|
|
83
83
|
"jest": "^30.4.2",
|
|
84
84
|
"ts-jest": "^29.4.12"
|
|
@@ -549,6 +549,7 @@ describe('--help never triggers side effects (issue #5581)', () => {
|
|
|
549
549
|
expect(exitCode).toBe(0)
|
|
550
550
|
const printed = consoleLogSpy.mock.calls.map((call) => String(call[0])).join('\n')
|
|
551
551
|
expect(printed).toContain('Usage: mercato init')
|
|
552
|
+
expect(printed).toContain('--skip-if-initialized')
|
|
552
553
|
|
|
553
554
|
consoleLogSpy.mockRestore()
|
|
554
555
|
consoleErrorSpy.mockRestore()
|
|
@@ -1267,6 +1268,95 @@ describe('init command failure output', () => {
|
|
|
1267
1268
|
})
|
|
1268
1269
|
})
|
|
1269
1270
|
|
|
1271
|
+
describe('init on an already initialized database', () => {
|
|
1272
|
+
const originalDatabaseUrl = process.env.DATABASE_URL
|
|
1273
|
+
|
|
1274
|
+
beforeEach(() => {
|
|
1275
|
+
jest.restoreAllMocks()
|
|
1276
|
+
jest.resetModules()
|
|
1277
|
+
process.env.DATABASE_URL = 'postgres://postgres:secret@db.example.com:6543/shop_a'
|
|
1278
|
+
})
|
|
1279
|
+
|
|
1280
|
+
afterEach(() => {
|
|
1281
|
+
jest.dontMock('child_process')
|
|
1282
|
+
jest.dontMock('pg')
|
|
1283
|
+
jest.dontMock('../lib/generators')
|
|
1284
|
+
jest.dontMock('../lib/resolver')
|
|
1285
|
+
jest.resetModules()
|
|
1286
|
+
})
|
|
1287
|
+
|
|
1288
|
+
afterAll(() => {
|
|
1289
|
+
process.env.DATABASE_URL = originalDatabaseUrl
|
|
1290
|
+
})
|
|
1291
|
+
|
|
1292
|
+
function mockSeededDatabase(usersCount: string) {
|
|
1293
|
+
const generateEntityIds = jest.fn().mockResolvedValue(undefined)
|
|
1294
|
+
jest.doMock('child_process', () => ({ execSync: jest.fn() }))
|
|
1295
|
+
jest.doMock('pg', () => ({
|
|
1296
|
+
Client: jest.fn().mockImplementation(() => ({
|
|
1297
|
+
connect: jest.fn().mockResolvedValue(undefined),
|
|
1298
|
+
end: jest.fn().mockResolvedValue(undefined),
|
|
1299
|
+
query: jest.fn().mockImplementation(async (sql: string) => {
|
|
1300
|
+
if (sql.includes('pg_database')) return { rows: [{ exists: 1 }] }
|
|
1301
|
+
if (sql.includes('to_regclass')) return { rows: [{ regclass: 'users' }] }
|
|
1302
|
+
if (sql.includes('COUNT(*)')) return { rows: [{ count: usersCount }] }
|
|
1303
|
+
return { rows: [] }
|
|
1304
|
+
}),
|
|
1305
|
+
})),
|
|
1306
|
+
}))
|
|
1307
|
+
jest.doMock('../lib/generators', () => ({
|
|
1308
|
+
generateEntityIds,
|
|
1309
|
+
generateModuleRegistries: jest.fn().mockResolvedValue(undefined),
|
|
1310
|
+
generateModuleEntities: jest.fn().mockResolvedValue(undefined),
|
|
1311
|
+
generateModuleDi: jest.fn().mockResolvedValue(undefined),
|
|
1312
|
+
generateModulePackageSources: jest.fn().mockResolvedValue(undefined),
|
|
1313
|
+
generateWebResearchAdapters: jest.fn().mockResolvedValue(undefined),
|
|
1314
|
+
generateOpenApi: jest.fn().mockResolvedValue(undefined),
|
|
1315
|
+
}))
|
|
1316
|
+
jest.doMock('../lib/resolver', () => ({
|
|
1317
|
+
createResolver: () => ({ getAppDir: () => '/tmp/test-app' }),
|
|
1318
|
+
}))
|
|
1319
|
+
return { generateEntityIds }
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
it('aborts without --skip-if-initialized and points at the explicit reinstall', async () => {
|
|
1323
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
|
|
1324
|
+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
|
|
1325
|
+
const { generateEntityIds } = mockSeededDatabase('2')
|
|
1326
|
+
|
|
1327
|
+
const mercato = await import('../mercato')
|
|
1328
|
+
const exitCode = await mercato.run(['node', 'mercato', 'init'])
|
|
1329
|
+
|
|
1330
|
+
expect(exitCode).toBe(1)
|
|
1331
|
+
const errors = consoleErrorSpy.mock.calls.map((call) => String(call[0])).join('\n')
|
|
1332
|
+
expect(errors).toContain('Initialization aborted: found 2 existing user(s)')
|
|
1333
|
+
expect(generateEntityIds).not.toHaveBeenCalled()
|
|
1334
|
+
|
|
1335
|
+
consoleErrorSpy.mockRestore()
|
|
1336
|
+
consoleLogSpy.mockRestore()
|
|
1337
|
+
})
|
|
1338
|
+
|
|
1339
|
+
it('keeps the data, names the target database and exits 0 with --skip-if-initialized', async () => {
|
|
1340
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
|
|
1341
|
+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
|
|
1342
|
+
const { generateEntityIds } = mockSeededDatabase('3')
|
|
1343
|
+
|
|
1344
|
+
const mercato = await import('../mercato')
|
|
1345
|
+
const exitCode = await mercato.run(['node', 'mercato', 'init', '--skip-if-initialized'])
|
|
1346
|
+
|
|
1347
|
+
expect(exitCode).toBe(0)
|
|
1348
|
+
const printed = consoleLogSpy.mock.calls.map((call) => String(call[0])).join('\n')
|
|
1349
|
+
expect(printed).toContain('Database already initialized (3 user(s) in db.example.com:6543/shop_a)')
|
|
1350
|
+
expect(printed).toContain('Check DATABASE_URL in .env')
|
|
1351
|
+
expect(printed).not.toContain('secret')
|
|
1352
|
+
expect(generateEntityIds).not.toHaveBeenCalled()
|
|
1353
|
+
expect(consoleErrorSpy).not.toHaveBeenCalled()
|
|
1354
|
+
|
|
1355
|
+
consoleErrorSpy.mockRestore()
|
|
1356
|
+
consoleLogSpy.mockRestore()
|
|
1357
|
+
})
|
|
1358
|
+
})
|
|
1359
|
+
|
|
1270
1360
|
describe('seed:defaults command', () => {
|
|
1271
1361
|
const originalDatabaseUrl = process.env.DATABASE_URL
|
|
1272
1362
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { decideExistingDatabase, describeDatabaseTarget, formatSkipIfInitializedMessage } from '../init-existing-database'
|
|
2
|
+
|
|
3
|
+
describe('init on an existing database', () => {
|
|
4
|
+
it('proceeds on an empty database regardless of the flag', () => {
|
|
5
|
+
expect(decideExistingDatabase(0, false)).toBe('proceed')
|
|
6
|
+
expect(decideExistingDatabase(0, true)).toBe('proceed')
|
|
7
|
+
expect(decideExistingDatabase(Number.NaN, true)).toBe('proceed')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('aborts on existing users unless --skip-if-initialized is passed', () => {
|
|
11
|
+
expect(decideExistingDatabase(2, false)).toBe('abort')
|
|
12
|
+
expect(decideExistingDatabase(2, true)).toBe('skip')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('describes the target database without credentials', () => {
|
|
16
|
+
expect(describeDatabaseTarget('postgres://postgres:secret@localhost:5432/open-mercato')).toBe('localhost:5432/open-mercato')
|
|
17
|
+
expect(describeDatabaseTarget('postgres://me:pw@db.example.com/shop%20a?sslmode=require')).toBe('db.example.com/shop a')
|
|
18
|
+
expect(describeDatabaseTarget('not a url')).toBe('the database from DATABASE_URL')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('tells the user which database was kept and how to check it', () => {
|
|
22
|
+
const lines = formatSkipIfInitializedMessage(4, 'postgres://postgres:secret@127.0.0.1:5432/app').join('\n')
|
|
23
|
+
expect(lines).toContain('4 user(s) in 127.0.0.1:5432/app')
|
|
24
|
+
expect(lines).toContain('DATABASE_URL')
|
|
25
|
+
expect(lines).not.toContain('secret')
|
|
26
|
+
})
|
|
27
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type ExistingDatabaseDecision = 'proceed' | 'skip' | 'abort'
|
|
2
|
+
|
|
3
|
+
export function decideExistingDatabase(existingUsersCount: number, skipIfInitialized: boolean): ExistingDatabaseDecision {
|
|
4
|
+
if (!Number.isFinite(existingUsersCount) || existingUsersCount <= 0) return 'proceed'
|
|
5
|
+
return skipIfInitialized ? 'skip' : 'abort'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function describeDatabaseTarget(databaseUrl: string): string {
|
|
9
|
+
try {
|
|
10
|
+
const url = new URL(databaseUrl)
|
|
11
|
+
const database = decodeURIComponent(url.pathname.replace(/^\/+/, '')) || '(default database)'
|
|
12
|
+
const host = url.hostname || 'localhost'
|
|
13
|
+
return `${host}${url.port ? `:${url.port}` : ''}/${database}`
|
|
14
|
+
} catch {
|
|
15
|
+
return 'the database from DATABASE_URL'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function formatSkipIfInitializedMessage(existingUsersCount: number, databaseUrl: string): string[] {
|
|
20
|
+
return [
|
|
21
|
+
`✅ Database already initialized (${existingUsersCount} user(s) in ${describeDatabaseTarget(databaseUrl)}) — keeping the existing data and skipping the first-run seed.`,
|
|
22
|
+
' Not the database you expected? Check DATABASE_URL in .env. To wipe it and seed from scratch: yarn mercato init --reinstall',
|
|
23
|
+
]
|
|
24
|
+
}
|
package/src/mercato.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { parseBooleanToken } from '@open-mercato/shared/lib/boolean'
|
|
|
10
10
|
import { getSslConfig } from '@open-mercato/shared/lib/db/ssl'
|
|
11
11
|
import { getRedisUrl, getRedisUrlOrThrow, parseRedisUrl } from '@open-mercato/shared/lib/redis/connection'
|
|
12
12
|
import { resolveInitDerivedSecrets } from './lib/init-secrets'
|
|
13
|
+
import { decideExistingDatabase, formatSkipIfInitializedMessage } from './lib/init-existing-database'
|
|
13
14
|
import {
|
|
14
15
|
resolveAutoSpawnWorkersMode,
|
|
15
16
|
resolveLazySpawnMode,
|
|
@@ -956,7 +957,7 @@ export function isHelpRequest(args: string[]): boolean {
|
|
|
956
957
|
// generic help branch. Without an entry here, `mercato init --help` runs a full install.
|
|
957
958
|
const TOP_LEVEL_COMMAND_HELP: Record<string, string[]> = {
|
|
958
959
|
init: [
|
|
959
|
-
'Usage: mercato init [--reinstall|-r] [--no-examples] [--no-demo-users] [--stresstest [--lite] [--count=<n>]]',
|
|
960
|
+
'Usage: mercato init [--reinstall|-r] [--skip-if-initialized] [--no-examples] [--no-demo-users] [--stresstest [--lite] [--count=<n>]]',
|
|
960
961
|
'Initializes this app: installs dependencies, runs generators, applies migrations and seeds data.',
|
|
961
962
|
],
|
|
962
963
|
'agentic:init': [
|
|
@@ -1029,6 +1030,7 @@ export async function run(argv = process.argv) {
|
|
|
1029
1030
|
} else if (process.env.OM_INIT_REINSTALL) {
|
|
1030
1031
|
delete process.env.OM_INIT_REINSTALL
|
|
1031
1032
|
}
|
|
1033
|
+
const skipIfInitialized = initArgs.includes('--skip-if-initialized')
|
|
1032
1034
|
const skipExamples = initArgs.includes('--no-examples')
|
|
1033
1035
|
const skipDemoUsers = initArgs.includes('--no-demo-users')
|
|
1034
1036
|
const stressTestEnabled =
|
|
@@ -1182,7 +1184,12 @@ export async function run(argv = process.argv) {
|
|
|
1182
1184
|
'SELECT COUNT(*)::text AS count FROM users',
|
|
1183
1185
|
)
|
|
1184
1186
|
const existingUsersCount = Number.parseInt(countResult.rows?.[0]?.count ?? '0', 10)
|
|
1185
|
-
|
|
1187
|
+
const existingDatabase = decideExistingDatabase(existingUsersCount, skipIfInitialized)
|
|
1188
|
+
if (existingDatabase === 'skip') {
|
|
1189
|
+
for (const line of formatSkipIfInitializedMessage(existingUsersCount, dbUrl)) console.log(line)
|
|
1190
|
+
return 0
|
|
1191
|
+
}
|
|
1192
|
+
if (existingDatabase === 'abort') {
|
|
1186
1193
|
console.error(
|
|
1187
1194
|
`❌ Initialization aborted: found ${existingUsersCount} existing user(s) in the database.`,
|
|
1188
1195
|
)
|
|
@@ -1480,8 +1487,12 @@ export async function run(argv = process.argv) {
|
|
|
1480
1487
|
console.log('╔══════════════════════════════════════════════════════════════╗')
|
|
1481
1488
|
console.log('║ 🚀 You\'re now ready to start development! ║')
|
|
1482
1489
|
console.log('║ ║')
|
|
1483
|
-
|
|
1484
|
-
|
|
1490
|
+
if (parseBooleanToken(process.env.OM_INIT_DEV_AUTOSTART) === true) {
|
|
1491
|
+
console.log('║ The dev server is starting now (next time run: yarn dev). ║')
|
|
1492
|
+
} else {
|
|
1493
|
+
console.log('║ Start the dev server: ║')
|
|
1494
|
+
console.log('║ yarn dev ║')
|
|
1495
|
+
}
|
|
1485
1496
|
console.log('║ ║')
|
|
1486
1497
|
console.log('║ Users created: ║')
|
|
1487
1498
|
for (const entry of createdUsers) {
|