gutterpress 0.10.8 → 0.10.9
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 +93 -90
- package/dist/{README-aaqapam1.md → README-6c7fda1s.md} +9 -7
- package/dist/{README-mdq34cmb.md → README-jntqyj1z.md} +19 -10
- package/dist/api/index.d.ts +8 -8
- package/dist/api/index.js +46 -46
- package/dist/{audit-m3ce9pvq.js → audit-fq7s1gsz.js} +4 -4
- package/dist/{build-qnecb3a1.js → build-dyat3fqd.js} +5 -8
- package/dist/checks/source/dangling-links.d.ts +18 -0
- package/dist/checks/source/index.d.ts +1 -0
- package/dist/checks/source/local-ref-parser.d.ts +13 -0
- package/dist/{cli-1hx14cgk.js → cli-8pg731p5.js} +2941 -2927
- package/dist/{cli-4vtgt2ng.js → cli-bx950tb4.js} +7 -7
- package/dist/{cli-pfpb1t3h.js → cli-bzxqtvrk.js} +1 -2
- package/dist/{cli-vcv5ewqj.js → cli-rh05byck.js} +2 -9
- package/dist/{cli-vxf151ea.js → cli-ypfvnhag.js} +1 -1
- package/dist/cli.js +24 -53
- package/dist/{doctor-qvqye1wd.js → doctor-yr85n080.js} +2 -2
- package/dist/{engine-daad33qn.js → engine-19mshh07.js} +2 -2
- package/dist/{engine-db8632w6.js → engine-d46wgg99.js} +3 -3
- package/dist/ext-jrg8c48s.js +268 -0
- package/dist/{index-rpt4vtby.js → index-dhgzkhs7.js} +1 -1
- package/dist/{index-dfw8hn8q.js → index-mey5vraz.js} +5852 -5899
- package/dist/{index-9pbaznww.js → index-zwcv1njy.js} +7 -7
- package/dist/index.js +47 -47
- package/dist/lib/build-runner.d.ts +0 -7
- package/dist/lib/build-staging.d.ts +36 -0
- package/dist/lib/cli-args.d.ts +0 -7
- package/dist/lib/{theme-import.d.ts → extension-import.d.ts} +20 -11
- package/dist/lib/extension-manager.d.ts +170 -0
- package/dist/lib/extension-manifest.d.ts +25 -17
- package/dist/lib/extension-specifier.d.ts +31 -0
- package/dist/lib/manifest-doc.d.ts +3 -9
- package/dist/lib/markdown/markers.d.ts +2 -2
- package/dist/lib/markdown/plugins.d.ts +4 -4
- package/dist/lib/missing-asset-placeholder.d.ts +11 -0
- package/dist/lib/presets.d.ts +1 -1
- package/dist/lib/publish/providers/gdrive.d.ts +1 -1
- package/dist/lib/snippets.d.ts +11 -15
- package/dist/lib/style-resolver.d.ts +1 -1
- package/dist/{lint-3p1s8agk.js → lint-enasqbqx.js} +4 -4
- package/dist/{manifest.schema-1q35yxs9.json → manifest.schema-hsn8rsgr.json} +18 -53
- package/dist/{new-xffarp40.js → new-r9c99wsn.js} +11 -12
- package/dist/{plugin.test.js-mv0ghv5n.tpl → plugin.test.js-npnfhyca.tpl} +0 -1
- package/dist/{preflight-z6xpty9w.js → preflight-shk7vqbs.js} +4 -4
- package/dist/preview/file-watcher.d.ts +4 -4
- package/dist/preview/lifecycle.d.ts +1 -1
- package/dist/{preview-xa1n7why.js → preview-52918mxk.js} +6 -10
- package/dist/{publish-zgmr99kd.js → publish-8s60vhx7.js} +4 -4
- package/dist/schema/manifest.types.d.ts +28 -44
- package/dist/{theme-cd6efzjw.json → theme-etj4gxck.json} +4 -1
- package/dist/{theme-tqfypc1w.json → theme-s2rg7xe7.json} +4 -1
- package/dist/{theme-xt0hjb1b.json → theme-vktedy8q.json} +4 -1
- package/dist/types.d.ts +0 -7
- package/dist/{validate-43hqgzz5.js → validate-awccx32r.js} +4 -4
- package/package.json +1 -1
- package/dist/lib/plugin-manager.d.ts +0 -106
- package/dist/lib/theme-manager.d.ts +0 -242
- package/dist/plugin-b05ck7zd.js +0 -126
- package/dist/theme-m9dtxkhj.js +0 -323
|
@@ -1430,7 +1430,7 @@ import { fileURLToPath } from "node:url";
|
|
|
1430
1430
|
var favicon_default = "./favicon-wkbm9cjn.ico";
|
|
1431
1431
|
|
|
1432
1432
|
// src/assets/manifest.schema.json
|
|
1433
|
-
var manifest_schema_default = "./manifest.schema-
|
|
1433
|
+
var manifest_schema_default = "./manifest.schema-hsn8rsgr.json";
|
|
1434
1434
|
|
|
1435
1435
|
// src/assets/preview/scripts/preview-interface.js
|
|
1436
1436
|
var preview_interface_default = "./preview-interface-9rwz21yw.js";
|
|
@@ -1475,7 +1475,7 @@ var gutterpress_default = "./gutterpress-m98e2w2d.json";
|
|
|
1475
1475
|
var package_default = "./package-rm9d2tht.json";
|
|
1476
1476
|
|
|
1477
1477
|
// src/assets/extension-templates/plugin/README.md
|
|
1478
|
-
var README_default = "./README-
|
|
1478
|
+
var README_default = "./README-jntqyj1z.md";
|
|
1479
1479
|
|
|
1480
1480
|
// src/assets/extension-templates/plugin/plugin.js.tpl
|
|
1481
1481
|
var plugin_js_default = "./plugin.js-aszz0zgh.tpl";
|
|
@@ -1493,13 +1493,13 @@ var fixture_default = "./fixture-2qnyqgb5.md";
|
|
|
1493
1493
|
var expected_default = "./expected-ycmacem8.html";
|
|
1494
1494
|
|
|
1495
1495
|
// src/assets/extension-templates/plugin/test/plugin.test.js.tpl
|
|
1496
|
-
var plugin_test_js_default = "./plugin.test.js-
|
|
1496
|
+
var plugin_test_js_default = "./plugin.test.js-npnfhyca.tpl";
|
|
1497
1497
|
|
|
1498
1498
|
// src/assets/extension-templates/theme/gutterpress.json
|
|
1499
1499
|
var gutterpress_default2 = "./gutterpress-x2ycdsb8.json";
|
|
1500
1500
|
|
|
1501
1501
|
// src/assets/extension-templates/theme/README.md
|
|
1502
|
-
var README_default2 = "./README-
|
|
1502
|
+
var README_default2 = "./README-6c7fda1s.md";
|
|
1503
1503
|
|
|
1504
1504
|
// src/assets/extension-templates/theme/components.yaml
|
|
1505
1505
|
var components_default = "./components-0mmswvvm.yaml";
|
|
@@ -1529,19 +1529,19 @@ var book_default = "./book-ted3tzrp.css";
|
|
|
1529
1529
|
var theme_default = "./theme-j2bagrfx.css";
|
|
1530
1530
|
|
|
1531
1531
|
// src/assets/themes/clean-book/theme.json
|
|
1532
|
-
var theme_default2 = "./theme-
|
|
1532
|
+
var theme_default2 = "./theme-vktedy8q.json";
|
|
1533
1533
|
|
|
1534
1534
|
// src/assets/themes/zine/theme.css
|
|
1535
1535
|
var theme_default3 = "./theme-h5recz6c.css";
|
|
1536
1536
|
|
|
1537
1537
|
// src/assets/themes/zine/theme.json
|
|
1538
|
-
var theme_default4 = "./theme-
|
|
1538
|
+
var theme_default4 = "./theme-etj4gxck.json";
|
|
1539
1539
|
|
|
1540
1540
|
// src/assets/themes/technical-doc/theme.css
|
|
1541
1541
|
var theme_default5 = "./theme-nn6d53zy.css";
|
|
1542
1542
|
|
|
1543
1543
|
// src/assets/themes/technical-doc/theme.json
|
|
1544
|
-
var theme_default6 = "./theme-
|
|
1544
|
+
var theme_default6 = "./theme-s2rg7xe7.json";
|
|
1545
1545
|
|
|
1546
1546
|
// src/lib/embedded-assets.ts
|
|
1547
1547
|
var __libdir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -21,8 +21,7 @@ var previewArgs = {
|
|
|
21
21
|
"skip-lint": { type: "boolean", description: "Skip CSS linting (pdf|pdfx only)" },
|
|
22
22
|
"skip-pre-validate": { type: "boolean", description: "Skip pre-build validation (pdf|pdfx only)" },
|
|
23
23
|
"skip-post-validate": { type: "boolean", description: "Skip post-build PDF/X validation (pdfx only)" },
|
|
24
|
-
"allow-shrink": { type: "boolean", description: "Build anyway when content is wider than the page content box, instead of failing. Chromium then scales the WHOLE book down to fit; the scale and each offender are reported as warnings. (pdf|pdfx only)" }
|
|
25
|
-
engine: { type: "string", description: "Pagination engine. Native is the only engine. This flag is accepted but ignored (a warning fires for --engine paged)." }
|
|
24
|
+
"allow-shrink": { type: "boolean", description: "Build anyway when content is wider than the page content box, instead of failing. Chromium then scales the WHOLE book down to fit; the scale and each offender are reported as warnings. (pdf|pdfx only)" }
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export { previewArgs };
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "gutterpress",
|
|
7
|
-
version: "0.10.
|
|
7
|
+
version: "0.10.9",
|
|
8
8
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
9
9
|
author: "itlackey",
|
|
10
10
|
license: "MPL-2.0",
|
|
@@ -257,13 +257,6 @@ function parsePdfxFlavor(raw, format) {
|
|
|
257
257
|
return raw;
|
|
258
258
|
throw new UsageError(`Invalid --pdfx-flavor value: "${raw}". Expected "x1a" or "x3".`);
|
|
259
259
|
}
|
|
260
|
-
function parseEngine(raw) {
|
|
261
|
-
if (raw === undefined)
|
|
262
|
-
return;
|
|
263
|
-
if (raw === "paged" || raw === "native")
|
|
264
|
-
return raw;
|
|
265
|
-
throw new UsageError(`Unknown --engine "${String(raw)}". Expected: paged | native`);
|
|
266
|
-
}
|
|
267
260
|
function resolvePort(raw) {
|
|
268
261
|
if (raw === undefined)
|
|
269
262
|
return NETWORK.DEFAULT_PORT;
|
|
@@ -287,4 +280,4 @@ function resolveProjectDir(dir) {
|
|
|
287
280
|
return resolve(typeof dir === "string" && dir ? dir : process.cwd());
|
|
288
281
|
}
|
|
289
282
|
|
|
290
|
-
export { package_default, DEBOUNCE, UsageError, rejectUnknownFlags, rejectExtraPositionals, parseFormat, parsePdfxFlavor,
|
|
283
|
+
export { package_default, DEBOUNCE, UsageError, rejectUnknownFlags, rejectExtraPositionals, parseFormat, parsePdfxFlavor, resolvePort, exitForUsage, resolveProjectDir };
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
previewArgs
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-bzxqtvrk.js";
|
|
5
5
|
import {
|
|
6
6
|
UsageError,
|
|
7
7
|
package_default,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-rh05byck.js";
|
|
10
10
|
import {
|
|
11
11
|
EXIT_CODES
|
|
12
12
|
} from "./cli-46ycxe6r.js";
|
|
@@ -18,17 +18,16 @@ import {
|
|
|
18
18
|
import { defineCommand, parseArgs, runMain } from "citty";
|
|
19
19
|
import { statSync } from "node:fs";
|
|
20
20
|
var SUBCOMMANDS = {
|
|
21
|
-
new: () => import("./new-
|
|
22
|
-
preview: () => import("./preview-
|
|
23
|
-
build: () => import("./build-
|
|
24
|
-
publish: () => import("./publish-
|
|
25
|
-
lint: () => import("./lint-
|
|
26
|
-
validate: () => import("./validate-
|
|
27
|
-
audit: () => import("./audit-
|
|
28
|
-
preflight: () => import("./preflight-
|
|
29
|
-
doctor: () => import("./doctor-
|
|
30
|
-
|
|
31
|
-
theme: () => import("./theme-m9dtxkhj.js").then((m) => m.default)
|
|
21
|
+
new: () => import("./new-r9c99wsn.js").then((m) => m.default),
|
|
22
|
+
preview: () => import("./preview-52918mxk.js").then((m) => m.default),
|
|
23
|
+
build: () => import("./build-dyat3fqd.js").then((m) => m.default),
|
|
24
|
+
publish: () => import("./publish-8s60vhx7.js").then((m) => m.default),
|
|
25
|
+
lint: () => import("./lint-enasqbqx.js").then((m) => m.default),
|
|
26
|
+
validate: () => import("./validate-awccx32r.js").then((m) => m.default),
|
|
27
|
+
audit: () => import("./audit-fq7s1gsz.js").then((m) => m.default),
|
|
28
|
+
preflight: () => import("./preflight-shk7vqbs.js").then((m) => m.default),
|
|
29
|
+
doctor: () => import("./doctor-yr85n080.js").then((m) => m.default),
|
|
30
|
+
ext: () => import("./ext-jrg8c48s.js").then((m) => m.default)
|
|
32
31
|
};
|
|
33
32
|
var VERSION = package_default.version;
|
|
34
33
|
var main = defineCommand({
|
|
@@ -53,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
53
52
|
const [command, ...commandArgs] = rawArgs;
|
|
54
53
|
try {
|
|
55
54
|
if (command === "new") {
|
|
56
|
-
const { newArgs } = await import("./new-
|
|
55
|
+
const { newArgs } = await import("./new-r9c99wsn.js");
|
|
57
56
|
rejectUnknownFlags(commandArgs, newArgs, "new");
|
|
58
57
|
const parsed = parseArgs(commandArgs, {
|
|
59
58
|
...newArgs,
|
|
@@ -65,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
65
64
|
return;
|
|
66
65
|
}
|
|
67
66
|
if (command === "preflight") {
|
|
68
|
-
const { preflightArgs } = await import("./preflight-
|
|
67
|
+
const { preflightArgs } = await import("./preflight-shk7vqbs.js");
|
|
69
68
|
rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
|
|
70
69
|
const parsed = parseArgs(commandArgs, {
|
|
71
70
|
...preflightArgs,
|
|
@@ -76,57 +75,29 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
76
75
|
}
|
|
77
76
|
return;
|
|
78
77
|
}
|
|
79
|
-
if (command === "
|
|
78
|
+
if (command === "ext") {
|
|
80
79
|
const [subcommand, ...subcommandArgs] = commandArgs;
|
|
81
80
|
if (subcommand === undefined)
|
|
82
81
|
return;
|
|
83
82
|
if (subcommand === "--" || subcommand === "-") {
|
|
84
|
-
throw new UsageError(`gutterpress
|
|
83
|
+
throw new UsageError(`gutterpress ext: expected a subcommand before ${subcommand}`);
|
|
85
84
|
}
|
|
86
85
|
if (subcommand.startsWith("-"))
|
|
87
86
|
return;
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-jrg8c48s.js");
|
|
88
|
+
if (!EXT_SUBCOMMANDS.includes(subcommand)) {
|
|
89
|
+
throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
rejectUnknownFlags(subcommandArgs, pluginAddArgs, "plugin add");
|
|
93
|
-
const parsed = parseArgs(subcommandArgs, {
|
|
94
|
-
...pluginAddArgs,
|
|
95
|
-
package: { ...pluginAddArgs.package, required: false }
|
|
96
|
-
});
|
|
97
|
-
if (parsed.package === undefined) {
|
|
98
|
-
throw new UsageError("gutterpress plugin add: missing required positional argument PACKAGE");
|
|
99
|
-
}
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (command === "theme") {
|
|
103
|
-
const [subcommand, ...subcommandArgs] = commandArgs;
|
|
104
|
-
if (subcommand === undefined)
|
|
105
|
-
return;
|
|
106
|
-
if (subcommand === "--" || subcommand === "-") {
|
|
107
|
-
throw new UsageError(`gutterpress theme: expected a subcommand before ${subcommand}`);
|
|
108
|
-
}
|
|
109
|
-
if (subcommand.startsWith("-"))
|
|
110
|
-
return;
|
|
111
|
-
const THEME_SUBCOMMANDS = ["list", "apply", "import", "revert", "remove"];
|
|
112
|
-
if (!THEME_SUBCOMMANDS.includes(subcommand)) {
|
|
113
|
-
throw new UsageError(`gutterpress theme: unknown command "${subcommand}"`);
|
|
114
|
-
}
|
|
115
|
-
if (subcommand === "list" || subcommand === "revert")
|
|
91
|
+
if (subcommand === "list")
|
|
116
92
|
return;
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
themeImportArgs,
|
|
120
|
-
themeRemoveArgs
|
|
121
|
-
} = await import("./theme-m9dtxkhj.js");
|
|
122
|
-
const [positionalKey, positionalLabel, commandArgsDef] = subcommand === "apply" ? ["id", "ID", themeApplyArgs] : subcommand === "import" ? ["source", "SOURCE", themeImportArgs] : ["id", "ID", themeRemoveArgs];
|
|
123
|
-
rejectUnknownFlags(subcommandArgs, commandArgsDef, `theme ${subcommand}`);
|
|
93
|
+
const [positionalKey, positionalLabel, commandArgsDef] = subcommand === "add" ? ["source", "SOURCE", extAddArgs] : subcommand === "remove" ? ["specifier", "SPECIFIER", extRemoveArgs] : subcommand === "enable" ? ["specifier", "SPECIFIER", extEnableArgs] : ["specifier", "SPECIFIER", extDisableArgs];
|
|
94
|
+
rejectUnknownFlags(subcommandArgs, commandArgsDef, `ext ${subcommand}`);
|
|
124
95
|
const parsed = parseArgs(subcommandArgs, {
|
|
125
96
|
...commandArgsDef,
|
|
126
97
|
[positionalKey]: { ...commandArgsDef[positionalKey], required: false }
|
|
127
98
|
});
|
|
128
99
|
if (parsed[positionalKey] === undefined) {
|
|
129
|
-
throw new UsageError(`gutterpress
|
|
100
|
+
throw new UsageError(`gutterpress ext ${subcommand}: missing required positional argument ${positionalLabel}`);
|
|
130
101
|
}
|
|
131
102
|
}
|
|
132
103
|
} catch (error) {
|
|
@@ -168,7 +139,7 @@ function resolveImplicitPreview(rawArgs) {
|
|
|
168
139
|
return positional === undefined || isDirectory(positional) ? { usePreview: true } : { usePreview: false, unknownCommand: positional };
|
|
169
140
|
}
|
|
170
141
|
var rawArgs = process.argv.slice(2);
|
|
171
|
-
if (rawArgs.length === 1 &&
|
|
142
|
+
if (rawArgs.length === 1 && rawArgs[0] === "ext") {
|
|
172
143
|
rawArgs.push("--help");
|
|
173
144
|
}
|
|
174
145
|
var wantsHelp = rawArgs.includes("--help") || rawArgs.includes("-h");
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getSystemDiagnostics,
|
|
3
3
|
log
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-ypfvnhag.js";
|
|
5
5
|
import {
|
|
6
6
|
UsageError,
|
|
7
7
|
rejectExtraPositionals,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-rh05byck.js";
|
|
10
10
|
import"./cli-c41yr7he.js";
|
|
11
11
|
import"./cli-46ycxe6r.js";
|
|
12
12
|
import"./cli-37x76zdn.js";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
build,
|
|
5
5
|
connectChromium,
|
|
6
6
|
getBrowser
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-bx950tb4.js";
|
|
8
8
|
import"./cli-c41yr7he.js";
|
|
9
9
|
import {
|
|
10
10
|
BuildError
|
|
@@ -31,7 +31,7 @@ async function buildNativePdf(htmlFile, outPdf, options = {}, getEngineBrowser)
|
|
|
31
31
|
await engineBrowser.close();
|
|
32
32
|
}
|
|
33
33
|
} catch (err) {
|
|
34
|
-
throw new BuildError(
|
|
34
|
+
throw new BuildError(`PDF build failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
35
35
|
}
|
|
36
36
|
await writeFile(outPdf, result.bytes);
|
|
37
37
|
return result.diagnostics;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
build
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-dhgzkhs7.js";
|
|
4
4
|
import {
|
|
5
5
|
BuildError,
|
|
6
6
|
RENDER_TIMEOUT_MS,
|
|
7
7
|
assertMilestone,
|
|
8
8
|
connectChromium,
|
|
9
9
|
getBrowser
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-zwcv1njy.js";
|
|
11
11
|
import"./index-37x76zdn.js";
|
|
12
12
|
|
|
13
13
|
// src/lib/engine.ts
|
|
@@ -30,7 +30,7 @@ async function buildNativePdf(htmlFile, outPdf, options = {}, getEngineBrowser)
|
|
|
30
30
|
await engineBrowser.close();
|
|
31
31
|
}
|
|
32
32
|
} catch (err) {
|
|
33
|
-
throw new BuildError(
|
|
33
|
+
throw new BuildError(`PDF build failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
34
34
|
}
|
|
35
35
|
await writeFile(outPdf, result.bytes);
|
|
36
36
|
return result.diagnostics;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BUILT_IN_STYLE_SET_IDS,
|
|
3
|
+
addBuiltInStyleSet,
|
|
4
|
+
addExtension,
|
|
5
|
+
importExtensionFromFile,
|
|
6
|
+
importExtensionFromUrl,
|
|
7
|
+
isPathSpecifier,
|
|
8
|
+
listProjectExtensions,
|
|
9
|
+
parseExtensionSpecifier,
|
|
10
|
+
removeExtension,
|
|
11
|
+
setExtensionEnabled
|
|
12
|
+
} from "./cli-8pg731p5.js";
|
|
13
|
+
import"./cli-ypfvnhag.js";
|
|
14
|
+
import {
|
|
15
|
+
UsageError,
|
|
16
|
+
exitForUsage,
|
|
17
|
+
rejectExtraPositionals,
|
|
18
|
+
rejectUnknownFlags,
|
|
19
|
+
resolveProjectDir
|
|
20
|
+
} from "./cli-rh05byck.js";
|
|
21
|
+
import"./cli-bx950tb4.js";
|
|
22
|
+
import"./cli-c41yr7he.js";
|
|
23
|
+
import {
|
|
24
|
+
EXIT_CODES
|
|
25
|
+
} from "./cli-46ycxe6r.js";
|
|
26
|
+
import"./cli-w692g6dx.js";
|
|
27
|
+
import"./cli-v5mp7a6q.js";
|
|
28
|
+
import"./cli-37x76zdn.js";
|
|
29
|
+
|
|
30
|
+
// src/commands/ext.ts
|
|
31
|
+
import { defineCommand } from "citty";
|
|
32
|
+
import { stat } from "node:fs/promises";
|
|
33
|
+
import path from "node:path";
|
|
34
|
+
var dirArg = {
|
|
35
|
+
type: "positional",
|
|
36
|
+
description: "Project directory (defaults to the current directory)",
|
|
37
|
+
required: false
|
|
38
|
+
};
|
|
39
|
+
var specifierArg = {
|
|
40
|
+
type: "positional",
|
|
41
|
+
description: "The extension's specifier as written in the manifest (an npm name, a bundled name, or a ./ path)",
|
|
42
|
+
required: true
|
|
43
|
+
};
|
|
44
|
+
var extListArgs = { dir: dirArg };
|
|
45
|
+
var extAddArgs = {
|
|
46
|
+
source: {
|
|
47
|
+
type: "positional",
|
|
48
|
+
description: "What to add: an npm package (name or name@version), a bundled feature (markdown-it-mark, …), a folder or plugin file path, a .zip or .css file, or an http(s) URL",
|
|
49
|
+
required: true
|
|
50
|
+
},
|
|
51
|
+
dir: dirArg,
|
|
52
|
+
export: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Named module export to use as the plugin function (npm and path extensions only)",
|
|
55
|
+
required: false
|
|
56
|
+
},
|
|
57
|
+
look: {
|
|
58
|
+
type: "boolean",
|
|
59
|
+
description: "Treat SOURCE as a built-in look id (clean-book, zine, technical-doc): copy it into extensions/ and add it",
|
|
60
|
+
required: false
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var extRemoveArgs = { specifier: specifierArg, dir: dirArg };
|
|
64
|
+
var extEnableArgs = { specifier: specifierArg, dir: dirArg };
|
|
65
|
+
var extDisableArgs = { specifier: specifierArg, dir: dirArg };
|
|
66
|
+
var EXT_SUBCOMMANDS = ["list", "add", "remove", "enable", "disable"];
|
|
67
|
+
var parentArgs = {};
|
|
68
|
+
function rejectParentFlags(rawArgs) {
|
|
69
|
+
const first = rawArgs[0];
|
|
70
|
+
if (first === undefined || EXT_SUBCOMMANDS.includes(first))
|
|
71
|
+
return;
|
|
72
|
+
if (!first.startsWith("-"))
|
|
73
|
+
return;
|
|
74
|
+
try {
|
|
75
|
+
rejectUnknownFlags(rawArgs, parentArgs, "ext");
|
|
76
|
+
} catch (error) {
|
|
77
|
+
exitForUsage(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function requireProjectDir(dir, verb) {
|
|
81
|
+
const projectDir = resolveProjectDir(dir);
|
|
82
|
+
let info;
|
|
83
|
+
try {
|
|
84
|
+
info = await stat(projectDir);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error.code === "ENOENT") {
|
|
87
|
+
throw new UsageError(`Project directory does not exist: ${projectDir}`);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
if (!info.isDirectory()) {
|
|
92
|
+
throw new UsageError(`Project path is not a directory: ${projectDir}`);
|
|
93
|
+
}
|
|
94
|
+
return projectDir;
|
|
95
|
+
}
|
|
96
|
+
function carriesLabel(entry) {
|
|
97
|
+
const parts = ["markdown", "styles", "snippets", "components"].filter((k) => entry.carries[k]);
|
|
98
|
+
return parts.length > 0 ? parts.join(", ") : "nothing declared";
|
|
99
|
+
}
|
|
100
|
+
function describeLine(entry) {
|
|
101
|
+
const state = entry.enabled ? "" : " (disabled)";
|
|
102
|
+
const label = entry.label !== entry.name ? ` ${entry.label}` : "";
|
|
103
|
+
return ` ${entry.use}${state} [${entry.kind}; ${carriesLabel(entry)}]${label}`;
|
|
104
|
+
}
|
|
105
|
+
function printAdded(entry, projectDir, warnings = []) {
|
|
106
|
+
if (entry.kind === "npm") {
|
|
107
|
+
console.log(`Installed ${entry.use}`);
|
|
108
|
+
console.log(` project: ${projectDir}`);
|
|
109
|
+
console.log(" vendored under: plugins/npm");
|
|
110
|
+
console.log(" manifest: exact version pinned");
|
|
111
|
+
} else if (entry.kind === "bundled") {
|
|
112
|
+
console.log(`Enabled bundled feature ${entry.use}`);
|
|
113
|
+
console.log(` project: ${projectDir}`);
|
|
114
|
+
} else {
|
|
115
|
+
console.log(`Added ${entry.use} (${carriesLabel(entry)})`);
|
|
116
|
+
console.log(` project: ${projectDir}`);
|
|
117
|
+
console.log(" referenced in place — edit the folder and the book follows");
|
|
118
|
+
}
|
|
119
|
+
for (const warning of [...entry.warnings ?? [], ...warnings])
|
|
120
|
+
console.warn(`Warning: ${warning}`);
|
|
121
|
+
}
|
|
122
|
+
function failPipeline(prefix, error) {
|
|
123
|
+
console.error(`${prefix}: ${error instanceof Error ? error.message : String(error)}`);
|
|
124
|
+
process.exit(EXIT_CODES.PIPELINE);
|
|
125
|
+
}
|
|
126
|
+
var list = defineCommand({
|
|
127
|
+
meta: { name: "list", description: "List the project's extensions in load (= cascade) order" },
|
|
128
|
+
args: extListArgs,
|
|
129
|
+
async run({ args, rawArgs }) {
|
|
130
|
+
let projectDir = "";
|
|
131
|
+
try {
|
|
132
|
+
rejectUnknownFlags(rawArgs, extListArgs, "ext list");
|
|
133
|
+
rejectExtraPositionals(args._, 1, "ext list");
|
|
134
|
+
projectDir = await requireProjectDir(args.dir, "list");
|
|
135
|
+
} catch (error) {
|
|
136
|
+
exitForUsage(error);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const entries = await listProjectExtensions(projectDir);
|
|
140
|
+
if (entries.length === 0) {
|
|
141
|
+
console.log("No extensions configured. Add one with: gutterpress ext add <source>");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
console.log("Extensions (top loads first; a later entry's CSS wins ties):");
|
|
145
|
+
for (const entry of entries) {
|
|
146
|
+
console.log(describeLine(entry));
|
|
147
|
+
for (const warning of entry.warnings ?? [])
|
|
148
|
+
console.log(` ! ${warning}`);
|
|
149
|
+
}
|
|
150
|
+
} catch (error) {
|
|
151
|
+
failPipeline("Could not list extensions", error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
var add = defineCommand({
|
|
156
|
+
meta: {
|
|
157
|
+
name: "add",
|
|
158
|
+
description: "Add an extension: an npm package, a bundled feature, a folder or plugin file, a .zip/.css file, or a URL"
|
|
159
|
+
},
|
|
160
|
+
args: extAddArgs,
|
|
161
|
+
async run({ args, rawArgs }) {
|
|
162
|
+
const source = String(args.source).trim();
|
|
163
|
+
const isUrl = /^https?:\/\//i.test(source);
|
|
164
|
+
const candidate = path.resolve(process.cwd(), source);
|
|
165
|
+
const existing = isUrl ? null : await stat(candidate).catch(() => null);
|
|
166
|
+
const isArchive = !!existing?.isFile() && /\.(zip|css)$/i.test(candidate);
|
|
167
|
+
let projectDir = "";
|
|
168
|
+
let exportName;
|
|
169
|
+
try {
|
|
170
|
+
rejectUnknownFlags(rawArgs, extAddArgs, "ext add");
|
|
171
|
+
rejectExtraPositionals(args._, 2, "ext add");
|
|
172
|
+
projectDir = await requireProjectDir(args.dir, "add");
|
|
173
|
+
exportName = typeof args.export === "string" ? args.export.trim() : undefined;
|
|
174
|
+
if (typeof args.export === "string" && !exportName) {
|
|
175
|
+
throw new UsageError("gutterpress ext add: --export requires a non-empty name");
|
|
176
|
+
}
|
|
177
|
+
if (args.look && !BUILT_IN_STYLE_SET_IDS.includes(source)) {
|
|
178
|
+
throw new UsageError(`gutterpress ext add --look: unknown built-in look "${source}" (one of: ${BUILT_IN_STYLE_SET_IDS.join(", ")})`);
|
|
179
|
+
}
|
|
180
|
+
if (!args.look && !isUrl && !existing) {
|
|
181
|
+
try {
|
|
182
|
+
if (path.isAbsolute(source) || isPathSpecifier(source)) {
|
|
183
|
+
throw new Error(`source not found: ${candidate}`);
|
|
184
|
+
}
|
|
185
|
+
parseExtensionSpecifier(source);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
throw new UsageError(`gutterpress ext add: ${error instanceof Error ? error.message : String(error)}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
} catch (error) {
|
|
191
|
+
exitForUsage(error);
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
if (args.look) {
|
|
195
|
+
const entry2 = await addBuiltInStyleSet(projectDir, source);
|
|
196
|
+
printAdded(entry2, projectDir);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (isUrl) {
|
|
200
|
+
const { entry: entry2, warnings } = await importExtensionFromUrl(projectDir, source);
|
|
201
|
+
printAdded(entry2, projectDir, warnings.map((w) => w.message));
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (isArchive) {
|
|
205
|
+
const { entry: entry2, warnings } = await importExtensionFromFile(projectDir, candidate);
|
|
206
|
+
printAdded(entry2, projectDir, warnings.map((w) => w.message));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const entry = await addExtension(projectDir, existing ? candidate : source, { exportName });
|
|
210
|
+
printAdded(entry, projectDir);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
failPipeline("Could not add extension", error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
function specifierCommand(name, description, argsDef, act) {
|
|
217
|
+
return defineCommand({
|
|
218
|
+
meta: { name, description },
|
|
219
|
+
args: argsDef,
|
|
220
|
+
async run({ args, rawArgs }) {
|
|
221
|
+
let projectDir = "";
|
|
222
|
+
try {
|
|
223
|
+
rejectUnknownFlags(rawArgs, argsDef, `ext ${name}`);
|
|
224
|
+
rejectExtraPositionals(args._, 2, `ext ${name}`);
|
|
225
|
+
projectDir = await requireProjectDir(args.dir, name);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
exitForUsage(error);
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
console.log(await act(projectDir, String(args.specifier).trim()));
|
|
231
|
+
} catch (error) {
|
|
232
|
+
exitForUsage(new UsageError(`gutterpress ext ${name}: ${error instanceof Error ? error.message : String(error)}`));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
var remove = specifierCommand("remove", "Remove an extension from the manifest (an npm extension's vendored copy is deleted too)", extRemoveArgs, async (projectDir, specifier) => {
|
|
238
|
+
await removeExtension(projectDir, specifier);
|
|
239
|
+
return `Removed ${specifier}`;
|
|
240
|
+
});
|
|
241
|
+
var enable = specifierCommand("enable", "Turn a configured extension on", extEnableArgs, async (projectDir, specifier) => {
|
|
242
|
+
await setExtensionEnabled(projectDir, specifier, true);
|
|
243
|
+
return `Enabled ${specifier}`;
|
|
244
|
+
});
|
|
245
|
+
var disable = specifierCommand("disable", "Turn a configured extension off without removing it", extDisableArgs, async (projectDir, specifier) => {
|
|
246
|
+
await setExtensionEnabled(projectDir, specifier, false);
|
|
247
|
+
return `Disabled ${specifier}`;
|
|
248
|
+
});
|
|
249
|
+
var ext_default = defineCommand({
|
|
250
|
+
meta: {
|
|
251
|
+
name: "ext",
|
|
252
|
+
description: "List, add, remove, enable, or disable the project's extensions"
|
|
253
|
+
},
|
|
254
|
+
args: parentArgs,
|
|
255
|
+
setup({ rawArgs }) {
|
|
256
|
+
rejectParentFlags(rawArgs);
|
|
257
|
+
},
|
|
258
|
+
subCommands: { list, add, remove, enable, disable }
|
|
259
|
+
});
|
|
260
|
+
export {
|
|
261
|
+
extRemoveArgs,
|
|
262
|
+
extListArgs,
|
|
263
|
+
extEnableArgs,
|
|
264
|
+
extDisableArgs,
|
|
265
|
+
extAddArgs,
|
|
266
|
+
ext_default as default,
|
|
267
|
+
EXT_SUBCOMMANDS
|
|
268
|
+
};
|