@drzl/cli 4.14.2 → 4.14.4

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/README.md CHANGED
@@ -56,3 +56,7 @@ Notes
56
56
  DRZL uses whichever it finds in your project, with your config. With neither installed the
57
57
  generated files are written exactly as rendered, which is the same valid TypeScript with worse
58
58
  whitespace. Add `prettier` as a dev dependency if you want it formatted.
59
+ - Naming an engine instead, `format.engine: 'prettier'` or `'biome'`, is a request rather than a
60
+ preference, so an engine that cannot be loaded is reported on stderr with the reason. The files
61
+ are still written, unformatted; nothing fails. `'auto'` stays silent, because it asked for
62
+ whatever happened to be installed and no formatter is a legitimate answer to that.
package/dist/cli.cjs CHANGED
@@ -56,6 +56,12 @@ function baseSchema(c, mode, target, checks, sets, lengths) {
56
56
  minItems: s.length,
57
57
  maxItems: s.length
58
58
  };
59
+ case "numberObject":
60
+ return {
61
+ type: "object",
62
+ properties: Object.fromEntries(s.fields.map((f) => [f, { type: "number" }])),
63
+ required: [...s.fields]
64
+ };
59
65
  case "numberVector":
60
66
  return {
61
67
  type: "array",
@@ -68,6 +74,8 @@ function baseSchema(c, mode, target, checks, sets, lengths) {
68
74
  pattern: "^[01]*$",
69
75
  ...s.length ? s.exact ? { minLength: s.length, maxLength: s.length } : { maxLength: s.length } : {}
70
76
  };
77
+ case "byteString":
78
+ return { type: "string", ...s.length ? { maxLength: s.length } : {} };
71
79
  }
72
80
  }
73
81
  const set = sets.find((x) => x.column === c.name);
@@ -82,6 +90,7 @@ function baseSchema(c, mode, target, checks, sets, lengths) {
82
90
  if (c.format === "uuid") out.format = UUID_FORMAT;
83
91
  else if (c.format && import_validation_core2.COLUMN_FORMATS[c.format]) out.pattern = import_validation_core2.COLUMN_FORMATS[c.format];
84
92
  if (c.maxLength !== void 0) out.maxLength = c.maxLength;
93
+ applyByteCap(out, c);
85
94
  applyLengths(out, c, lengths);
86
95
  return out;
87
96
  }
@@ -102,6 +111,11 @@ function baseSchema(c, mode, target, checks, sets, lengths) {
102
111
  return {};
103
112
  }
104
113
  }
