@onroad/core 4.0.0-alpha.1 → 4.0.0-alpha.11

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 (42) hide show
  1. package/README.md +444 -8
  2. package/dist/OnRoadExpress.d.ts.map +1 -1
  3. package/dist/OnRoadExpress.js +12 -3
  4. package/dist/OnRoadExpress.js.map +1 -1
  5. package/dist/container/Container.d.ts +1 -1
  6. package/dist/container/Container.d.ts.map +1 -1
  7. package/dist/container/Container.js +15 -6
  8. package/dist/container/Container.js.map +1 -1
  9. package/dist/core/AbstractService.d.ts +12 -0
  10. package/dist/core/AbstractService.d.ts.map +1 -1
  11. package/dist/core/AbstractService.js +14 -0
  12. package/dist/core/AbstractService.js.map +1 -1
  13. package/dist/core/index.d.ts +1 -1
  14. package/dist/core/index.d.ts.map +1 -1
  15. package/dist/database/ConnectionManager.d.ts +1 -0
  16. package/dist/database/ConnectionManager.d.ts.map +1 -1
  17. package/dist/database/ConnectionManager.js +2 -0
  18. package/dist/database/ConnectionManager.js.map +1 -1
  19. package/dist/dev/DevServer.d.ts +51 -0
  20. package/dist/dev/DevServer.d.ts.map +1 -0
  21. package/dist/dev/DevServer.js +417 -0
  22. package/dist/dev/DevServer.js.map +1 -0
  23. package/dist/dev/MigrationCLI.d.ts +19 -0
  24. package/dist/dev/MigrationCLI.d.ts.map +1 -0
  25. package/dist/dev/MigrationCLI.js +140 -0
  26. package/dist/dev/MigrationCLI.js.map +1 -0
  27. package/dist/dev/index.d.ts +5 -0
  28. package/dist/dev/index.d.ts.map +1 -0
  29. package/dist/dev/index.js +3 -0
  30. package/dist/dev/index.js.map +1 -0
  31. package/dist/entity/EntityRegistry.d.ts +25 -0
  32. package/dist/entity/EntityRegistry.d.ts.map +1 -1
  33. package/dist/entity/EntityRegistry.js +130 -4
  34. package/dist/entity/EntityRegistry.js.map +1 -1
  35. package/dist/entity/decorators.d.ts +1 -0
  36. package/dist/entity/decorators.d.ts.map +1 -1
  37. package/dist/entity/decorators.js.map +1 -1
  38. package/dist/index.d.ts +3 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -0
  41. package/dist/index.js.map +1 -1
  42. package/package.json +6 -2
