@housekit/kit 0.1.30 → 0.1.32

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 (3) hide show
  1. package/README.md +20 -0
  2. package/dist/index.js +63 -2
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -42,6 +42,7 @@ Perfect for early-stage projects or local development. It computes the delta bet
42
42
  - **Safe**: Asks for confirmation before any destructive change.
43
43
  - **Fast**: Skips the creation of migration files.
44
44
  - **Smart**: Handles column renames and type changes.
45
+ - **CI/CD Ready**: Use `-y` flag or pipe commands for non-interactive mode.
45
46
 
46
47
  ### 2. Controlled Production: `housekit generate` & `migrate`
47
48
  The standard for CI/CD and production environments.
@@ -65,6 +66,25 @@ The standard for CI/CD and production environments.
65
66
  | `list` | Summarizes row counts, engines, and sizes for all tables. |
66
67
  | `reset` | Wipes the database and restarts from your code schema (Dev only). |
67
68
 
69
+ ### Global Options
70
+
71
+ | Option | Description |
72
+ | :--- | :--- |
73
+ | `-y, --yes` | Auto-confirm all prompts (useful for CI/CD and scripts). |
74
+ | `-d, --database <name>` | Target a specific database from your config. |
75
+
76
+ ### Non-Interactive Mode
77
+
78
+ When running in non-interactive environments (CI/CD pipelines, scripts with piped input), HouseKit automatically detects this and uses default values for prompts. For explicit control, use the `-y` flag:
79
+
80
+ ```bash
81
+ # Auto-confirm all prompts
82
+ bunx housekit push -y
83
+
84
+ # Works in CI/CD pipelines
85
+ bunx housekit migrate -y --database production
86
+ ```
87
+
68
88
  ---
69
89
 
70
90
  ## ⚙️ Configuration
package/dist/index.js CHANGED
@@ -7949,9 +7949,16 @@ var globalYes = false;
7949
7949
  function setGlobalYesMode(enabled) {
7950
7950
  globalYes = enabled;
7951
7951
  }
