@quillmark/quiver 0.9.0 → 0.11.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.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Quiver CLI — build, test, and preview a quiver collection.
4
+ *
5
+ * Commands:
6
+ * quiver build [--out <dir>]
7
+ * quiver test
8
+ * quiver preview [--out <dir>] [--format <fmt>] [--quiet]
9
+ * [--include <ref>...] [--exclude <ref>...]
10
+ *
11
+ * Engine discovery (for `test` and `preview`):
12
+ * 1. Named exports `engine` and `Document` from `quiver.config.js` at the
13
+ * collection root, if the file exists.
14
+ * 2. Auto-imported `@quillmark/wasm` from the collection's node_modules.
15
+ */
16
+ export {};
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Quiver CLI — build, test, and preview a quiver collection.
4
+ *
5
+ * Commands:
6
+ * quiver build [--out <dir>]
7
+ * quiver test
8
+ * quiver preview [--out <dir>] [--format <fmt>] [--quiet]
9
+ * [--include <ref>...] [--exclude <ref>...]
10
+ *
11
+ * Engine discovery (for `test` and `preview`):
12
+ * 1. Named exports `engine` and `Document` from `quiver.config.js` at the
13
+ * collection root, if the file exists.
14
+ * 2. Auto-imported `@quillmark/wasm` from the collection's node_modules.
15
+ */
16
+ import { createRequire } from "node:module";
17
+ import { join } from "node:path";
18
+ import { pathToFileURL } from "node:url";
19
+ import { Quiver } from "../node.js";
20
+ import { renderQuiverSamples } from "../preview.js";
21
+ // ---------------------------------------------------------------------------
22
+ // Arg parsing helpers
23
+ // ---------------------------------------------------------------------------
24
+ const argv = process.argv.slice(2);
25
+ const command = argv[0];
26
+ function flag(name) {
27
+ const i = argv.indexOf(name);
28
+ return i !== -1 && i + 1 < argv.length ? argv[i + 1] : undefined;
29
+ }
30
+ function multiFlag(name) {
31
+ const out = [];
32
+ for (let i = 0; i < argv.length - 1; i++) {
33
+ if (argv[i] === name)
34
+ out.push(argv[i + 1]);
35
+ }
36
+ return out;
37
+ }
38
+ function hasFlag(name) {
39
+ return argv.includes(name);
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Engine discovery
43
+ // ---------------------------------------------------------------------------
44
+ async function loadEngine(cwd) {
45
+ // 1. Named exports from quiver.config.js, if present.
46
+ try {
47
+ const cfg = await import(pathToFileURL(join(cwd, "quiver.config.js")).href);
48
+ if (cfg.engine != null && cfg.Document != null) {
49
+ return {
50
+ engine: cfg.engine,
51
+ Document: cfg.Document,
52
+ };
53
+ }
54
+ }
55
+ catch {
56
+ // File absent or incomplete — fall through to auto-discovery.
57
+ }
58
+ // 2. Auto-discover @quillmark/wasm from the collection's own node_modules.
59
+ const req = createRequire(pathToFileURL(join(cwd, "package.json")).href);
60
+ let wasmPath;
61
+ try {
62
+ wasmPath = req.resolve("@quillmark/wasm");
63
+ }
64
+ catch {
65
+ throw new Error("Cannot find @quillmark/wasm in this collection's node_modules.\n" +
66
+ " Install it: npm install @quillmark/wasm\n" +
67
+ " Or export { engine, Document } from quiver.config.js for a custom engine.");
68
+ }
69
+ const wasm = (await import(pathToFileURL(wasmPath).href));
70
+ return { engine: new wasm.Quillmark(), Document: wasm.Document };
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // Commands
74
+ // ---------------------------------------------------------------------------
75
+ async function build() {
76
+ const cwd = process.cwd();
77
+ const outDir = flag("--out") ?? "dist";
78
+ console.log(`quiver build: ${cwd} → ${outDir}`);
79
+ await Quiver.build(cwd, outDir);
80
+ console.log("done.");
81
+ }
82
+ async function test() {
83
+ const cwd = process.cwd();
84
+ const { engine, Document } = await loadEngine(cwd);
85
+ const quiver = await Quiver.fromDir(cwd);
86
+ const names = quiver.quillNames();
87
+ if (names.length === 0) {
88
+ console.error("error: quiver has no quills");
89
+ process.exit(1);
90
+ }
91
+ let pass = 0;
92
+ let fail = 0;
93
+ for (const name of names) {
94
+ for (const version of quiver.versionsOf(name)) {
95
+ const ref = `${name}@${version}`;
96
+ try {
97
+ const quill = await quiver.getQuill(ref, { engine });
98
+ const doc = Document.fromMarkdown(quill.blueprint);
99
+ const result = quill.render(doc);
100
+ if (!Array.isArray(result.artifacts) || result.artifacts.length === 0) {
101
+ throw new Error("blueprint render produced no artifacts");
102
+ }
103
+ console.log(`pass ${ref}`);
104
+ pass++;
105
+ }
106
+ catch (err) {
107
+ console.error(`FAIL ${ref} — ${err.message}`);
108
+ fail++;
109
+ }
110
+ }
111
+ }
112
+ const total = pass + fail;
113
+ console.log(`\n${pass}/${total} passed`);
114
+ if (fail > 0)
115
+ process.exit(1);
116
+ }
117
+ async function preview() {
118
+ const cwd = process.cwd();
119
+ const { engine, Document } = await loadEngine(cwd);
120
+ const outDir = flag("--out");
121
+ const format = flag("--format");
122
+ const quiet = hasFlag("--quiet");
123
+ const include = multiFlag("--include");
124
+ const exclude = multiFlag("--exclude");
125
+ await renderQuiverSamples(cwd, {
126
+ engine,
127
+ Document,
128
+ ...(outDir !== undefined && { outDir }),
129
+ ...(format !== undefined && { format }),
130
+ quiet,
131
+ ...(include.length > 0 && { include }),
132
+ ...(exclude.length > 0 && { exclude }),
133
+ });
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Dispatch
137
+ // ---------------------------------------------------------------------------
138
+ function usage() {
139
+ console.error([
140
+ "Usage:",
141
+ " quiver build [--out <dir>]",
142
+ " quiver test",
143
+ " quiver preview [--out <dir>] [--format <fmt>] [--quiet]",
144
+ " [--include <ref>...] [--exclude <ref>...]",
145
+ ].join("\n"));
146
+ }
147
+ function die(err) {
148
+ const msg = err instanceof Error ? err.message : String(err);
149
+ console.error(`error: ${msg}`);
150
+ process.exit(1);
151
+ }
152
+ switch (command) {
153
+ case "build":
154
+ build().catch(die);
155
+ break;
156
+ case "test":
157
+ test().catch(die);
158
+ break;
159
+ case "preview":
160
+ preview().catch(die);
161
+ break;
162
+ default:
163
+ usage();
164
+ process.exit(1);
165
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quillmark/quiver",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Quiver registry and build tooling for Quillmark",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -51,18 +51,21 @@
51
51
  "README.md"
52
52
  ],
53
53
  "peerDependencies": {
54
- "@quillmark/wasm": ">=0.79.0"
54
+ "@quillmark/wasm": ">=0.80.0"
55
55
  },
56
56
  "dependencies": {
57
57
  "fflate": "^0.8.2",
58
58
  "yaml": "^2.8.3"
59
59
  },
60
60
  "devDependencies": {
61
- "@quillmark/wasm": "^0.79.0",
61
+ "@quillmark/wasm": "^0.80.0",
62
62
  "@types/node": "^25.3.3",
63
63
  "typescript": "^5.9.3",
64
64
  "vitest": "^4.0.18"
65
65
  },
66
+ "bin": {
67
+ "quiver": "./dist/bin/quiver.js"
68
+ },
66
69
  "scripts": {
67
70
  "build": "tsc",
68
71
  "test": "vitest run",