@davidorex/pi-context-cli 0.30.0 → 0.31.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/render.js ADDED
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Structural guard for a pi-context {@link ValidationError}.
3
+ *
4
+ * `instanceof ValidationError` is UNRELIABLE across this package boundary: the op
5
+ * registry reaches `schema-validator` through one module-resolution path and the
6
+ * CLI imports the class through the `@davidorex/pi-context/schema-validator`
7
+ * subpath export — Node can give these two distinct class objects, so a real
8
+ * ValidationError thrown by an op fails `instanceof` here (observed: `e.name` ===
9
+ * "ValidationError" yet `e instanceof ValidationError` === false). Detect by the
10
+ * stable shape instead: a `name` of "ValidationError" carrying the `errors`
11
+ * (AJV `ErrorObject[]`) and `label` fields `formatAjvError` reads.
12
+ */
13
+ export function isValidationError(err) {
14
+ return (err instanceof Error &&
15
+ err.name === "ValidationError" &&
16
+ Array.isArray(err.errors) &&
17
+ typeof err.label === "string");
18
+ }
19
+ /**
20
+ * Render an array of objects as a compact markdown table.
21
+ *
22
+ * Lifted from `scripts/orchestrator/filter-block-items.ts`'s `renderTable` so the
23
+ * `--format table` CLI surface produces the same projection the script twin does.
24
+ * Column selection is best-effort terse: `id` first when present, then up to three
25
+ * more keys from the first row (≤4 columns total); if the first row has no `id`,
26
+ * the first four keys. Cells: null/undefined → empty; strings verbatim; non-string
27
+ * values `JSON.stringify`'d; internal newlines collapsed to a single space; capped
28
+ * at 80 chars (>80 → first 77 + "...").
29
+ *
30
+ * Non-array / empty inputs are NOT a table: an empty array (or any non-array) yields
31
+ * the sentinel `"(no rows)"` so the dispatch layer can fall back to text rather than
32
+ * emit a degenerate table.
33
+ */
34
+ export function renderTable(rows) {
35
+ if (!Array.isArray(rows) || rows.length === 0)
36
+ return "(no rows)";
37
+ const first = rows[0];
38
+ const keys = Object.keys(first);
39
+ const hasId = keys.includes("id");
40
+ const others = keys.filter((k) => k !== "id").slice(0, 3);
41
+ const cols = hasId ? ["id", ...others] : keys.slice(0, 4);
42
+ const header = `| ${cols.join(" | ")} |`;
43
+ const sep = `| ${cols.map(() => "---").join(" | ")} |`;
44
+ const body = rows.map((raw) => {
45
+ const it = raw;
46
+ return `| ${cols
47
+ .map((c) => {
48
+ const v = it[c];
49
+ if (v === undefined || v === null)
50
+ return "";
51
+ const s = typeof v === "string" ? v : JSON.stringify(v);
52
+ const oneLine = s.replace(/\s*\n\s*/g, " ");
53
+ return oneLine.length > 80 ? `${oneLine.slice(0, 77)}...` : oneLine;
54
+ })
55
+ .join(" | ")} |`;
56
+ });
57
+ return [header, sep, ...body].join("\n");
58
+ }
59
+ /**
60
+ * Translate an AJV {@link ValidationError} into field-named guidance.
61
+ *
62
+ * The raw `ValidationError.message` concatenates AJV's terse `instancePath: message`
63
+ * fragments (e.g. "must have required property 'package'"), which name the JSON
64
+ * pointer but bury the actionable field name and constraint. This re-shapes each
65
+ * `err.errors[]` AJV `ErrorObject` into one guidance line per error, keyword-aware:
66
+ * - required → `<path>`: missing required field `<missingProperty>`
67
+ * - type → `<path>`: expected <type>
68
+ * - enum → `<path>`: must be one of <allowedValues…>
69
+ * - additionalProperties → `<path>`: unexpected property `<additionalProperty>`
70
+ * - (any other keyword) → `<path>`: <raw message>
71
+ * Segments join with "; " — one segment per error, so the error COUNT is never
72
+ * dropped — and the whole is prefixed `validation failed for <label>: …`.
73
+ */
74
+ export function formatAjvError(err) {
75
+ const segments = err.errors.map((e) => {
76
+ const at = e.instancePath || "/";
77
+ const params = (e.params ?? {});
78
+ switch (e.keyword) {
79
+ case "required":
80
+ return `\`${at}\`: missing required field \`${String(params.missingProperty)}\``;
81
+ case "type":
82
+ return `\`${at}\`: expected ${String(params.type)}`;
83
+ case "enum": {
84
+ const allowed = Array.isArray(params.allowedValues) ? params.allowedValues.join(", ") : "";
85
+ return `\`${at}\`: must be one of ${allowed}`;
86
+ }
87
+ case "additionalProperties":
88
+ return `\`${at}\`: unexpected property \`${String(params.additionalProperty)}\``;
89
+ default:
90
+ return `\`${at}\`: ${e.message ?? "invalid"}`;
91
+ }
92
+ });
93
+ return `validation failed for ${err.label}: ${segments.join("; ")}`;
94
+ }
95
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davidorex/pi-context-cli",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -28,12 +28,13 @@
28
28
  ],
29
29
  "scripts": {
30
30
  "clean": "rm -rf dist",
31
- "build": "rm -rf dist && tsc -p tsconfig.build.json",
31
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/bin.js",
32
32
  "prepublishOnly": "npm run clean && npm run build",
33
33
  "test": "tsx --test src/*.test.ts"
34
34
  },
35
35
  "dependencies": {
36
- "@davidorex/pi-context": "^0.30.0",
36
+ "@davidorex/pi-context": "^0.31.0",
37
+ "@davidorex/pi-project-workflows": "^0.31.0",
37
38
  "typebox": "^1.1.24"
38
39
  },
39
40
  "engines": {