@lark-apaas/db-schema-sync 0.1.23 → 0.1.24-alpha.20261028024931

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/dist/bin.js CHANGED
@@ -1,13 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
3
3
  import {
4
+ DATASOURCE_CONF_ENV,
5
+ DATASOURCE_TYPES,
4
6
  __commonJS,
5
7
  __require,
6
8
  __toESM,
7
- generateSchema,
9
+ detectEngine,
10
+ fetchListTableView,
11
+ generateSchemaFromData,
12
+ normalizeApiResponse,
13
+ parseDatasourceConf,
8
14
  resolveEnvOptions,
9
15
  validateGeneratedSchema
10
- } from "./chunk-PXGXJ64L.js";
16
+ } from "./chunk-KHVF5NNE.js";
11
17
 
12
18
  // node_modules/dotenv/package.json
13
19
  var require_package = __commonJS({
@@ -300,8 +306,8 @@ var require_main = __commonJS({
300
306
  const shortPaths = [];
301
307
  for (const filePath of optionPaths) {
302
308
  try {
303
- const relative = path.relative(process.cwd(), filePath);
304
- shortPaths.push(relative);
309
+ const relative2 = path.relative(process.cwd(), filePath);
310
+ shortPaths.push(relative2);
305
311
  } catch (e) {
306
312
  if (debug) {
307
313
  _debug(`Failed to load ${filePath} ${e.message}`);
@@ -406,10 +412,11 @@ var require_main = __commonJS({
406
412
 
407
413
  // src/bin.ts
408
414
  var import_dotenv = __toESM(require_main(), 1);
409
- import { resolve, dirname } from "path";
410
- import { writeFileSync, mkdirSync, existsSync } from "fs";
415
+ import { resolve as resolve2 } from "path";
416
+ import { existsSync as existsSync2 } from "fs";
411
417
 
412
418
  // src/cli-args.ts
419
+ var ENGINES = ["auto", "dataloom", "base"];
413
420
  function parseArgs(argv) {
414
421
  const args = argv.slice(2);
415
422
  const command = args[0] === "validate" ? "validate" : "generate";
@@ -424,9 +431,179 @@ function parseArgs(argv) {
424
431
  output: getArg("--output"),
425
432
  input: getArg("--input"),
426
433
  project: getArg("--project"),
427
- exportCustomTypes: hasFlag("--export-custom-types")
434
+ exportCustomTypes: hasFlag("--export-custom-types"),
435
+ engine: parseEngine(getArg("--engine")),
436
+ type: parseType(getArg("--type"))
428
437
  };
429
438
  }
439
+ function parseType(value) {
440
+ if (value === void 0) return void 0;
441
+ if (DATASOURCE_TYPES.includes(value)) return value;
442
+ throw new Error(
443
+ `[db-schema-sync] Invalid --type "${value}", expected one of: ${DATASOURCE_TYPES.join(", ")}`
444
+ );
445
+ }
446
+ function parseEngine(value) {
447
+ if (value === void 0) return "auto";
448
+ if (ENGINES.includes(value)) return value;
449
+ throw new Error(
450
+ `[db-schema-sync] Invalid --engine "${value}", expected one of: ${ENGINES.join(", ")}`
451
+ );
452
+ }
453
+
454
+ // src/sync.ts
455
+ import { dirname, join, relative, resolve } from "path";
456
+ import {
457
+ existsSync,
458
+ mkdirSync,
459
+ renameSync,
460
+ rmSync,
461
+ writeFileSync
462
+ } from "fs";
463
+ var DEFAULT_OUTPUT = "server/database/schema.ts";
464
+ var BASE_FILE_NAME = "base.ts";
465
+ var errorMessage = (err) => err instanceof Error ? err.message : String(err);
466
+ function writeFilesAtomic(files) {
467
+ const suffix = `.tmp-${process.pid}-${Date.now()}`;
468
+ const temps = [];
469
+ try {
470
+ for (const f of files) {
471
+ mkdirSync(dirname(f.path), { recursive: true });
472
+ temps.push(f.path + suffix);
473
+ writeFileSync(f.path + suffix, f.content, "utf8");
474
+ }
475
+ } catch (err) {
476
+ for (const t of temps) rmSync(t, { force: true });
477
+ throw err;
478
+ }
479
+ for (const f of files) renameSync(f.path + suffix, f.path);
480
+ }
481
+ function generatePgSchema(raw, engine, exportCustomTypes) {
482
+ const source = generateSchemaFromData(
483
+ // Base apps are treated as one default schema for now: pgTable, no pgSchema prefix
484
+ normalizeApiResponse(raw, engine, { baseSchemas: false }),
485
+ { exportCustomTypes }
486
+ );
487
+ if (!source.includes("pgTable") && !source.includes("pgView")) {
488
+ console.warn(
489
+ "[db-schema-sync] \u26A0 Warning: No tables or views found in database. The generated schema will be empty."
490
+ );
491
+ }
492
+ return source;
493
+ }
494
+ function resolveOutput(o) {
495
+ return o.args.output || o.env.DB_SCHEMA_OUTPUT || DEFAULT_OUTPUT;
496
+ }
497
+ async function runSync(o) {
498
+ let conf;
499
+ try {
500
+ conf = parseDatasourceConf(o.env[DATASOURCE_CONF_ENV]);
501
+ } catch (err) {
502
+ console.error(`[db-schema-sync] \u2717 ${errorMessage(err)}`);
503
+ return {
504
+ mode: "datasources",
505
+ failures: [{ name: DATASOURCE_CONF_ENV, message: errorMessage(err) }]
506
+ };
507
+ }
508
+ return conf ? runDatasources(conf, o) : runLegacy(o);
509
+ }
510
+ async function runLegacy(o) {
511
+ const { args } = o;
512
+ if (args.type === "base") {
513
+ console.log(
514
+ `[db-schema-sync] \u672A\u914D\u7F6E ${DATASOURCE_CONF_ENV}\uFF0C\u6CA1\u6709 base \u6570\u636E\u6E90\u53EF\u540C\u6B65`
515
+ );
516
+ return { mode: "legacy", failures: [] };
517
+ }
518
+ const output = resolveOutput(o);
519
+ const fetchSchema = o.fetchSchema ?? fetchListTableView;
520
+ try {
521
+ const options = resolveEnvOptions(o.env);
522
+ console.log("[db-schema-sync] Starting...");
523
+ console.log(
524
+ `[db-schema-sync] app_id=${options.appId}, dbBranch=${options.dbBranch}, exportCustomTypes=${args.exportCustomTypes}, engine=${args.engine}`
525
+ );
526
+ const raw = await fetchSchema(options);
527
+ const schema = generatePgSchema(raw, args.engine, args.exportCustomTypes);
528
+ writeFilesAtomic([{ path: resolve(o.cwd, output), content: schema }]);
529
+ console.log(`[db-schema-sync] \u2713 Schema written to ${output}`);
530
+ return { mode: "legacy", failures: [] };
531
+ } catch (err) {
532
+ console.error(`[db-schema-sync] \u2717 Failed:`, errorMessage(err));
533
+ return {
534
+ mode: "legacy",
535
+ failures: [{ name: "schema", message: errorMessage(err) }]
536
+ };
537
+ }
538
+ }
539
+ function assertEngineMatches(ds, raw) {
540
+ const engine = detectEngine(raw);
541
+ if (ds.type === "base" && engine !== "base") {
542
+ throw new Error(
543
+ `\u914D\u7F6E\u4E3A base\uFF0C\u4F46\u63A5\u53E3\u8FD4\u56DE\u7684\u4E0D\u662F Base \u5F15\u64CE\uFF08engine=${String(raw?.engine ?? "\u672A\u6807\u8BB0")}\uFF0C\u5B57\u6BB5 extraInfo \u4E5F\u4E0D\u5E26 Base \u5C5E\u6027\uFF09`
544
+ );
545
+ }
546
+ if (ds.type === "pg" && engine === "base") {
547
+ throw new Error("\u914D\u7F6E\u4E3A pg\uFF0C\u4F46\u63A5\u53E3\u8FD4\u56DE\u7684\u662F Base \u5F15\u64CE");
548
+ }
549
+ }
550
+ async function runDatasources(conf, o) {
551
+ const { args, cwd } = o;
552
+ const fetchSchema = o.fetchSchema ?? fetchListTableView;
553
+ const pgPath = resolve(cwd, resolveOutput(o));
554
+ const basePath = join(dirname(pgPath), BASE_FILE_NAME);
555
+ const rel = (p) => relative(cwd, p) || ".";
556
+ const types = args.type ? [args.type] : DATASOURCE_TYPES;
557
+ const failures = [];
558
+ let appOptions;
559
+ try {
560
+ appOptions = resolveEnvOptions(o.env);
561
+ } catch (err) {
562
+ console.error(`[db-schema-sync] \u2717 Failed:`, errorMessage(err));
563
+ return { mode: "datasources", failures: [{ name: "app_id", message: errorMessage(err) }] };
564
+ }
565
+ console.log("[db-schema-sync] Starting...");
566
+ const listed = conf.datasources.map((d) => `${d.type}:${d.id}`).join(", ") || "(none)";
567
+ console.log(
568
+ `[db-schema-sync] app_id=${appOptions.appId}, dbBranch=${appOptions.dbBranch}, datasources=${listed}, type=${args.type ?? "all"}`
569
+ );
570
+ if (args.engine !== "auto") {
571
+ console.warn(
572
+ `[db-schema-sync] \u26A0 \u5DF2\u914D\u7F6E ${DATASOURCE_CONF_ENV}\uFF0C\u5FFD\u7565 --engine\uFF08\u5F15\u64CE\u7531\u6570\u636E\u6E90 type \u51B3\u5B9A\uFF09`
573
+ );
574
+ }
575
+ for (const type of types) {
576
+ if (conf.datasources.some((d) => d.type === type)) continue;
577
+ const existing = type === "pg" ? pgPath : basePath;
578
+ console.log(
579
+ existsSync(existing) ? `[db-schema-sync] \u914D\u7F6E\u4E2D\u6CA1\u6709 ${type} \u6570\u636E\u6E90\uFF0C\u4FDD\u7559\u5DF2\u6709\u7684 ${rel(existing)}` : `[db-schema-sync] \u914D\u7F6E\u4E2D\u6CA1\u6709 ${type} \u6570\u636E\u6E90\uFF0C\u8DF3\u8FC7`
580
+ );
581
+ }
582
+ for (const ds of conf.datasources.filter((d) => types.includes(d.type))) {
583
+ const label = `${ds.type} \u6570\u636E\u6E90 ${ds.id}`;
584
+ try {
585
+ const raw = await fetchSchema({
586
+ appId: appOptions.appId,
587
+ timeoutMs: appOptions.timeoutMs,
588
+ datasourceId: ds.id,
589
+ ...ds.type === "pg" ? { dbBranch: appOptions.dbBranch } : {}
590
+ });
591
+ assertEngineMatches(ds, raw);
592
+ const [path, schema] = ds.type === "pg" ? [pgPath, generatePgSchema(raw, "dataloom", args.exportCustomTypes)] : [basePath, generatePgSchema(raw, "base", true)];
593
+ writeFilesAtomic([{ path, content: schema }]);
594
+ console.log(`[db-schema-sync] \u2713 ${label} \u2192 ${rel(path)}`);
595
+ } catch (err) {
596
+ failures.push({ name: label, message: errorMessage(err) });
597
+ console.error(`[db-schema-sync] \u2717 ${label} \u540C\u6B65\u5931\u8D25\uFF1A${errorMessage(err)}`);
598
+ }
599
+ }
600
+ if (failures.length > 0) {
601
+ console.error(
602
+ `[db-schema-sync] \u2717 ${failures.length} \u4E2A\u6570\u636E\u6E90\u540C\u6B65\u5931\u8D25\uFF0C\u5176\u6587\u4EF6\u4FDD\u6301\u539F\u6837\uFF1A${failures.map((f) => f.name).join("\u3001")}`
603
+ );
604
+ }
605
+ return { mode: "datasources", failures };
606
+ }
430
607
 
431
608
  // src/bin.ts
432
609
  function getValidateExitCode(result) {
@@ -436,59 +613,44 @@ function getValidateExitCode(result) {
436
613
  return 1;
437
614
  }
438
615
  async function main() {
439
- const cliArgs = parseArgs(process.argv);
616
+ let cliArgs;
617
+ try {
618
+ cliArgs = parseArgs(process.argv);
619
+ } catch (err) {
620
+ console.error(err instanceof Error ? err.message : String(err));
621
+ process.exit(1);
622
+ }
440
623
  if (cliArgs.command === "validate") {
441
624
  if (!cliArgs.input) {
442
- const output3 = {
625
+ const output2 = {
443
626
  ok: false,
444
627
  status: "inconclusive",
445
628
  errorType: "validation_runner_failed",
446
629
  durationMs: 0,
447
630
  message: "--input is required for validate command"
448
631
  };
449
- console.log(JSON.stringify(output3));
632
+ console.log(JSON.stringify(output2));
450
633
  process.exit(1);
451
634
  }
452
- const output2 = validateGeneratedSchema({
635
+ const output = validateGeneratedSchema({
453
636
  input: cliArgs.input,
454
637
  project: cliArgs.project
455
638
  });
456
- console.log(JSON.stringify(output2));
457
- process.exit(getValidateExitCode(output2));
639
+ console.log(JSON.stringify(output));
640
+ process.exit(getValidateExitCode(output));
458
641
  }
459
642
  for (const name of [".env.local", ".env"]) {
460
- const envPath = resolve(process.cwd(), name);
461
- if (existsSync(envPath)) {
643
+ const envPath = resolve2(process.cwd(), name);
644
+ if (existsSync2(envPath)) {
462
645
  (0, import_dotenv.config)({ path: envPath });
463
646
  console.log(`[db-schema-sync] \u2713 Loaded ${name}`);
464
647
  }
465
648
  }
466
- const output = cliArgs.output || process.env.DB_SCHEMA_OUTPUT || "server/database/schema.ts";
467
- try {
468
- const options = resolveEnvOptions();
469
- console.log("[db-schema-sync] Starting...");
470
- console.log(
471
- `[db-schema-sync] app_id=${options.appId}, dbBranch=${options.dbBranch}, exportCustomTypes=${cliArgs.exportCustomTypes}`
472
- );
473
- const schema = await generateSchema({
474
- ...options,
475
- exportCustomTypes: cliArgs.exportCustomTypes
476
- });
477
- if (!schema.includes("pgTable") && !schema.includes("pgView")) {
478
- console.warn(
479
- "[db-schema-sync] \u26A0 Warning: No tables or views found in database. The generated schema will be empty."
480
- );
481
- }
482
- const outputPath = resolve(process.cwd(), output);
483
- mkdirSync(dirname(outputPath), { recursive: true });
484
- writeFileSync(outputPath, schema, "utf8");
485
- console.log(`[db-schema-sync] \u2713 Schema written to ${output}`);
486
- } catch (err) {
487
- console.error(
488
- `[db-schema-sync] \u2717 Failed:`,
489
- err instanceof Error ? err.message : String(err)
490
- );
491
- process.exit(1);
492
- }
649
+ const { failures } = await runSync({
650
+ cwd: process.cwd(),
651
+ env: process.env,
652
+ args: cliArgs
653
+ });
654
+ if (failures.length > 0) process.exit(1);
493
655
  }
494
656
  main();