@drzl/validation-core 3.15.1 → 3.16.0

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/index.cjs CHANGED
@@ -513,32 +513,50 @@ function updateColumns(table) {
513
513
  function selectColumns(table) {
514
514
  return table.columns;
515
515
  }
516
+ var reportedEngines = /* @__PURE__ */ new Set();
517
+ var ENGINE_PACKAGE = { prettier: "prettier", biome: "@biomejs/biome" };
518
+ function reportUnusableFormatter(engine, cause) {
519
+ if (reportedEngines.has(engine)) return;
520
+ reportedEngines.add(engine);
521
+ const pkg = ENGINE_PACKAGE[engine];
522
+ const remedy = engine === "prettier" ? 'Install prettier, which is an optional peer of @drzl/validation-core, or set format.engine to "auto" to accept whatever formatter is present.' : 'drzl formats with Biome by importing @biomejs/biome as a module; run the Biome CLI over the output instead, or set format.engine to "auto" or "prettier".';
523
+ const reason = cause instanceof Error ? cause.message : String(cause);
524
+ console.warn(
525
+ `[drzl] format.engine is "${engine}" but ${pkg} could not be used, so the generated files were left unformatted. ${remedy} Reason: ${reason}`
526
+ );
527
+ }
516
528
  async function formatCode(code, filePath, fmt) {
517
529
  if (fmt && fmt.enabled === false) return code;
518
530
  const engine = fmt?.engine ?? "auto";
519
- try {
520
- if (engine === "prettier" || engine === "auto") {
531
+ if (engine === "prettier" || engine === "auto") {
532
+ try {
521
533
  const prettier = await import("prettier");
522
534
  const cfgRef = fmt?.configPath ?? filePath;
523
535
  const cfg = await prettier.resolveConfig(cfgRef).catch(() => null);
524
536
  return prettier.format(code, { ...cfg ?? {}, parser: "typescript", filepath: filePath });
537
+ } catch (err) {
538
+ if (engine === "prettier") reportUnusableFormatter("prettier", err);
525
539
  }
526
- } catch {
527
540
  }
528
- try {
529
- if (engine === "biome" || engine === "auto") {
541
+ if (engine === "biome" || engine === "auto") {
542
+ try {
530
543
  const dynamicImport = Function("s", "return import(s)");
531
- const biome = await dynamicImport("@biomejs/biome").catch(() => null);
544
+ const biome = await dynamicImport("@biomejs/biome");
532
545
  if (biome?.formatContent) {
533
546
  const res = await biome.formatContent(code, { filePath });
534
- return (res && (res.content || res.formatted)) ?? code;
547
+ const out = res && (res.content || res.formatted);
548
+ if (typeof out === "string") return out;
549
+ throw new Error("@biomejs/biome formatContent returned no formatted content");
535
550
  }
536
551
  if (biome?.format) {
537
552
  const res = await biome.format(code, { filePath });
538
- return res ?? code;
553
+ if (typeof res === "string") return res;
554
+ throw new Error("@biomejs/biome format returned no formatted content");
539
555
  }
556
+ throw new Error("@biomejs/biome exposes neither formatContent nor format");
557
+ } catch (err) {
558
+ if (engine === "biome") reportUnusableFormatter("biome", err);
540
559
  }
541
- } catch {
542
560
  }
543
561
  return code;
544
562
  }
package/dist/index.d.cts CHANGED
@@ -512,9 +512,21 @@ declare function selectColumns(table: Table): Column[];
512
512
  * anyone installing @drzl/cli. It is `--external` in every build script that can reach it, and
513
513
  * no-bundled-formatter.spec.ts builds those scripts and checks.
514
514
  *
515
- * Neither absence is an error. A consumer with no formatter gets the code as rendered, which is
516
- * valid TypeScript that merely looks worse, and losing generated files at the last step would be
517
- * a far worse trade than losing their whitespace.
515
+ * An absent formatter is never fatal. A consumer with no formatter gets the code as rendered,
516
+ * which is valid TypeScript that merely looks worse, and losing generated files at the last step
517
+ * would be a far worse trade than losing their whitespace.
518
+ *
519
+ * Whether it is worth saying so depends on what was asked for, which is the difference between the
520
+ * two branches below. `engine: 'auto'` asked for whatever happens to be installed, so finding
521
+ * nothing is an outcome and the code comes back unchanged in silence. Naming an engine is a
522
+ * request, and an unmet request that produces neither formatted output nor a message reads as
523
+ * "this is fine" when it is not: the consumer configured something, it did not happen, and nothing
524
+ * in the run says which. So a named engine that cannot be loaded warns on stderr and still returns
525
+ * the code, rather than throwing. Throwing would lose a whole generation over whitespace, and the
526
+ * consumer would not even be told what for: every generator branch in the CLI except the oRPC one
527
+ * wraps its `generate()` in a catch that prints "<name> generator missing. Install with: npm
528
+ * install @drzl/generator-<name>", so the headline would name a package they already have and the
529
+ * real reason would arrive as a trailing detail line. Measured, with a throw wired in on purpose.
518
530
  */
519
531
  declare function formatCode(code: string, filePath: string, fmt?: FormatOptions): Promise<any>;
520
532
 
package/dist/index.d.ts CHANGED
@@ -512,9 +512,21 @@ declare function selectColumns(table: Table): Column[];
512
512
  * anyone installing @drzl/cli. It is `--external` in every build script that can reach it, and
513
513
  * no-bundled-formatter.spec.ts builds those scripts and checks.
514
514
  *
515
- * Neither absence is an error. A consumer with no formatter gets the code as rendered, which is
516
- * valid TypeScript that merely looks worse, and losing generated files at the last step would be
517
- * a far worse trade than losing their whitespace.
515
+ * An absent formatter is never fatal. A consumer with no formatter gets the code as rendered,
516
+ * which is valid TypeScript that merely looks worse, and losing generated files at the last step
517
+ * would be a far worse trade than losing their whitespace.
518
+ *
519
+ * Whether it is worth saying so depends on what was asked for, which is the difference between the
520
+ * two branches below. `engine: 'auto'` asked for whatever happens to be installed, so finding
521
+ * nothing is an outcome and the code comes back unchanged in silence. Naming an engine is a
522
+ * request, and an unmet request that produces neither formatted output nor a message reads as
523
+ * "this is fine" when it is not: the consumer configured something, it did not happen, and nothing
524
+ * in the run says which. So a named engine that cannot be loaded warns on stderr and still returns
525
+ * the code, rather than throwing. Throwing would lose a whole generation over whitespace, and the
526
+ * consumer would not even be told what for: every generator branch in the CLI except the oRPC one
527
+ * wraps its `generate()` in a catch that prints "<name> generator missing. Install with: npm
528
+ * install @drzl/generator-<name>", so the headline would name a package they already have and the
529
+ * real reason would arrive as a trailing detail line. Measured, with a throw wired in on purpose.
518
530
  */
519
531
  declare function formatCode(code: string, filePath: string, fmt?: FormatOptions): Promise<any>;
520
532
 
package/dist/index.js CHANGED
@@ -450,32 +450,50 @@ function updateColumns(table) {
450
450
  function selectColumns(table) {
451
451
  return table.columns;
452
452
  }
453
+ var reportedEngines = /* @__PURE__ */ new Set();
454
+ var ENGINE_PACKAGE = { prettier: "prettier", biome: "@biomejs/biome" };
455
+ function reportUnusableFormatter(engine, cause) {
456
+ if (reportedEngines.has(engine)) return;
457
+ reportedEngines.add(engine);
458
+ const pkg = ENGINE_PACKAGE[engine];
459
+ const remedy = engine === "prettier" ? 'Install prettier, which is an optional peer of @drzl/validation-core, or set format.engine to "auto" to accept whatever formatter is present.' : 'drzl formats with Biome by importing @biomejs/biome as a module; run the Biome CLI over the output instead, or set format.engine to "auto" or "prettier".';
460
+ const reason = cause instanceof Error ? cause.message : String(cause);
461
+ console.warn(
462
+ `[drzl] format.engine is "${engine}" but ${pkg} could not be used, so the generated files were left unformatted. ${remedy} Reason: ${reason}`
463
+ );
464
+ }
453
465
  async function formatCode(code, filePath, fmt) {
454
466
  if (fmt && fmt.enabled === false) return code;
455
467
  const engine = fmt?.engine ?? "auto";
456
- try {
457
- if (engine === "prettier" || engine === "auto") {
468
+ if (engine === "prettier" || engine === "auto") {
469
+ try {
458
470
  const prettier = await import("prettier");
459
471
  const cfgRef = fmt?.configPath ?? filePath;
460
472
  const cfg = await prettier.resolveConfig(cfgRef).catch(() => null);
461
473
  return prettier.format(code, { ...cfg ?? {}, parser: "typescript", filepath: filePath });
474
+ } catch (err) {
475
+ if (engine === "prettier") reportUnusableFormatter("prettier", err);
462
476
  }
463
- } catch {
464
477
  }
465
- try {
466
- if (engine === "biome" || engine === "auto") {
478
+ if (engine === "biome" || engine === "auto") {
479
+ try {
467
480
  const dynamicImport = Function("s", "return import(s)");
468
- const biome = await dynamicImport("@biomejs/biome").catch(() => null);
481
+ const biome = await dynamicImport("@biomejs/biome");
469
482
  if (biome?.formatContent) {
470
483
  const res = await biome.formatContent(code, { filePath });
471
- return (res && (res.content || res.formatted)) ?? code;
484
+ const out = res && (res.content || res.formatted);
485
+ if (typeof out === "string") return out;
486
+ throw new Error("@biomejs/biome formatContent returned no formatted content");
472
487
  }
473
488
  if (biome?.format) {
474
489
  const res = await biome.format(code, { filePath });
475
- return res ?? code;
490
+ if (typeof res === "string") return res;
491
+ throw new Error("@biomejs/biome format returned no formatted content");
476
492
  }
493
+ throw new Error("@biomejs/biome exposes neither formatContent nor format");
494
+ } catch (err) {
495
+ if (engine === "biome") reportUnusableFormatter("biome", err);
477
496
  }
478
- } catch {
479
497
  }
480
498
  return code;
481
499
  }
package/package.json CHANGED
@@ -1,17 +1,30 @@
1
1
  {
2
2
  "name": "@drzl/validation-core",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "private": false,
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
- "main": "dist/index.js",
8
- "types": "dist/index.d.ts",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "require": {
17
+ "types": "./dist/index.d.cts",
18
+ "default": "./dist/index.cjs"
19
+ }
20
+ }
21
+ },
9
22
  "files": [
10
23
  "dist"
11
24
  ],
12
25
  "sideEffects": false,
13
26
  "dependencies": {
14
- "@drzl/analyzer": "^1.15.0"
27
+ "@drzl/analyzer": "^1.18.0"
15
28
  },
16
29
  "peerDependencies": {
17
30
  "prettier": ">=3"