gutterpress 0.11.9-alpha.3 → 0.11.10-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.
@@ -72,6 +72,7 @@ export { diagnoseProjectRemote, parseRemoteOrigin, forgeKindForHost, } from "../
72
72
  export type { ProjectRemoteDiagnosis, DiagnoseProjectRemoteOptions, RemoteProtocol, RemoteGuidanceId, ForgeKind, } from "../lib/remote-auth/diagnose.ts";
73
73
  export { syncProject, refreshRemoteCopies, SYNC_SNAPSHOT_MESSAGE, } from "../lib/remote-auth/sync.ts";
74
74
  export { repairOnlineBackup, REPAIR_SNAPSHOT_MESSAGE, type RepairOnlineBackupOptions, type RepairOnlineBackupResult, } from "../lib/remote-auth/repair.ts";
75
+ export { scorchedEarth, type ScorchedEarthOptions, type ScorchedEarthResult, } from "../lib/remote-auth/scorched-earth.ts";
75
76
  export type { SyncOutcome, SyncProjectOptions, KeptBothFile, } from "../lib/remote-auth/sync.ts";
76
77
  export type { SnapshotEntry, InitVersionHistoryOptions, SnapshotOptions, RestoreSnapshotOptions, RestoreVersionOptions, RestoreVersionResult, SourceProvider, } from "../lib/source-provider.ts";
77
78
  export { runPublish, resolvePublishRequest, resolvePublishFormat, } from "../lib/publish/run-publish.ts";
package/dist/api/index.js CHANGED
@@ -112,6 +112,7 @@ import {
112
112
  saveSnippet,
113
113
  scaffoldExtension,
114
114
  scaffoldProject,
115
+ scorchedEarth,
115
116
  searchNpmExtensions,
116
117
  setActiveStyles,
117
118
  setExtensionEnabled,
@@ -124,7 +125,7 @@ import {
124
125
  syncProject,
125
126
  testRemoteAccess,
126
127
  validateProjectExtensions
127
- } from "../index-27xa2tfd.js";
128
+ } from "../index-6gvecewt.js";
128
129
  import {
129
130
  BuildError,
130
131
  DEFAULT_PRINT_OPTS,
@@ -170,6 +171,7 @@ export {
170
171
  setExtensionEnabled,
171
172
  setActiveStyles,
172
173
  searchNpmExtensions,
174
+ scorchedEarth,
173
175
  scaffoldProject,
174
176
  scaffoldExtension,
175
177
  saveSnippet,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-edn2tver.js";
3
+ } from "./cli-e5t9zmkr.js";
4
4
  import {
5
5
  log
6
- } from "./cli-nc752ryp.js";
6
+ } from "./cli-9hbkm31q.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-ervhbr00.js";
11
+ } from "./cli-d3wvk0ys.js";
12
12
  import"./cli-d8rdk1y7.js";
13
13
  import"./cli-c41yr7he.js";
14
14
  import {
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  runBuild,
3
3
  splitOutPath
4
- } from "./cli-edn2tver.js";
4
+ } from "./cli-e5t9zmkr.js";
5
5
  import {
6
6
  log
7
- } from "./cli-nc752ryp.js";
7
+ } from "./cli-9hbkm31q.js";
8
8
  import {
9
9
  UsageError,
10
10
  parseFormat,
11
11
  parsePdfxFlavor,
12
12
  rejectExtraPositionals,
13
13
  rejectUnknownFlags
14
- } from "./cli-ervhbr00.js";
14
+ } from "./cli-d3wvk0ys.js";
15
15
  import"./cli-d8rdk1y7.js";
16
16
  import"./cli-c41yr7he.js";
17
17
  import {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./cli-ervhbr00.js";
3
+ } from "./cli-d3wvk0ys.js";
4
4
  import {
5
5
  execCapture,
6
6
  findTool,
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.11.9-alpha.3",
7
+ version: "0.11.10-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",
@@ -13,12 +13,12 @@ import {
13
13
  stampCreator,
14
14
  stripAnnotations,
15
15
  warn
16
- } from "./cli-nc752ryp.js";
16
+ } from "./cli-9hbkm31q.js";
17
17
  import {
18
18
  DEBOUNCE,
19
19
  UsageError,
20
20
  resolvePort
21
- } from "./cli-ervhbr00.js";
21
+ } from "./cli-d3wvk0ys.js";
22
22
  import {
23
23
  MARGIN_BOX_IGNORED_PROPERTIES,
24
24
  RENDER_TIMEOUT_MS,
@@ -13592,6 +13592,8 @@ import git5 from "isomorphic-git";
13592
13592
  import diff3Merge from "diff3";
13593
13593
  // src/lib/remote-auth/repair.ts
13594
13594
  import git7 from "isomorphic-git";
13595
+ // src/lib/remote-auth/scorched-earth.ts
13596
+ import git8 from "isomorphic-git";
13595
13597
  // src/lib/publish/selections.ts
13596
13598
  import { chmod as chmod2, mkdir as mkdir14, readFile as readFile30, writeFile as writeFile12 } from "node:fs/promises";
13597
13599
  import path24 from "node:path";
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UsageError,
7
7
  package_default,
8
8
  rejectUnknownFlags
9
- } from "./cli-ervhbr00.js";
9
+ } from "./cli-d3wvk0ys.js";
10
10
  import {
11
11
  EXIT_CODES
12
12
  } from "./cli-46ycxe6r.js";