114
+ function applyByteCap(out, c) {
115
+ if (!c.maxBytes) return;
116
+ out.maxLength = Math.min(Number(out.maxLength ?? Infinity), c.maxBytes);
117
+ out.description = `At most ${c.maxBytes} bytes of UTF-8, which JSON Schema has no keyword for. maxLength counts characters: it refuses nothing the column accepts, and a string of multi-byte characters can satisfy it and still be too long for the column.`;
118
+ }
105
119
  function applyLengths(out, c, lengths) {
106
120
  for (const k of lengths.filter((x) => x.column === c.name)) {
107
121
  const n = Number(k.value);
@@ -768,6 +782,30 @@ async function restoreSnapshot(before, after) {
768
782
  }
769
783
  }
770
784
 
785
+ // src/generator-loader.ts
786
+ var GeneratorNotInstalledError = class extends Error {
787
+ constructor(specifier, reason) {
788
+ super(`${specifier} is not installed`);
789
+ this.specifier = specifier;
790
+ this.reason = reason;
791
+ this.name = "GeneratorNotInstalledError";
792
+ }
793
+ };
794
+ function isPackageMissing(err, specifier) {
795
+ const code = err?.code;
796
+ if (code !== "ERR_MODULE_NOT_FOUND") return false;
797
+ const message = err?.message;
798
+ return typeof message === "string" && message.includes(`'${specifier}'`);
799
+ }
800
+ async function loadGenerator(specifier, load) {
801
+ try {
802
+ return await load();
803
+ } catch (e) {
804
+ if (isPackageMissing(e, specifier)) throw new GeneratorNotInstalledError(specifier, e);
805
+ throw e;
806
+ }
807
+ }
808
+
771
809
  // src/sponsor.ts
772
810
  var import_chalk = __toESM(require("chalk"), 1);
773
811
  var import_node_fs2 = require("fs");
@@ -871,6 +909,17 @@ function readCliVersion() {
871
909
  var CLI_VERSION = readCliVersion();
872
910
 
873
911
  // src/cli.ts
912
+ function reportGeneratorFailure(kind, e) {
913
+ if (e instanceof GeneratorNotInstalledError) {
914
+ console.error(
915
+ import_chalk2.default.red(`The ${kind} generator is not installed.`),
916
+ import_chalk2.default.yellow(`
917
+ Install with: npm install ${e.specifier}`)
918
+ );
919
+ return;
920
+ }
921
+ console.error(import_chalk2.default.red(`The ${kind} generator failed:`), e?.message ?? e);
922
+ }
874
923
  var program = new import_commander.Command();
875
924
  program.name("drzl").description("DRZL - Drizzle Developer Toolkit").version(CLI_VERSION);
876
925
  program.addHelpText(
@@ -969,7 +1018,10 @@ program.command("generate").description("Run configured generators (drzl.config.
969
1018
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
970
1019
  } else if (g.kind === "service") {
971
1020
  try {
972
- const { ServiceGenerator } = await import("@drzl/generator-service");
1021
+ const { ServiceGenerator } = await loadGenerator(
1022
+ "@drzl/generator-service",
1023
+ () => import("@drzl/generator-service")
1024
+ );
973
1025
  const gen = new ServiceGenerator(analysis);
974
1026
  const target = g.path ?? "src/services";
975
1027
  const files = await gen.generate({
@@ -986,16 +1038,15 @@ program.command("generate").description("Run configured generators (drzl.config.
986
1038
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
987
1039
  } catch (e) {
988
1040
  progress.stop();
989
- console.error(
990
- import_chalk2.default.red("Service generator missing."),
991
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-service")
992
- );
993
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1041
+ reportGeneratorFailure(g.kind, e);
994
1042
  process.exit(1);
995
1043
  }
996
1044
  } else if (g.kind === "zod") {
997
1045
  try {
998
- const { ZodGenerator } = await import("@drzl/generator-zod");
1046
+ const { ZodGenerator } = await loadGenerator(
1047
+ "@drzl/generator-zod",
1048
+ () => import("@drzl/generator-zod")
1049
+ );
999
1050
  const gen = new ZodGenerator(analysis);
1000
1051
  const target = g.path ?? "src/validators/zod";
1001
1052
  const files = await gen.generate(
@@ -1006,16 +1057,15 @@ program.command("generate").description("Run configured generators (drzl.config.
1006
1057
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
1007
1058
  } catch (e) {
1008
1059
  progress.stop();
1009
- console.error(
1010
- import_chalk2.default.red("Zod generator missing."),
1011
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-zod")
1012
- );
1013
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1060
+ reportGeneratorFailure(g.kind, e);
1014
1061
  process.exit(1);
1015
1062
  }
1016
1063
  } else if (g.kind === "valibot") {
1017
1064
  try {
1018
- const { ValibotGenerator } = await import("@drzl/generator-valibot");
1065
+ const { ValibotGenerator } = await loadGenerator(
1066
+ "@drzl/generator-valibot",
1067
+ () => import("@drzl/generator-valibot")
1068
+ );
1019
1069
  const gen = new ValibotGenerator(analysis);
1020
1070
  const target = g.path ?? "src/validators/valibot";
1021
1071
  const files = await gen.generate(
@@ -1026,16 +1076,15 @@ program.command("generate").description("Run configured generators (drzl.config.
1026
1076
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
1027
1077
  } catch (e) {
1028
1078
  progress.stop();
1029
- console.error(
1030
- import_chalk2.default.red("Valibot generator missing."),
1031
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-valibot")
1032
- );
1033
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1079
+ reportGeneratorFailure(g.kind, e);
1034
1080
  process.exit(1);
1035
1081
  }
1036
1082
  } else if (g.kind === "arktype") {
1037
1083
  try {
1038
- const { ArkTypeGenerator } = await import("@drzl/generator-arktype");
1084
+ const { ArkTypeGenerator } = await loadGenerator(
1085
+ "@drzl/generator-arktype",
1086
+ () => import("@drzl/generator-arktype")
1087
+ );
1039
1088
  const gen = new ArkTypeGenerator(analysis);
1040
1089
  const target = g.path ?? "src/validators/arktype";
1041
1090
  const files = await gen.generate(
@@ -1046,16 +1095,15 @@ program.command("generate").description("Run configured generators (drzl.config.
1046
1095
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
1047
1096
  } catch (e) {
1048
1097
  progress.stop();
1049
- console.error(
1050
- import_chalk2.default.red("ArkType generator missing."),
1051
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-arktype")
1052
- );
1053
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1098
+ reportGeneratorFailure(g.kind, e);
1054
1099
  process.exit(1);
1055
1100
  }
1056
1101
  } else if (g.kind === "json-schema") {
1057
1102
  try {
1058
- const { JsonSchemaGenerator: JsonSchemaGenerator2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
1103
+ const { JsonSchemaGenerator: JsonSchemaGenerator2 } = await loadGenerator(
1104
+ "@drzl/generator-json-schema",
1105
+ () => Promise.resolve().then(() => (init_dist(), dist_exports))
1106
+ );
1059
1107
  const gen = new JsonSchemaGenerator2(analysis);
1060
1108
  const target = g.path ?? "src/validators/json-schema";
1061
1109
  const files = await gen.generate({
@@ -1069,20 +1117,15 @@ program.command("generate").description("Run configured generators (drzl.config.
1069
1117
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
1070
1118
  } catch (e) {
1071
1119
  progress.stop();
1072
- console.error(
1073
- import_chalk2.default.red("JSON Schema generator missing."),
1074
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-json-schema"),
1075
- // An optional dependency, unlike the other generators, until its npm trusted
1076
- // publisher exists. A missing optional dependency is skipped rather than failing
1077
- // the install, which is what keeps `npm i @drzl/cli` working meanwhile.
1078
- ""
1079
- );
1080
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1120
+ reportGeneratorFailure(g.kind, e);
1081
1121
  process.exit(1);
1082
1122
  }
1083
1123
  } else if (g.kind === "typebox") {
1084
1124
  try {
1085
- const { TypeBoxGenerator } = await import("@drzl/generator-typebox");
1125
+ const { TypeBoxGenerator } = await loadGenerator(
1126
+ "@drzl/generator-typebox",
1127
+ () => import("@drzl/generator-typebox")
1128
+ );
1086
1129
  const gen = new TypeBoxGenerator(analysis);
1087
1130
  const target = g.path ?? "src/validators/typebox";
1088
1131
  const files = await gen.generate(
@@ -1093,11 +1136,7 @@ program.command("generate").description("Run configured generators (drzl.config.
1093
1136
  files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
1094
1137
  } catch (e) {
1095
1138
  progress.stop();
1096
- console.error(
1097
- import_chalk2.default.red("TypeBox generator missing."),
1098
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-typebox")
1099
- );
1100
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1139
+ reportGeneratorFailure(g.kind, e);
1101
1140
  process.exit(1);
1102
1141
  }
1103
1142
  }
@@ -1281,7 +1320,10 @@ program.command("watch").description("Watch schema and regenerate on changes").o
1281
1320
  newFiles.push(...files);
1282
1321
  } else if (g.kind === "service") {
1283
1322
  try {
1284
- const { ServiceGenerator } = await import("@drzl/generator-service");
1323
+ const { ServiceGenerator } = await loadGenerator(
1324
+ "@drzl/generator-service",
1325
+ () => import("@drzl/generator-service")
1326
+ );
1285
1327
  const gen = new ServiceGenerator(analysis);
1286
1328
  const target = g.path ?? "src/services";
1287
1329
  const files = await gen.generate({
@@ -1299,16 +1341,15 @@ program.command("watch").description("Watch schema and regenerate on changes").o
1299
1341
  );
1300
1342
  newFiles.push(...files);
1301
1343
  } catch (e) {
1302
- console.error(
1303
- import_chalk2.default.red("Service generator missing."),
1304
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-service")
1305
- );
1306
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1344
+ reportGeneratorFailure(g.kind, e);
1307
1345
  return;
1308
1346
  }
1309
1347
  } else if (g.kind === "zod") {
1310
1348
  try {
1311
- const { ZodGenerator } = await import("@drzl/generator-zod");
1349
+ const { ZodGenerator } = await loadGenerator(
1350
+ "@drzl/generator-zod",
1351
+ () => import("@drzl/generator-zod")
1352
+ );
1312
1353
  const gen = new ZodGenerator(analysis);
1313
1354
  const target = g.path ?? "src/validators/zod";
1314
1355
  const files = await gen.generate({
@@ -1326,16 +1367,15 @@ program.command("watch").description("Watch schema and regenerate on changes").o
1326
1367
  );
1327
1368
  newFiles.push(...files);
1328
1369
  } catch (e) {
1329
- console.error(
1330
- import_chalk2.default.red("Zod generator missing."),
1331
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-zod")
1332
- );
1333
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1370
+ reportGeneratorFailure(g.kind, e);
1334
1371
  return;
1335
1372
  }
1336
1373
  } else if (g.kind === "valibot") {
1337
1374
  try {
1338
- const { ValibotGenerator } = await import("@drzl/generator-valibot");
1375
+ const { ValibotGenerator } = await loadGenerator(
1376
+ "@drzl/generator-valibot",
1377
+ () => import("@drzl/generator-valibot")
1378
+ );
1339
1379
  const gen = new ValibotGenerator(analysis);
1340
1380
  const target = g.path ?? "src/validators/valibot";
1341
1381
  const files = await gen.generate({
@@ -1353,16 +1393,15 @@ program.command("watch").description("Watch schema and regenerate on changes").o
1353
1393
  );
1354
1394
  newFiles.push(...files);
1355
1395
  } catch (e) {
1356
- console.error(
1357
- import_chalk2.default.red("Valibot generator missing."),
1358
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-valibot")
1359
- );
1360
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1396
+ reportGeneratorFailure(g.kind, e);
1361
1397
  return;
1362
1398
  }
1363
1399
  } else if (g.kind === "arktype") {
1364
1400
  try {
1365
- const { ArkTypeGenerator } = await import("@drzl/generator-arktype");
1401
+ const { ArkTypeGenerator } = await loadGenerator(
1402
+ "@drzl/generator-arktype",
1403
+ () => import("@drzl/generator-arktype")
1404
+ );
1366
1405
  const gen = new ArkTypeGenerator(analysis);
1367
1406
  const target = g.path ?? "src/validators/arktype";
1368
1407
  const files = await gen.generate({
@@ -1380,11 +1419,7 @@ program.command("watch").description("Watch schema and regenerate on changes").o
1380
1419
  );
1381
1420
  newFiles.push(...files);
1382
1421
  } catch (e) {
1383
- console.error(
1384
- import_chalk2.default.red("ArkType generator missing."),
1385
- import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-arktype")
1386
- );
1387
- console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
1422
+ reportGeneratorFailure(g.kind, e);
1388
1423
  return;
1389
1424
  }
1390
1425
  }