gutterpress 0.0.0 → 0.9.0-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/README.md +21 -16
- package/dist/api/index.d.ts +6 -2
- package/dist/api/index.js +15 -3
- package/dist/{audit-1jrwwacz.js → audit-k16v3n98.js} +5 -5
- package/dist/{build-5s92kgpc.js → build-8tqr4gbb.js} +5 -5
- package/dist/checks/types.d.ts +6 -0
- package/dist/{cli-hvqjs342.js → cli-rkqxbnkq.js} +2 -2
- package/dist/{cli-h7phg3ka.js → cli-v2dze8ja.js} +258 -258
- package/dist/{index-1tyj4bk3.js → cli-wchtvxvw.js} +4 -1
- package/dist/{cli-7ykx7pp0.js → cli-yp0d2hp8.js} +611 -259
- package/dist/{cli-5bxx0c4y.js → cli-yzrh708h.js} +2 -2
- package/dist/cli.js +15 -15
- package/dist/{doctor-25zjt8dz.js → doctor-57czxy3q.js} +2 -2
- package/dist/{index-3h3fef7r.js → index-m3pa4wyf.js} +826 -335
- package/dist/{cli-1tyj4bk3.js → index-wchtvxvw.js} +4 -1
- package/dist/{index-5bxx0c4y.js → index-yzrh708h.js} +2 -2
- package/dist/index.js +15 -3
- package/dist/lib/asset-inline.d.ts +19 -0
- package/dist/lib/build-error.d.ts +0 -1
- package/dist/lib/build-fingerprint.d.ts +14 -0
- package/dist/lib/build-runner.d.ts +21 -1
- package/dist/lib/ghostscript.d.ts +0 -9
- package/dist/lib/manifest-config.d.ts +7 -0
- package/dist/lib/manifest.d.ts +8 -0
- package/dist/lib/markdown/index.d.ts +0 -1
- package/dist/lib/npm-plugin-installer.d.ts +1 -1
- package/dist/lib/output-paths.d.ts +0 -1
- package/dist/lib/pagination.d.ts +0 -20
- package/dist/lib/pdf-inspect.d.ts +2 -2
- package/dist/lib/pdf-parse.d.ts +2 -1
- package/dist/lib/plugin-manager.d.ts +0 -2
- package/dist/lib/presets.d.ts +36 -7
- package/dist/lib/project-scaffold.d.ts +39 -2
- package/dist/lib/project-source.d.ts +11 -9
- package/dist/lib/project-templates.d.ts +45 -7
- package/dist/lib/publish/providers/azure-swa.d.ts +0 -1
- package/dist/lib/publish/providers/itch.d.ts +0 -1
- package/dist/lib/publish/providers/shopify.d.ts +0 -1
- package/dist/lib/remote-auth/github-repos.d.ts +0 -2
- package/dist/lib/remote-auth/recovery/dispatch.d.ts +0 -5
- package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +3 -2
- package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +0 -8
- package/dist/lib/remote-auth/sync.d.ts +2 -10
- package/dist/lib/remote-auth/test-access.d.ts +0 -2
- package/dist/lib/remote-auth/test-support/git-http-server.d.ts +0 -37
- package/dist/lib/source-provider.d.ts +0 -14
- package/dist/lib/static-serve.d.ts +39 -0
- package/dist/lib/style-resolver.d.ts +10 -1
- package/dist/lib/targets.d.ts +84 -0
- package/dist/lib/theme-import.d.ts +0 -2
- package/dist/lib/theme-manager.d.ts +1 -1
- package/dist/lib/validation-exec.d.ts +4 -3
- package/dist/{lint-f63nxjfj.js → lint-4sq0dvf6.js} +5 -5
- package/dist/{manifest.schema-rn1dpdpn.json → manifest.schema-z61rzw44.json} +12 -6
- package/dist/new-f2nmyr5b.js +185 -0
- package/dist/{plugin-wf2cbmwc.js → plugin-xskq3dtx.js} +5 -5
- package/dist/{preflight-tg4mpz1h.js → preflight-epcffags.js} +24 -29
- package/dist/preview/file-watcher.d.ts +9 -22
- package/dist/preview/server-context.d.ts +22 -0
- package/dist/{preview-h2bwbb2x.js → preview-xf5dktz2.js} +5 -5
- package/dist/{project-source-0tg0r6vm.js → project-source-p0gn1wd5.js} +3 -3
- package/dist/{publish-ztaet53r.js → publish-97vdwq31.js} +5 -5
- package/dist/{repair-jkp4n3j8.js → repair-cz4z4hkg.js} +5 -5
- package/dist/schema/manifest.types.d.ts +14 -3
- package/dist/{source-provider-hp96b5jf.js → source-provider-c1rjm2c0.js} +2 -8
- package/dist/types.d.ts +0 -1
- package/dist/{validate-k2drs19j.js → validate-swzejnd8.js} +8 -8
- package/package.json +2 -2
- package/dist/chapter-01-jj8ftn4c.md +0 -29
- package/dist/lib/validation-profile.d.ts +0 -18
- package/dist/manifest-ryyg71nf.yaml +0 -9
- package/dist/new-7b08a42h.js +0 -105
- package/dist/theme-0yzvthe8.css +0 -65
- package/dist/theme-6a2fngc8.json +0 -6
|
@@ -20,13 +20,13 @@ import {
|
|
|
20
20
|
stampCreator,
|
|
21
21
|
stripAnnotations,
|
|
22
22
|
warn
|
|
23
|
-
} from "./cli-
|
|
23
|
+
} from "./cli-v2dze8ja.js";
|
|
24
24
|
import {
|
|
25
25
|
BuildError,
|
|
26
26
|
DEBOUNCE,
|
|
27
27
|
UsageError,
|
|
28
28
|
resolvePort
|
|
29
|
-
} from "./cli-
|
|
29
|
+
} from "./cli-rkqxbnkq.js";
|
|
30
30
|
import {
|
|
31
31
|
gitDirFor,
|
|
32
32
|
gitScopeFor,
|
|
@@ -40,11 +40,11 @@ import {
|
|
|
40
40
|
snapshotWorkingTreeUnlocked,
|
|
41
41
|
stageChanges,
|
|
42
42
|
withRepoLock
|
|
43
|
-
} from "./cli-
|
|
43
|
+
} from "./cli-yzrh708h.js";
|
|
44
44
|
import {
|
|
45
45
|
detectProjectSource,
|
|
46
46
|
syncRemoteFor
|
|
47
|
-
} from "./cli-
|
|
47
|
+
} from "./cli-wchtvxvw.js";
|
|
48
48
|
import {
|
|
49
49
|
defaultGitHttp
|
|
50
50
|
} from "./cli-yja077f6.js";
|
|
@@ -52,14 +52,10 @@ import {
|
|
|
52
52
|
__require
|
|
53
53
|
} from "./cli-37x76zdn.js";
|
|
54
54
|
|
|
55
|
-
// src/lib/manifest.ts
|
|
56
|
-
import { readFile } from "node:fs/promises";
|
|
57
|
-
import { existsSync, statSync } from "node:fs";
|
|
58
|
-
import { resolve, dirname } from "node:path";
|
|
59
|
-
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
60
|
-
|
|
61
55
|
// src/lib/presets.ts
|
|
56
|
+
var PRESET_IDS = ["dtrpg", "book", "custom"];
|
|
62
57
|
var DTRPG_PRESET = {
|
|
58
|
+
defaultTargets: ["dtrpg"],
|
|
63
59
|
plugins: [],
|
|
64
60
|
source: {
|
|
65
61
|
files: null
|
|
@@ -131,6 +127,7 @@ var DTRPG_PRESET = {
|
|
|
131
127
|
}
|
|
132
128
|
};
|
|
133
129
|
var BOOK_PRESET = {
|
|
130
|
+
defaultTargets: [],
|
|
134
131
|
plugins: [],
|
|
135
132
|
source: {
|
|
136
133
|
files: null
|
|
@@ -195,9 +192,15 @@ var BOOK_PRESET = {
|
|
|
195
192
|
}
|
|
196
193
|
}
|
|
197
194
|
};
|
|
195
|
+
var CUSTOM_PRESET = {
|
|
196
|
+
...BOOK_PRESET,
|
|
197
|
+
page: null,
|
|
198
|
+
defaultTargets: []
|
|
199
|
+
};
|
|
198
200
|
var PRESETS = {
|
|
199
201
|
dtrpg: DTRPG_PRESET,
|
|
200
|
-
book: BOOK_PRESET
|
|
202
|
+
book: BOOK_PRESET,
|
|
203
|
+
custom: CUSTOM_PRESET
|
|
201
204
|
};
|
|
202
205
|
var warnedIds = new Set;
|
|
203
206
|
function warnOnce(id, message, sink = defaultWarnSink) {
|
|
@@ -211,7 +214,7 @@ function defaultWarnSink(message) {
|
|
|
211
214
|
}
|
|
212
215
|
function resolvePreset(presetName) {
|
|
213
216
|
if (presetName === undefined) {
|
|
214
|
-
warnOnce("no-preset-set", '[gutterpress] No `preset`
|
|
217
|
+
warnOnce("no-preset-set", '[gutterpress] No `preset` in manifest.yaml — using "dtrpg" ' + "(DriveThruRPG print-ready defaults). Set `preset: dtrpg`, `book`, " + "or `custom` to choose explicitly.");
|
|
215
218
|
return DTRPG_PRESET;
|
|
216
219
|
}
|
|
217
220
|
const preset = PRESETS[presetName];
|
|
@@ -221,7 +224,126 @@ function resolvePreset(presetName) {
|
|
|
221
224
|
return preset;
|
|
222
225
|
}
|
|
223
226
|
|
|
227
|
+
// src/lib/targets.ts
|
|
228
|
+
var DTRPG_TARGET = {
|
|
229
|
+
id: "dtrpg",
|
|
230
|
+
label: "DriveThruRPG",
|
|
231
|
+
overlay: {
|
|
232
|
+
pdfx: { flavor: DTRPG_PRESET.pdfx.flavor },
|
|
233
|
+
ink: {
|
|
234
|
+
maxTac: DTRPG_PRESET.ink.maxTac,
|
|
235
|
+
tacTolerance: DTRPG_PRESET.ink.tacTolerance
|
|
236
|
+
},
|
|
237
|
+
validate: {
|
|
238
|
+
checks: {
|
|
239
|
+
"pdf.structure.qpdf": { enabled: true, severity: "error" },
|
|
240
|
+
"pdf.print.pdfx-markers": { enabled: true, severity: "error" },
|
|
241
|
+
"pdf.print.pdfx-metadata": { enabled: true, severity: "error" },
|
|
242
|
+
"pdf.print.embedded-fonts": { enabled: true, severity: "error" }
|
|
243
|
+
},
|
|
244
|
+
assets: {
|
|
245
|
+
allowedColorSpaces: [...DTRPG_PRESET.validate.assets.allowedColorSpaces]
|
|
246
|
+
},
|
|
247
|
+
pdf: {
|
|
248
|
+
forbidTransparency: DTRPG_PRESET.validate.pdf.forbidTransparency,
|
|
249
|
+
minImageResolution: DTRPG_PRESET.validate.pdf.minImageResolution
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
requiredChecks: [
|
|
254
|
+
"pdf.structure.qpdf",
|
|
255
|
+
"pdf.print.pdfx-markers",
|
|
256
|
+
"pdf.print.pdfx-metadata",
|
|
257
|
+
"pdf.print.embedded-fonts"
|
|
258
|
+
],
|
|
259
|
+
requiredTools: ["qpdf", "gs"]
|
|
260
|
+
};
|
|
261
|
+
var ITCH_TARGET = {
|
|
262
|
+
id: "itch",
|
|
263
|
+
label: "itch.io",
|
|
264
|
+
overlay: {
|
|
265
|
+
validate: {
|
|
266
|
+
checks: {
|
|
267
|
+
"pdf.structure.qpdf": { enabled: true, severity: "error" },
|
|
268
|
+
"pdf.print.embedded-fonts": { enabled: true, severity: "error" },
|
|
269
|
+
"pdf.print.pdfx-markers": false,
|
|
270
|
+
"pdf.print.pdfx-metadata": false,
|
|
271
|
+
"pdf.print.ink-coverage": false,
|
|
272
|
+
"asset.image.tac-raster": false
|
|
273
|
+
},
|
|
274
|
+
assets: {
|
|
275
|
+
allowedColorSpaces: ["RGB", "CMYK", "Grayscale"],
|
|
276
|
+
allowAlpha: true
|
|
277
|
+
},
|
|
278
|
+
pdf: {
|
|
279
|
+
forbidTransparency: false,
|
|
280
|
+
requireBleed: false
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
requiredChecks: ["pdf.structure.qpdf", "pdf.print.embedded-fonts"],
|
|
285
|
+
requiredTools: []
|
|
286
|
+
};
|
|
287
|
+
var TARGETS = {
|
|
288
|
+
dtrpg: DTRPG_TARGET,
|
|
289
|
+
itch: ITCH_TARGET
|
|
290
|
+
};
|
|
291
|
+
var TARGET_IDS = Object.keys(TARGETS);
|
|
292
|
+
function publishTargetFor(id) {
|
|
293
|
+
const target = TARGETS[id];
|
|
294
|
+
if (!target) {
|
|
295
|
+
throw new UsageError(`Unknown publish target "${id}". Known targets: ${TARGET_IDS.join(", ")}.`);
|
|
296
|
+
}
|
|
297
|
+
return target;
|
|
298
|
+
}
|
|
299
|
+
function resolveTargets(requested, fallback) {
|
|
300
|
+
const ids = requested ?? fallback;
|
|
301
|
+
const seen = new Set;
|
|
302
|
+
const out = [];
|
|
303
|
+
for (const id of ids) {
|
|
304
|
+
publishTargetFor(id);
|
|
305
|
+
if (!seen.has(id)) {
|
|
306
|
+
seen.add(id);
|
|
307
|
+
out.push(id);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return out;
|
|
311
|
+
}
|
|
312
|
+
function overlayPreset(preset, target) {
|
|
313
|
+
const o = target.overlay;
|
|
314
|
+
return {
|
|
315
|
+
...preset,
|
|
316
|
+
pdfx: { ...preset.pdfx, ...o.pdfx },
|
|
317
|
+
ink: { ...preset.ink, ...o.ink },
|
|
318
|
+
validate: {
|
|
319
|
+
...preset.validate,
|
|
320
|
+
checks: { ...preset.validate.checks, ...o.validate?.checks },
|
|
321
|
+
assets: { ...preset.validate.assets, ...o.validate?.assets },
|
|
322
|
+
pdf: { ...preset.validate.pdf, ...o.validate?.pdf }
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
var DEFAULT_STRICT_PDF_CHECKS = [
|
|
327
|
+
"pdf.structure.qpdf",
|
|
328
|
+
"pdf.print.pdfx-markers",
|
|
329
|
+
"pdf.print.pdfx-metadata",
|
|
330
|
+
"pdf.print.embedded-fonts"
|
|
331
|
+
];
|
|
332
|
+
function applyDefaultPdfStrictChecks(config) {
|
|
333
|
+
const next = structuredClone(config);
|
|
334
|
+
for (const checkId of DEFAULT_STRICT_PDF_CHECKS) {
|
|
335
|
+
if (next.validate.checks[checkId] === undefined) {
|
|
336
|
+
next.validate.checks[checkId] = { enabled: true, severity: "error" };
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return next;
|
|
340
|
+
}
|
|
341
|
+
|
|
224
342
|
// src/lib/manifest.ts
|
|
343
|
+
import { readFile } from "node:fs/promises";
|
|
344
|
+
import { existsSync, statSync } from "node:fs";
|
|
345
|
+
import { resolve, dirname } from "node:path";
|
|
346
|
+
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
225
347
|
var MANIFEST_FILENAMES = [
|
|
226
348
|
"manifest.yaml"
|
|
227
349
|
];
|
|
@@ -298,8 +420,34 @@ function mergeShape(cli, manifest, preset) {
|
|
|
298
420
|
return out;
|
|
299
421
|
}
|
|
300
422
|
function resolveConfig(cliOverrides, manifest) {
|
|
423
|
+
const presetName = cliOverrides.preset ?? manifest.preset;
|
|
424
|
+
return resolveWithPreset(cliOverrides, manifest, resolvePreset(presetName));
|
|
425
|
+
}
|
|
426
|
+
function resolveConfigForTarget(cliOverrides, manifest, targetId) {
|
|
301
427
|
const presetName = cliOverrides.preset ?? manifest.preset;
|
|
302
428
|
const preset = resolvePreset(presetName);
|
|
429
|
+
return resolveWithPreset(cliOverrides, manifest, overlayPreset(preset, publishTargetFor(targetId)));
|
|
430
|
+
}
|
|
431
|
+
function resolveCustomPage(c, m) {
|
|
432
|
+
const width = c.page?.width ?? m.page?.width;
|
|
433
|
+
const height = c.page?.height ?? m.page?.height;
|
|
434
|
+
const missing = [
|
|
435
|
+
width === undefined ? "page.width" : null,
|
|
436
|
+
height === undefined ? "page.height" : null
|
|
437
|
+
].filter((f) => f !== null);
|
|
438
|
+
if (missing.length > 0) {
|
|
439
|
+
throw new UsageError(`preset: custom requires ${missing.join(" and ")} in manifest.yaml ` + `(points; 72pt = 1in). Example for US Letter:
|
|
440
|
+
` + ` page:
|
|
441
|
+
width: 612
|
|
442
|
+
height: 792`);
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
width,
|
|
446
|
+
height,
|
|
447
|
+
tolerance: c.page?.tolerance ?? m.page?.tolerance ?? 0.5
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
303
451
|
const m = manifest;
|
|
304
452
|
const c = cliOverrides;
|
|
305
453
|
const legacy = m;
|
|
@@ -321,9 +469,10 @@ function resolveConfig(cliOverrides, manifest) {
|
|
|
321
469
|
authors: c.authors ?? m.authors ?? [],
|
|
322
470
|
styles: c.styles ?? m.styles,
|
|
323
471
|
plugins,
|
|
472
|
+
targets: resolveTargets(c.targets ?? m.targets, preset.defaultTargets),
|
|
324
473
|
source: mergeShape(c.source, m.source, preset.source),
|
|
325
474
|
pdfx: mergeShape(c.pdfx, m.pdfx, preset.pdfx),
|
|
326
|
-
page: mergeShape(c.page, m.page, preset.page),
|
|
475
|
+
page: preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m),
|
|
327
476
|
ink: mergeShape(c.ink, m.ink, preset.ink),
|
|
328
477
|
lint: mergeShape(c.lint, m.lint, preset.lint),
|
|
329
478
|
validate: {
|
|
@@ -2575,6 +2724,22 @@ function decodeRef(ref) {
|
|
|
2575
2724
|
function toPosix(p) {
|
|
2576
2725
|
return p.split(path3.sep).join("/");
|
|
2577
2726
|
}
|
|
2727
|
+
function escapesProjectRoot(projectDir, absPath) {
|
|
2728
|
+
const rel = path3.relative(projectDir, absPath);
|
|
2729
|
+
return rel === ".." || rel.startsWith(`..${path3.sep}`) || path3.isAbsolute(rel);
|
|
2730
|
+
}
|
|
2731
|
+
function proseImageRefError(ref, projectDir) {
|
|
2732
|
+
const cleaned = stripUrlSuffix(decodeRef(ref));
|
|
2733
|
+
if (path3.isAbsolute(cleaned)) {
|
|
2734
|
+
return `Image reference must be relative to the project: ${ref}
|
|
2735
|
+
` + ` Copy the file into your project folder and reference it from there.`;
|
|
2736
|
+
}
|
|
2737
|
+
if (escapesProjectRoot(projectDir, path3.resolve(projectDir, cleaned))) {
|
|
2738
|
+
return `Image reference points outside the project: ${ref}
|
|
2739
|
+
` + ` Copy the file into your project folder and reference it from there.`;
|
|
2740
|
+
}
|
|
2741
|
+
return null;
|
|
2742
|
+
}
|
|
2578
2743
|
function mimeFor(ext) {
|
|
2579
2744
|
return MIME_BY_EXT[ext] ?? "application/octet-stream";
|
|
2580
2745
|
}
|
|
@@ -2677,7 +2842,7 @@ async function inlineOne(cssPath, projectDir, copies, warnings, seen) {
|
|
|
2677
2842
|
return dataUri(bytes, ext);
|
|
2678
2843
|
}
|
|
2679
2844
|
const projectRel = path3.relative(projectDir, absAsset);
|
|
2680
|
-
const dest = projectRel && !
|
|
2845
|
+
const dest = projectRel && !escapesProjectRoot(projectDir, absAsset) ? toPosix(projectRel) : `${HASHED_ASSET_DIR}/${contentHash(bytes)}${ext}`;
|
|
2681
2846
|
copies.set(dest, { from: absAsset, to: dest });
|
|
2682
2847
|
return dest;
|
|
2683
2848
|
});
|
|
@@ -2768,19 +2933,14 @@ async function planImageCopies(projectDir, refs) {
|
|
|
2768
2933
|
for (const ref of refs) {
|
|
2769
2934
|
if (isNonFileUrl(ref))
|
|
2770
2935
|
continue;
|
|
2771
|
-
const
|
|
2772
|
-
if (
|
|
2773
|
-
errors.push(
|
|
2774
|
-
` + ` Copy the file into your project folder and reference it from there.`);
|
|
2936
|
+
const refError = proseImageRefError(ref, projectDir);
|
|
2937
|
+
if (refError) {
|
|
2938
|
+
errors.push(refError);
|
|
2775
2939
|
continue;
|
|
2776
2940
|
}
|
|
2941
|
+
const cleaned = stripUrlSuffix(decodeRef(ref));
|
|
2777
2942
|
const abs = path3.resolve(projectDir, cleaned);
|
|
2778
2943
|
const rel = path3.relative(projectDir, abs);
|
|
2779
|
-
if (rel.startsWith("..")) {
|
|
2780
|
-
errors.push(`Image reference points outside the project: ${ref}
|
|
2781
|
-
` + ` Copy the file into your project folder and reference it from there.`);
|
|
2782
|
-
continue;
|
|
2783
|
-
}
|
|
2784
2944
|
const dest = toPosix(rel);
|
|
2785
2945
|
copies.set(dest, { from: abs, to: dest });
|
|
2786
2946
|
}
|
|
@@ -2814,6 +2974,16 @@ var check19 = {
|
|
|
2814
2974
|
if (inFence)
|
|
2815
2975
|
continue;
|
|
2816
2976
|
for (const { ref, kind } of extractLocalRefs(line)) {
|
|
2977
|
+
const escape = kind === "image" ? proseImageRefError(ref, ctx.inputDir) : null;
|
|
2978
|
+
if (escape) {
|
|
2979
|
+
results.push(finding(check19.id, {
|
|
2980
|
+
severity: "error",
|
|
2981
|
+
message: escape,
|
|
2982
|
+
file,
|
|
2983
|
+
line: i + 1
|
|
2984
|
+
}));
|
|
2985
|
+
continue;
|
|
2986
|
+
}
|
|
2817
2987
|
if (localRefExists(ref, kind, file, ctx.inputDir))
|
|
2818
2988
|
continue;
|
|
2819
2989
|
results.push(finding(check19.id, {
|
|
@@ -3796,7 +3966,7 @@ function reportMissingTools(result) {
|
|
|
3796
3966
|
|
|
3797
3967
|
// src/lib/validation-exec.ts
|
|
3798
3968
|
import { existsSync as existsSync7 } from "node:fs";
|
|
3799
|
-
import { join as join2, resolve as resolve6 } from "node:path";
|
|
3969
|
+
import { dirname as dirname3, join as join2, resolve as resolve6 } from "node:path";
|
|
3800
3970
|
|
|
3801
3971
|
// src/lib/output-paths.ts
|
|
3802
3972
|
import path4 from "node:path";
|
|
@@ -4523,19 +4693,19 @@ function formatReport(report, format = "text") {
|
|
|
4523
4693
|
}
|
|
4524
4694
|
function formatText(report) {
|
|
4525
4695
|
for (const r of report.infos) {
|
|
4526
|
-
const loc = formatLocation(r.file, r.line, r.column);
|
|
4696
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
4527
4697
|
log.info(`${loc}${r.message}`);
|
|
4528
4698
|
if (r.detail)
|
|
4529
4699
|
log.info(` ${r.detail}`);
|
|
4530
4700
|
}
|
|
4531
4701
|
for (const r of report.warnings) {
|
|
4532
|
-
const loc = formatLocation(r.file, r.line, r.column);
|
|
4702
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
4533
4703
|
log.warn(`${loc}${r.message}`);
|
|
4534
4704
|
if (r.detail)
|
|
4535
4705
|
log.warn(` ${r.detail}`);
|
|
4536
4706
|
}
|
|
4537
4707
|
for (const r of report.errors) {
|
|
4538
|
-
const loc = formatLocation(r.file, r.line, r.column);
|
|
4708
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
4539
4709
|
log.error(`${loc}${r.message}`);
|
|
4540
4710
|
if (r.detail)
|
|
4541
4711
|
log.error(` ${r.detail}`);
|
|
@@ -4549,6 +4719,9 @@ function formatText(report) {
|
|
|
4549
4719
|
log.success("VALIDATION PASSED");
|
|
4550
4720
|
}
|
|
4551
4721
|
}
|
|
4722
|
+
function targetPrefix(target) {
|
|
4723
|
+
return target ? `[${target}] ` : "";
|
|
4724
|
+
}
|
|
4552
4725
|
function formatJson(report) {
|
|
4553
4726
|
console.log(JSON.stringify({
|
|
4554
4727
|
results: report.results,
|
|
@@ -4650,58 +4823,46 @@ function emptyReport() {
|
|
|
4650
4823
|
};
|
|
4651
4824
|
}
|
|
4652
4825
|
|
|
4653
|
-
// src/lib/validation-
|
|
4654
|
-
var
|
|
4655
|
-
"
|
|
4656
|
-
"
|
|
4657
|
-
"
|
|
4658
|
-
"
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4826
|
+
// src/lib/validation-exec.ts
|
|
4827
|
+
var SHIPPED_ASSET_EXTS = new Set([
|
|
4828
|
+
".woff2",
|
|
4829
|
+
".woff",
|
|
4830
|
+
".ttf",
|
|
4831
|
+
".otf",
|
|
4832
|
+
".png",
|
|
4833
|
+
".jpg",
|
|
4834
|
+
".jpeg",
|
|
4835
|
+
".gif",
|
|
4836
|
+
".webp",
|
|
4837
|
+
".avif",
|
|
4838
|
+
".svg",
|
|
4839
|
+
".tif",
|
|
4840
|
+
".tiff"
|
|
4841
|
+
]);
|
|
4842
|
+
async function sharedAssetDirs(manifestDir, relStyles, inputDir) {
|
|
4843
|
+
let closure;
|
|
4844
|
+
try {
|
|
4845
|
+
closure = await collectStyleDependencies(manifestDir, relStyles);
|
|
4846
|
+
} catch {
|
|
4847
|
+
return [];
|
|
4668
4848
|
}
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
const
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
if (profile === "dtrpg") {
|
|
4679
|
-
next.pdfx.flavor = DTRPG_PRESET.pdfx.flavor;
|
|
4680
|
-
next.ink.maxTac = DTRPG_PRESET.ink.maxTac;
|
|
4681
|
-
next.ink.tacTolerance = DTRPG_PRESET.ink.tacTolerance;
|
|
4682
|
-
next.validate.pdf.forbidTransparency = DTRPG_PRESET.validate.pdf.forbidTransparency;
|
|
4683
|
-
next.validate.pdf.minImageResolution = DTRPG_PRESET.validate.pdf.minImageResolution;
|
|
4684
|
-
next.validate.assets.allowedColorSpaces = [
|
|
4685
|
-
...DTRPG_PRESET.validate.assets.allowedColorSpaces
|
|
4686
|
-
];
|
|
4687
|
-
enforceStrictPdfChecks(next, true);
|
|
4849
|
+
const projectRoot = resolve6(inputDir);
|
|
4850
|
+
const dirs = new Set;
|
|
4851
|
+
for (const file of closure) {
|
|
4852
|
+
const ext = file.slice(file.lastIndexOf(".")).toLowerCase();
|
|
4853
|
+
if (!SHIPPED_ASSET_EXTS.has(ext))
|
|
4854
|
+
continue;
|
|
4855
|
+
const dir = dirname3(resolve6(file));
|
|
4856
|
+
if (escapesProjectRoot(projectRoot, dir))
|
|
4857
|
+
dirs.add(dir);
|
|
4688
4858
|
}
|
|
4689
|
-
return
|
|
4859
|
+
return [...dirs];
|
|
4690
4860
|
}
|
|
4691
|
-
|
|
4692
|
-
// src/lib/validation-exec.ts
|
|
4693
4861
|
function parseCsv(value) {
|
|
4694
4862
|
if (!value)
|
|
4695
4863
|
return;
|
|
4696
4864
|
return value.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
4697
4865
|
}
|
|
4698
|
-
function parseProfile(raw) {
|
|
4699
|
-
if (!raw)
|
|
4700
|
-
return;
|
|
4701
|
-
if (raw === "dtrpg")
|
|
4702
|
-
return raw;
|
|
4703
|
-
throw new Error(`Unsupported profile: ${raw}. Supported profiles: dtrpg`);
|
|
4704
|
-
}
|
|
4705
4866
|
function resolvePhaseArg(raw) {
|
|
4706
4867
|
const normalized = raw.trim().toLowerCase();
|
|
4707
4868
|
if (normalized === "pre" || normalized === "pre-build")
|
|
@@ -4724,20 +4885,16 @@ function resolveCategoryArg(raw) {
|
|
|
4724
4885
|
}
|
|
4725
4886
|
return parsed;
|
|
4726
4887
|
}
|
|
4727
|
-
function
|
|
4728
|
-
if (!profile)
|
|
4729
|
-
return report;
|
|
4730
|
-
const required = profile === "dtrpg" ? DTRPG_STRICT_PDF_CHECKS : [];
|
|
4731
|
-
if (required.length === 0)
|
|
4732
|
-
return report;
|
|
4888
|
+
function withTargetRequiredCheckErrors(report, tools, target) {
|
|
4733
4889
|
const skippedSet = new Set(tools.skippedChecks);
|
|
4734
|
-
const missingRequired =
|
|
4890
|
+
const missingRequired = target.requiredChecks.filter((checkId) => skippedSet.has(checkId));
|
|
4735
4891
|
if (missingRequired.length === 0)
|
|
4736
4892
|
return report;
|
|
4737
4893
|
const syntheticErrors = missingRequired.map((checkId) => ({
|
|
4738
4894
|
checkId,
|
|
4895
|
+
target: target.id,
|
|
4739
4896
|
severity: "error",
|
|
4740
|
-
message: `
|
|
4897
|
+
message: `Target ${target.id} requires check ${checkId}, but it was skipped because required tools are not available.`
|
|
4741
4898
|
}));
|
|
4742
4899
|
const results = [...report.results, ...syntheticErrors];
|
|
4743
4900
|
const errors = [...report.errors, ...syntheticErrors];
|
|
@@ -4751,19 +4908,115 @@ function withProfileRequiredCheckErrors(report, tools, profile) {
|
|
|
4751
4908
|
}
|
|
4752
4909
|
};
|
|
4753
4910
|
}
|
|
4911
|
+
var TARGET_INDEPENDENT_CATEGORIES = ["source", "heuristic"];
|
|
4912
|
+
var TARGET_DEPENDENT_CATEGORIES = ["asset", "pdf"];
|
|
4913
|
+
function tagReport(report, targetId) {
|
|
4914
|
+
const tag = (r) => ({ ...r, target: targetId });
|
|
4915
|
+
return {
|
|
4916
|
+
results: report.results.map(tag),
|
|
4917
|
+
errors: report.errors.map(tag),
|
|
4918
|
+
warnings: report.warnings.map(tag),
|
|
4919
|
+
infos: report.infos.map(tag),
|
|
4920
|
+
passed: report.passed,
|
|
4921
|
+
summary: report.summary
|
|
4922
|
+
};
|
|
4923
|
+
}
|
|
4924
|
+
function mergeReports(reports) {
|
|
4925
|
+
const merged = {
|
|
4926
|
+
results: [],
|
|
4927
|
+
errors: [],
|
|
4928
|
+
warnings: [],
|
|
4929
|
+
infos: [],
|
|
4930
|
+
passed: [],
|
|
4931
|
+
summary: { total: 0, errors: 0, warnings: 0, infos: 0, passed: 0 }
|
|
4932
|
+
};
|
|
4933
|
+
for (const r of reports) {
|
|
4934
|
+
merged.results.push(...r.results);
|
|
4935
|
+
merged.errors.push(...r.errors);
|
|
4936
|
+
merged.warnings.push(...r.warnings);
|
|
4937
|
+
merged.infos.push(...r.infos);
|
|
4938
|
+
merged.passed.push(...r.passed);
|
|
4939
|
+
merged.summary.total += r.summary.total;
|
|
4940
|
+
merged.summary.errors += r.summary.errors;
|
|
4941
|
+
merged.summary.warnings += r.summary.warnings;
|
|
4942
|
+
merged.summary.infos += r.summary.infos;
|
|
4943
|
+
merged.summary.passed += r.summary.passed;
|
|
4944
|
+
}
|
|
4945
|
+
return merged;
|
|
4946
|
+
}
|
|
4947
|
+
function mergeTools(results) {
|
|
4948
|
+
const available = new Set;
|
|
4949
|
+
const missing = new Set;
|
|
4950
|
+
const skippedChecks = new Set;
|
|
4951
|
+
const toolToChecks = new Map;
|
|
4952
|
+
for (const r of results) {
|
|
4953
|
+
for (const t of r.available)
|
|
4954
|
+
available.add(t);
|
|
4955
|
+
for (const t of r.missing)
|
|
4956
|
+
missing.add(t);
|
|
4957
|
+
for (const id of r.skippedChecks)
|
|
4958
|
+
skippedChecks.add(id);
|
|
4959
|
+
for (const [tool, ids] of r.toolToChecks) {
|
|
4960
|
+
const merged = new Set([...toolToChecks.get(tool) ?? [], ...ids]);
|
|
4961
|
+
toolToChecks.set(tool, [...merged]);
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
return {
|
|
4965
|
+
available: [...available],
|
|
4966
|
+
missing: [...missing],
|
|
4967
|
+
skippedChecks: [...skippedChecks],
|
|
4968
|
+
toolToChecks
|
|
4969
|
+
};
|
|
4970
|
+
}
|
|
4971
|
+
function planRuns(opts) {
|
|
4972
|
+
const { manifest, baseConfig, targetIds, pdfPath, categories, only } = opts;
|
|
4973
|
+
const finalize = (config) => pdfPath ? applyDefaultPdfStrictChecks(config) : config;
|
|
4974
|
+
if (targetIds.length === 0) {
|
|
4975
|
+
return [{ targetId: null, config: finalize(baseConfig), category: categories, only }];
|
|
4976
|
+
}
|
|
4977
|
+
const requested = categories ?? [...TARGET_INDEPENDENT_CATEGORIES, ...TARGET_DEPENDENT_CATEGORIES];
|
|
4978
|
+
const independentCats = requested.filter((c) => TARGET_INDEPENDENT_CATEGORIES.includes(c));
|
|
4979
|
+
const dependentCats = requested.filter((c) => TARGET_DEPENDENT_CATEGORIES.includes(c));
|
|
4980
|
+
let baseOnly;
|
|
4981
|
+
let dependentOnly;
|
|
4982
|
+
if (only && only.length > 0) {
|
|
4983
|
+
const { resolved, unmatched } = resolveCheckSelectors(only);
|
|
4984
|
+
const categoryById = new Map(getChecks({}).map((c) => [c.id, c.category]));
|
|
4985
|
+
const independentIds = resolved.filter((id) => TARGET_INDEPENDENT_CATEGORIES.includes(categoryById.get(id) ?? ""));
|
|
4986
|
+
const dependentIds = resolved.filter((id) => TARGET_DEPENDENT_CATEGORIES.includes(categoryById.get(id) ?? ""));
|
|
4987
|
+
baseOnly = [...independentIds, ...unmatched];
|
|
4988
|
+
dependentOnly = dependentIds;
|
|
4989
|
+
}
|
|
4990
|
+
const runs = [];
|
|
4991
|
+
const baseWanted = only ? (baseOnly?.length ?? 0) > 0 : independentCats.length > 0;
|
|
4992
|
+
if (baseWanted) {
|
|
4993
|
+
runs.push({
|
|
4994
|
+
targetId: null,
|
|
4995
|
+
config: baseConfig,
|
|
4996
|
+
category: only ? undefined : independentCats,
|
|
4997
|
+
only: baseOnly
|
|
4998
|
+
});
|
|
4999
|
+
}
|
|
5000
|
+
const dependentWanted = only ? (dependentOnly?.length ?? 0) > 0 : dependentCats.length > 0;
|
|
5001
|
+
if (dependentWanted) {
|
|
5002
|
+
for (const targetId of targetIds) {
|
|
5003
|
+
runs.push({
|
|
5004
|
+
targetId,
|
|
5005
|
+
config: finalize(resolveConfigForTarget({}, manifest, targetId)),
|
|
5006
|
+
category: only ? undefined : dependentCats,
|
|
5007
|
+
only: dependentOnly
|
|
5008
|
+
});
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
return runs;
|
|
5012
|
+
}
|
|
4754
5013
|
async function executeValidation(args) {
|
|
4755
5014
|
const manifestPath = typeof args.manifest === "string" ? args.manifest : undefined;
|
|
4756
5015
|
const { manifest, manifestDir } = await loadManifestWithPath(manifestPath ?? args.input ?? undefined, { explicit: manifestPath !== undefined });
|
|
4757
|
-
const
|
|
4758
|
-
|
|
5016
|
+
const config = resolveConfig({}, manifest);
|
|
5017
|
+
const targetIds = resolveTargets(parseCsv(typeof args.target === "string" ? args.target : undefined), config.targets);
|
|
4759
5018
|
const pdfPath = typeof args.pdf === "string" ? resolve6(args.pdf) : undefined;
|
|
4760
5019
|
const inputDir = typeof args.input === "string" ? resolve6(args.input) : undefined;
|
|
4761
|
-
if (pdfPath) {
|
|
4762
|
-
config = applyDtrpgPdfDefaults(config);
|
|
4763
|
-
}
|
|
4764
|
-
if (profile) {
|
|
4765
|
-
config = applyValidationProfile(config, profile);
|
|
4766
|
-
}
|
|
4767
5020
|
if (pdfPath && !existsSync7(pdfPath)) {
|
|
4768
5021
|
throw new Error(`File not found: ${pdfPath}`);
|
|
4769
5022
|
}
|
|
@@ -4792,11 +5045,11 @@ async function executeValidation(args) {
|
|
|
4792
5045
|
let htmlPath;
|
|
4793
5046
|
const outDir = resolveOutputDir(manifestDir, config.title);
|
|
4794
5047
|
if (inputDir) {
|
|
4795
|
-
const relMarkdown = await resolveActiveMarkdownFiles(
|
|
4796
|
-
markdownFiles = relMarkdown.map((f) => join2(
|
|
4797
|
-
const relStyles = await resolveActiveStyles(
|
|
4798
|
-
cssFiles = relStyles.map((rel) => resolve6(
|
|
4799
|
-
assetDirs = [inputDir];
|
|
5048
|
+
const relMarkdown = await resolveActiveMarkdownFiles(manifestDir, config.source.files);
|
|
5049
|
+
markdownFiles = relMarkdown.map((f) => join2(manifestDir, canonicalChapterId(f)));
|
|
5050
|
+
const relStyles = await resolveActiveStyles(manifestDir, config.styles);
|
|
5051
|
+
cssFiles = relStyles.map((rel) => resolve6(manifestDir, rel)).filter((f) => !f.endsWith(".min.css"));
|
|
5052
|
+
assetDirs = [inputDir, ...await sharedAssetDirs(manifestDir, relStyles, inputDir)];
|
|
4800
5053
|
const possibleHtml = join2(outDir, BOOK_HTML_FILENAME);
|
|
4801
5054
|
if (existsSync7(possibleHtml)) {
|
|
4802
5055
|
htmlPath = possibleHtml;
|
|
@@ -4818,15 +5071,30 @@ async function executeValidation(args) {
|
|
|
4818
5071
|
only,
|
|
4819
5072
|
skip
|
|
4820
5073
|
};
|
|
4821
|
-
const
|
|
4822
|
-
const
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
5074
|
+
const runs = planRuns({ manifest, baseConfig: config, targetIds, pdfPath, categories, only });
|
|
5075
|
+
const reports = [];
|
|
5076
|
+
const toolResults = [];
|
|
5077
|
+
for (const run of runs) {
|
|
5078
|
+
const runOptions = {
|
|
5079
|
+
category: run.category,
|
|
5080
|
+
phase,
|
|
5081
|
+
only: run.only,
|
|
5082
|
+
skip
|
|
5083
|
+
};
|
|
5084
|
+
const runTools = await checkToolAvailability(run.config, runOptions);
|
|
5085
|
+
toolResults.push(runTools);
|
|
5086
|
+
let runReport = await runChecks({ ...context, config: run.config }, { ...runOptions, skipMissingTools: runTools.skippedChecks });
|
|
5087
|
+
if (run.targetId !== null) {
|
|
5088
|
+
runReport = withTargetRequiredCheckErrors(runReport, runTools, publishTargetFor(run.targetId));
|
|
5089
|
+
runReport = tagReport(runReport, run.targetId);
|
|
5090
|
+
}
|
|
5091
|
+
reports.push(runReport);
|
|
5092
|
+
}
|
|
5093
|
+
const tools = mergeTools(toolResults);
|
|
5094
|
+
const report = mergeReports(reports);
|
|
4827
5095
|
return {
|
|
4828
5096
|
config,
|
|
4829
|
-
|
|
5097
|
+
targets: targetIds,
|
|
4830
5098
|
context,
|
|
4831
5099
|
runnerOptions,
|
|
4832
5100
|
tools,
|
|
@@ -4887,7 +5155,7 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
4887
5155
|
import { existsSync as existsSync8, lstatSync, realpathSync, rmSync, statSync as statSync2, unlinkSync } from "node:fs";
|
|
4888
5156
|
import { cp, link, mkdir as mkdir2, mkdtemp, readFile as readFile16, rm, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
4889
5157
|
import { tmpdir } from "node:os";
|
|
4890
|
-
import { resolve as resolve7, join as join3, dirname as
|
|
5158
|
+
import { resolve as resolve7, join as join3, dirname as dirname4, basename, extname, relative, isAbsolute } from "node:path";
|
|
4891
5159
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4892
5160
|
import Module, { builtinModules, createRequire } from "node:module";
|
|
4893
5161
|
import { parse as parseJavaScript } from "acorn";
|
|
@@ -5256,7 +5524,7 @@ async function createIsolatedVendorTree(verified, address) {
|
|
|
5256
5524
|
for (let index = 0;index < sorted.length; index++) {
|
|
5257
5525
|
const source = sorted[index];
|
|
5258
5526
|
const destination = join3(loadRoot, "packages", String(index), "package");
|
|
5259
|
-
await mkdir2(
|
|
5527
|
+
await mkdir2(dirname4(destination), { recursive: true });
|
|
5260
5528
|
await cp(source.packageDir, destination, {
|
|
5261
5529
|
recursive: true,
|
|
5262
5530
|
filter: (candidate) => isolatedPackageCopyFilter(source.packageDir, candidate)
|
|
@@ -5315,7 +5583,7 @@ async function snapshotAndIsolateVendoredPlugin(baseDir, packageName, version) {
|
|
|
5315
5583
|
const snapshotProject = join3(container, "project");
|
|
5316
5584
|
const snapshotRoot = vendoredNpmPluginRoot(snapshotProject, packageName, version);
|
|
5317
5585
|
try {
|
|
5318
|
-
await mkdir2(
|
|
5586
|
+
await mkdir2(dirname4(snapshotRoot), { recursive: true });
|
|
5319
5587
|
await cp(sourceRoot, snapshotRoot, {
|
|
5320
5588
|
recursive: true,
|
|
5321
5589
|
dereference: false,
|
|
@@ -5453,7 +5721,7 @@ function shadowPathFor(pluginPath, mtimeMs) {
|
|
|
5453
5721
|
const ext = extname(pluginPath);
|
|
5454
5722
|
const stem = basename(pluginPath, ext);
|
|
5455
5723
|
const token = String(mtimeMs).replace(/\./g, "-");
|
|
5456
|
-
return join3(
|
|
5724
|
+
return join3(dirname4(pluginPath), `.${stem}.gutterpress-reload-${process.pid}-${token}${ext}`);
|
|
5457
5725
|
}
|
|
5458
5726
|
async function loadCachedPathPluginModule(pluginPath) {
|
|
5459
5727
|
const mtimeMs = statSync2(pluginPath).mtimeMs;
|
|
@@ -5731,7 +5999,7 @@ async function writeBuildFingerprint(input) {
|
|
|
5731
5999
|
iccPath: input.pdfx.iccPath,
|
|
5732
6000
|
stripAnnotations: input.pdfx.stripAnnotations
|
|
5733
6001
|
},
|
|
5734
|
-
outputDir
|
|
6002
|
+
outputDir: input.recordedOutputDir ? path5.resolve(input.recordedOutputDir) : outputDir
|
|
5735
6003
|
},
|
|
5736
6004
|
sourceRevision,
|
|
5737
6005
|
tools
|
|
@@ -5745,14 +6013,14 @@ async function writeBuildFingerprint(input) {
|
|
|
5745
6013
|
import { existsSync as existsSync9 } from "node:fs";
|
|
5746
6014
|
import { mkdtemp as mkdtemp2, mkdir as mkdir4, writeFile as writeFile4, readFile as readFile17 } from "node:fs/promises";
|
|
5747
6015
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
5748
|
-
import { dirname as
|
|
6016
|
+
import { dirname as dirname5, join as join4, resolve as resolve8 } from "node:path";
|
|
5749
6017
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5750
6018
|
|
|
5751
6019
|
// src/assets/favicon.ico
|
|
5752
6020
|
var favicon_default = "./favicon-wkbm9cjn.ico";
|
|
5753
6021
|
|
|
5754
6022
|
// src/assets/manifest.schema.json
|
|
5755
|
-
var manifest_schema_default = "./manifest.schema-
|
|
6023
|
+
var manifest_schema_default = "./manifest.schema-z61rzw44.json";
|
|
5756
6024
|
|
|
5757
6025
|
// src/assets/preview/scripts/pagedjs-interface.js
|
|
5758
6026
|
var pagedjs_interface_default = "./pagedjs-interface-80g3xa8p.js";
|
|
@@ -5775,23 +6043,17 @@ var manifest_default = "./manifest-n1gh3qw5.yaml";
|
|
|
5775
6043
|
// src/assets/templates/book/chapter-01.md
|
|
5776
6044
|
var chapter_01_default = "./chapter-01-rkpyvjna.md";
|
|
5777
6045
|
|
|
5778
|
-
// src/assets/templates/ttrpg/manifest.yaml
|
|
5779
|
-
var manifest_default2 = "./manifest-ryyg71nf.yaml";
|
|
5780
|
-
|
|
5781
|
-
// src/assets/templates/ttrpg/chapter-01.md
|
|
5782
|
-
var chapter_01_default2 = "./chapter-01-jj8ftn4c.md";
|
|
5783
|
-
|
|
5784
6046
|
// src/assets/templates/zine/manifest.yaml
|
|
5785
|
-
var
|
|
6047
|
+
var manifest_default2 = "./manifest-n1gh3qw5.yaml";
|
|
5786
6048
|
|
|
5787
6049
|
// src/assets/templates/zine/chapter-01.md
|
|
5788
|
-
var
|
|
6050
|
+
var chapter_01_default2 = "./chapter-01-7jwqg1ct.md";
|
|
5789
6051
|
|
|
5790
6052
|
// src/assets/templates/technical/manifest.yaml
|
|
5791
|
-
var
|
|
6053
|
+
var manifest_default3 = "./manifest-n1gh3qw5.yaml";
|
|
5792
6054
|
|
|
5793
6055
|
// src/assets/templates/technical/chapter-01.md
|
|
5794
|
-
var
|
|
6056
|
+
var chapter_01_default3 = "./chapter-01-6fn9pvd0.md";
|
|
5795
6057
|
|
|
5796
6058
|
// src/assets/themes/clean-book/theme.css
|
|
5797
6059
|
var theme_default = "./theme-570zmh2t.css";
|
|
@@ -5799,26 +6061,20 @@ var theme_default = "./theme-570zmh2t.css";
|
|
|
5799
6061
|
// src/assets/themes/clean-book/theme.json
|
|
5800
6062
|
var theme_default2 = "./theme-xt0hjb1b.json";
|
|
5801
6063
|
|
|
5802
|
-
// src/assets/themes/ttrpg-supplement/theme.css
|
|
5803
|
-
var theme_default3 = "./theme-0yzvthe8.css";
|
|
5804
|
-
|
|
5805
|
-
// src/assets/themes/ttrpg-supplement/theme.json
|
|
5806
|
-
var theme_default4 = "./theme-6a2fngc8.json";
|
|
5807
|
-
|
|
5808
6064
|
// src/assets/themes/zine/theme.css
|
|
5809
|
-
var
|
|
6065
|
+
var theme_default3 = "./theme-zz2ktzqs.css";
|
|
5810
6066
|
|
|
5811
6067
|
// src/assets/themes/zine/theme.json
|
|
5812
|
-
var
|
|
6068
|
+
var theme_default4 = "./theme-cd6efzjw.json";
|
|
5813
6069
|
|
|
5814
6070
|
// src/assets/themes/technical-doc/theme.css
|
|
5815
|
-
var
|
|
6071
|
+
var theme_default5 = "./theme-nya4nqh6.css";
|
|
5816
6072
|
|
|
5817
6073
|
// src/assets/themes/technical-doc/theme.json
|
|
5818
|
-
var
|
|
6074
|
+
var theme_default6 = "./theme-tqfypc1w.json";
|
|
5819
6075
|
|
|
5820
6076
|
// src/lib/embedded-assets.ts
|
|
5821
|
-
var __libdir =
|
|
6077
|
+
var __libdir = dirname5(fileURLToPath2(import.meta.url));
|
|
5822
6078
|
var abs = (p) => resolve8(__libdir, p);
|
|
5823
6079
|
var filePath = (v) => v;
|
|
5824
6080
|
var EMBEDDED_ASSETS = {
|
|
@@ -5831,27 +6087,23 @@ var EMBEDDED_ASSETS = {
|
|
|
5831
6087
|
"profiles/CGATS21_CRPC1.icc": abs(filePath(CGATS21_CRPC1_default)),
|
|
5832
6088
|
"templates/book/manifest.yaml": abs(filePath(manifest_default)),
|
|
5833
6089
|
"templates/book/chapter-01.md": abs(filePath(chapter_01_default)),
|
|
5834
|
-
"templates/
|
|
5835
|
-
"templates/
|
|
5836
|
-
"templates/
|
|
5837
|
-
"templates/
|
|
5838
|
-
"templates/technical/manifest.yaml": abs(filePath(manifest_default4)),
|
|
5839
|
-
"templates/technical/chapter-01.md": abs(filePath(chapter_01_default4)),
|
|
6090
|
+
"templates/zine/manifest.yaml": abs(filePath(manifest_default2)),
|
|
6091
|
+
"templates/zine/chapter-01.md": abs(filePath(chapter_01_default2)),
|
|
6092
|
+
"templates/technical/manifest.yaml": abs(filePath(manifest_default3)),
|
|
6093
|
+
"templates/technical/chapter-01.md": abs(filePath(chapter_01_default3)),
|
|
5840
6094
|
"themes/clean-book/theme.css": abs(filePath(theme_default)),
|
|
5841
6095
|
"themes/clean-book/theme.json": abs(filePath(theme_default2)),
|
|
5842
|
-
"themes/
|
|
5843
|
-
"themes/
|
|
5844
|
-
"themes/
|
|
5845
|
-
"themes/
|
|
5846
|
-
"themes/technical-doc/theme.css": abs(filePath(theme_default7)),
|
|
5847
|
-
"themes/technical-doc/theme.json": abs(filePath(theme_default8))
|
|
6096
|
+
"themes/zine/theme.css": abs(filePath(theme_default3)),
|
|
6097
|
+
"themes/zine/theme.json": abs(filePath(theme_default4)),
|
|
6098
|
+
"themes/technical-doc/theme.css": abs(filePath(theme_default5)),
|
|
6099
|
+
"themes/technical-doc/theme.json": abs(filePath(theme_default6))
|
|
5848
6100
|
};
|
|
5849
6101
|
var extractPromise = null;
|
|
5850
6102
|
async function extractAssets() {
|
|
5851
6103
|
const root = await mkdtemp2(join4(tmpdir2(), "gutterpress-assets-"));
|
|
5852
6104
|
for (const [relPath, srcPath] of Object.entries(EMBEDDED_ASSETS)) {
|
|
5853
6105
|
const dest = join4(root, relPath);
|
|
5854
|
-
await mkdir4(
|
|
6106
|
+
await mkdir4(dirname5(dest), { recursive: true });
|
|
5855
6107
|
const bytes = await readFile17(srcPath);
|
|
5856
6108
|
await writeFile4(dest, bytes);
|
|
5857
6109
|
}
|
|
@@ -5905,7 +6157,7 @@ ${m.installHint}`).join(`
|
|
|
5905
6157
|
|
|
5906
6158
|
${list}
|
|
5907
6159
|
|
|
5908
|
-
Install the missing tools and re-run, or set GHOSTSCRIPT_PATH, CHROMIUM_PATH, or system PATH so gutterpress can find them. See the User Guide Chapter
|
|
6160
|
+
Install the missing tools and re-run, or set GHOSTSCRIPT_PATH, CHROMIUM_PATH, or system PATH so gutterpress can find them. See the User Guide Chapter 7 (System Setup) at examples/gutterpress-user-guide/07-system-setup.md for the full per-feature matrix.`, 2);
|
|
5909
6161
|
}
|
|
5910
6162
|
function computeGates(format, opts, config) {
|
|
5911
6163
|
if (format === "html") {
|
|
@@ -5999,6 +6251,15 @@ function resolveWithinRoot(relPath, root) {
|
|
|
5999
6251
|
}
|
|
6000
6252
|
return candidate;
|
|
6001
6253
|
}
|
|
6254
|
+
function hasDotSegment(urlPathname) {
|
|
6255
|
+
let decoded;
|
|
6256
|
+
try {
|
|
6257
|
+
decoded = decodeURIComponent(urlPathname);
|
|
6258
|
+
} catch {
|
|
6259
|
+
return true;
|
|
6260
|
+
}
|
|
6261
|
+
return decoded.split(/[/\\]/).some((segment) => segment.startsWith("."));
|
|
6262
|
+
}
|
|
6002
6263
|
function resolveStaticPath(urlPathname, root) {
|
|
6003
6264
|
let decoded;
|
|
6004
6265
|
try {
|
|
@@ -6397,14 +6658,25 @@ async function resolveBuildContext(opts) {
|
|
|
6397
6658
|
const outDir = target.kind === "file" ? path9.dirname(target.file) : target.dir;
|
|
6398
6659
|
const gates = computeGates(format, opts, config);
|
|
6399
6660
|
const workDir = target.kind === "project" ? path9.join(path9.dirname(target.dir), `.${path9.basename(target.dir)}-build-${randomBytes(6).toString("hex")}`) : path9.join(os2.tmpdir(), `gutterpress-build-${randomBytes(6).toString("hex")}`);
|
|
6400
|
-
return {
|
|
6661
|
+
return {
|
|
6662
|
+
opts,
|
|
6663
|
+
format,
|
|
6664
|
+
inputDir,
|
|
6665
|
+
renderDir: manifestDir,
|
|
6666
|
+
outDir,
|
|
6667
|
+
workDir,
|
|
6668
|
+
target,
|
|
6669
|
+
manifestDir,
|
|
6670
|
+
config,
|
|
6671
|
+
gates
|
|
6672
|
+
};
|
|
6401
6673
|
}
|
|
6402
6674
|
async function runQualityGates(ctx) {
|
|
6403
|
-
const { gates, opts,
|
|
6675
|
+
const { gates, opts, renderDir } = ctx;
|
|
6404
6676
|
if (gates.lint) {
|
|
6405
6677
|
log.info("Lint: CSS print-safety");
|
|
6406
6678
|
const lintResult = await runLint({
|
|
6407
|
-
manifest: opts.manifestPath ??
|
|
6679
|
+
manifest: opts.manifestPath ?? renderDir
|
|
6408
6680
|
});
|
|
6409
6681
|
if (!lintResult.ok) {
|
|
6410
6682
|
throw new BuildError("CSS lint failed", 2);
|
|
@@ -6413,7 +6685,7 @@ async function runQualityGates(ctx) {
|
|
|
6413
6685
|
if (gates.preValidate) {
|
|
6414
6686
|
log.info("Pre-build validation");
|
|
6415
6687
|
const result = await executeAndReport({
|
|
6416
|
-
input:
|
|
6688
|
+
input: renderDir,
|
|
6417
6689
|
phase: "pre-build",
|
|
6418
6690
|
manifest: opts.manifestPath
|
|
6419
6691
|
}, "text");
|
|
@@ -6423,7 +6695,7 @@ async function runQualityGates(ctx) {
|
|
|
6423
6695
|
}
|
|
6424
6696
|
}
|
|
6425
6697
|
async function renderBook(ctx) {
|
|
6426
|
-
const { config,
|
|
6698
|
+
const { config, renderDir, workDir } = ctx;
|
|
6427
6699
|
if (config.source.files && config.source.files.length > 0) {
|
|
6428
6700
|
log.info(`Using specified files (${config.source.files.length} total)`);
|
|
6429
6701
|
} else {
|
|
@@ -6432,13 +6704,13 @@ async function renderBook(ctx) {
|
|
|
6432
6704
|
if (config.plugins.length > 0) {
|
|
6433
6705
|
log.info(`Loading ${config.plugins.length} plugin(s)...`);
|
|
6434
6706
|
}
|
|
6435
|
-
const { plugins, pluginCss } = await loadPluginsWithCss(config.plugins,
|
|
6707
|
+
const { plugins, pluginCss } = await loadPluginsWithCss(config.plugins, renderDir);
|
|
6436
6708
|
if (plugins && plugins.length > 0) {
|
|
6437
6709
|
log.success(`Loaded ${plugins.length} plugin(s)`);
|
|
6438
6710
|
}
|
|
6439
6711
|
const imageRefs = [];
|
|
6440
6712
|
const cssAssets = [];
|
|
6441
|
-
const htmlFile = await renderChaptersToFile(
|
|
6713
|
+
const htmlFile = await renderChaptersToFile(renderDir, workDir, {
|
|
6442
6714
|
title: config.title,
|
|
6443
6715
|
styles: config.styles,
|
|
6444
6716
|
files: config.source.files,
|
|
@@ -6457,7 +6729,7 @@ async function renderBook(ctx) {
|
|
|
6457
6729
|
}
|
|
6458
6730
|
});
|
|
6459
6731
|
log.success(`Wrote ${htmlFile}`);
|
|
6460
|
-
const { copies: imageCopies, errors } = await planImageCopies(
|
|
6732
|
+
const { copies: imageCopies, errors } = await planImageCopies(renderDir, imageRefs);
|
|
6461
6733
|
if (errors.length > 0) {
|
|
6462
6734
|
throw new BuildError(`Cannot resolve ${errors.length} image reference(s):
|
|
6463
6735
|
` + errors.map((e) => ` - ${e}`).join(`
|
|
@@ -6496,7 +6768,8 @@ async function resolveIccProfile(icc, manifestDir, explicitIccPath) {
|
|
|
6496
6768
|
async function finalizeBuild(ctx, fingerprint, wroteMessage, paths, artifactName2 = null) {
|
|
6497
6769
|
const workFingerprint = await writeBuildFingerprint({
|
|
6498
6770
|
...fingerprint,
|
|
6499
|
-
outputDir: ctx.workDir
|
|
6771
|
+
outputDir: ctx.workDir,
|
|
6772
|
+
recordedOutputDir: fingerprint.outputDir
|
|
6500
6773
|
});
|
|
6501
6774
|
await publishBuild(ctx, artifactName2);
|
|
6502
6775
|
const delivered = ctx.target.kind !== "file";
|
|
@@ -6587,7 +6860,9 @@ class PdfOutput {
|
|
|
6587
6860
|
await renderHtmlToPdf(htmlFile, rawPdf, opts.pdfRenderer, staticHtmlRaw);
|
|
6588
6861
|
if (staticHtmlRaw && fs2.existsSync(staticHtmlRaw)) {
|
|
6589
6862
|
await finalizeStaticBook(await fsp3.readFile(staticHtmlRaw, "utf-8"), htmlFile, workDir);
|
|
6590
|
-
|
|
6863
|
+
if (ctx.target.kind !== "file") {
|
|
6864
|
+
log.success(`Wrote static desktop: ${path9.join(outDir, BOOK_HTML)}`);
|
|
6865
|
+
}
|
|
6591
6866
|
}
|
|
6592
6867
|
if (!pdfxMode) {
|
|
6593
6868
|
try {
|
|
@@ -6749,6 +7024,7 @@ async function renderPreviewBook(inputPath, config, opts) {
|
|
|
6749
7024
|
plugins,
|
|
6750
7025
|
pluginCss,
|
|
6751
7026
|
wrapChapters: opts.wrapChapters,
|
|
7027
|
+
...opts.onCssAssets ? { onCssAssets: opts.onCssAssets } : {},
|
|
6752
7028
|
onChapterWarnings: (file, warnings) => {
|
|
6753
7029
|
for (const w of warnings) {
|
|
6754
7030
|
warn(` ${file}, line ${w.line}: ${w.message}`);
|
|
@@ -6763,15 +7039,24 @@ function injectPreviewScripts(html) {
|
|
|
6763
7039
|
return html.replace(pagedjsPolyfillTagRegex(), iface + BREAK_INSIDE_HANDLER + `
|
|
6764
7040
|
<script src="/vendor/paged.polyfill.js"></script>`);
|
|
6765
7041
|
}
|
|
6766
|
-
async function generateAndWriteHtml(inputPath, tempDir, config) {
|
|
7042
|
+
async function generateAndWriteHtml(inputPath, tempDir, config, cssAssets) {
|
|
6767
7043
|
if (!inputPath) {
|
|
7044
|
+
cssAssets.clear();
|
|
6768
7045
|
await fsp4.writeFile(path10.join(tempDir, BOOK_HTML_FILENAME), EMPTY_BOOK_HTML, "utf-8");
|
|
6769
7046
|
return;
|
|
6770
7047
|
}
|
|
7048
|
+
const nextAssets = new Map;
|
|
6771
7049
|
const html = await renderPreviewBook(inputPath, config, {
|
|
6772
7050
|
files: config.source?.files ?? null,
|
|
6773
|
-
wrapChapters: true
|
|
7051
|
+
wrapChapters: true,
|
|
7052
|
+
onCssAssets: (copies) => {
|
|
7053
|
+
for (const copy of copies)
|
|
7054
|
+
nextAssets.set(copy.to, copy.from);
|
|
7055
|
+
}
|
|
6774
7056
|
});
|
|
7057
|
+
cssAssets.clear();
|
|
7058
|
+
for (const [to, from] of nextAssets)
|
|
7059
|
+
cssAssets.set(to, from);
|
|
6775
7060
|
await fsp4.writeFile(path10.join(tempDir, BOOK_HTML_FILENAME), injectPreviewScripts(html), "utf-8");
|
|
6776
7061
|
}
|
|
6777
7062
|
function isDotPathUnderRoot(candidatePath, root) {
|
|
@@ -6789,11 +7074,24 @@ function isDotPathUnderRoot(candidatePath, root) {
|
|
|
6789
7074
|
return false;
|
|
6790
7075
|
return rel.split("/").some((segment) => segment.startsWith("."));
|
|
6791
7076
|
}
|
|
7077
|
+
function isGeneratedProjectPath(relative2) {
|
|
7078
|
+
const segments = relative2.split("/");
|
|
7079
|
+
for (let i = 0;i < segments.length; i++) {
|
|
7080
|
+
const segment = segments[i];
|
|
7081
|
+
if (segment === "dist" || segment === "node_modules")
|
|
7082
|
+
return true;
|
|
7083
|
+
if (segment === "plugins" && segments[i + 1] === "npm")
|
|
7084
|
+
return true;
|
|
7085
|
+
}
|
|
7086
|
+
return false;
|
|
7087
|
+
}
|
|
6792
7088
|
function isIgnoredWatchPath(candidatePath, projectRoot) {
|
|
6793
7089
|
const normalizedRoot = projectRoot.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
6794
7090
|
const normalizedPath = candidatePath.replace(/\\/g, "/");
|
|
6795
|
-
|
|
6796
|
-
|
|
7091
|
+
if (!normalizedPath.startsWith(normalizedRoot + "/"))
|
|
7092
|
+
return false;
|
|
7093
|
+
const relative2 = normalizedPath.slice(normalizedRoot.length + 1);
|
|
7094
|
+
return isDotPathUnderRoot(candidatePath, projectRoot) || isGeneratedProjectPath(relative2);
|
|
6797
7095
|
}
|
|
6798
7096
|
function isExternalWatchCandidate(candidatePath, targets) {
|
|
6799
7097
|
const candidate = path10.resolve(candidatePath);
|
|
@@ -6972,7 +7270,7 @@ function createFileWatcher(state) {
|
|
|
6972
7270
|
await syncExternalWatches();
|
|
6973
7271
|
if (closed)
|
|
6974
7272
|
return;
|
|
6975
|
-
await generateAndWriteHtml(inputResolved, state.tempDir, updatedConfig);
|
|
7273
|
+
await generateAndWriteHtml(inputResolved, state.tempDir, updatedConfig, state.cssAssets);
|
|
6976
7274
|
if (closed)
|
|
6977
7275
|
return;
|
|
6978
7276
|
state.previewServer?.broadcastReload();
|
|
@@ -7089,7 +7387,7 @@ async function restartPreview(newInputPath, state) {
|
|
|
7089
7387
|
state.currentInputPath = newInputPath;
|
|
7090
7388
|
const manifest = await loadManifest(newInputPath);
|
|
7091
7389
|
state.config = resolveConfig({}, manifest);
|
|
7092
|
-
await generateAndWriteHtml(newInputPath, state.tempDir, state.config);
|
|
7390
|
+
await generateAndWriteHtml(newInputPath, state.tempDir, state.config, state.cssAssets);
|
|
7093
7391
|
startFileWatcher(state);
|
|
7094
7392
|
state.previewServer?.broadcastReload();
|
|
7095
7393
|
info("Preview restarted successfully");
|
|
@@ -7147,7 +7445,8 @@ function createServerState(inputPath, tempDir, config, options) {
|
|
|
7147
7445
|
isShuttingDown: false,
|
|
7148
7446
|
tempDir,
|
|
7149
7447
|
config,
|
|
7150
|
-
options
|
|
7448
|
+
options,
|
|
7449
|
+
cssAssets: new Map
|
|
7151
7450
|
};
|
|
7152
7451
|
}
|
|
7153
7452
|
|
|
@@ -7350,15 +7649,6 @@ function matchesEmbedded(urlPathname) {
|
|
|
7350
7649
|
return true;
|
|
7351
7650
|
return EMBEDDED_PREFIXES.some((p) => urlPathname.startsWith(p));
|
|
7352
7651
|
}
|
|
7353
|
-
function isDotfileRequest(urlPathname) {
|
|
7354
|
-
let decoded;
|
|
7355
|
-
try {
|
|
7356
|
-
decoded = decodeURIComponent(urlPathname);
|
|
7357
|
-
} catch {
|
|
7358
|
-
return true;
|
|
7359
|
-
}
|
|
7360
|
-
return decoded.split("/").some((segment) => segment.startsWith("."));
|
|
7361
|
-
}
|
|
7362
7652
|
async function createPreviewServer(state, port) {
|
|
7363
7653
|
const clients = new Set;
|
|
7364
7654
|
const wss = new WebSocketServer({ noServer: true });
|
|
@@ -7409,8 +7699,18 @@ async function createPreviewServer(state, port) {
|
|
|
7409
7699
|
return;
|
|
7410
7700
|
}
|
|
7411
7701
|
const pathname = url.pathname === "/" ? "/book.html" : url.pathname;
|
|
7702
|
+
const cssAssetSource = state.cssAssets.get(pathname.replace(/^\/+/, ""));
|
|
7703
|
+
if (cssAssetSource) {
|
|
7704
|
+
await serveStatic(cssAssetSource, res).catch((err) => {
|
|
7705
|
+
if (!res.headersSent) {
|
|
7706
|
+
res.writeHead(500);
|
|
7707
|
+
res.end(`Internal Server Error: ${err.message}`);
|
|
7708
|
+
}
|
|
7709
|
+
});
|
|
7710
|
+
return;
|
|
7711
|
+
}
|
|
7412
7712
|
const servingProjectRoot = pathname !== "/book.html";
|
|
7413
|
-
if (servingProjectRoot && (!state.currentInputPath ||
|
|
7713
|
+
if (servingProjectRoot && (!state.currentInputPath || hasDotSegment(pathname))) {
|
|
7414
7714
|
res.writeHead(404);
|
|
7415
7715
|
res.end("Not Found");
|
|
7416
7716
|
return;
|
|
@@ -7495,8 +7795,8 @@ async function startPreviewServer(options) {
|
|
|
7495
7795
|
}
|
|
7496
7796
|
const config = await initializeConfiguration(inputPath);
|
|
7497
7797
|
const tempDir = await initializePreviewDirectories();
|
|
7498
|
-
await generateAndWriteHtml(inputPath, tempDir, config);
|
|
7499
7798
|
const state = createServerState(inputPath, tempDir, config, options);
|
|
7799
|
+
await generateAndWriteHtml(inputPath, tempDir, config, state.cssAssets);
|
|
7500
7800
|
const restartPreview2 = async (newInputPath) => {
|
|
7501
7801
|
await restartPreview(newInputPath, state);
|
|
7502
7802
|
};
|
|
@@ -7534,12 +7834,66 @@ async function startPreviewServer(options) {
|
|
|
7534
7834
|
}
|
|
7535
7835
|
|
|
7536
7836
|
// src/lib/project-scaffold.ts
|
|
7537
|
-
import { access, copyFile, cp as cp2, mkdir as
|
|
7538
|
-
import { constants as FS, existsSync as
|
|
7837
|
+
import { access, copyFile, cp as cp2, mkdir as mkdir7, readdir as readdir5, readFile as readFile22, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
|
|
7838
|
+
import { constants as FS, existsSync as existsSync11 } from "node:fs";
|
|
7839
|
+
import path14 from "node:path";
|
|
7840
|
+
|
|
7841
|
+
// src/lib/manifest-doc.ts
|
|
7842
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
7843
|
+
import { randomUUID } from "node:crypto";
|
|
7844
|
+
import { mkdir as mkdir6, open, readFile as readFile21, rename, rm as rm2 } from "node:fs/promises";
|
|
7539
7845
|
import path13 from "node:path";
|
|
7846
|
+
import { parseDocument, isSeq, YAMLSeq } from "yaml";
|
|
7847
|
+
function resolveManifestPath(projectDir) {
|
|
7848
|
+
const existing = MANIFEST_FILENAMES.find((name) => existsSync10(path13.join(projectDir, name)));
|
|
7849
|
+
return path13.join(projectDir, existing ?? MANIFEST_FILENAMES[0]);
|
|
7850
|
+
}
|
|
7851
|
+
async function loadManifestDoc(projectDir) {
|
|
7852
|
+
const file = resolveManifestPath(projectDir);
|
|
7853
|
+
let text = "";
|
|
7854
|
+
try {
|
|
7855
|
+
text = await readFile21(file, "utf8");
|
|
7856
|
+
} catch (error2) {
|
|
7857
|
+
if (error2.code !== "ENOENT")
|
|
7858
|
+
throw error2;
|
|
7859
|
+
}
|
|
7860
|
+
return { doc: parseDocument(text), file };
|
|
7861
|
+
}
|
|
7862
|
+
async function writeManifestDoc(file, doc) {
|
|
7863
|
+
const dir = path13.dirname(file);
|
|
7864
|
+
await mkdir6(dir, { recursive: true });
|
|
7865
|
+
const temporary = path13.join(dir, `.${path13.basename(file)}.tmp-${process.pid}-${randomUUID()}`);
|
|
7866
|
+
try {
|
|
7867
|
+
const handle = await open(temporary, "wx", 438);
|
|
7868
|
+
try {
|
|
7869
|
+
await handle.writeFile(doc.toString(), "utf8");
|
|
7870
|
+
await handle.sync();
|
|
7871
|
+
} finally {
|
|
7872
|
+
await handle.close();
|
|
7873
|
+
}
|
|
7874
|
+
await rename(temporary, file);
|
|
7875
|
+
const directory = await open(dir, "r").catch(() => null);
|
|
7876
|
+
if (directory) {
|
|
7877
|
+
await directory.sync().catch(() => {});
|
|
7878
|
+
await directory.close();
|
|
7879
|
+
}
|
|
7880
|
+
} finally {
|
|
7881
|
+
await rm2(temporary, { force: true });
|
|
7882
|
+
}
|
|
7883
|
+
}
|
|
7884
|
+
function ensureSeq(doc, key) {
|
|
7885
|
+
let seq = doc.get(key, true);
|
|
7886
|
+
if (!isSeq(seq)) {
|
|
7887
|
+
const fresh = new YAMLSeq(doc.schema);
|
|
7888
|
+
doc.set(key, fresh);
|
|
7889
|
+
seq = fresh;
|
|
7890
|
+
}
|
|
7891
|
+
return seq;
|
|
7892
|
+
}
|
|
7893
|
+
|
|
7894
|
+
// src/lib/project-scaffold.ts
|
|
7540
7895
|
var STARTER_THEME_FOR_TEMPLATE = {
|
|
7541
7896
|
book: "clean-book",
|
|
7542
|
-
ttrpg: "ttrpg-supplement",
|
|
7543
7897
|
zine: "zine",
|
|
7544
7898
|
technical: "technical-doc"
|
|
7545
7899
|
};
|
|
@@ -7559,6 +7913,39 @@ function escapeYamlScalar(value) {
|
|
|
7559
7913
|
return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
7560
7914
|
}
|
|
7561
7915
|
var DEFAULT_AUTHOR = "Anonymous";
|
|
7916
|
+
function isPositivePoints(value) {
|
|
7917
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
7918
|
+
}
|
|
7919
|
+
function requirePreset(preset, customPage) {
|
|
7920
|
+
if (!preset || !PRESET_IDS.includes(preset)) {
|
|
7921
|
+
const got = preset ? ` (got "${preset}")` : "";
|
|
7922
|
+
throw new CreateProjectErrorImpl("preset-required", `A preset is required to create a book${got}. Choose one of: ${PRESET_IDS.join(", ")}.`);
|
|
7923
|
+
}
|
|
7924
|
+
if (preset === "custom") {
|
|
7925
|
+
const missing = [];
|
|
7926
|
+
if (!customPage || !isPositivePoints(customPage.width))
|
|
7927
|
+
missing.push("page width");
|
|
7928
|
+
if (!customPage || !isPositivePoints(customPage.height))
|
|
7929
|
+
missing.push("page height");
|
|
7930
|
+
if (missing.length > 0) {
|
|
7931
|
+
throw new CreateProjectErrorImpl("custom-page-required", `The custom preset needs a trim size: ${missing.join(" and ")} in points ` + `(72pt = 1in — e.g. US Letter is 612 x 792).`);
|
|
7932
|
+
}
|
|
7933
|
+
} else if (customPage && (!isPositivePoints(customPage.width) || !isPositivePoints(customPage.height))) {
|
|
7934
|
+
throw new CreateProjectErrorImpl("custom-page-required", "Page overrides need a positive width and height in points (72pt = 1in).");
|
|
7935
|
+
}
|
|
7936
|
+
if (customPage?.tolerance !== undefined && !isPositivePoints(customPage.tolerance)) {
|
|
7937
|
+
throw new CreateProjectErrorImpl("custom-page-required", "Page tolerance must be a positive number of points.");
|
|
7938
|
+
}
|
|
7939
|
+
return preset;
|
|
7940
|
+
}
|
|
7941
|
+
function resolveScaffoldTargets(requested, preset) {
|
|
7942
|
+
const ids = requested ?? [...PRESETS[preset].defaultTargets];
|
|
7943
|
+
const unknown = ids.filter((id) => !TARGETS[id]);
|
|
7944
|
+
if (unknown.length > 0) {
|
|
7945
|
+
throw new CreateProjectErrorImpl("invalid-targets", `Unknown publish target${unknown.length > 1 ? "s" : ""} "${unknown.join('", "')}". ` + `Known targets: ${TARGET_IDS.join(", ")}.`);
|
|
7946
|
+
}
|
|
7947
|
+
return [...new Set(ids)];
|
|
7948
|
+
}
|
|
7562
7949
|
async function scaffoldProject(options) {
|
|
7563
7950
|
const name = (options.name ?? "").trim();
|
|
7564
7951
|
if (!name) {
|
|
@@ -7570,7 +7957,7 @@ async function scaffoldProject(options) {
|
|
|
7570
7957
|
throw new CreateProjectErrorImpl("invalid-name", `Could not derive a valid folder name from "${name}".`);
|
|
7571
7958
|
}
|
|
7572
7959
|
const parentDir = options.parentDir;
|
|
7573
|
-
if (!parentDir || !
|
|
7960
|
+
if (!parentDir || !path14.isAbsolute(parentDir)) {
|
|
7574
7961
|
throw new CreateProjectErrorImpl("parent-not-writable", "The save location must be an absolute path.");
|
|
7575
7962
|
}
|
|
7576
7963
|
try {
|
|
@@ -7578,7 +7965,7 @@ async function scaffoldProject(options) {
|
|
|
7578
7965
|
} catch {
|
|
7579
7966
|
throw new CreateProjectErrorImpl("parent-not-writable", `The chosen save location can't be written to: ${parentDir}`);
|
|
7580
7967
|
}
|
|
7581
|
-
const projectDir =
|
|
7968
|
+
const projectDir = path14.join(parentDir, folderName);
|
|
7582
7969
|
let targetExists = true;
|
|
7583
7970
|
try {
|
|
7584
7971
|
await access(projectDir, FS.F_OK);
|
|
@@ -7590,26 +7977,28 @@ async function scaffoldProject(options) {
|
|
|
7590
7977
|
}
|
|
7591
7978
|
const template = options.template ?? "book";
|
|
7592
7979
|
const customTemplateDir = options.templateDir;
|
|
7980
|
+
const preset = customTemplateDir && options.preset === undefined ? undefined : requirePreset(options.preset, options.customPage);
|
|
7981
|
+
const targets = preset ? resolveScaffoldTargets(options.targets, preset) : undefined;
|
|
7593
7982
|
try {
|
|
7594
|
-
await
|
|
7983
|
+
await mkdir7(projectDir, { recursive: true });
|
|
7595
7984
|
if (customTemplateDir) {
|
|
7596
7985
|
const entries = await readdir5(customTemplateDir, { withFileTypes: true });
|
|
7597
7986
|
for (const entry of entries) {
|
|
7598
7987
|
if (entry.name === ".gutterpress-template.json")
|
|
7599
7988
|
continue;
|
|
7600
|
-
await cp2(
|
|
7989
|
+
await cp2(path14.join(customTemplateDir, entry.name), path14.join(projectDir, entry.name), { recursive: true });
|
|
7601
7990
|
}
|
|
7602
|
-
await
|
|
7991
|
+
await mkdir7(path14.join(projectDir, "assets"), { recursive: true });
|
|
7603
7992
|
} else {
|
|
7604
7993
|
const tplManifest = await getAssetPath(`templates/${template}/manifest.yaml`);
|
|
7605
7994
|
const tplChapter = await getAssetPath(`templates/${template}/chapter-01.md`);
|
|
7606
|
-
await
|
|
7607
|
-
await copyFile(tplManifest,
|
|
7608
|
-
await copyFile(tplChapter,
|
|
7995
|
+
await mkdir7(path14.join(projectDir, "assets"), { recursive: true });
|
|
7996
|
+
await copyFile(tplManifest, path14.join(projectDir, MANIFEST_FILENAMES[0]));
|
|
7997
|
+
await copyFile(tplChapter, path14.join(projectDir, "chapter-01.md"));
|
|
7609
7998
|
const starterThemeId = STARTER_THEME_FOR_TEMPLATE[template] ?? "clean-book";
|
|
7610
7999
|
const starterCss = await getAssetPath(`themes/${starterThemeId}/theme.css`);
|
|
7611
|
-
await
|
|
7612
|
-
await copyFile(starterCss,
|
|
8000
|
+
await mkdir7(path14.join(projectDir, "styles"), { recursive: true });
|
|
8001
|
+
await copyFile(starterCss, path14.join(projectDir, "styles", "book.css"));
|
|
7613
8002
|
}
|
|
7614
8003
|
} catch (e) {
|
|
7615
8004
|
throw new CreateProjectErrorImpl("scaffold-io", `Could not create the project files: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -7619,18 +8008,34 @@ async function scaffoldProject(options) {
|
|
|
7619
8008
|
} catch (e) {
|
|
7620
8009
|
throw new CreateProjectErrorImpl("scaffold-io", `Could not write .gitignore: ${e instanceof Error ? e.message : String(e)}`);
|
|
7621
8010
|
}
|
|
7622
|
-
const manifestPath = MANIFEST_FILENAMES.map((name2) =>
|
|
8011
|
+
const manifestPath = MANIFEST_FILENAMES.map((name2) => path14.join(projectDir, name2)).find(existsSync11) ?? path14.join(projectDir, MANIFEST_FILENAMES[0]);
|
|
7623
8012
|
const author = (options.author ?? "").trim() || DEFAULT_AUTHOR;
|
|
7624
8013
|
const substitutions = {
|
|
7625
8014
|
"{{TITLE}}": escapeYamlScalar(name),
|
|
7626
8015
|
"{{AUTHOR}}": escapeYamlScalar(author)
|
|
7627
8016
|
};
|
|
7628
|
-
let openFile =
|
|
8017
|
+
let openFile = path14.join(projectDir, "chapter-01.md");
|
|
7629
8018
|
try {
|
|
7630
8019
|
await fillTemplateFile(manifestPath, substitutions);
|
|
8020
|
+
if (preset) {
|
|
8021
|
+
const { doc, file } = await loadManifestDoc(projectDir);
|
|
8022
|
+
doc.set("preset", preset);
|
|
8023
|
+
doc.set("targets", doc.createNode(targets ?? []));
|
|
8024
|
+
if (options.customPage) {
|
|
8025
|
+
const page = {
|
|
8026
|
+
width: options.customPage.width,
|
|
8027
|
+
height: options.customPage.height
|
|
8028
|
+
};
|
|
8029
|
+
if (options.customPage.tolerance !== undefined) {
|
|
8030
|
+
page.tolerance = options.customPage.tolerance;
|
|
8031
|
+
}
|
|
8032
|
+
doc.set("page", doc.createNode(page));
|
|
8033
|
+
}
|
|
8034
|
+
await writeManifestDoc(file, doc);
|
|
8035
|
+
}
|
|
7631
8036
|
const firstSource = await firstSourceFile(manifestPath);
|
|
7632
8037
|
if (firstSource)
|
|
7633
|
-
openFile =
|
|
8038
|
+
openFile = path14.join(projectDir, firstSource);
|
|
7634
8039
|
await fillTemplateFile(openFile, { "{{TITLE}}": name }).catch(() => {});
|
|
7635
8040
|
} catch (e) {
|
|
7636
8041
|
throw new CreateProjectErrorImpl("scaffold-io", `Could not finalise the project files: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -7640,7 +8045,7 @@ async function scaffoldProject(options) {
|
|
|
7640
8045
|
let versionHistoryError;
|
|
7641
8046
|
if (requested === "local-git") {
|
|
7642
8047
|
try {
|
|
7643
|
-
const { providerFor } = await import("./source-provider-
|
|
8048
|
+
const { providerFor } = await import("./source-provider-c1rjm2c0.js");
|
|
7644
8049
|
const provider = providerFor({ type: "local-folder", path: projectDir });
|
|
7645
8050
|
await provider.initVersionHistory({
|
|
7646
8051
|
projectDir,
|
|
@@ -7650,9 +8055,9 @@ async function scaffoldProject(options) {
|
|
|
7650
8055
|
versionHistory = "local-git";
|
|
7651
8056
|
} catch (e) {
|
|
7652
8057
|
versionHistory = "none";
|
|
7653
|
-
const { findEnclosingRepoDir } = await import("./project-source-
|
|
8058
|
+
const { findEnclosingRepoDir } = await import("./project-source-p0gn1wd5.js");
|
|
7654
8059
|
const enclosingRepoDir = await findEnclosingRepoDir(projectDir);
|
|
7655
|
-
versionHistoryError = enclosingRepoDir ? `This book was added to ${
|
|
8060
|
+
versionHistoryError = enclosingRepoDir ? `This book was added to ${path14.basename(enclosingRepoDir)}'s shared version history; save a snapshot to record it.` : e instanceof Error ? e.message : String(e);
|
|
7656
8061
|
}
|
|
7657
8062
|
}
|
|
7658
8063
|
const result = {
|
|
@@ -7667,10 +8072,10 @@ async function scaffoldProject(options) {
|
|
|
7667
8072
|
return result;
|
|
7668
8073
|
}
|
|
7669
8074
|
async function ensureGitignoreHasDist(projectDir) {
|
|
7670
|
-
const gitignorePath =
|
|
8075
|
+
const gitignorePath = path14.join(projectDir, ".gitignore");
|
|
7671
8076
|
let existing = null;
|
|
7672
8077
|
try {
|
|
7673
|
-
existing = await
|
|
8078
|
+
existing = await readFile22(gitignorePath, "utf8");
|
|
7674
8079
|
} catch {}
|
|
7675
8080
|
if (existing === null) {
|
|
7676
8081
|
await writeFile6(gitignorePath, `dist/
|
|
@@ -7690,7 +8095,7 @@ async function ensureGitignoreHasDist(projectDir) {
|
|
|
7690
8095
|
async function firstSourceFile(manifestPath) {
|
|
7691
8096
|
let text;
|
|
7692
8097
|
try {
|
|
7693
|
-
text = await
|
|
8098
|
+
text = await readFile22(manifestPath, "utf8");
|
|
7694
8099
|
} catch {
|
|
7695
8100
|
return;
|
|
7696
8101
|
}
|
|
@@ -7702,7 +8107,7 @@ async function firstSourceFile(manifestPath) {
|
|
|
7702
8107
|
return m ? m[1].trim() : undefined;
|
|
7703
8108
|
}
|
|
7704
8109
|
async function fillTemplateFile(filePath2, substitutions) {
|
|
7705
|
-
let text = await
|
|
8110
|
+
let text = await readFile22(filePath2, "utf8");
|
|
7706
8111
|
for (const [token, value] of Object.entries(substitutions)) {
|
|
7707
8112
|
text = text.split(token).join(value);
|
|
7708
8113
|
}
|
|
@@ -7710,9 +8115,9 @@ async function fillTemplateFile(filePath2, substitutions) {
|
|
|
7710
8115
|
}
|
|
7711
8116
|
|
|
7712
8117
|
// src/lib/project-templates.ts
|
|
8118
|
+
import { isMap, isScalar, isSeq as isSeq2, parseDocument as parseDocument2 } from "yaml";
|
|
7713
8119
|
var BUILT_IN_TEMPLATE_IDS = [
|
|
7714
8120
|
"book",
|
|
7715
|
-
"ttrpg",
|
|
7716
8121
|
"zine",
|
|
7717
8122
|
"technical"
|
|
7718
8123
|
];
|
|
@@ -7728,60 +8133,7 @@ var SKIP_ENTRIES = new Set([
|
|
|
7728
8133
|
|
|
7729
8134
|
// src/lib/plugin-manager.ts
|
|
7730
8135
|
import path16 from "node:path";
|
|
7731
|
-
import { isSeq as
|
|
7732
|
-
|
|
7733
|
-
// src/lib/manifest-doc.ts
|
|
7734
|
-
import { existsSync as existsSync11 } from "node:fs";
|
|
7735
|
-
import { randomUUID } from "node:crypto";
|
|
7736
|
-
import { mkdir as mkdir7, open, readFile as readFile22, rename, rm as rm2 } from "node:fs/promises";
|
|
7737
|
-
import path14 from "node:path";
|
|
7738
|
-
import { parseDocument, isSeq, YAMLSeq } from "yaml";
|
|
7739
|
-
function resolveManifestPath(projectDir) {
|
|
7740
|
-
const existing = MANIFEST_FILENAMES.find((name) => existsSync11(path14.join(projectDir, name)));
|
|
7741
|
-
return path14.join(projectDir, existing ?? MANIFEST_FILENAMES[0]);
|
|
7742
|
-
}
|
|
7743
|
-
async function loadManifestDoc(projectDir) {
|
|
7744
|
-
const file = resolveManifestPath(projectDir);
|
|
7745
|
-
let text = "";
|
|
7746
|
-
try {
|
|
7747
|
-
text = await readFile22(file, "utf8");
|
|
7748
|
-
} catch (error2) {
|
|
7749
|
-
if (error2.code !== "ENOENT")
|
|
7750
|
-
throw error2;
|
|
7751
|
-
}
|
|
7752
|
-
return { doc: parseDocument(text), file };
|
|
7753
|
-
}
|
|
7754
|
-
async function writeManifestDoc(file, doc) {
|
|
7755
|
-
const dir = path14.dirname(file);
|
|
7756
|
-
await mkdir7(dir, { recursive: true });
|
|
7757
|
-
const temporary = path14.join(dir, `.${path14.basename(file)}.tmp-${process.pid}-${randomUUID()}`);
|
|
7758
|
-
try {
|
|
7759
|
-
const handle = await open(temporary, "wx", 438);
|
|
7760
|
-
try {
|
|
7761
|
-
await handle.writeFile(doc.toString(), "utf8");
|
|
7762
|
-
await handle.sync();
|
|
7763
|
-
} finally {
|
|
7764
|
-
await handle.close();
|
|
7765
|
-
}
|
|
7766
|
-
await rename(temporary, file);
|
|
7767
|
-
const directory = await open(dir, "r").catch(() => null);
|
|
7768
|
-
if (directory) {
|
|
7769
|
-
await directory.sync().catch(() => {});
|
|
7770
|
-
await directory.close();
|
|
7771
|
-
}
|
|
7772
|
-
} finally {
|
|
7773
|
-
await rm2(temporary, { force: true });
|
|
7774
|
-
}
|
|
7775
|
-
}
|
|
7776
|
-
function ensureSeq(doc, key) {
|
|
7777
|
-
let seq = doc.get(key, true);
|
|
7778
|
-
if (!isSeq(seq)) {
|
|
7779
|
-
const fresh = new YAMLSeq(doc.schema);
|
|
7780
|
-
doc.set(key, fresh);
|
|
7781
|
-
seq = fresh;
|
|
7782
|
-
}
|
|
7783
|
-
return seq;
|
|
7784
|
-
}
|
|
8136
|
+
import { isSeq as isSeq3, isMap as isMap2, isScalar as isScalar2, YAMLMap, Scalar } from "yaml";
|
|
7785
8137
|
|
|
7786
8138
|
// src/lib/npm-plugin-installer.ts
|
|
7787
8139
|
import { createHash as createHash4, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
|
|
@@ -8549,9 +8901,9 @@ function isLocalRef2(ref) {
|
|
|
8549
8901
|
return ref.startsWith("./") || ref.startsWith("../") || ref.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(ref) || /\.(m?js|cjs|ts)$/i.test(ref) || !ref.startsWith("@") && ref.includes("/");
|
|
8550
8902
|
}
|
|
8551
8903
|
function itemRef(item) {
|
|
8552
|
-
if (
|
|
8904
|
+
if (isScalar2(item))
|
|
8553
8905
|
return typeof item.value === "string" ? item.value : null;
|
|
8554
|
-
if (
|
|
8906
|
+
if (isMap2(item)) {
|
|
8555
8907
|
const p = item.get("path");
|
|
8556
8908
|
const n = item.get("name");
|
|
8557
8909
|
if (typeof p === "string")
|
|
@@ -8567,7 +8919,7 @@ function refKind(ref) {
|
|
|
8567
8919
|
async function listProjectPlugins(projectDir) {
|
|
8568
8920
|
const { doc } = await loadManifestDoc(projectDir);
|
|
8569
8921
|
const seq = doc.get("plugins", true);
|
|
8570
|
-
if (!
|
|
8922
|
+
if (!isSeq3(seq))
|
|
8571
8923
|
return [];
|
|
8572
8924
|
const out = [];
|
|
8573
8925
|
for (const item of seq.items) {
|
|
@@ -8578,7 +8930,7 @@ async function listProjectPlugins(projectDir) {
|
|
|
8578
8930
|
let kind;
|
|
8579
8931
|
let version;
|
|
8580
8932
|
let exportName;
|
|
8581
|
-
if (
|
|
8933
|
+
if (isMap2(item)) {
|
|
8582
8934
|
const e = item.get("enabled");
|
|
8583
8935
|
if (e === false)
|
|
8584
8936
|
enabled = false;
|
|
@@ -8623,7 +8975,7 @@ async function recordInstalledNpmPlugin(projectDir, name, version, exportName) {
|
|
|
8623
8975
|
const seq = ensureSeq(doc, "plugins");
|
|
8624
8976
|
const idx = indexOfRef(seq, name);
|
|
8625
8977
|
let map;
|
|
8626
|
-
if (idx >= 0 &&
|
|
8978
|
+
if (idx >= 0 && isMap2(seq.items[idx])) {
|
|
8627
8979
|
map = seq.items[idx];
|
|
8628
8980
|
} else {
|
|
8629
8981
|
map = new YAMLMap(doc.schema);
|
|
@@ -9955,8 +10307,8 @@ var drivethrurpgProvider = {
|
|
|
9955
10307
|
}
|
|
9956
10308
|
issues.push({
|
|
9957
10309
|
severity: "info",
|
|
9958
|
-
id: "drivethrurpg/validate-
|
|
9959
|
-
message: "Tip: run `gutterpress validate --
|
|
10310
|
+
id: "drivethrurpg/validate-target",
|
|
10311
|
+
message: "Tip: run `gutterpress validate --target dtrpg` for DriveThruRPG's print-compliance checks before uploading."
|
|
9960
10312
|
});
|
|
9961
10313
|
return issues;
|
|
9962
10314
|
},
|
|
@@ -10070,7 +10422,7 @@ var info4 = {
|
|
|
10070
10422
|
label: "itch.io",
|
|
10071
10423
|
kind: "api",
|
|
10072
10424
|
format: "pdf",
|
|
10073
|
-
description: "Upload the PDF to your itch.io project page (games,
|
|
10425
|
+
description: "Upload the PDF to your itch.io project page (games, zines, and other printable projects).",
|
|
10074
10426
|
configFields: [
|
|
10075
10427
|
{ key: "target", label: "Project (user/game)", placeholder: "you/your-book" },
|
|
10076
10428
|
{ key: "channel", label: "Channel", placeholder: "pdf" }
|
|
@@ -12253,7 +12605,7 @@ async function dispatchToHandler(kind, ctx, error2) {
|
|
|
12253
12605
|
return result;
|
|
12254
12606
|
}
|
|
12255
12607
|
// src/lib/theme-manager.ts
|
|
12256
|
-
import { isSeq as
|
|
12608
|
+
import { isSeq as isSeq4, Scalar as Scalar2 } from "yaml";
|
|
12257
12609
|
var THEMES_DIR = "themes";
|
|
12258
12610
|
var THEME_HREF_RE = new RegExp(`^${THEMES_DIR}/([^/]+)/theme\\.css$`);
|
|
12259
12611
|
// src/lib/theme-import.ts
|
|
@@ -12277,7 +12629,7 @@ var ALLOWED_ASSET_EXTS = new Set([
|
|
|
12277
12629
|
".css"
|
|
12278
12630
|
]);
|
|
12279
12631
|
// src/lib/manifest-config.ts
|
|
12280
|
-
import { isSeq as
|
|
12632
|
+
import { isSeq as isSeq5, isMap as isMap3, YAMLSeq as YAMLSeq3, Scalar as Scalar3 } from "yaml";
|
|
12281
12633
|
// src/lib/host-policy.ts
|
|
12282
12634
|
var AUTO_SNAPSHOT_MAX_MINUTES = 24 * 60;
|
|
12283
12635
|
var AUTO_SYNC_MAX_MINUTES = 24 * 60;
|
|
@@ -12374,5 +12726,5 @@ function normalizeProjectKey(projectDir) {
|
|
|
12374
12726
|
return projectDir.replace(/[\\/]+$/, "");
|
|
12375
12727
|
}
|
|
12376
12728
|
// src/lib/publish/manifest-publish.ts
|
|
12377
|
-
import { isMap as
|
|
12378
|
-
export { MANIFEST_FILENAMES, parseNpmPluginSpec, runLint, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, BUILT_IN_TEMPLATE_IDS, addNpmPlugin, isAppHeartbeatFresh, classifyFromHealth, classifyGitError, makeManualGuidance, inspectRepo, verifyRepoReadable, isUnbornRepo, publishCredentialKey, publishConnectionStatus, listPublishAccounts, listPublishProviders, publishProviderFor, runPublish, connectPublishProvider, buildRecoveryContext, recover16 as recover };
|
|
12729
|
+
import { isMap as isMap4 } from "yaml";
|
|
12730
|
+
export { PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, MANIFEST_FILENAMES, parseNpmPluginSpec, runLint, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, BUILT_IN_TEMPLATE_IDS, addNpmPlugin, isAppHeartbeatFresh, classifyFromHealth, classifyGitError, makeManualGuidance, inspectRepo, verifyRepoReadable, isUnbornRepo, publishCredentialKey, publishConnectionStatus, listPublishAccounts, listPublishProviders, publishProviderFor, runPublish, connectPublishProvider, buildRecoveryContext, recover16 as recover };
|