@@ -0,0 +1,417 @@
1
+ import { execSync } from "child_process";
2
+ import { existsSync, writeFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ // --- Main Class ---
5
+ export class DevServer {
6
+ app;
7
+ logger;
8
+ databases;
9
+ frontendVars;
10
+ migrationsPath;
11
+ projectRoot;
12
+ autoMigrate;
13
+ composeFile;
14
+ tenants;
15
+ containers = [];
16
+ composeCmd = null;
17
+ constructor(config) {
18
+ this.app = config.app;
19
+ this.logger = config.app.logger;
20
+ this.databases = config.databases ?? [{ engine: "postgres" }];
21
+ this.frontendVars = config.frontendVars ?? {};
22
+ this.migrationsPath = config.migrationsPath;
23
+ this.projectRoot = config.projectRoot ?? process.cwd();
24
+ this.autoMigrate = config.autoMigrate ?? true;
25
+ this.composeFile = config.composeFile ?? "docker-compose.dev.yml";
26
+ this.tenants = config.tenants ?? ["default"];
27
+ }
28
+ // --- Public API ---
29
+ async start(buildConfig = {}) {
30
+ this.printBanner();
31
+ // 1. Generate docker-compose if not exists
32
+ this.ensureComposeFile();
33
+ // 2. Start database containers
34
+ await this.startContainers();
35
+ // 3. Wait for database readiness
36
+ await this.waitForDatabases();
37
+ // 4. Run migrations (if configured)
38
+ if (this.autoMigrate && this.migrationsPath) {
39
+ await this.runMigrations();
40
+ }
41
+ // 5. Build and start the OnRoadExpress server
42
+ const port = buildConfig.port ?? 3000;
43
+ await this.app.buildServer({
44
+ ...buildConfig,
45
+ port,
46
+ });
47
+ // 6. Log frontend env vars
48
+ this.printFrontendEnvVars(port);
49
+ // 7. Log summary
50
+ this.printSummary(port);
51
+ }
52
+ async stop() {
53
+ this.logger.info("Stopping DevServer...");
54
+ await this.app.shutdown();
55
+ this.stopContainers();
56
+ this.logger.info("DevServer stopped");
57
+ }
58
+ // --- Docker Compose ---
59
+ ensureComposeFile() {
60
+ const composePath = resolve(this.projectRoot, this.composeFile);
61
+ if (existsSync(composePath)) {
62
+ this.logger.debug("Docker Compose file already exists", { path: composePath });
63
+ return;
64
+ }
65
+ const content = this.generateComposeContent();
66
+ writeFileSync(composePath, content, "utf-8");
67
+ this.logger.info("Generated docker-compose.dev.yml", { path: composePath });
68
+ }
69
+ generateComposeContent() {
70
+ const services = [];
71
+ const volumes = [];
72
+ for (const db of this.databases) {
73
+ const defaults = DB_DEFAULTS[db.engine];
74
+ const containerName = db.containerName ?? `typeroad-dev-${db.engine}`;
75
+ const port = db.port ?? defaults.port;
76
+ const user = db.user ?? defaults.user;
77
+ const password = db.password ?? defaults.password;
78
+ const database = db.database ?? defaults.database;
79
+ const image = db.image ?? defaults.image;
80
+ const volumeName = `${containerName}-data`;
81
+ this.containers.push({
82
+ name: containerName,
83
+ port,
84
+ engine: db.engine,
85
+ host: "localhost",
86
+ user,
87
+ password,
88
+ database,
89
+ });
90
+ if (db.engine === "postgres") {
91
+ services.push(` ${containerName}:
92
+ image: ${image}
93
+ container_name: ${containerName}
94
+ restart: unless-stopped
95
+ ports:
96
+ - "${port}:5432"
97
+ environment:
98
+ POSTGRES_USER: ${user}
99
+ POSTGRES_PASSWORD: ${password}
100
+ POSTGRES_DB: ${database}
101
+ volumes:
102
+ - ${volumeName}:/var/lib/postgresql/data
103
+ healthcheck:
104
+ test: ["CMD-SHELL", "pg_isready -U ${user} -d ${database}"]
105
+ interval: 2s
106
+ timeout: 5s
107
+ retries: 15`);
108
+ }
109
+ else if (db.engine === "mysql") {
110
+ services.push(` ${containerName}:
111
+ image: ${image}
112
+ container_name: ${containerName}
113
+ restart: unless-stopped
114
+ ports:
115
+ - "${port}:3306"
116
+ environment:
117
+ MYSQL_ROOT_PASSWORD: ${password}
118
+ MYSQL_USER: ${user}
119
+ MYSQL_PASSWORD: ${password}
120
+ MYSQL_DATABASE: ${database}
121
+ volumes:
122
+ - ${volumeName}:/var/lib/mysql
123
+ healthcheck:
124
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "${user}", "-p${password}"]
125
+ interval: 2s
126
+ timeout: 5s
127
+ retries: 15`);
128
+ }
129
+ volumes.push(` ${volumeName}:`);
130
+ }
131
+ return `# Auto-generated by TypeRoad DevServer
132
+ # Do not commit — add to .gitignore
133
+
134
+ services:
135
+ ${services.join("\n\n")}
136
+
137
+ volumes:
138
+ ${volumes.join("\n")}
139
+ `;
140
+ }
141
+ // --- Container Management ---
142
+ getComposeCommand() {
143
+ if (this.composeCmd)
144
+ return this.composeCmd;
145
+ // Try docker compose v2 (plugin) first, then docker-compose v1 (standalone)
146
+ try {
147
+ execSync("docker compose version", { stdio: "pipe" });
148
+ this.composeCmd = "docker compose";
149
+ return this.composeCmd;
150
+ }
151
+ catch {
152
+ // v2 not available
153
+ }
154
+ try {
155
+ execSync("docker-compose --version", { stdio: "pipe" });
156
+ this.composeCmd = "docker-compose";
157
+ return this.composeCmd;
158
+ }
159
+ catch {
160
+ // v1 not available
161
+ }
162
+ throw new Error("[TypeRoad DevServer] Neither 'docker compose' (v2) nor 'docker-compose' (v1) found. Install Docker Desktop or Docker Compose.");
163
+ }
164
+ async startContainers() {
165
+ const composePath = resolve(this.projectRoot, this.composeFile);
166
+ if (!this.isDockerAvailable()) {
167
+ throw new Error("[TypeRoad DevServer] Docker is not available. Install Docker Desktop or Docker Engine to use DevServer.");
168
+ }
169
+ const cmd = this.getComposeCommand();
170
+ this.logger.info(`Starting database containers... (using: ${cmd})`);
171
+ const maxRetries = 3;
172
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
173
+ try {
174
+ execSync(`${cmd} -f "${composePath}" up -d`, {
175
+ cwd: this.projectRoot,
176
+ stdio: "pipe",
177
+ });
178
+ return;
179
+ }
180
+ catch (err) {
181
+ const msg = err instanceof Error ? err.message : String(err);
182
+ // Transient Docker errors (closed pipe, daemon restart) — retry
183
+ if (attempt < maxRetries && (msg.includes("closed pipe") || msg.includes("connection refused"))) {
184
+ this.logger.warn(`Docker transient error (attempt ${attempt}/${maxRetries}), retrying in 3s...`);
185
+ execSync("sleep 3");
186
+ continue;
187
+ }
188
+ throw new Error(`[TypeRoad DevServer] Failed to start containers: ${msg}`);
189
+ }
190
+ }
191
+ }
192
+ stopContainers() {
193
+ const composePath = resolve(this.projectRoot, this.composeFile);
194
+ try {
195
+ const cmd = this.getComposeCommand();
196
+ execSync(`${cmd} -f "${composePath}" down`, {
197
+ cwd: this.projectRoot,
198
+ stdio: "pipe",
199
+ });
200
+ }
201
+ catch {
202
+ this.logger.warn("Failed to stop containers — stop them manually");
203
+ }
204
+ }
205
+ isDockerAvailable() {
206
+ try {
207
+ execSync("docker info", { stdio: "pipe" });
208
+ return true;
209
+ }
210
+ catch {
211
+ return false;
212
+ }
213
+ }
214
+ // --- DB Readiness ---
215
+ async waitForDatabases() {
216
+ // Re-read containers info from compose if not already populated
217
+ if (this.containers.length === 0) {
218
+ this.populateContainersFromConfig();
219
+ }
220
+ for (const container of this.containers) {
221
+ this.logger.info(`Waiting for ${container.engine} (${container.name}) to be ready...`);
222
+ await this.waitForContainer(container);
223
+ this.logger.info(`${container.engine} (${container.name}) is ready`);
224
+ }
225
+ }
226
+ async waitForContainer(container, maxRetries = 30) {
227
+ for (let i = 0; i < maxRetries; i++) {
228
+ try {
229
+ if (container.engine === "postgres") {
230
+ execSync(`docker exec ${container.name} pg_isready -U ${container.user} -d ${container.database}`, { stdio: "pipe" });
231
+ return;
232
+ }
233
+ else if (container.engine === "mysql") {
234
+ execSync(`docker exec ${container.name} mysqladmin ping -h localhost -u ${container.user} -p${container.password}`, { stdio: "pipe" });
235
+ return;
236
+ }
237
+ }
238
+ catch {
239
+ // Not ready yet
240
+ }
241
+ await sleep(1000);
242
+ }
243
+ throw new Error(`[TypeRoad DevServer] Database ${container.name} failed to start within ${maxRetries}s`);
244
+ }
245
+ populateContainersFromConfig() {
246
+ for (const db of this.databases) {
247
+ const defaults = DB_DEFAULTS[db.engine];
248
+ this.containers.push({
249
+ name: db.containerName ?? `typeroad-dev-${db.engine}`,
250
+ port: db.port ?? defaults.port,
251
+ engine: db.engine,
252
+ host: "localhost",
253
+ user: db.user ?? defaults.user,
254
+ password: db.password ?? defaults.password,
255
+ database: db.database ?? defaults.database,
256
+ });
257
+ }
258
+ }
259
+ // --- Migrations ---
260
+ async waitForSequelizeConnection(maxRetries = 15) {
261
+ // Use a raw Sequelize connection to verify readiness
262
+ // without going through getConnection() which triggers runOnConnect migrations
263
+ if (this.containers.length === 0)
264
+ return;
265
+ const container = this.containers[0];
266
+ const { Sequelize } = await import("sequelize");
267
+ for (let i = 0; i < maxRetries; i++) {
268
+ let probe = null;
269
+ try {
270
+ probe = new Sequelize(container.database, container.user, container.password, {
271
+ host: container.host,
272
+ port: container.port,
273
+ dialect: container.engine,
274
+ logging: false,
275
+ });
276
+ await probe.authenticate();
277
+ await probe.close();
278
+ this.logger.info("Database connection verified");
279
+ return;
280
+ }
281
+ catch {
282
+ if (probe)
283
+ try {
284
+ await probe.close();
285
+ }
286
+ catch { /* ignore */ }
287
+ if (i < maxRetries - 1) {
288
+ await sleep(2000);
289
+ }
290
+ }
291
+ }
292
+ this.logger.warn("Could not verify Sequelize connection — proceeding anyway");
293
+ }
294
+ async runMigrations() {
295
+ // Wait for the actual Sequelize connection to be stable
296
+ await this.waitForSequelizeConnection();
297
+ this.logger.info("Running database migrations...");
298
+ const connections = this.app.getConnections();
299
+ for (const conn of connections) {
300
+ if (conn.engine !== "sequelize")
301
+ continue;
302
+ const seqConn = conn;
303
+ for (const tenant of this.tenants) {
304
+ try {
305
+ const runner = await seqConn.getMigrationRunner(tenant);
306
+ const applied = await runner.up();
307
+ if (applied.length > 0) {
308
+ this.logger.info(`Migrations applied for tenant "${tenant}"`, {
309
+ count: applied.length,
310
+ migrations: applied,
311
+ });
312
+ }
313
+ else {
314
+ this.logger.info(`No pending migrations for tenant "${tenant}"`);
315
+ }
316
+ }
317
+ catch (err) {
318
+ this.logger.warn(`Migration failed for tenant "${tenant}" — continuing`, {
319
+ error: err instanceof Error ? err.message : String(err),
320
+ });
321
+ }
322
+ }
323
+ }
324
+ }
325
+ // --- Frontend Env Var Logging ---
326
+ printFrontendEnvVars(port) {
327
+ const baseUrl = `http://localhost:${port}`;
328
+ const vars = {
329
+ REACT_APP_API_URL: baseUrl,
330
+ NEXT_PUBLIC_API_URL: baseUrl,
331
+ VITE_API_URL: baseUrl,
332
+ API_BASE_URL: baseUrl,
333
+ ...this.frontendVars,
334
+ };
335
+ // Add database connection vars
336
+ for (const container of this.containers) {
337
+ const prefix = container.engine.toUpperCase();
338
+ vars[`${prefix}_HOST`] = container.host;
339
+ vars[`${prefix}_PORT`] = String(container.port);
340
+ vars[`${prefix}_USER`] = container.user;
341
+ vars[`${prefix}_PASSWORD`] = container.password;
342
+ vars[`${prefix}_DATABASE`] = container.database;
343
+ if (container.engine === "postgres") {
344
+ vars.DATABASE_URL = `postgresql://${container.user}:${container.password}@${container.host}:${container.port}/${container.database}`;
345
+ }
346
+ else if (container.engine === "mysql") {
347
+ vars.DATABASE_URL = `mysql://${container.user}:${container.password}@${container.host}:${container.port}/${container.database}`;
348
+ }
349
+ }
350
+ console.log("");
351
+ console.log("┌──────────────────────────────────────────────────────────────┐");
352
+ console.log("│ FRONTEND ENVIRONMENT VARIABLES │");
353
+ console.log("├──────────────────────────────────────────────────────────────┤");
354
+ const envFileLines = [];
355
+ for (const [key, value] of Object.entries(vars)) {
356
+ console.log(`│ ${key}=${value}`);
357
+ envFileLines.push(`${key}=${value}`);
358
+ }
359
+ console.log("├──────────────────────────────────────────────────────────────┤");
360
+ console.log("│ Copy the above to your frontend .env file │");
361
+ console.log("└──────────────────────────────────────────────────────────────┘");
362
+ console.log("");
363
+ // Write .env.local for convenience
364
+ const envPath = resolve(this.projectRoot, ".env.dev");
365
+ writeFileSync(envPath, envFileLines.join("\n") + "\n", "utf-8");
366
+ this.logger.info("Environment variables written to .env.dev", { path: envPath });
367
+ }
368
+ // --- Banner & Summary ---
369
+ printBanner() {
370
+ console.log("");
371
+ console.log(" ╔══════════════════════════════════════╗");
372
+ console.log(" ║ TypeRoad DevServer v1.0 ║");
373
+ console.log(" ║ Local Development Environment ║");
374
+ console.log(" ╚══════════════════════════════════════╝");
375
+ console.log("");
376
+ }
377
+ printSummary(port) {
378
+ console.log("");
379
+ console.log("┌──────────────────────────────────────────────────────────────┐");
380
+ console.log("│ SERVER READY │");
381
+ console.log("├──────────────────────────────────────────────────────────────┤");
382
+ console.log(`│ API: http://localhost:${port}`);
383
+ console.log(`│ Health: http://localhost:${port}/health`);
384
+ for (const container of this.containers) {
385
+ console.log(`│ ${container.engine.toUpperCase()}: ${container.host}:${container.port} (${container.name})`);
386
+ }
387
+ if (this.migrationsPath) {
388
+ console.log(`│ Migrations: ${this.migrationsPath}`);
389
+ }
390
+ console.log("├──────────────────────────────────────────────────────────────┤");
391
+ console.log("│ Press Ctrl+C to stop │");
392
+ console.log("└──────────────────────────────────────────────────────────────┘");
393
+ console.log("");
394
+ }
395
+ }
396
+ // --- Defaults ---
397
+ const DB_DEFAULTS = {
398
+ postgres: {
399
+ port: 5432,
400
+ user: "typeroad",
401
+ password: "typeroad_dev",
402
+ database: "typeroad_dev",
403
+ image: "postgres:16-alpine",
404
+ },
405
+ mysql: {
406
+ port: 3306,
407
+ user: "typeroad",
408
+ password: "typeroad_dev",
409
+ database: "typeroad_dev",
410
+ image: "mysql:8.0",
411
+ },
412
+ };
413
+ // --- Helpers ---
414
+ function sleep(ms) {
415
+ return new Promise((resolve) => setTimeout(resolve, ms));
416
+ }
417
+ //# sourceMappingURL=DevServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DevServer.js","sourceRoot":"","sources":["../../src/dev/DevServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { SequelizeConnectionManager } from "../database/SequelizeConnectionManager.js";
2
+ export interface MigrationCLIConfig {
3
+ migrationsPath: string;
4
+ connection: SequelizeConnectionManager;
5
+ tenant?: string;
6
+ }
7
+ export declare class MigrationCLI {
8
+ private readonly migrationsPath;
9
+ private readonly connection;
10
+ private readonly tenant;
11
+ constructor(config: MigrationCLIConfig);
12
+ run(args?: string[]): Promise<void>;
13
+ create(name: string): void;
14
+ up(steps?: number): Promise<void>;
15
+ down(steps?: number): Promise<void>;
16
+ status(): Promise<void>;
17
+ private getRunner;
18
+ }
19
+ //# sourceMappingURL=MigrationCLI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationCLI.d.ts","sourceRoot":"","sources":["../../src/dev/MigrationCLI.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAA;AAI3F,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,0BAA0B,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,MAAM,EAAE,kBAAkB;IAMhC,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAuChE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBpB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjC,IAAI,CAAC,KAAK,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;YA8Bf,SAAS;CAGxB"}
@@ -0,0 +1,140 @@
1
+ import { existsSync, writeFileSync, mkdirSync } from "fs";
2
+ import { resolve, join } from "path";
3
+ // --- CLI ---
4
+ export class MigrationCLI {
5
+ migrationsPath;
6
+ connection;
7
+ tenant;
8
+ constructor(config) {
9
+ this.migrationsPath = config.migrationsPath;
10
+ this.connection = config.connection;
11
+ this.tenant = config.tenant ?? "default";
12
+ }
13
+ async run(args = process.argv.slice(2)) {
14
+ const command = args[0];
15
+ const param = args[1];
16
+ switch (command) {
17
+ case "create":
18
+ if (!param) {
19
+ console.error("Usage: migration create <name>");
20
+ process.exit(1);
21
+ }
22
+ this.create(param);
23
+ break;
24
+ case "up":
25
+ await this.up(param ? parseInt(param, 10) : undefined);
26
+ break;
27
+ case "down":
28
+ await this.down(param ? parseInt(param, 10) : 1);
29
+ break;
30
+ case "status":
31
+ await this.status();
32
+ break;
33
+ default:
34
+ console.log("Usage: migration <create|up|down|status> [param]");
35
+ console.log("");
36
+ console.log("Commands:");
37
+ console.log(" create <name> Create a new migration file");
38
+ console.log(" up [steps] Run pending migrations (all or N steps)");
39
+ console.log(" down [steps] Revert last N migrations (default: 1)");
40
+ console.log(" status Show migration status");
41
+ break;
42
+ }
43
+ }
44
+ // --- Commands ---
45
+ create(name) {
46
+ const timestamp = new Date().toISOString().replace(/[-:T]/g, "").slice(0, 14);
47
+ const safeName = name.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
48
+ const fileName = `${timestamp}-${safeName}.ts`;
49
+ const dirPath = resolve(this.migrationsPath);
50
+ if (!existsSync(dirPath)) {
51
+ mkdirSync(dirPath, { recursive: true });
52
+ }
53
+ const filePath = join(dirPath, fileName);
54
+ writeFileSync(filePath, MIGRATION_TEMPLATE(safeName), "utf-8");
55
+ console.log(`Migration created: ${filePath}`);
56
+ }
57
+ async up(steps) {
58
+ const runner = await this.getRunner();
59
+ const applied = await runner.up(steps);
60
+ if (applied.length === 0) {
61
+ console.log("No pending migrations.");
62
+ }
63
+ else {
64
+ console.log(`Applied ${applied.length} migration(s):`);
65
+ for (const name of applied) {
66
+ console.log(` + ${name}`);
67
+ }
68
+ }
69
+ }
70
+ async down(steps = 1) {
71
+ const runner = await this.getRunner();
72
+ const reverted = await runner.down(steps);
73
+ if (reverted.length === 0) {
74
+ console.log("No migrations to revert.");
75
+ }
76
+ else {
77
+ console.log(`Reverted ${reverted.length} migration(s):`);
78
+ for (const name of reverted) {
79
+ console.log(` - ${name}`);
80
+ }
81
+ }
82
+ }
83
+ async status() {
84
+ const runner = await this.getRunner();
85
+ const statuses = await runner.status();
86
+ if (statuses.length === 0) {
87
+ console.log("No migrations found.");
88
+ return;
89
+ }
90
+ console.log("");
91
+ console.log("Migration Status:");
92
+ console.log("─".repeat(60));
93
+ for (const s of statuses) {
94
+ const icon = s.isApplied ? "✓" : "○";
95
+ const status = s.isApplied ? "applied" : "pending";
96
+ console.log(` ${icon} ${s.name} (${status})`);
97
+ }
98
+ console.log("─".repeat(60));
99
+ const applied = statuses.filter((s) => s.isApplied).length;
100
+ const pending = statuses.filter((s) => !s.isApplied).length;
101
+ console.log(` Total: ${statuses.length} | Applied: ${applied} | Pending: ${pending}`);
102
+ console.log("");
103
+ }
104
+ // --- Internal ---
105
+ async getRunner() {
106
+ return this.connection.getMigrationRunner(this.tenant);
107
+ }
108
+ }
109
+ // --- Template ---
110
+ function MIGRATION_TEMPLATE(name) {
111
+ return `import type { QueryInterface, Sequelize } from "sequelize"
112
+
113
+ export default {
114
+ async up(queryInterface: QueryInterface, sequelize: Sequelize): Promise<void> {
115
+ // TODO: implement migration "${name}"
116
+ // Example:
117
+ // await queryInterface.createTable("my_table", {
118
+ // id: {
119
+ // type: sequelize.constructor["DataTypes"].UUID,
120
+ // primaryKey: true,
121
+ // defaultValue: sequelize.constructor["DataTypes"].UUIDV4,
122
+ // },
123
+ // name: {
124
+ // type: sequelize.constructor["DataTypes"].STRING,
125
+ // allowNull: false,
126
+ // },
127
+ // createdAt: sequelize.constructor["DataTypes"].DATE,
128
+ // updatedAt: sequelize.constructor["DataTypes"].DATE,
129
+ // })
130
+ },
131
+
132
+ async down(queryInterface: QueryInterface, _sequelize: Sequelize): Promise<void> {
133
+ // TODO: implement rollback for "${name}"
134
+ // Example:
135
+ // await queryInterface.dropTable("my_table")
136
+ },
137
+ }
138
+ `;
139
+ }
140
+ //# sourceMappingURL=MigrationCLI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationCLI.js","sourceRoot":"","sources":["../../src/dev/MigrationCLI.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { DevServer } from "./DevServer.js";
2
+ export type { DevServerConfig, DevDatabaseConfig } from "./DevServer.js";
3
+ export { MigrationCLI } from "./MigrationCLI.js";
4
+ export type { MigrationCLIConfig } from "./MigrationCLI.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dev/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { DevServer } from "./DevServer.js";
2
+ export { MigrationCLI } from "./MigrationCLI.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dev/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA"}