7952
+ function isInteractive() {
7953
+ return process.stdin.isTTY === true;
7954
+ }
7952
7955
  async function confirmPrompt(message, defaultYes = true) {
7953
7956
  if (globalYes)
7954
7957
  return true;
7958
+ if (!isInteractive()) {
7959
+ info(`${message} (auto-confirmed, non-interactive mode)`);
7960
+ return defaultYes;
7961
+ }
7955
7962
  const { ok } = await inquirer.prompt([{
7956
7963
  type: "confirm",
7957
7964
  name: "ok",
@@ -7967,6 +7974,12 @@ async function listPrompt(message, choices, defaultValue) {
7967
7974
  if (choices.length === 0) {
7968
7975
  throw new Error("No choices provided to listPrompt");
7969
7976
  }
7977
+ if (!isInteractive()) {
7978
+ const selected = defaultValue !== undefined ? defaultValue : choices[0].value;
7979
+ const selectedName = choices.find((c) => c.value === selected)?.name || String(selected);
7980
+ info(`${message} → ${selectedName} (auto-selected, non-interactive mode)`);
7981
+ return selected;
7982
+ }
7970
7983
  const defaultIndex = defaultValue !== undefined ? choices.findIndex((c) => c.value === defaultValue) : 0;
7971
7984
  const result = await inquirer.prompt([{
7972
7985
  type: "rawlist",
@@ -7990,6 +8003,13 @@ async function inputPrompt(message, defaultValue, validate2) {
7990
8003
  if (globalYes && defaultValue !== undefined) {
7991
8004
  return defaultValue;
7992
8005
  }
8006
+ if (!isInteractive()) {
8007
+ if (defaultValue !== undefined) {
8008
+ info(`${message} → ${defaultValue} (auto-selected, non-interactive mode)`);
8009
+ return defaultValue;
8010
+ }
8011
+ throw new Error(`Input required for "${message}" but running in non-interactive mode without default value. Use -y flag with appropriate defaults.`);
8012
+ }
7993
8013
  const { value } = await inquirer.prompt([{
7994
8014
  type: "input",
7995
8015
  name: "value",
@@ -8009,6 +8029,11 @@ async function checkboxPrompt(message, choices, defaultSelected) {
8009
8029
  if (choices.length === 0) {
8010
8030
  throw new Error("No choices provided to checkboxPrompt");
8011
8031
  }
8032
+ if (!isInteractive()) {
8033
+ const selected = defaultSelected || [];
8034
+ info(`${message} → [${selected.length} items] (auto-selected, non-interactive mode)`);
8035
+ return selected;
8036
+ }
8012
8037
  const defaultValues = defaultSelected || [];
8013
8038
  const result = await inquirer.prompt([{
8014
8039
  type: "checkbox",
@@ -9446,7 +9471,24 @@ async function pushCommand(options) {
9446
9471
  } catch (e) {
9447
9472
  error("Push failed");
9448
9473
  error("Error during push:");
9449
- error(String(e));
9474
+ if (e instanceof AggregateError) {
9475
+ error("Multiple errors occurred:");
9476
+ for (const err of e.errors) {
9477
+ error(` • ${err instanceof Error ? err.message : String(err)}`);
9478
+ if (err instanceof Error && err.stack) {
9479
+ const stackLines = err.stack.split(`
9480
+ `).slice(1, 3);
9481
+ stackLines.forEach((line) => error(` ${line.trim()}`));
9482
+ }
9483
+ }
9484
+ } else if (e instanceof Error) {
9485
+ error(e.message);
9486
+ if (e.cause) {
9487
+ error(`Caused by: ${e.cause instanceof Error ? e.cause.message : String(e.cause)}`);
9488
+ }
9489
+ } else {
9490
+ error(String(e));
9491
+ }
9450
9492
  } finally {
9451
9493
  await client.close();
9452
9494
  }
@@ -11556,13 +11598,32 @@ program.hook("preAction", (thisCommand) => {
11556
11598
  const opts = thisCommand.optsWithGlobals?.() ?? thisCommand.opts();
11557
11599
  setGlobalYesMode(Boolean(opts.yes));
11558
11600
  });
11601
+ function formatError(err) {
11602
+ const lines = [];
11603
+ if (err instanceof AggregateError) {
11604
+ lines.push("Multiple errors occurred:");
11605
+ for (const e of err.errors) {
11606
+ lines.push(` • ${e instanceof Error ? e.message : String(e)}`);
11607
+ }
11608
+ } else if (err instanceof Error) {
11609
+ lines.push(err.message);
11610
+ if (err.cause) {
11611
+ lines.push(`Caused by: ${err.cause instanceof Error ? err.cause.message : String(err.cause)}`);
11612
+ }
11613
+ } else {
11614
+ lines.push(String(err));
11615
+ }
11616
+ return lines;
11617
+ }
11559
11618
  function withErrorHandling(fn) {
11560
11619
  return async (...args) => {
11561
11620
  try {
11562
11621
  await fn(...args);
11563
11622
  } catch (error3) {
11623
+ const errorLines = formatError(error3);
11564
11624
  console.error(chalk5.red(`
11565
- ✖ Error: ` + (error3.message || String(error3))));
11625
+ ✖ Error: ` + errorLines[0]));
11626
+ errorLines.slice(1).forEach((line) => console.error(chalk5.red(line)));
11566
11627
  if (process.env.DEBUG) {
11567
11628
  console.error(error3);
11568
11629
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@housekit/kit",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "CLI tool for HouseKit - manage ClickHouse schemas, migrations, and database operations with type-safe workflows.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -48,7 +48,7 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@clickhouse/client": "^1.14.0",
51
- "@housekit/orm": "^0.1.36",
51
+ "@housekit/orm": "^0.1.38",
52
52
  "boxen": "8.0.1",
53
53
  "chalk": "^5.6.2",
54
54
  "cli-table3": "^0.6.5",