@@ -18,16 +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-3a5ng8yv.js").then((m) => m.default),
22
- preview: () => import("./preview-aska26g4.js").then((m) => m.default),
23
- build: () => import("./build-9ze0fcgq.js").then((m) => m.default),
24
- publish: () => import("./publish-jam8mqes.js").then((m) => m.default),
25
- lint: () => import("./lint-qxcpd3ry.js").then((m) => m.default),
26
- validate: () => import("./validate-3cwwe0d5.js").then((m) => m.default),
27
- audit: () => import("./audit-z6hp3dep.js").then((m) => m.default),
28
- preflight: () => import("./preflight-qwbkp4pq.js").then((m) => m.default),
29
- doctor: () => import("./doctor-yk3ah4yk.js").then((m) => m.default),
30
- ext: () => import("./ext-8hrf9n6f.js").then((m) => m.default)
21
+ new: () => import("./new-cwee3zys.js").then((m) => m.default),
22
+ preview: () => import("./preview-a4tm0e4q.js").then((m) => m.default),
23
+ build: () => import("./build-q3aqfwxr.js").then((m) => m.default),
24
+ publish: () => import("./publish-17dm4xnd.js").then((m) => m.default),
25
+ lint: () => import("./lint-yeczry71.js").then((m) => m.default),
26
+ validate: () => import("./validate-2pr6nmer.js").then((m) => m.default),
27
+ audit: () => import("./audit-zfhjrhc8.js").then((m) => m.default),
28
+ preflight: () => import("./preflight-jancad9s.js").then((m) => m.default),
29
+ doctor: () => import("./doctor-7mp7nj35.js").then((m) => m.default),
30
+ ext: () => import("./ext-8g8brq6b.js").then((m) => m.default)
31
31
  };
32
32
  var VERSION = package_default.version;
