@bobbykim/manguito-cms-cli 0.11.0 → 0.11.2

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 (2) hide show
  1. package/dist/index.js +81 -35
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -17217,27 +17217,59 @@ async function runDevMigration(configPath) {
17217
17217
  env: resolvedPathEnv()
17218
17218
  });
17219
17219
  }
17220
- async function generateMigration(configPath, migrationsFolder) {
17220
+ async function runGenerate(configPath, outFolder, cwd) {
17221
17221
  let beforeFiles = [];
17222
17222
  try {
17223
- const entries = await fs.readdir(migrationsFolder);
17223
+ const entries = await fs.readdir(outFolder);
17224
17224
  beforeFiles = entries.filter((f) => f.endsWith(".sql"));
17225
17225
  } catch {
17226
17226
  }
17227
17227
  execSync(`drizzle-kit generate --config=${configPath}`, {
17228
17228
  stdio: "inherit",
17229
- cwd: path.dirname(configPath),
17229
+ cwd,
17230
17230
  env: resolvedPathEnv()
17231
17231
  });
17232
17232
  let afterFiles = [];
17233
17233
  try {
17234
- const entries = await fs.readdir(migrationsFolder);
17234
+ const entries = await fs.readdir(outFolder);
17235
17235
  afterFiles = entries.filter((f) => f.endsWith(".sql"));
17236
17236
  } catch {
17237
17237
  }
17238
17238
  const beforeSet = new Set(beforeFiles);
17239
17239
  return afterFiles.filter((f) => !beforeSet.has(f));
17240
17240
  }
17241
+ async function generateMigration(configPath, migrationsFolder) {
17242
+ return runGenerate(configPath, migrationsFolder, path.dirname(configPath));
17243
+ }
17244
+ async function previewMigration(configPath, migrationsFolder) {
17245
+ const configDir = path.dirname(configPath);
17246
+ const tmp = await fs.mkdtemp(path.join(configDir, ".migration-preview-"));
17247
+ try {
17248
+ const out = path.join(tmp, "migrations");
17249
+ try {
17250
+ await fs.cp(migrationsFolder, out, { recursive: true });
17251
+ } catch (err) {
17252
+ if (err.code !== "ENOENT") throw err;
17253
+ }
17254
+ const base = `./${path.basename(configPath).replace(/\.[cm]?[jt]s$/, "")}`;
17255
+ const tmpConfig = path.join(tmp, "drizzle.config.ts");
17256
+ await fs.writeFile(
17257
+ tmpConfig,
17258
+ [
17259
+ `import base from '.${base}'`,
17260
+ // Relative to the real config's folder, where drizzle-kit runs.
17261
+ `export default { ...base, out: './${path.relative(configDir, out).split(path.sep).join("/")}' }`,
17262
+ ""
17263
+ ].join("\n")
17264
+ );
17265
+ const names = await runGenerate(tmpConfig, out, configDir);
17266
+ return await Promise.all(
17267
+ names.map(async (name) => ({ name, sql: await fs.readFile(path.join(out, name), "utf8") }))
17268
+ );
17269
+ } finally {
17270
+ await fs.rm(tmp, { recursive: true, force: true });
17271
+ }
17272
+ }
17241
17273
  async function applyMigrations(configPath, db, options) {
17242
17274
  const { migrationsTable, migrationsFolder } = options;
17243
17275
  await db.execute(
@@ -17379,11 +17411,14 @@ function formatAlterColumnType(line2) {
17379
17411
  return `ALTER COLUMN ${tableName}.${colName} TYPE ${newType}`;
17380
17412
  }
17381
17413
  function scanMigrationFiles(filePaths) {
17414
+ return scanMigrationSql(
17415
+ filePaths.map((filePath) => ({ name: path2.basename(filePath), sql: readFileSync(filePath, "utf-8") }))
17416
+ );
17417
+ }
17418
+ function scanMigrationSql(migrations) {
17382
17419
  const operations = [];
17383
- for (const filePath of filePaths) {
17384
- const content = readFileSync(filePath, "utf-8");
17420
+ for (const { name: filename, sql: content } of migrations) {
17385
17421
  const lines = content.split("\n");
17386
- const filename = path2.basename(filePath);
17387
17422
  for (const line2 of lines) {
17388
17423
  const upper = line2.trim().toUpperCase();
17389
17424
  if (upper.includes("DROP COLUMN")) {
@@ -24739,7 +24774,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
24739
24774
  }
24740
24775
  var API_VERSION = (() => {
24741
24776
  try {
24742
- return "0.9.0";
24777
+ return "0.9.1";
24743
24778
  } catch {
24744
24779
  return "0.0.0";
24745
24780
  }
@@ -26124,6 +26159,16 @@ function buildDeps(options, cwd) {
26124
26159
  prompt: createPromptAdapter()
26125
26160
  };
26126
26161
  }
26162
+ function printDestructiveOperations(scan) {
26163
+ process.stdout.write("\u26A0 This migration contains destructive operations:\n");
26164
+ for (const op of scan.operations) process.stdout.write(` - ${op.operation}
26165
+ `);
26166
+ process.stdout.write("\n");
26167
+ }
26168
+ async function readPendingMigrations(db, migrationsTable, migrationsFolder) {
26169
+ const { pending } = await getMigrationStatus(db.getDb(), { migrationsTable, migrationsFolder });
26170
+ return Promise.all(pending.map(async (name) => ({ name, sql: await readFile2(join12(migrationsFolder, name), "utf-8") })));
26171
+ }
26127
26172
  async function runMigrate(options, deps) {
26128
26173
  if (options.status) {
26129
26174
  loadEnvFile(options.env);
@@ -26189,19 +26234,39 @@ async function runMigrate(options, deps) {
26189
26234
  printSuccess("Build complete");
26190
26235
  const generatedDir = resolve8(cwd, "dist/generated");
26191
26236
  await generateDrizzleConfig(config2, generatedDir);
26237
+ if (options.dryRun) {
26238
+ const pending2 = await readPendingMigrations(deps.db, migrationsTable, migrationsFolder);
26239
+ const preview = await previewMigration(deps.configPath, migrationsFolder);
26240
+ const all = [...pending2, ...preview];
26241
+ if (pending2.length > 0) {
26242
+ printSuccess(`Generated earlier, not yet applied: ${pending2.map((m2) => m2.name).join(", ")}`);
26243
+ }
26244
+ printSuccess(
26245
+ preview.length === 0 ? "No new migration would be generated" : `Would generate ${preview.length} migration file${preview.length !== 1 ? "s" : ""}: ${preview.map((m2) => m2.name).join(", ")}`
26246
+ );
26247
+ process.stdout.write("\nDry run \u2014 no migration files written, no changes applied.\n\n");
26248
+ if (all.length > 0) {
26249
+ process.stdout.write("SQL `manguito migrate` would apply:\n");
26250
+ process.stdout.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
26251
+ for (const m2 of all) process.stdout.write(`-- ${m2.name}
26252
+ ${m2.sql}
26253
+ `);
26254
+ process.stdout.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
26255
+ const scan = scanMigrationSql(all);
26256
+ if (scan.hasDestructiveOperations) printDestructiveOperations(scan);
26257
+ else process.stdout.write("No destructive operations detected.\n\n");
26258
+ process.stdout.write("Run `manguito migrate` to generate and apply these.\n");
26259
+ }
26260
+ process.exit(0);
26261
+ }
26192
26262
  const newFileNames = await generateMigration(deps.configPath, migrationsFolder);
26193
- const newFilePaths = newFileNames.map((f) => join12(migrationsFolder, f));
26194
26263
  printSuccess(
26195
26264
  newFileNames.length === 0 ? "No new migration files generated" : `Generated ${newFileNames.length} migration file${newFileNames.length !== 1 ? "s" : ""}: ${newFileNames.join(", ")}`
26196
26265
  );
26197
- const scanResult = newFilePaths.length > 0 ? scanMigrationFiles(newFilePaths) : { hasDestructiveOperations: false, operations: [] };
26266
+ const { pending } = await getMigrationStatus(deps.db.getDb(), { migrationsTable, migrationsFolder });
26267
+ const scanResult = scanMigrationFiles(pending.map((f) => join12(migrationsFolder, f)));
26198
26268
  if (scanResult.hasDestructiveOperations) {
26199
- process.stdout.write("\u26A0 This migration contains destructive operations:\n");
26200
- for (const op of scanResult.operations) {
26201
- process.stdout.write(` - ${op.operation}
26202
- `);
26203
- }
26204
- process.stdout.write("\n");
26269
+ printDestructiveOperations(scanResult);
26205
26270
  process.stdout.write(" These changes are irreversible and may cause data loss.\n");
26206
26271
  const uniqueFiles = [...new Set(scanResult.operations.map((op) => op.file))];
26207
26272
  for (const file of uniqueFiles) {
@@ -26219,25 +26284,6 @@ async function runMigrate(options, deps) {
26219
26284
  }
26220
26285
  }
26221
26286
  }
26222
- if (options.dryRun) {
26223
- process.stdout.write("\nDry run \u2014 no files will be written, no changes applied.\n\n");
26224
- if (newFilePaths.length > 0) {
26225
- process.stdout.write("Generated SQL:\n");
26226
- process.stdout.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
26227
- for (const filePath of newFilePaths) {
26228
- const sql2 = await readFile2(filePath, "utf-8");
26229
- process.stdout.write(sql2);
26230
- }
26231
- process.stdout.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n");
26232
- } else {
26233
- process.stdout.write("No SQL changes generated.\n\n");
26234
- }
26235
- if (!scanResult.hasDestructiveOperations) {
26236
- process.stdout.write("No destructive operations detected.\n\n");
26237
- }
26238
- process.stdout.write("Run `manguito migrate` to generate and apply this migration.\n");
26239
- process.exit(0);
26240
- }
26241
26287
  const migrationResult = await applyMigrations(deps.configPath, deps.db.getDb(), {
26242
26288
  migrationsTable,
26243
26289
  migrationsFolder
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobbykim/manguito-cms-cli",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "license": "MIT",
5
5
  "author": "Bobby Kim <bobby.sihun.kim@gmail.com>",
6
6
  "homepage": "https://github.com/bobbykim89/manguito-cms",
@@ -29,10 +29,10 @@
29
29
  "tsup": "^8.5.1",
30
30
  "typescript": "^6.0.3",
31
31
  "vite": "^8.1.3",
32
- "@bobbykim/manguito-cms-admin": "0.5.4",
33
- "@bobbykim/manguito-cms-api": "0.9.0",
32
+ "@bobbykim/manguito-cms-admin": "0.6.0",
33
+ "@bobbykim/manguito-cms-db": "0.2.0",
34
34
  "@bobbykim/manguito-cms-core": "0.10.0",
35
- "@bobbykim/manguito-cms-db": "0.1.10"
35
+ "@bobbykim/manguito-cms-api": "0.9.1"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^25.9.5",