gutterpress 0.11.13-alpha.1 → 0.11.14-alpha.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/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +5 -1
- package/dist/{build-ncxz7s6y.js → build-9ccmg4jw.js} +3 -3
- package/dist/{cli-2r5m5wyx.js → cli-cmyfeqg6.js} +1 -1
- package/dist/{cli-ahhc9qhq.js → cli-s38v88rv.js} +91 -8
- package/dist/{cli-e9matqtf.js → cli-tctw7rcm.js} +1 -1
- package/dist/cli.js +12 -12
- package/dist/{doctor-94fx1qh5.js → doctor-2kp6wsnx.js} +2 -2
- package/dist/{ext-4trpk0nf.js → ext-kct0k4ne.js} +102 -7
- package/dist/{index-3gxxb075.js → index-ch9k0kam.js} +97 -14
- package/dist/index.js +5 -1
- package/dist/lib/extension-manager.d.ts +44 -0
- package/dist/{new-f7b04mv4.js → new-pa0pgcat.js} +3 -3
- package/dist/{preflight-kpnbhs0r.js → preflight-6v0j7ae8.js} +3 -3
- package/dist/{preview-5b8vk6vc.js → preview-msq4mz3a.js} +3 -3
- package/dist/{publish-0zrtaezn.js → publish-2rgbacn1.js} +3 -3
- package/dist/{validate-yagx07vv.js → validate-ekbmn8wh.js} +3 -3
- package/package.json +1 -1
package/dist/api/index.d.ts
CHANGED
|
@@ -33,8 +33,8 @@ export { listBuiltInTemplates, listCustomTemplates, saveProjectAsTemplate, impor
|
|
|
33
33
|
export type { TemplateInfo, SaveProjectAsTemplateOptions, } from "../lib/project-templates.ts";
|
|
34
34
|
export { extractVariables, substituteVariables, listSnippets, readSnippet, saveSnippet, deleteSnippet, listMergedSnippets, readExtensionSnippet, SNIPPETS_DIR, } from "../lib/snippets.ts";
|
|
35
35
|
export type { SnippetEntry, SnippetSource } from "../lib/snippets.ts";
|
|
36
|
-
export { listProjectExtensions, describeExtension, addExtension, removeExtension, setExtensionEnabled, reorderExtensions, validateProjectExtensions, readExtensionCss, listBuiltInStyleSets, addBuiltInStyleSet, sameExtension, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, EXTENSIONS_DIR, PLUGINS_DIR, } from "../lib/extension-manager.ts";
|
|
37
|
-
export type { ProjectExtensionEntry, ExtensionValidationResult, RecommendedExtension, ExtensionSourceKind, BuiltInStyleSet, BuiltInStyleSetId, AddExtensionOptions, } from "../lib/extension-manager.ts";
|
|
36
|
+
export { listProjectExtensions, describeExtension, addExtension, checkExtensionUpdates, updateExtensions, removeExtension, setExtensionEnabled, reorderExtensions, validateProjectExtensions, readExtensionCss, listBuiltInStyleSets, addBuiltInStyleSet, sameExtension, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, EXTENSIONS_DIR, PLUGINS_DIR, } from "../lib/extension-manager.ts";
|
|
37
|
+
export type { ProjectExtensionEntry, ExtensionValidationResult, RecommendedExtension, ExtensionSourceKind, BuiltInStyleSet, BuiltInStyleSetId, AddExtensionOptions, ExtensionUpdateCheck, ExtensionUpdateResult, CheckExtensionUpdatesOptions, UpdateExtensionsOptions, } from "../lib/extension-manager.ts";
|
|
38
38
|
export { BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, } from "../lib/extension-specifier.ts";
|
|
39
39
|
export type { ParsedExtensionSpecifier } from "../lib/extension-specifier.ts";
|
|
40
40
|
export { importExtensionFromFile, importExtensionFromUrl } from "../lib/extension-import.ts";
|
package/dist/api/index.js
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
assertExtensionContained,
|
|
37
37
|
autoSnapshotDelayMs,
|
|
38
38
|
autoSyncDelayMs,
|
|
39
|
+
checkExtensionUpdates,
|
|
39
40
|
cloneRepository,
|
|
40
41
|
connectGenericHost,
|
|
41
42
|
connectGoogleDrive,
|
|
@@ -126,8 +127,9 @@ import {
|
|
|
126
127
|
substituteVariables,
|
|
127
128
|
syncProject,
|
|
128
129
|
testRemoteAccess,
|
|
130
|
+
updateExtensions,
|
|
129
131
|
validateProjectExtensions
|
|
130
|
-
} from "../index-
|
|
132
|
+
} from "../index-ch9k0kam.js";
|
|
131
133
|
import {
|
|
132
134
|
BuildError
|
|
133
135
|
} from "../index-mw8b25yx.js";
|
|
@@ -162,6 +164,7 @@ import"../index-37x76zdn.js";
|
|
|
162
164
|
export {
|
|
163
165
|
whenGitIdle,
|
|
164
166
|
validateProjectExtensions,
|
|
167
|
+
updateExtensions,
|
|
165
168
|
testRemoteAccess,
|
|
166
169
|
syncProject,
|
|
167
170
|
switchBranch,
|
|
@@ -264,6 +267,7 @@ export {
|
|
|
264
267
|
connectGoogleDrive,
|
|
265
268
|
connectGenericHost,
|
|
266
269
|
cloneRepository,
|
|
270
|
+
checkExtensionUpdates,
|
|
267
271
|
capabilitiesFor,
|
|
268
272
|
autoSyncDelayMs,
|
|
269
273
|
autoSnapshotDelayMs,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
splitOutPath
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-s38v88rv.js";
|
|
5
5
|
import {
|
|
6
6
|
log
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-cmyfeqg6.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError,
|
|
10
10
|
parseFormat,
|
|
11
11
|
parsePdfxFlavor,
|
|
12
12
|
rejectExtraPositionals,
|
|
13
13
|
rejectUnknownFlags
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-tctw7rcm.js";
|
|
15
15
|
import"./cli-tjhn2mdn.js";
|
|
16
16
|
import {
|
|
17
17
|
BuildError
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
stampCreator,
|
|
14
14
|
stripAnnotations,
|
|
15
15
|
warn
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-cmyfeqg6.js";
|
|
17
17
|
import {
|
|
18
18
|
DEBOUNCE,
|
|
19
19
|
UsageError,
|
|
20
20
|
resolvePort
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-tctw7rcm.js";
|
|
22
22
|
import {
|
|
23
23
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
24
24
|
getAssetPath,
|
|
@@ -9347,7 +9347,7 @@ var SKIP_ENTRIES = new Set([
|
|
|
9347
9347
|
]);
|
|
9348
9348
|
|
|
9349
9349
|
// src/lib/extension-manager.ts
|
|
9350
|
-
import { cp as cp2, mkdir as mkdir8, readFile as readFile26, rm as rm3, stat as stat6 } from "node:fs/promises";
|
|
9350
|
+
import { cp as cp2, mkdir as mkdir8, readdir as readdir5, readFile as readFile26, rm as rm3, stat as stat6 } from "node:fs/promises";
|
|
9351
9351
|
import { existsSync as existsSync12 } from "node:fs";
|
|
9352
9352
|
import path17 from "node:path";
|
|
9353
9353
|
import { isSeq as isSeq3, isMap as isMap2, isScalar as isScalar2, YAMLMap, Scalar } from "yaml";
|
|
@@ -10013,6 +10013,7 @@ async function rollbackNpmPluginInstall(installed) {
|
|
|
10013
10013
|
}
|
|
10014
10014
|
|
|
10015
10015
|
// src/lib/extension-manager.ts
|
|
10016
|
+
import { gt as semverGt } from "semver";
|
|
10016
10017
|
var EXTENSIONS_DIR = "extensions";
|
|
10017
10018
|
var RECOMMENDED_EXTENSIONS = [
|
|
10018
10019
|
{
|
|
@@ -10377,9 +10378,91 @@ async function addExtensionUnlocked(projectDir, specifier, options) {
|
|
|
10377
10378
|
await finalizeNpmPluginInstall(installed).catch((error2) => {
|
|
10378
10379
|
warnings.push(`The extension was installed, but an old backup could not be removed: ` + `${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
10379
10380
|
});
|
|
10381
|
+
await pruneOtherVersions(projectDir, installed.name, installed.version).catch((error2) => {
|
|
10382
|
+
warnings.push(`The extension was installed, but a previous version's vendored copy could not be removed: ` + `${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
10383
|
+
});
|
|
10380
10384
|
const entry = await describeExtension(projectDir, use);
|
|
10381
10385
|
return warnings.length > 0 ? { ...entry, warnings: [...entry.warnings ?? [], ...warnings] } : entry;
|
|
10382
10386
|
}
|
|
10387
|
+
async function pruneOtherVersions(projectDir, name, keep) {
|
|
10388
|
+
const parent = path17.dirname(vendoredNpmPluginRoot(projectDir, name, keep));
|
|
10389
|
+
let entries;
|
|
10390
|
+
try {
|
|
10391
|
+
entries = await readdir5(parent, { withFileTypes: true });
|
|
10392
|
+
} catch {
|
|
10393
|
+
return;
|
|
10394
|
+
}
|
|
10395
|
+
for (const entry of entries) {
|
|
10396
|
+
if (!entry.isDirectory() || entry.name === keep || !isExactNpmVersion(entry.name))
|
|
10397
|
+
continue;
|
|
10398
|
+
await rm3(path17.join(parent, entry.name), { recursive: true, force: true });
|
|
10399
|
+
}
|
|
10400
|
+
}
|
|
10401
|
+
var LATEST_LOOKUP_TIMEOUT_MS = 30000;
|
|
10402
|
+
var MAX_PACKUMENT_BYTES = 15 * 1024 * 1024;
|
|
10403
|
+
async function latestNpmVersion(name, options) {
|
|
10404
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
10405
|
+
return withFetchTimeout({
|
|
10406
|
+
timeoutMs: LATEST_LOOKUP_TIMEOUT_MS,
|
|
10407
|
+
signal: options.signal,
|
|
10408
|
+
timeoutMessage: `Looking up ${name} on npm timed out. Check your connection and try again.`,
|
|
10409
|
+
offlineMessage: (cause) => `Looking up ${name} on npm failed (${cause instanceof Error ? cause.message : String(cause)}).`
|
|
10410
|
+
}, async (signal) => {
|
|
10411
|
+
const response = await fetchImpl(`${npmRegistryUrl()}/${encodeURIComponent(name)}`, {
|
|
10412
|
+
signal,
|
|
10413
|
+
redirect: "error",
|
|
10414
|
+
headers: { accept: "application/vnd.npm.install-v1+json" }
|
|
10415
|
+
});
|
|
10416
|
+
if (response.status === 404)
|
|
10417
|
+
throw new FriendlyHttpError(`npm package "${name}" was not found.`);
|
|
10418
|
+
if (!response.ok)
|
|
10419
|
+
throw new FriendlyHttpError(`Looking up ${name} on npm failed (HTTP ${response.status}).`);
|
|
10420
|
+
const bytes = await response.arrayBuffer();
|
|
10421
|
+
if (bytes.byteLength > MAX_PACKUMENT_BYTES) {
|
|
10422
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" is too large to read.`);
|
|
10423
|
+
}
|
|
10424
|
+
let latest;
|
|
10425
|
+
try {
|
|
10426
|
+
latest = JSON.parse(Buffer.from(bytes).toString("utf8"))["dist-tags"]?.latest;
|
|
10427
|
+
} catch {
|
|
10428
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" is not valid JSON.`);
|
|
10429
|
+
}
|
|
10430
|
+
if (typeof latest !== "string" || !isExactNpmVersion(latest)) {
|
|
10431
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" has no latest version.`);
|
|
10432
|
+
}
|
|
10433
|
+
return latest;
|
|
10434
|
+
});
|
|
10435
|
+
}
|
|
10436
|
+
async function checkExtensionUpdates(projectDir, options = {}) {
|
|
10437
|
+
const entries = await listProjectExtensions(projectDir);
|
|
10438
|
+
const pinned = entries.filter((e) => e.kind === "npm" && e.version);
|
|
10439
|
+
return Promise.all(pinned.map(async (e) => {
|
|
10440
|
+
const current = e.version;
|
|
10441
|
+
const latest = await latestNpmVersion(e.name, options);
|
|
10442
|
+
return { use: e.use, name: e.name, current, latest, outdated: semverGt(latest, current) };
|
|
10443
|
+
}));
|
|
10444
|
+
}
|
|
10445
|
+
async function updateExtensions(projectDir, options = {}) {
|
|
10446
|
+
let checks2 = await checkExtensionUpdates(projectDir, options);
|
|
10447
|
+
if (options.only) {
|
|
10448
|
+
checks2 = checks2.filter((c) => c.name === options.only);
|
|
10449
|
+
if (checks2.length === 0) {
|
|
10450
|
+
throw new Error(`"${options.only}" is not a pinned npm extension of this book.`);
|
|
10451
|
+
}
|
|
10452
|
+
}
|
|
10453
|
+
const updated = [];
|
|
10454
|
+
for (const check37 of checks2) {
|
|
10455
|
+
if (!check37.outdated)
|
|
10456
|
+
continue;
|
|
10457
|
+
await addExtension(projectDir, pinnedNpmSpecifier(check37.name, check37.latest), {
|
|
10458
|
+
fetch: options.fetch,
|
|
10459
|
+
signal: options.signal,
|
|
10460
|
+
limits: options.limits
|
|
10461
|
+
});
|
|
10462
|
+
updated.push({ name: check37.name, from: check37.current, to: check37.latest });
|
|
10463
|
+
}
|
|
10464
|
+
return updated;
|
|
10465
|
+
}
|
|
10383
10466
|
async function uniqueExtensionId(projectDir, base) {
|
|
10384
10467
|
const slug = slugify(base) || "extension";
|
|
10385
10468
|
let candidate = slug;
|
|
@@ -11429,7 +11512,7 @@ var drivethrurpgProvider = {
|
|
|
11429
11512
|
};
|
|
11430
11513
|
|
|
11431
11514
|
// src/lib/publish/providers/gdrive.ts
|
|
11432
|
-
import { mkdtemp as mkdtemp3, readFile as readFile28, readdir as
|
|
11515
|
+
import { mkdtemp as mkdtemp3, readFile as readFile28, readdir as readdir6, rm as rm5, stat as stat7, writeFile as writeFile9 } from "node:fs/promises";
|
|
11433
11516
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
11434
11517
|
import path20 from "node:path";
|
|
11435
11518
|
import { Zip, ZipDeflate } from "fflate";
|
|
@@ -11814,7 +11897,7 @@ function zipEntriesNonBlocking(entries, opts) {
|
|
|
11814
11897
|
});
|
|
11815
11898
|
}
|
|
11816
11899
|
async function collectZipEntries(root, dir, out, onWarn) {
|
|
11817
|
-
const entries = await
|
|
11900
|
+
const entries = await readdir6(dir, { withFileTypes: true });
|
|
11818
11901
|
for (const entry of entries) {
|
|
11819
11902
|
const full = path20.join(dir, entry.name);
|
|
11820
11903
|
if (entry.isDirectory()) {
|
|
@@ -12487,7 +12570,7 @@ function publishProviderFor(id) {
|
|
|
12487
12570
|
}
|
|
12488
12571
|
|
|
12489
12572
|
// src/lib/publish/run-publish.ts
|
|
12490
|
-
import { readdir as
|
|
12573
|
+
import { readdir as readdir7, stat as stat10 } from "node:fs/promises";
|
|
12491
12574
|
import path23 from "node:path";
|
|
12492
12575
|
function resolvePublishFormat(info9, providerConfig) {
|
|
12493
12576
|
if (info9.formats && info9.formats.length > 0) {
|
|
@@ -12583,7 +12666,7 @@ async function htmlDirIssues(dir) {
|
|
|
12583
12666
|
message: `${dir} has no ${BOOK_HTML} — it isn't an HTML export. ${HTML_HINT}`
|
|
12584
12667
|
});
|
|
12585
12668
|
}
|
|
12586
|
-
const entries = await
|
|
12669
|
+
const entries = await readdir7(dir).catch(() => []);
|
|
12587
12670
|
const extras = entries.filter((name) => name.toLowerCase().endsWith(".pdf") || name === BUILD_FINGERPRINT_FILENAME);
|
|
12588
12671
|
if (extras.length > 0) {
|
|
12589
12672
|
issues.push({
|
|
@@ -12899,4 +12982,4 @@ function normalizeProjectKey(projectDir) {
|
|
|
12899
12982
|
}
|
|
12900
12983
|
// src/lib/publish/manifest-publish.ts
|
|
12901
12984
|
import { isMap as isMap4 } from "yaml";
|
|
12902
|
-
export { isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, loadManifestWithPath, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, EXTENSION_KINDS, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, BUILT_IN_STYLE_SET_IDS, listProjectExtensions, setExtensionEnabled, removeExtension, addExtension, addBuiltInStyleSet, importExtensionFromFile, importExtensionFromUrl, searchNpmExtensions, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listPublishProviders, publishProviderFor, resolvePublishFormat, runPublish, connectPublishProvider, disconnectPublishCredential };
|
|
12985
|
+
export { isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, loadManifestWithPath, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, EXTENSION_KINDS, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, BUILT_IN_STYLE_SET_IDS, listProjectExtensions, setExtensionEnabled, removeExtension, addExtension, checkExtensionUpdates, updateExtensions, addBuiltInStyleSet, importExtensionFromFile, importExtensionFromUrl, searchNpmExtensions, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listPublishProviders, publishProviderFor, resolvePublishFormat, runPublish, connectPublishProvider, disconnectPublishCredential };
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "gutterpress",
|
|
7
|
-
version: "0.11.
|
|
7
|
+
version: "0.11.14-alpha.1",
|
|
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",
|
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
UsageError,
|
|
7
7
|
package_default,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-tctw7rcm.js";
|
|
10
10
|
import {
|
|
11
11
|
EXIT_CODES
|
|
12
12
|
} from "./cli-46ycxe6r.js";
|
|
@@ -18,14 +18,14 @@ 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
|
-
validate: () => import("./validate-
|
|
26
|
-
preflight: () => import("./preflight-
|
|
27
|
-
doctor: () => import("./doctor-
|
|
28
|
-
ext: () => import("./ext-
|
|
21
|
+
new: () => import("./new-pa0pgcat.js").then((m) => m.default),
|
|
22
|
+
preview: () => import("./preview-msq4mz3a.js").then((m) => m.default),
|
|
23
|
+
build: () => import("./build-9ccmg4jw.js").then((m) => m.default),
|
|
24
|
+
publish: () => import("./publish-2rgbacn1.js").then((m) => m.default),
|
|
25
|
+
validate: () => import("./validate-ekbmn8wh.js").then((m) => m.default),
|
|
26
|
+
preflight: () => import("./preflight-6v0j7ae8.js").then((m) => m.default),
|
|
27
|
+
doctor: () => import("./doctor-2kp6wsnx.js").then((m) => m.default),
|
|
28
|
+
ext: () => import("./ext-kct0k4ne.js").then((m) => m.default)
|
|
29
29
|
};
|
|
30
30
|
var VERSION = package_default.version;
|
|
31
31
|
var main = defineCommand({
|
|
@@ -50,7 +50,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
50
50
|
const [command, ...commandArgs] = rawArgs;
|
|
51
51
|
try {
|
|
52
52
|
if (command === "new") {
|
|
53
|
-
const { newArgs } = await import("./new-
|
|
53
|
+
const { newArgs } = await import("./new-pa0pgcat.js");
|
|
54
54
|
rejectUnknownFlags(commandArgs, newArgs, "new");
|
|
55
55
|
const parsed = parseArgs(commandArgs, {
|
|
56
56
|
...newArgs,
|
|
@@ -62,7 +62,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
if (command === "preflight") {
|
|
65
|
-
const { preflightArgs } = await import("./preflight-
|
|
65
|
+
const { preflightArgs } = await import("./preflight-6v0j7ae8.js");
|
|
66
66
|
rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
|
|
67
67
|
const parsed = parseArgs(commandArgs, {
|
|
68
68
|
...preflightArgs,
|
|
@@ -82,7 +82,7 @@ async function preflightRequiredInvocations(rawArgs) {
|
|
|
82
82
|
}
|
|
83
83
|
if (subcommand.startsWith("-"))
|
|
84
84
|
return;
|
|
85
|
-
const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-
|
|
85
|
+
const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-kct0k4ne.js");
|
|
86
86
|
if (!EXT_SUBCOMMANDS.includes(subcommand)) {
|
|
87
87
|
throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
|
|
88
88
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getSystemDiagnostics,
|
|
3
3
|
log
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-cmyfeqg6.js";
|
|
5
5
|
import {
|
|
6
6
|
UsageError,
|
|
7
7
|
rejectExtraPositionals,
|
|
8
8
|
rejectUnknownFlags
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-tctw7rcm.js";
|
|
10
10
|
import"./cli-46ycxe6r.js";
|
|
11
11
|
import"./cli-7fkhgtfn.js";
|
|
12
12
|
import"./cli-37x76zdn.js";
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
BUILT_IN_STYLE_SET_IDS,
|
|
3
3
|
addBuiltInStyleSet,
|
|
4
4
|
addExtension,
|
|
5
|
+
checkExtensionUpdates,
|
|
5
6
|
importExtensionFromFile,
|
|
6
7
|
importExtensionFromUrl,
|
|
7
8
|
isPathSpecifier,
|
|
@@ -9,16 +10,17 @@ import {
|
|
|
9
10
|
parseExtensionSpecifier,
|
|
10
11
|
removeExtension,
|
|
11
12
|
searchNpmExtensions,
|
|
12
|
-
setExtensionEnabled
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
setExtensionEnabled,
|
|
14
|
+
updateExtensions
|
|
15
|
+
} from "./cli-s38v88rv.js";
|
|
16
|
+
import"./cli-cmyfeqg6.js";
|
|
15
17
|
import {
|
|
16
18
|
UsageError,
|
|
17
19
|
exitForUsage,
|
|
18
20
|
rejectExtraPositionals,
|
|
19
21
|
rejectUnknownFlags,
|
|
20
22
|
resolveProjectDir
|
|
21
|
-
} from "./cli-
|
|
23
|
+
} from "./cli-tctw7rcm.js";
|
|
22
24
|
import"./cli-tjhn2mdn.js";
|
|
23
25
|
import {
|
|
24
26
|
EXIT_CODES
|
|
@@ -72,7 +74,16 @@ var extSearchArgs = {
|
|
|
72
74
|
required: false
|
|
73
75
|
}
|
|
74
76
|
};
|
|
75
|
-
var
|
|
77
|
+
var extOutdatedArgs = { dir: dirArg };
|
|
78
|
+
var extUpdateArgs = {
|
|
79
|
+
name: {
|
|
80
|
+
type: "positional",
|
|
81
|
+
description: "The npm package to update; omit to update every pinned npm extension",
|
|
82
|
+
required: false
|
|
83
|
+
},
|
|
84
|
+
dir: dirArg
|
|
85
|
+
};
|
|
86
|
+
var EXT_SUBCOMMANDS = ["list", "add", "remove", "enable", "disable", "search", "outdated", "update"];
|
|
76
87
|
var parentArgs = {};
|
|
77
88
|
function rejectParentFlags(rawArgs) {
|
|
78
89
|
const first = rawArgs[0];
|
|
@@ -290,20 +301,104 @@ var search = defineCommand({
|
|
|
290
301
|
}
|
|
291
302
|
}
|
|
292
303
|
});
|
|
304
|
+
var outdated = defineCommand({
|
|
305
|
+
meta: {
|
|
306
|
+
name: "outdated",
|
|
307
|
+
description: "Compare each pinned npm extension with npm's latest (network); exit 1 when one is behind"
|
|
308
|
+
},
|
|
309
|
+
args: extOutdatedArgs,
|
|
310
|
+
async run({ args, rawArgs }) {
|
|
311
|
+
let projectDir = "";
|
|
312
|
+
try {
|
|
313
|
+
rejectUnknownFlags(rawArgs, extOutdatedArgs, "ext outdated");
|
|
314
|
+
rejectExtraPositionals(args._, 1, "ext outdated");
|
|
315
|
+
projectDir = await requireProjectDir(args.dir, "outdated");
|
|
316
|
+
} catch (error) {
|
|
317
|
+
exitForUsage(error);
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
const checks = await checkExtensionUpdates(projectDir);
|
|
321
|
+
if (checks.length === 0) {
|
|
322
|
+
console.log("No pinned npm extensions to check.");
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const behind = checks.filter((c) => c.outdated);
|
|
326
|
+
if (behind.length === 0) {
|
|
327
|
+
console.log(`Every pinned npm extension is at its latest version (${checks.map((c) => c.use).join(", ")}).`);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
console.log("Extensions with a newer version on npm:");
|
|
331
|
+
for (const c of behind)
|
|
332
|
+
console.log(` ${c.name} ${c.current} -> ${c.latest}`);
|
|
333
|
+
for (const c of checks)
|
|
334
|
+
if (!c.outdated)
|
|
335
|
+
console.log(` ${c.name} ${c.current} (latest)`);
|
|
336
|
+
console.log("Update with: gutterpress ext update [name] [dir]");
|
|
337
|
+
process.exit(EXIT_CODES.FINDINGS);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
failPipeline("Could not check npm for updates", error);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
var update = defineCommand({
|
|
344
|
+
meta: {
|
|
345
|
+
name: "update",
|
|
346
|
+
description: "Re-pin every outdated npm extension (or one, by name) to npm's latest: download, verify, vendor, load-test"
|
|
347
|
+
},
|
|
348
|
+
args: extUpdateArgs,
|
|
349
|
+
async run({ args, rawArgs }) {
|
|
350
|
+
let projectDir = "";
|
|
351
|
+
let only;
|
|
352
|
+
try {
|
|
353
|
+
rejectUnknownFlags(rawArgs, extUpdateArgs, "ext update");
|
|
354
|
+
rejectExtraPositionals(args._, 2, "ext update");
|
|
355
|
+
let name = typeof args.name === "string" ? args.name.trim() : "";
|
|
356
|
+
let dir = args.dir;
|
|
357
|
+
if (name && dir === undefined) {
|
|
358
|
+
const looksLikePath = path.isAbsolute(name) || isPathSpecifier(name);
|
|
359
|
+
const isDir = await stat(path.resolve(process.cwd(), name)).then((s) => s.isDirectory()).catch(() => false);
|
|
360
|
+
if (looksLikePath || isDir) {
|
|
361
|
+
dir = name;
|
|
362
|
+
name = "";
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
projectDir = await requireProjectDir(dir, "update");
|
|
366
|
+
only = name || undefined;
|
|
367
|
+
} catch (error) {
|
|
368
|
+
exitForUsage(error);
|
|
369
|
+
}
|
|
370
|
+
try {
|
|
371
|
+
const updated = await updateExtensions(projectDir, { only });
|
|
372
|
+
if (updated.length === 0) {
|
|
373
|
+
console.log(only ? `${only} is already at its latest version.` : "Every pinned npm extension is already at its latest version.");
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
for (const u of updated)
|
|
377
|
+
console.log(`Updated ${u.name} ${u.from} -> ${u.to}`);
|
|
378
|
+
console.log(` project: ${projectDir}`);
|
|
379
|
+
console.log(" vendored under: plugins/npm (previous version removed)");
|
|
380
|
+
console.log(" manifest: exact version re-pinned");
|
|
381
|
+
} catch (error) {
|
|
382
|
+
failPipeline("Could not update extensions", error);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
});
|
|
293
386
|
var ext_default = defineCommand({
|
|
294
387
|
meta: {
|
|
295
388
|
name: "ext",
|
|
296
|
-
description: "List, add, remove, enable, disable the project's extensions, or search npm"
|
|
389
|
+
description: "List, add, remove, enable, disable or update the project's extensions, or search npm"
|
|
297
390
|
},
|
|
298
391
|
args: parentArgs,
|
|
299
392
|
setup({ rawArgs }) {
|
|
300
393
|
rejectParentFlags(rawArgs);
|
|
301
394
|
},
|
|
302
|
-
subCommands: { list, add, remove, enable, disable, search }
|
|
395
|
+
subCommands: { list, add, remove, enable, disable, search, outdated, update }
|
|
303
396
|
});
|
|
304
397
|
export {
|
|
398
|
+
extUpdateArgs,
|
|
305
399
|
extSearchArgs,
|
|
306
400
|
extRemoveArgs,
|
|
401
|
+
extOutdatedArgs,
|
|
307
402
|
extListArgs,
|
|
308
403
|
extEnableArgs,
|
|
309
404
|
extDisableArgs,
|
|
@@ -3858,7 +3858,7 @@ import git from "isomorphic-git";
|
|
|
3858
3858
|
// package.json
|
|
3859
3859
|
var package_default = {
|
|
3860
3860
|
name: "gutterpress",
|
|
3861
|
-
version: "0.11.
|
|
3861
|
+
version: "0.11.14-alpha.1",
|
|
3862
3862
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
3863
3863
|
author: "itlackey",
|
|
3864
3864
|
license: "MPL-2.0",
|
|
@@ -10400,11 +10400,11 @@ async function importTemplateFromFolder(options) {
|
|
|
10400
10400
|
return saveProjectAsTemplate({ projectDir: sourceDir, name, templatesRoot });
|
|
10401
10401
|
}
|
|
10402
10402
|
// src/lib/snippets.ts
|
|
10403
|
-
import { readdir as
|
|
10403
|
+
import { readdir as readdir8, readFile as readFile30, writeFile as writeFile10, mkdir as mkdir11, rm as rm4 } from "node:fs/promises";
|
|
10404
10404
|
import path20 from "node:path";
|
|
10405
10405
|
|
|
10406
10406
|
// src/lib/extension-manager.ts
|
|
10407
|
-
import { cp as cp3, mkdir as mkdir10, readFile as readFile29, rm as rm3, stat as stat7 } from "node:fs/promises";
|
|
10407
|
+
import { cp as cp3, mkdir as mkdir10, readdir as readdir7, readFile as readFile29, rm as rm3, stat as stat7 } from "node:fs/promises";
|
|
10408
10408
|
import { existsSync as existsSync14 } from "node:fs";
|
|
10409
10409
|
import path19 from "node:path";
|
|
10410
10410
|
import { isSeq as isSeq3, isMap as isMap2, isScalar as isScalar2, YAMLMap, Scalar } from "yaml";
|
|
@@ -11070,6 +11070,7 @@ async function rollbackNpmPluginInstall(installed) {
|
|
|
11070
11070
|
}
|
|
11071
11071
|
|
|
11072
11072
|
// src/lib/extension-manager.ts
|
|
11073
|
+
import { gt as semverGt } from "semver";
|
|
11073
11074
|
var EXTENSIONS_DIR = "extensions";
|
|
11074
11075
|
var RECOMMENDED_EXTENSIONS = [
|
|
11075
11076
|
{
|
|
@@ -11457,9 +11458,91 @@ async function addExtensionUnlocked(projectDir, specifier, options) {
|
|
|
11457
11458
|
await finalizeNpmPluginInstall(installed).catch((error2) => {
|
|
11458
11459
|
warnings.push(`The extension was installed, but an old backup could not be removed: ` + `${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
11459
11460
|
});
|
|
11461
|
+
await pruneOtherVersions(projectDir, installed.name, installed.version).catch((error2) => {
|
|
11462
|
+
warnings.push(`The extension was installed, but a previous version's vendored copy could not be removed: ` + `${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
11463
|
+
});
|
|
11460
11464
|
const entry = await describeExtension(projectDir, use);
|
|
11461
11465
|
return warnings.length > 0 ? { ...entry, warnings: [...entry.warnings ?? [], ...warnings] } : entry;
|
|
11462
11466
|
}
|
|
11467
|
+
async function pruneOtherVersions(projectDir, name, keep) {
|
|
11468
|
+
const parent = path19.dirname(vendoredNpmPluginRoot(projectDir, name, keep));
|
|
11469
|
+
let entries;
|
|
11470
|
+
try {
|
|
11471
|
+
entries = await readdir7(parent, { withFileTypes: true });
|
|
11472
|
+
} catch {
|
|
11473
|
+
return;
|
|
11474
|
+
}
|
|
11475
|
+
for (const entry of entries) {
|
|
11476
|
+
if (!entry.isDirectory() || entry.name === keep || !isExactNpmVersion(entry.name))
|
|
11477
|
+
continue;
|
|
11478
|
+
await rm3(path19.join(parent, entry.name), { recursive: true, force: true });
|
|
11479
|
+
}
|
|
11480
|
+
}
|
|
11481
|
+
var LATEST_LOOKUP_TIMEOUT_MS = 30000;
|
|
11482
|
+
var MAX_PACKUMENT_BYTES = 15 * 1024 * 1024;
|
|
11483
|
+
async function latestNpmVersion(name, options) {
|
|
11484
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
11485
|
+
return withFetchTimeout({
|
|
11486
|
+
timeoutMs: LATEST_LOOKUP_TIMEOUT_MS,
|
|
11487
|
+
signal: options.signal,
|
|
11488
|
+
timeoutMessage: `Looking up ${name} on npm timed out. Check your connection and try again.`,
|
|
11489
|
+
offlineMessage: (cause) => `Looking up ${name} on npm failed (${cause instanceof Error ? cause.message : String(cause)}).`
|
|
11490
|
+
}, async (signal) => {
|
|
11491
|
+
const response = await fetchImpl(`${npmRegistryUrl()}/${encodeURIComponent(name)}`, {
|
|
11492
|
+
signal,
|
|
11493
|
+
redirect: "error",
|
|
11494
|
+
headers: { accept: "application/vnd.npm.install-v1+json" }
|
|
11495
|
+
});
|
|
11496
|
+
if (response.status === 404)
|
|
11497
|
+
throw new FriendlyHttpError(`npm package "${name}" was not found.`);
|
|
11498
|
+
if (!response.ok)
|
|
11499
|
+
throw new FriendlyHttpError(`Looking up ${name} on npm failed (HTTP ${response.status}).`);
|
|
11500
|
+
const bytes = await response.arrayBuffer();
|
|
11501
|
+
if (bytes.byteLength > MAX_PACKUMENT_BYTES) {
|
|
11502
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" is too large to read.`);
|
|
11503
|
+
}
|
|
11504
|
+
let latest;
|
|
11505
|
+
try {
|
|
11506
|
+
latest = JSON.parse(Buffer.from(bytes).toString("utf8"))["dist-tags"]?.latest;
|
|
11507
|
+
} catch {
|
|
11508
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" is not valid JSON.`);
|
|
11509
|
+
}
|
|
11510
|
+
if (typeof latest !== "string" || !isExactNpmVersion(latest)) {
|
|
11511
|
+
throw new FriendlyHttpError(`npm metadata for "${name}" has no latest version.`);
|
|
11512
|
+
}
|
|
11513
|
+
return latest;
|
|
11514
|
+
});
|
|
11515
|
+
}
|
|
11516
|
+
async function checkExtensionUpdates(projectDir, options = {}) {
|
|
11517
|
+
const entries = await listProjectExtensions(projectDir);
|
|
11518
|
+
const pinned = entries.filter((e) => e.kind === "npm" && e.version);
|
|
11519
|
+
return Promise.all(pinned.map(async (e) => {
|
|
11520
|
+
const current = e.version;
|
|
11521
|
+
const latest = await latestNpmVersion(e.name, options);
|
|
11522
|
+
return { use: e.use, name: e.name, current, latest, outdated: semverGt(latest, current) };
|
|
11523
|
+
}));
|
|
11524
|
+
}
|
|
11525
|
+
async function updateExtensions(projectDir, options = {}) {
|
|
11526
|
+
let checks2 = await checkExtensionUpdates(projectDir, options);
|
|
11527
|
+
if (options.only) {
|
|
11528
|
+
checks2 = checks2.filter((c) => c.name === options.only);
|
|
11529
|
+
if (checks2.length === 0) {
|
|
11530
|
+
throw new Error(`"${options.only}" is not a pinned npm extension of this book.`);
|
|
11531
|
+
}
|
|
11532
|
+
}
|
|
11533
|
+
const updated = [];
|
|
11534
|
+
for (const check37 of checks2) {
|
|
11535
|
+
if (!check37.outdated)
|
|
11536
|
+
continue;
|
|
11537
|
+
await addExtension(projectDir, pinnedNpmSpecifier(check37.name, check37.latest), {
|
|
11538
|
+
fetch: options.fetch,
|
|
11539
|
+
signal: options.signal,
|
|
11540
|
+
limits: options.limits
|
|
11541
|
+
});
|
|
11542
|
+
updated.push({ name: check37.name, from: check37.current, to: check37.latest });
|
|
11543
|
+
}
|
|
11544
|
+
return updated;
|
|
11545
|
+
}
|
|
11463
11546
|
async function listBuiltInStyleSets() {
|
|
11464
11547
|
const assets = await getAssetsDir();
|
|
11465
11548
|
const out = [];
|
|
@@ -11566,7 +11649,7 @@ function resolveSnippetPath(projectDir, fileName) {
|
|
|
11566
11649
|
async function scanSnippetFiles(dir) {
|
|
11567
11650
|
let names;
|
|
11568
11651
|
try {
|
|
11569
|
-
names = await
|
|
11652
|
+
names = await readdir8(dir);
|
|
11570
11653
|
} catch {
|
|
11571
11654
|
return [];
|
|
11572
11655
|
}
|
|
@@ -12786,7 +12869,7 @@ async function listGitHubBranches(credential, owner, repo, options = {}) {
|
|
|
12786
12869
|
return branches;
|
|
12787
12870
|
}
|
|
12788
12871
|
// src/lib/remote-auth/clone.ts
|
|
12789
|
-
import { mkdir as mkdir13, readdir as
|
|
12872
|
+
import { mkdir as mkdir13, readdir as readdir9, rm as rm6 } from "node:fs/promises";
|
|
12790
12873
|
import path22 from "node:path";
|
|
12791
12874
|
import git3 from "isomorphic-git";
|
|
12792
12875
|
|
|
@@ -13087,7 +13170,7 @@ function sanitizeCloneFolderName(name) {
|
|
|
13087
13170
|
}
|
|
13088
13171
|
async function assertCloneTarget(dir) {
|
|
13089
13172
|
try {
|
|
13090
|
-
const entries = await
|
|
13173
|
+
const entries = await readdir9(dir);
|
|
13091
13174
|
if (entries.length > 0) {
|
|
13092
13175
|
throw new Error("That folder already has files in it. Choose an empty folder for the book.");
|
|
13093
13176
|
}
|
|
@@ -14009,16 +14092,16 @@ async function repairOnlineBackup(options) {
|
|
|
14009
14092
|
}
|
|
14010
14093
|
// src/lib/remote-auth/scorched-earth.ts
|
|
14011
14094
|
import git8 from "isomorphic-git";
|
|
14012
|
-
import { cp as cp6, mkdir as mkdir16, readdir as
|
|
14095
|
+
import { cp as cp6, mkdir as mkdir16, readdir as readdir10, rm as rm8 } from "node:fs/promises";
|
|
14013
14096
|
import path25 from "node:path";
|
|
14014
14097
|
async function emptyDir(dir) {
|
|
14015
|
-
for (const entry of await
|
|
14098
|
+
for (const entry of await readdir10(dir)) {
|
|
14016
14099
|
await rm8(path25.join(dir, entry), { recursive: true, force: true });
|
|
14017
14100
|
}
|
|
14018
14101
|
}
|
|
14019
14102
|
async function copyFilesBack(from, to) {
|
|
14020
14103
|
const skip = path25.join(from, ".git");
|
|
14021
|
-
for (const entry of await
|
|
14104
|
+
for (const entry of await readdir10(from)) {
|
|
14022
14105
|
const src = path25.join(from, entry);
|
|
14023
14106
|
if (src === skip)
|
|
14024
14107
|
continue;
|
|
@@ -14071,7 +14154,7 @@ async function scorchedEarth(options) {
|
|
|
14071
14154
|
}
|
|
14072
14155
|
}
|
|
14073
14156
|
// src/lib/publish/run-publish.ts
|
|
14074
|
-
import { readdir as
|
|
14157
|
+
import { readdir as readdir12, stat as stat12 } from "node:fs/promises";
|
|
14075
14158
|
import path30 from "node:path";
|
|
14076
14159
|
|
|
14077
14160
|
// src/lib/publish/command-runner.ts
|
|
@@ -14302,7 +14385,7 @@ var drivethrurpgProvider = {
|
|
|
14302
14385
|
};
|
|
14303
14386
|
|
|
14304
14387
|
// src/lib/publish/providers/gdrive.ts
|
|
14305
|
-
import { mkdtemp as mkdtemp3, readFile as readFile32, readdir as
|
|
14388
|
+
import { mkdtemp as mkdtemp3, readFile as readFile32, readdir as readdir11, rm as rm9, stat as stat9, writeFile as writeFile14 } from "node:fs/promises";
|
|
14306
14389
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
14307
14390
|
import path27 from "node:path";
|
|
14308
14391
|
import { Zip, ZipDeflate } from "fflate";
|
|
@@ -14687,7 +14770,7 @@ function zipEntriesNonBlocking(entries, opts) {
|
|
|
14687
14770
|
});
|
|
14688
14771
|
}
|
|
14689
14772
|
async function collectZipEntries(root, dir, out, onWarn) {
|
|
14690
|
-
const entries = await
|
|
14773
|
+
const entries = await readdir11(dir, { withFileTypes: true });
|
|
14691
14774
|
for (const entry of entries) {
|
|
14692
14775
|
const full = path27.join(dir, entry.name);
|
|
14693
14776
|
if (entry.isDirectory()) {
|
|
@@ -15454,7 +15537,7 @@ async function htmlDirIssues(dir) {
|
|
|
15454
15537
|
message: `${dir} has no ${BOOK_HTML} — it isn't an HTML export. ${HTML_HINT}`
|
|
15455
15538
|
});
|
|
15456
15539
|
}
|
|
15457
|
-
const entries = await
|
|
15540
|
+
const entries = await readdir12(dir).catch(() => []);
|
|
15458
15541
|
const extras = entries.filter((name) => name.toLowerCase().endsWith(".pdf") || name === BUILD_FINGERPRINT_FILENAME);
|
|
15459
15542
|
if (extras.length > 0) {
|
|
15460
15543
|
issues.push({
|
|
@@ -15691,4 +15774,4 @@ async function setPublishProviderConfig(projectDir, providerId, values) {
|
|
|
15691
15774
|
await writeManifestDoc(file, doc);
|
|
15692
15775
|
return settingsFromDoc(doc);
|
|
15693
15776
|
}
|
|
15694
|
-
export { BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, SYNC_SNAPSHOT_MESSAGE, log, resolveActiveStyles, listProjectStyles, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, getChecks, getCheckById, resolveCheckSelectors, formatReport, ruleRemoteUrls, ruleRiskyProps, ruleSyntax, checkCss, inspectImage, runChecks, checkToolAvailability, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, defaultConfigDir, FileTokenStore, extractUrlCredential, getSystemDiagnostics, slugifyProjectName, escapeYamlScalar, scaffoldProject, adoptFolder, ensureGitignoreHasDist, EXTENSION_KINDS, RESERVED_PREFIX, resolveExtensionPrefix, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, listBuiltInTemplates, saveProjectAsTemplate, listCustomTemplates, importTemplateFromFolder, DEFAULT_NPM_REGISTRY, npmRegistryUrl, EXTENSIONS_DIR, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, sameExtension, listProjectExtensions, describeExtension, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listBuiltInStyleSets, addBuiltInStyleSet, validateProjectExtensions, readExtensionCss, SNIPPETS_DIR, extractVariables, substituteVariables, listSnippets, readSnippet, saveSnippet, deleteSnippet, listMergedSnippets, readExtensionSnippet, importExtensionFromFile, importExtensionFromUrl, MAX_SEARCH_BYTES, SEARCH_KEYWORDS, searchNpmExtensions, setManifestFields, readManifestFields, setActiveStyles, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, AUTO_SYNC_PUSH_INTERVAL_MINUTES, autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, resolveGitHubClientId, GITHUB_HOST, GitHubAuthProvider, GDRIVE_HOST, resolveGoogleClientId, resolveGoogleClientSecret, GOOGLE_NOT_CONFIGURED_MESSAGE, requireGoogleClientCredentials, pkceChallengeFromVerifier, GoogleAuthProvider, revokeGoogleCredential, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listGitHubRepositories, listRepoBooks, listGitHubBranches, sanitizeCloneFolderName, cloneRepository, isSshRemoteUrl, testRemoteAccess, knownForgeTokenUrl, connectGenericHost, parseRemoteOrigin, forgeKindForHost, diagnoseProjectRemote, syncProject, refreshRemoteCopies, REPAIR_SNAPSHOT_MESSAGE, repairOnlineBackup, scorchedEarth, listPublishProviders, publishProviderFor, resolvePublishFormat, resolvePublishRequest, runPublish, connectPublishProvider, disconnectPublishCredential, PublishSelectionsStore, readPublishSettings, setPublishProviderConfig };
|
|
15777
|
+
export { BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, SYNC_SNAPSHOT_MESSAGE, log, resolveActiveStyles, listProjectStyles, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, getChecks, getCheckById, resolveCheckSelectors, formatReport, ruleRemoteUrls, ruleRiskyProps, ruleSyntax, checkCss, inspectImage, runChecks, checkToolAvailability, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, defaultConfigDir, FileTokenStore, extractUrlCredential, getSystemDiagnostics, slugifyProjectName, escapeYamlScalar, scaffoldProject, adoptFolder, ensureGitignoreHasDist, EXTENSION_KINDS, RESERVED_PREFIX, resolveExtensionPrefix, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, listBuiltInTemplates, saveProjectAsTemplate, listCustomTemplates, importTemplateFromFolder, DEFAULT_NPM_REGISTRY, npmRegistryUrl, EXTENSIONS_DIR, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, sameExtension, listProjectExtensions, describeExtension, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, checkExtensionUpdates, updateExtensions, listBuiltInStyleSets, addBuiltInStyleSet, validateProjectExtensions, readExtensionCss, SNIPPETS_DIR, extractVariables, substituteVariables, listSnippets, readSnippet, saveSnippet, deleteSnippet, listMergedSnippets, readExtensionSnippet, importExtensionFromFile, importExtensionFromUrl, MAX_SEARCH_BYTES, SEARCH_KEYWORDS, searchNpmExtensions, setManifestFields, readManifestFields, setActiveStyles, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, AUTO_SYNC_PUSH_INTERVAL_MINUTES, autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, resolveGitHubClientId, GITHUB_HOST, GitHubAuthProvider, GDRIVE_HOST, resolveGoogleClientId, resolveGoogleClientSecret, GOOGLE_NOT_CONFIGURED_MESSAGE, requireGoogleClientCredentials, pkceChallengeFromVerifier, GoogleAuthProvider, revokeGoogleCredential, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listGitHubRepositories, listRepoBooks, listGitHubBranches, sanitizeCloneFolderName, cloneRepository, isSshRemoteUrl, testRemoteAccess, knownForgeTokenUrl, connectGenericHost, parseRemoteOrigin, forgeKindForHost, diagnoseProjectRemote, syncProject, refreshRemoteCopies, REPAIR_SNAPSHOT_MESSAGE, repairOnlineBackup, scorchedEarth, listPublishProviders, publishProviderFor, resolvePublishFormat, resolvePublishRequest, runPublish, connectPublishProvider, disconnectPublishCredential, PublishSelectionsStore, readPublishSettings, setPublishProviderConfig };
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
autoSnapshotDelayMs,
|
|
38
38
|
autoSyncDelayMs,
|
|
39
39
|
checkCss,
|
|
40
|
+
checkExtensionUpdates,
|
|
40
41
|
checkToolAvailability,
|
|
41
42
|
cloneRepository,
|
|
42
43
|
connectGenericHost,
|
|
@@ -143,8 +144,9 @@ import {
|
|
|
143
144
|
substituteVariables,
|
|
144
145
|
syncProject,
|
|
145
146
|
testRemoteAccess,
|
|
147
|
+
updateExtensions,
|
|
146
148
|
validateProjectExtensions
|
|
147
|
-
} from "./index-
|
|
149
|
+
} from "./index-ch9k0kam.js";
|
|
148
150
|
import {
|
|
149
151
|
BUILD_DIAGNOSTIC_CODES
|
|
150
152
|
} from "./index-b6p1fh61.js";
|
|
@@ -182,6 +184,7 @@ import"./index-37x76zdn.js";
|
|
|
182
184
|
export {
|
|
183
185
|
whenGitIdle,
|
|
184
186
|
validateProjectExtensions,
|
|
187
|
+
updateExtensions,
|
|
185
188
|
testRemoteAccess,
|
|
186
189
|
syncProject,
|
|
187
190
|
switchBranch,
|
|
@@ -300,6 +303,7 @@ export {
|
|
|
300
303
|
connectGenericHost,
|
|
301
304
|
cloneRepository,
|
|
302
305
|
checkToolAvailability,
|
|
306
|
+
checkExtensionUpdates,
|
|
303
307
|
checkCss,
|
|
304
308
|
capabilitiesFor,
|
|
305
309
|
autoSyncDelayMs,
|
|
@@ -146,6 +146,50 @@ export interface AddExtensionOptions extends NpmPluginInstallOptions {
|
|
|
146
146
|
* Returns the described entry.
|
|
147
147
|
*/
|
|
148
148
|
export declare function addExtension(projectDir: string, specifier: string, options?: AddExtensionOptions): Promise<ProjectExtensionEntry>;
|
|
149
|
+
/** One pinned npm extension against npm's `latest` tag. */
|
|
150
|
+
export interface ExtensionUpdateCheck {
|
|
151
|
+
/** The specifier as written in the manifest (`name@current`). */
|
|
152
|
+
use: string;
|
|
153
|
+
name: string;
|
|
154
|
+
/** The pinned version. */
|
|
155
|
+
current: string;
|
|
156
|
+
/** npm's `latest` dist-tag. */
|
|
157
|
+
latest: string;
|
|
158
|
+
/** `latest` is newer than `current` (semver). */
|
|
159
|
+
outdated: boolean;
|
|
160
|
+
}
|
|
161
|
+
export interface CheckExtensionUpdatesOptions {
|
|
162
|
+
/** Dependency injection for tests; production uses global fetch. */
|
|
163
|
+
fetch?: typeof globalThis.fetch;
|
|
164
|
+
signal?: AbortSignal;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Every pinned npm extension of the book against npm's `latest`, in manifest
|
|
168
|
+
* order. Bundled, path and unpinned entries are not npm's to answer for and
|
|
169
|
+
* are skipped. One lookup per package, in parallel; a failed lookup throws
|
|
170
|
+
* with the package named.
|
|
171
|
+
*/
|
|
172
|
+
export declare function checkExtensionUpdates(projectDir: string, options?: CheckExtensionUpdatesOptions): Promise<ExtensionUpdateCheck[]>;
|
|
173
|
+
/** One extension `updateExtensions` moved. */
|
|
174
|
+
export interface ExtensionUpdateResult {
|
|
175
|
+
name: string;
|
|
176
|
+
from: string;
|
|
177
|
+
to: string;
|
|
178
|
+
}
|
|
179
|
+
export interface UpdateExtensionsOptions extends CheckExtensionUpdatesOptions {
|
|
180
|
+
/** Update only this package (its npm name); default every pinned npm entry. */
|
|
181
|
+
only?: string;
|
|
182
|
+
/** Test/specialized-host install limits — see `NpmPluginInstallOptions`. */
|
|
183
|
+
limits?: NpmPluginInstallOptions["limits"];
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Re-pin every outdated npm extension (or just `only`) to npm's `latest`,
|
|
187
|
+
* one `addExtension(name@latest)` each — the same download, verification,
|
|
188
|
+
* vendoring, load test and in-place re-pin as `ext add`, keeping the entry's
|
|
189
|
+
* `export:` and `enabled:` as written and removing the old version's folder.
|
|
190
|
+
* Returns what moved; an up-to-date book returns `[]`.
|
|
191
|
+
*/
|
|
192
|
+
export declare function updateExtensions(projectDir: string, options?: UpdateExtensionsOptions): Promise<ExtensionUpdateResult[]>;
|
|
149
193
|
/** List the built-in looks (metadata read from the embedded assets). */
|
|
150
194
|
export declare function listBuiltInStyleSets(): Promise<BuiltInStyleSet[]>;
|
|
151
195
|
/** A folder name under `extensions/` not yet taken: `<slug>`, `<slug>-2`, … */
|
|
@@ -7,15 +7,15 @@ import {
|
|
|
7
7
|
TARGET_IDS,
|
|
8
8
|
scaffoldExtension,
|
|
9
9
|
scaffoldProject
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-s38v88rv.js";
|
|
11
11
|
import {
|
|
12
12
|
resolveGhostscript
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-cmyfeqg6.js";
|
|
14
14
|
import {
|
|
15
15
|
UsageError,
|
|
16
16
|
rejectExtraPositionals,
|
|
17
17
|
rejectUnknownFlags
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-tctw7rcm.js";
|
|
19
19
|
import"./cli-tjhn2mdn.js";
|
|
20
20
|
import {
|
|
21
21
|
EXIT_CODES
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
executeValidation,
|
|
3
3
|
publishTargetFor,
|
|
4
4
|
reportMissingTools
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-s38v88rv.js";
|
|
6
6
|
import {
|
|
7
7
|
log
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-cmyfeqg6.js";
|
|
9
9
|
import {
|
|
10
10
|
UsageError,
|
|
11
11
|
rejectExtraPositionals,
|
|
12
12
|
rejectUnknownFlags
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-tctw7rcm.js";
|
|
14
14
|
import"./cli-tjhn2mdn.js";
|
|
15
15
|
import {
|
|
16
16
|
EXIT_CODES
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
runBuild,
|
|
7
7
|
splitOutPath,
|
|
8
8
|
startPreviewServer
|
|
9
|
-
} from "./cli-
|
|
9
|
+
} from "./cli-s38v88rv.js";
|
|
10
10
|
import {
|
|
11
11
|
log
|
|
12
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-cmyfeqg6.js";
|
|
13
13
|
import {
|
|
14
14
|
UsageError,
|
|
15
15
|
parseFormat,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
rejectExtraPositionals,
|
|
18
18
|
rejectUnknownFlags,
|
|
19
19
|
resolvePort
|
|
20
|
-
} from "./cli-
|
|
20
|
+
} from "./cli-tctw7rcm.js";
|
|
21
21
|
import"./cli-tjhn2mdn.js";
|
|
22
22
|
import {
|
|
23
23
|
BuildError
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
publishProviderFor,
|
|
12
12
|
resolvePublishFormat,
|
|
13
13
|
runPublish
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-s38v88rv.js";
|
|
15
15
|
import {
|
|
16
16
|
FileTokenStore,
|
|
17
17
|
log
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-cmyfeqg6.js";
|
|
19
19
|
import {
|
|
20
20
|
UsageError,
|
|
21
21
|
rejectExtraPositionals,
|
|
22
22
|
rejectUnknownFlags
|
|
23
|
-
} from "./cli-
|
|
23
|
+
} from "./cli-tctw7rcm.js";
|
|
24
24
|
import"./cli-tjhn2mdn.js";
|
|
25
25
|
import {
|
|
26
26
|
EXIT_CODES
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
executeAndReport
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-s38v88rv.js";
|
|
4
4
|
import {
|
|
5
5
|
log
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-cmyfeqg6.js";
|
|
7
7
|
import {
|
|
8
8
|
UsageError,
|
|
9
9
|
rejectExtraPositionals,
|
|
10
10
|
rejectUnknownFlags
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-tctw7rcm.js";
|
|
12
12
|
import"./cli-tjhn2mdn.js";
|
|
13
13
|
import {
|
|
14
14
|
EXIT_CODES
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gutterpress",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.14-alpha.1",
|
|
4
4
|
"description": "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
5
5
|
"author": "itlackey",
|
|
6
6
|
"license": "MPL-2.0",
|