33
33
  var main = defineCommand({
@@ -52,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
52
52
  const [command, ...commandArgs] = rawArgs;
53
53
  try {
54
54
  if (command === "new") {
55
- const { newArgs } = await import("./new-3a5ng8yv.js");
55
+ const { newArgs } = await import("./new-cwee3zys.js");
56
56
  rejectUnknownFlags(commandArgs, newArgs, "new");
57
57
  const parsed = parseArgs(commandArgs, {
58
58
  ...newArgs,
@@ -64,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
64
64
  return;
65
65
  }
66
66
  if (command === "preflight") {
67
- const { preflightArgs } = await import("./preflight-qwbkp4pq.js");
67
+ const { preflightArgs } = await import("./preflight-jancad9s.js");
68
68
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
69
69
  const parsed = parseArgs(commandArgs, {
70
70
  ...preflightArgs,
@@ -84,7 +84,7 @@ async function preflightRequiredInvocations(rawArgs) {
84
84
  }
85
85
  if (subcommand.startsWith("-"))
86
86
  return;
87
- const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-8hrf9n6f.js");
87
+ const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-8g8brq6b.js");
88
88
  if (!EXT_SUBCOMMANDS.includes(subcommand)) {
89
89
  throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
90
90
  }
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getSystemDiagnostics,
3
3
  log
4
- } from "./cli-nc752ryp.js";
4
+ } from "./cli-9hbkm31q.js";
5
5
  import {
6
6
  UsageError,
7
7
  rejectExtraPositionals,
8
8
  rejectUnknownFlags
9
- } from "./cli-ervhbr00.js";
9
+ } from "./cli-d3wvk0ys.js";
10
10
  import"./cli-c41yr7he.js";
11
11
  import"./cli-46ycxe6r.js";
12
12
  import"./cli-37x76zdn.js";
@@ -10,15 +10,15 @@ import {
10
10
  removeExtension,
11
11
  searchNpmExtensions,
12
12
  setExtensionEnabled
13
- } from "./cli-edn2tver.js";
14
- import"./cli-nc752ryp.js";
13
+ } from "./cli-e5t9zmkr.js";
14
+ import"./cli-9hbkm31q.js";
15
15
  import {
16
16
  UsageError,
17
17
  exitForUsage,
18
18
  rejectExtraPositionals,
19
19
  rejectUnknownFlags,
20
20
  resolveProjectDir
21
- } from "./cli-ervhbr00.js";
21
+ } from "./cli-d3wvk0ys.js";
22
22
  import"./cli-d8rdk1y7.js";
23
23
  import"./cli-c41yr7he.js";
24
24
  import {
@@ -4301,7 +4301,7 @@ import git from "isomorphic-git";
4301
4301
  // package.json
4302
4302
  var package_default = {
4303
4303
  name: "gutterpress",
4304
- version: "0.11.9-alpha.3",
4304
+ version: "0.11.10-alpha.1",
4305
4305
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
4306
4306
  author: "itlackey",
4307
4307
  license: "MPL-2.0",
@@ -14793,9 +14793,72 @@ async function repairOnlineBackup(options) {
14793
14793
  logger.info("result", "repair complete", { status: outcome.status, restored: restoredFiles.length });
14794
14794
  return { outcome, movedGitTo, restoredFiles };
14795
14795
  }
14796
+ // src/lib/remote-auth/scorched-earth.ts
14797
+ import git8 from "isomorphic-git";
14798
+ import { cp as cp7, mkdir as mkdir17, readdir as readdir9, rm as rm9 } from "node:fs/promises";
14799
+ import path25 from "node:path";
14800
+ async function emptyDir(dir) {
14801
+ for (const entry of await readdir9(dir)) {
14802
+ await rm9(path25.join(dir, entry), { recursive: true, force: true });
14803
+ }
14804
+ }
14805
+ async function copyFilesBack(from, to) {
14806
+ const skip = path25.join(from, ".git");
14807
+ for (const entry of await readdir9(from)) {
14808
+ const src = path25.join(from, entry);
14809
+ if (src === skip)
14810
+ continue;
14811
+ await cp7(src, path25.join(to, entry), { recursive: true, force: true });
14812
+ }
14813
+ }
14814
+ async function scorchedEarth(options) {
14815
+ const logger = resolveLogger(options.logFile, "scorched-earth");
14816
+ const dir = await repoDirFor(options.projectDir);
14817
+ const backupDir = options.backupDir;
14818
+ try {
14819
+ const { transport, branch } = await withRepoLock(dir, async () => {
14820
+ const transport2 = await resolveTransport(dir, options);
14821
+ let branch2;
14822
+ try {
14823
+ branch2 = await git8.currentBranch({ fs: gitFs, dir }) ?? undefined;
14824
+ } catch {
14825
+ branch2 = undefined;
14826
+ }
14827
+ logger.info("backup", "copying folder", { to: backupDir });
14828
+ await mkdir17(backupDir, { recursive: true });
14829
+ await cp7(dir, backupDir, { recursive: true });
14830
+ logger.info("delete", "emptying folder", { dir });
14831
+ await emptyDir(dir);
14832
+ return { transport: transport2, branch: branch2 };
14833
+ });
14834
+ let fresh;
14835
+ try {
14836
+ logger.info("download", "starting", { remote: transport.remote, branch: branch ?? "default" });
14837
+ fresh = await cloneRepository({
14838
+ url: transport.url,
14839
+ dir,
14840
+ ...transport.credential ? { credential: transport.credential } : {},
14841
+ ...branch ? { branch } : {},
14842
+ tokenStore: options.tokenStore,
14843
+ httpClient: options.httpClient
14844
+ });
14845
+ } catch (e) {
14846
+ logger.warn("download", "failed — restoring the folder from the backup", errorLogData(e));
14847
+ await emptyDir(dir);
14848
+ await cp7(backupDir, dir, { recursive: true });
14849
+ throw e;
14850
+ }
14851
+ await withRepoLock(dir, () => copyFilesBack(backupDir, dir));
14852
+ logger.info("result", "scorched earth complete", { branch: fresh.branch });
14853
+ return { dir, backupDir, ...fresh.branch ? { branch: fresh.branch } : {} };
14854
+ } catch (e) {
14855
+ logger.error("scorched-earth", "failed", errorLogData(e));
14856
+ throw e;
14857
+ }
14858
+ }
14796
14859
  // src/lib/publish/run-publish.ts
14797
- import { readdir as readdir10, stat as stat12 } from "node:fs/promises";
14798
- import path29 from "node:path";
14860
+ import { readdir as readdir11, stat as stat12 } from "node:fs/promises";
14861
+ import path30 from "node:path";
14799
14862
 
14800
14863
  // src/lib/publish/command-runner.ts
14801
14864
  var CAPTURE_LIMIT = 64 * 1024;
@@ -14944,25 +15007,25 @@ ${tail}` : ""}`);
14944
15007
  };
14945
15008
 
14946
15009
  // src/lib/publish/providers/guided.ts
14947
- import { copyFile as copyFile2, mkdir as mkdir17, writeFile as writeFile14 } from "node:fs/promises";
14948
- import path25 from "node:path";
15010
+ import { copyFile as copyFile2, mkdir as mkdir18, writeFile as writeFile14 } from "node:fs/promises";
15011
+ import path26 from "node:path";
14949
15012
  async function stageGuidedPackage(req, providerId, listingLines) {
14950
- const packageDir = path25.join(path25.dirname(req.artifact.path), "publish", providerId);
14951
- await mkdir17(packageDir, { recursive: true });
14952
- await copyFile2(req.artifact.path, path25.join(packageDir, path25.basename(req.artifact.path)));
15013
+ const packageDir = path26.join(path26.dirname(req.artifact.path), "publish", providerId);
15014
+ await mkdir18(packageDir, { recursive: true });
15015
+ await copyFile2(req.artifact.path, path26.join(packageDir, path26.basename(req.artifact.path)));
14953
15016
  const { title, authors } = req.project;
14954
15017
  const sheet = [
14955
15018
  `# ${title || "Untitled"}`,
14956
15019
  "",
14957
15020
  `- **Authors:** ${authors.length ? authors.join(", ") : "(not set)"}`,
14958
- `- **File:** ${path25.basename(req.artifact.path)}`,
15021
+ `- **File:** ${path26.basename(req.artifact.path)}`,
14959
15022
  ...listingLines,
14960
15023
  "",
14961
15024
  "Copy these details into the platform's listing form when uploading.",
14962
15025
  ""
14963
15026
  ].join(`
14964
15027
  `);
14965
- await writeFile14(path25.join(packageDir, "LISTING.md"), sheet, "utf8");
15028
+ await writeFile14(path26.join(packageDir, "LISTING.md"), sheet, "utf8");
14966
15029
  return packageDir;
14967
15030
  }
14968
15031
 
@@ -15025,9 +15088,9 @@ var drivethrurpgProvider = {
15025
15088
  };
15026
15089
 
15027
15090
  // src/lib/publish/providers/gdrive.ts
15028
- import { mkdtemp as mkdtemp4, readFile as readFile33, readdir as readdir9, rm as rm9, stat as stat9, writeFile as writeFile15 } from "node:fs/promises";
15091
+ import { mkdtemp as mkdtemp4, readFile as readFile33, readdir as readdir10, rm as rm10, stat as stat9, writeFile as writeFile15 } from "node:fs/promises";
15029
15092
  import { tmpdir as tmpdir4 } from "node:os";
15030
- import path26 from "node:path";
15093
+ import path27 from "node:path";
15031
15094
  import { Zip, ZipDeflate } from "fflate";
15032
15095
 
15033
15096
  // src/lib/publish/google-drive.ts
@@ -15410,26 +15473,26 @@ function zipEntriesNonBlocking(entries, opts) {
15410
15473
  });
15411
15474
  }
15412
15475
  async function collectZipEntries(root, dir, out, onWarn) {
15413
- const entries = await readdir9(dir, { withFileTypes: true });
15476
+ const entries = await readdir10(dir, { withFileTypes: true });
15414
15477
  for (const entry of entries) {
15415
- const full = path26.join(dir, entry.name);
15478
+ const full = path27.join(dir, entry.name);
15416
15479
  if (entry.isDirectory()) {
15417
15480
  await collectZipEntries(root, full, out, onWarn);
15418
15481
  } else if (entry.isFile()) {
15419
- const rel = path26.relative(root, full).split(path26.sep).join("/");
15482
+ const rel = path27.relative(root, full).split(path27.sep).join("/");
15420
15483
  out[rel] = await readFile33(full);
15421
15484
  } else if (entry.isSymbolicLink()) {
15422
15485
  const resolved = await stat9(full).catch(() => null);
15423
15486
  if (resolved?.isFile()) {
15424
- const rel = path26.relative(root, full).split(path26.sep).join("/");
15487
+ const rel = path27.relative(root, full).split(path27.sep).join("/");
15425
15488
  out[rel] = await readFile33(full);
15426
15489
  } else if (resolved?.isDirectory()) {
15427
15490
  await collectZipEntries(root, full, out, onWarn);
15428
15491
  } else {
15429
- onWarn?.(`Skipped "${path26.relative(root, full)}" in the website export — it's a broken symlink.`);
15492
+ onWarn?.(`Skipped "${path27.relative(root, full)}" in the website export — it's a broken symlink.`);
15430
15493
  }
15431
15494
  } else {
15432
- onWarn?.(`Skipped "${path26.relative(root, full)}" in the website export — not a file, folder, or symlink.`);
15495
+ onWarn?.(`Skipped "${path27.relative(root, full)}" in the website export — not a file, folder, or symlink.`);
15433
15496
  }
15434
15497
  }
15435
15498
  }
@@ -15437,19 +15500,19 @@ async function zipHtmlExport(exportDir, title, onWarn, writeArchiveImpl = writeF
15437
15500
  const entries = {};
15438
15501
  await collectZipEntries(exportDir, exportDir, entries, onWarn);
15439
15502
  const fileName = `${bookSlug(title)}-website.zip`;
15440
- const tmpRoot = await mkdtemp4(path26.join(tmpdir4(), "gutterpress-gdrive-"));
15503
+ const tmpRoot = await mkdtemp4(path27.join(tmpdir4(), "gutterpress-gdrive-"));
15441
15504
  try {
15442
- const filePath = path26.join(tmpRoot, fileName);
15505
+ const filePath = path27.join(tmpRoot, fileName);
15443
15506
  const zipped = await zipEntriesNonBlocking(entries, { level: 6 });
15444
15507
  await writeArchiveImpl(filePath, zipped);
15445
15508
  return {
15446
15509
  filePath,
15447
15510
  fileName,
15448
15511
  mimeType: "application/zip",
15449
- cleanup: () => rm9(tmpRoot, { recursive: true, force: true })
15512
+ cleanup: () => rm10(tmpRoot, { recursive: true, force: true })
15450
15513
  };
15451
15514
  } catch (e) {
15452
- await rm9(tmpRoot, { recursive: true, force: true }).catch(() => {});
15515
+ await rm10(tmpRoot, { recursive: true, force: true }).catch(() => {});
15453
15516
  throw e;
15454
15517
  }
15455
15518
  }
@@ -15487,7 +15550,7 @@ var gdriveProvider = {
15487
15550
  const isHtml = req.artifact.format === "html";
15488
15551
  const source = isHtml ? await zipHtmlExport(req.artifact.path, req.project.title, (msg) => req.deps.onProgress?.(msg)) : {
15489
15552
  filePath: req.artifact.path,
15490
- fileName: path26.basename(req.artifact.path),
15553
+ fileName: path27.basename(req.artifact.path),
15491
15554
  mimeType: "application/pdf",
15492
15555
  cleanup: async () => {}
15493
15556
  };
@@ -15537,8 +15600,8 @@ var gdriveProvider = {
15537
15600
  };
15538
15601
 
15539
15602
  // src/lib/publish/butler.ts
15540
- import { chmod as chmod2, mkdir as mkdir18, stat as stat10, writeFile as writeFile16 } from "node:fs/promises";
15541
- import path27 from "node:path";
15603
+ import { chmod as chmod2, mkdir as mkdir19, stat as stat10, writeFile as writeFile16 } from "node:fs/promises";
15604
+ import path28 from "node:path";
15542
15605
  import { unzipSync as unzipSync2 } from "fflate";
15543
15606
  var BUTLER_DOWNLOAD_TIMEOUT_MS = 300000;
15544
15607
  function butlerBrothChannel(platform2 = process.platform, arch2 = process.arch) {
@@ -15575,8 +15638,8 @@ async function ensureButler(deps) {
15575
15638
  }
15576
15639
  if (await commandExists("butler", runCommand, deps.env))
15577
15640
  return "butler";
15578
- const cacheDir = path27.join(deps.configDir ?? defaultConfigDir(), "tools", "butler");
15579
- const cached = path27.join(cacheDir, butlerBinaryName());
15641
+ const cacheDir = path28.join(deps.configDir ?? defaultConfigDir(), "tools", "butler");
15642
+ const cached = path28.join(cacheDir, butlerBinaryName());
15580
15643
  if (await fileExists2(cached))
15581
15644
  return cached;
15582
15645
  const channel = butlerBrothChannel();
@@ -15598,14 +15661,14 @@ async function ensureButler(deps) {
15598
15661
  return new Uint8Array(await response.arrayBuffer());
15599
15662
  });
15600
15663
  const files = unzipSync2(archive);
15601
- await mkdir18(cacheDir, { recursive: true });
15664
+ await mkdir19(cacheDir, { recursive: true });
15602
15665
  let foundBinary = false;
15603
15666
  for (const [name, data] of Object.entries(files)) {
15604
15667
  if (name.endsWith("/"))
15605
15668
  continue;
15606
- const target = path27.join(cacheDir, path27.basename(name));
15669
+ const target = path28.join(cacheDir, path28.basename(name));
15607
15670
  await writeFile16(target, data);
15608
- if (path27.basename(name) === butlerBinaryName()) {
15671
+ if (path28.basename(name) === butlerBinaryName()) {
15609
15672
  await chmod2(target, 493).catch(() => {});
15610
15673
  foundBinary = true;
15611
15674
  }
@@ -15801,8 +15864,8 @@ var kdpProvider = {
15801
15864
  };
15802
15865
 
15803
15866
  // src/lib/publish/providers/local-folder.ts
15804
- import { cp as cp7, mkdir as mkdir19, stat as stat11 } from "node:fs/promises";
15805
- import path28 from "node:path";
15867
+ import { cp as cp8, mkdir as mkdir20, stat as stat11 } from "node:fs/promises";
15868
+ import path29 from "node:path";
15806
15869
  var LOCAL_PUBLISH_DEFAULT_DIR = "dist";
15807
15870
  var info7 = {
15808
15871
  id: "local",
@@ -15818,7 +15881,7 @@ var info7 = {
15818
15881
  };
15819
15882
  function localPublishDir(req) {
15820
15883
  const dir = typeof req.config.dir === "string" && req.config.dir.trim() ? req.config.dir.trim() : LOCAL_PUBLISH_DEFAULT_DIR;
15821
- return path28.resolve(req.project.projectDir, dir);
15884
+ return path29.resolve(req.project.projectDir, dir);
15822
15885
  }
15823
15886
  var localFolderProvider = {
15824
15887
  info: info7,
@@ -15839,10 +15902,10 @@ var localFolderProvider = {
15839
15902
  },
15840
15903
  async upload(req) {
15841
15904
  const dir = localPublishDir(req);
15842
- await mkdir19(dir, { recursive: true });
15843
- const dest = req.artifact.format === "html" ? dir : path28.join(dir, path28.basename(req.artifact.path));
15844
- if (path28.resolve(dest) !== path28.resolve(req.artifact.path)) {
15845
- await cp7(req.artifact.path, dest, { recursive: true });
15905
+ await mkdir20(dir, { recursive: true });
15906
+ const dest = req.artifact.format === "html" ? dir : path29.join(dir, path29.basename(req.artifact.path));
15907
+ if (path29.resolve(dest) !== path29.resolve(req.artifact.path)) {
15908
+ await cp8(req.artifact.path, dest, { recursive: true });
15846
15909
  }
15847
15910
  return { kind: "published", detail: `Saved to ${dest}` };
15848
15911
  }
@@ -16103,9 +16166,9 @@ async function resolvePublishRequest(options, deps) {
16103
16166
  const effectiveDeps = effectiveAccount ? { ...deps, credentialAccount: effectiveAccount } : deps;
16104
16167
  const outDir = resolveOutputDir(manifestDir, config.title);
16105
16168
  const effectiveFormat = resolvePublishFormat(provider.info, providerConfig);
16106
- const defaultArtifact = effectiveFormat === "pdf" ? path29.join(outDir, artifactName(config.title, "pdf")) : outDir;
16169
+ const defaultArtifact = effectiveFormat === "pdf" ? path30.join(outDir, artifactName(config.title, "pdf")) : outDir;
16107
16170
  const artifact = {
16108
- path: options.artifactPath ? path29.resolve(options.projectDir, options.artifactPath) : defaultArtifact,
16171
+ path: options.artifactPath ? path30.resolve(options.projectDir, options.artifactPath) : defaultArtifact,
16109
16172
  format: effectiveFormat
16110
16173
  };
16111
16174
  return {
@@ -16169,7 +16232,7 @@ async function artifactIssues(artifact) {
16169
16232
  var BUILD_FINGERPRINT_FILENAME = "build-fingerprint.json";
16170
16233
  async function htmlDirIssues(dir) {
16171
16234
  const issues = [];
16172
- const isThere = async (rel) => stat12(path29.join(dir, rel)).then(() => true, () => false);
16235
+ const isThere = async (rel) => stat12(path30.join(dir, rel)).then(() => true, () => false);
16173
16236
  if (!await isThere(BOOK_HTML)) {
16174
16237
  issues.push({
16175
16238
  severity: "error",
@@ -16177,7 +16240,7 @@ async function htmlDirIssues(dir) {
16177
16240
  message: `${dir} has no ${BOOK_HTML} — it isn't an HTML export. ${HTML_HINT}`
16178
16241
  });
16179
16242
  }
16180
- const entries = await readdir10(dir).catch(() => []);
16243
+ const entries = await readdir11(dir).catch(() => []);
16181
16244
  const extras = entries.filter((name) => name.toLowerCase().endsWith(".pdf") || name === BUILD_FINGERPRINT_FILENAME);
16182
16245
  if (extras.length > 0) {
16183
16246
  issues.push({
@@ -16288,13 +16351,13 @@ async function disconnectPublishCredential(key, deps, options = {}) {
16288
16351
  }
16289
16352
  }
16290
16353
  // src/lib/publish/selections.ts
16291
- import { chmod as chmod3, mkdir as mkdir20, readFile as readFile34, writeFile as writeFile17 } from "node:fs/promises";
16292
- import path30 from "node:path";
16354
+ import { chmod as chmod3, mkdir as mkdir21, readFile as readFile34, writeFile as writeFile17 } from "node:fs/promises";
16355
+ import path31 from "node:path";
16293
16356
  class PublishSelectionsStore {
16294
16357
  filePath;
16295
16358
  queue = Promise.resolve();
16296
16359
  constructor(filePath) {
16297
- this.filePath = filePath ?? path30.join(defaultConfigDir(), "publish-selections.json");
16360
+ this.filePath = filePath ?? path31.join(defaultConfigDir(), "publish-selections.json");
16298
16361
  }
16299
16362
  async read() {
16300
16363
  try {
@@ -16311,7 +16374,7 @@ class PublishSelectionsStore {
16311
16374
  return { version: 1, global: {}, projects: {} };
16312
16375
  }
16313
16376
  async write(data) {
16314
- await mkdir20(path30.dirname(this.filePath), { recursive: true });
16377
+ await mkdir21(path31.dirname(this.filePath), { recursive: true });
16315
16378
  await writeFile17(this.filePath, JSON.stringify(data, null, 2), {
16316
16379
  encoding: "utf8",
16317
16380
  mode: 384
@@ -16414,4 +16477,4 @@ async function setPublishProviderConfig(projectDir, providerId, values) {
16414
16477
  await writeManifestDoc(file, doc);
16415
16478
  return settingsFromDoc(doc);
16416
16479
  }
16417
- 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, loadPluginsWithCss, getChecks, getCheckById, resolveCheckSelectors, formatReport, ruleRemoteUrls, ruleRiskyProps, ruleSyntax, rulePageContainment, 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, 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, listPublishProviders, publishProviderFor, resolvePublishFormat, resolvePublishRequest, runPublish, connectPublishProvider, disconnectPublishCredential, PublishSelectionsStore, readPublishSettings, setPublishProviderConfig };
16480
+ 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, loadPluginsWithCss, getChecks, getCheckById, resolveCheckSelectors, formatReport, ruleRemoteUrls, ruleRiskyProps, ruleSyntax, rulePageContainment, 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, 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 };
package/dist/index.js CHANGED
@@ -131,6 +131,7 @@ import {
131
131
  saveSnippet,
132
132
  scaffoldExtension,
133
133
  scaffoldProject,
134
+ scorchedEarth,
134
135
  searchNpmExtensions,
135
136
  setActiveStyles,
136
137
  setExtensionEnabled,
@@ -143,7 +144,7 @@ import {
143
144
  syncProject,
144
145
  testRemoteAccess,
145
146
  validateProjectExtensions
146
- } from "./index-27xa2tfd.js";
147
+ } from "./index-6gvecewt.js";
147
148
  import {
148
149
  BUILD_DIAGNOSTIC_CODES
149
150
  } from "./index-kqftehgy.js";
@@ -268,6 +269,7 @@ export {
268
269
  setExtensionEnabled,
269
270
  setActiveStyles,
270
271
  searchNpmExtensions,
272
+ scorchedEarth,
271
273
  scaffoldProject,
272
274
  scaffoldExtension,
273
275
  saveSnippet,
@@ -0,0 +1,14 @@
1
+ import type { SyncProjectOptions } from "./sync-types.ts";
2
+ export interface ScorchedEarthOptions extends Pick<SyncProjectOptions, "projectDir" | "credential" | "tokenStore" | "logFile" | "httpClient"> {
3
+ /** Where the full copy of the folder goes — OUTSIDE the folder. Kept indefinitely. */
4
+ backupDir: string;
5
+ }
6
+ export interface ScorchedEarthResult {
7
+ /** The folder that was reset (the repo root of `projectDir`). */
8
+ dir: string;
9
+ /** Where the full copy of the folder (old `.git` included) was kept. */
10
+ backupDir: string;
11
+ /** The branch the fresh copy has checked out. */
12
+ branch?: string;
13
+ }
14
+ export declare function scorchedEarth(options: ScorchedEarthOptions): Promise<ScorchedEarthResult>;
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  MANIFEST_FILENAMES,
3
3
  runLint
4
- } from "./cli-edn2tver.js";
4
+ } from "./cli-e5t9zmkr.js";
5
5
  import {
6
6
  log
7
- } from "./cli-nc752ryp.js";
7
+ } from "./cli-9hbkm31q.js";
8
8
  import {
9
9
  UsageError,
10
10
  rejectExtraPositionals,
11
11
  rejectUnknownFlags
12
- } from "./cli-ervhbr00.js";
12
+ } from "./cli-d3wvk0ys.js";
13
13
  import"./cli-d8rdk1y7.js";
14
14
  import"./cli-c41yr7he.js";
15
15
  import {
@@ -7,15 +7,15 @@ import {
7
7
  TARGET_IDS,
8
8
  scaffoldExtension,
9
9
  scaffoldProject
10
- } from "./cli-edn2tver.js";
10
+ } from "./cli-e5t9zmkr.js";
11
11
  import {
12
12
  resolveGhostscript
13
- } from "./cli-nc752ryp.js";
13
+ } from "./cli-9hbkm31q.js";
14
14
  import {
15
15
  UsageError,
16
16
  rejectExtraPositionals,
17
17
  rejectUnknownFlags
18
- } from "./cli-ervhbr00.js";
18
+ } from "./cli-d3wvk0ys.js";
19
19
  import"./cli-d8rdk1y7.js";
20
20
  import {
21
21
  isToolAvailable
@@ -2,15 +2,15 @@ import {
2
2
  executeValidation,
3
3
  publishTargetFor,
4
4
  reportMissingTools
5
- } from "./cli-edn2tver.js";
5
+ } from "./cli-e5t9zmkr.js";
6
6
  import {
7
7
  log
8
- } from "./cli-nc752ryp.js";
8
+ } from "./cli-9hbkm31q.js";
9
9
  import {
10
10
  UsageError,
11
11
  rejectExtraPositionals,
12
12
  rejectUnknownFlags
13
- } from "./cli-ervhbr00.js";
13
+ } from "./cli-d3wvk0ys.js";
14
14
  import"./cli-d8rdk1y7.js";
15
15
  import"./cli-c41yr7he.js";
16
16
  import {
@@ -6,10 +6,10 @@ import {
6
6
  runBuild,
7
7
  splitOutPath,
8
8
  startPreviewServer
9
- } from "./cli-edn2tver.js";
9
+ } from "./cli-e5t9zmkr.js";
10
10
  import {
11
11
  log
12
- } from "./cli-nc752ryp.js";
12
+ } from "./cli-9hbkm31q.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-ervhbr00.js";
20
+ } from "./cli-d3wvk0ys.js";
21
21
  import"./cli-d8rdk1y7.js";
22
22
  import"./cli-c41yr7he.js";
23
23
  import {
@@ -11,16 +11,16 @@ import {
11
11
  publishProviderFor,
12
12
  resolvePublishFormat,
13
13
  runPublish
14
- } from "./cli-edn2tver.js";
14
+ } from "./cli-e5t9zmkr.js";
15
15
  import {
16
16
  FileTokenStore,
17
17
  log
18
- } from "./cli-nc752ryp.js";
18
+ } from "./cli-9hbkm31q.js";
19
19
  import {
20
20
  UsageError,
21
21
  rejectExtraPositionals,
22
22
  rejectUnknownFlags
23
- } from "./cli-ervhbr00.js";
23
+ } from "./cli-d3wvk0ys.js";
24
24
  import"./cli-d8rdk1y7.js";
25
25
  import"./cli-c41yr7he.js";
26
26
  import {
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-edn2tver.js";
3
+ } from "./cli-e5t9zmkr.js";
4
4
  import {
5
5
  log
6
- } from "./cli-nc752ryp.js";
6
+ } from "./cli-9hbkm31q.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-ervhbr00.js";
11
+ } from "./cli-d3wvk0ys.js";
12
12
  import"./cli-d8rdk1y7.js";
13
13
  import"./cli-c41yr7he.js";
14
14
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.11.9-alpha.3",
3
+ "version": "0.11.10-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",