gutterpress 0.10.8 → 0.10.9-beta.1
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 +88 -87
- 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-2x958vnj.js} +4 -4
- package/dist/{build-qnecb3a1.js → build-dqv3505a.js} +5 -8
- package/dist/{cli-vcv5ewqj.js → cli-0tgbgwnj.js} +2 -9
- package/dist/{cli-4vtgt2ng.js → cli-bx950tb4.js} +7 -7
- package/dist/{cli-pfpb1t3h.js → cli-bzxqtvrk.js} +1 -2
- package/dist/{cli-vxf151ea.js → cli-fwh6rkev.js} +1 -1
- package/dist/{cli-1hx14cgk.js → cli-vhdvkqdd.js} +2372 -2449
- package/dist/cli.js +24 -53
- package/dist/{doctor-qvqye1wd.js → doctor-55r0ghtc.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-04n7hydk.js +268 -0
- package/dist/{index-rpt4vtby.js → index-dhgzkhs7.js} +1 -1
- package/dist/{index-dfw8hn8q.js → index-erwh3bww.js} +5292 -5430
- 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/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/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-c7a4j3ww.js} +4 -4
- package/dist/{manifest.schema-1q35yxs9.json → manifest.schema-hsn8rsgr.json} +18 -53
- package/dist/{new-xffarp40.js → new-pw3eez61.js} +11 -12
- package/dist/{plugin.test.js-mv0ghv5n.tpl → plugin.test.js-npnfhyca.tpl} +0 -1
- package/dist/{preflight-z6xpty9w.js → preflight-77zyws1q.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-x7qqhmxf.js} +6 -10
- package/dist/{publish-zgmr99kd.js → publish-ms6abf6g.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-vw59jcq7.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
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-0tgbgwnj.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-pw3eez61.js").then((m) => m.default),
|
|
22
|
+
preview: () => import("./preview-x7qqhmxf.js").then((m) => m.default),
|
|
23
|
+
build: () => import("./build-dqv3505a.js").then((m) => m.default),
|
|
24
|
+
publish: () => import("./publish-ms6abf6g.js").then((m) => m.default),
|
|
25
|
+
lint: () => import("./lint-c7a4j3ww.js").then((m) => m.default),
|
|
26
|
+
validate: () => import("./validate-vw59jcq7.js").then((m) => m.default),
|
|
27
|
+
audit: () => import("./audit-2x958vnj.js").then((m) => m.default),
|
|
28
|
+
preflight: () => import("./preflight-77zyws1q.js").then((m) => m.default),
|
|
29
|
+
doctor: () => import("./doctor-55r0ghtc.js").then((m) => m.default),
|
|
30
|
+
ext: () => import("./ext-04n7hydk.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-pw3eez61.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-77zyws1q.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-04n7hydk.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-fwh6rkev.js";
|
|
5
5
|
import {
|
|
6
6
|
UsageError,
|
|
7
7
|
rejectExtraPositionals,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-0tgbgwnj.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-vhdvkqdd.js";
|
|
13
|
+
import"./cli-fwh6rkev.js";
|
|
14
|
+
import {
|
|
15
|
+
UsageError,
|
|
16
|
+
exitForUsage,
|
|
17
|
+
rejectExtraPositionals,
|
|
18
|
+
rejectUnknownFlags,
|
|
19
|
+
resolveProjectDir
|
|
20
|
+
} from "./cli-0tgbgwnj.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
|
+
};
|