gutterpress 0.11.23-beta.2 → 0.11.23
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 +12 -2
- package/dist/api/index.d.ts +5 -5
- package/dist/api/index.js +19 -7
- package/dist/{build-3e18wnqj.js → build-ph6jn930.js} +9 -9
- package/dist/checks/asset/approved-fonts.d.ts +8 -0
- package/dist/checks/asset/extensions.d.ts +1 -1
- package/dist/checks/asset/index.d.ts +1 -0
- package/dist/{cli-88arpdke.js → cli-axqsy7xn.js} +296 -65
- package/dist/{cli-9n9kg58f.js → cli-b8rmyy7t.js} +1 -1
- package/dist/{cli-x7gcdg6w.js → cli-ep43hgqb.js} +1 -1
- package/dist/{cli-v0evdpdf.js → cli-eymdsefg.js} +1 -1
- package/dist/{cli-pd2cje5b.js → cli-fsjre61x.js} +1 -1
- package/dist/{cli-0ep11b0q.js → cli-gy95bxec.js} +1 -1
- package/dist/{cli-pnrararp.js → cli-vqt6808y.js} +162 -55
- package/dist/{cli-tgnyvra3.js → cli-w6ywbxym.js} +35 -16
- package/dist/cli.js +12 -12
- package/dist/{doctor-2f4s9dyn.js → doctor-rx93cd3j.js} +3 -3
- package/dist/{engine-c4pxz79g.js → engine-17v87vq5.js} +1 -1
- package/dist/{engine-cs5g2ez0.js → engine-y9fnarfa.js} +2 -2
- package/dist/{ext-70gv86v5.js → ext-3b64v44z.js} +27 -10
- package/dist/{extension-restore-chj5nx3t.js → extension-restore-3yy4pzy9.js} +3 -3
- package/dist/{extension-restore-pd87p8r2.js → extension-restore-6hsxgmvn.js} +5 -5
- package/dist/{index-80vg3ed6.js → index-37cxffyb.js} +35 -16
- package/dist/{index-ytjkvwy5.js → index-7wgf4bqz.js} +321 -66
- package/dist/{index-swfdgn2n.js → index-d9w3r89w.js} +1 -1
- package/dist/{index-5x42amh8.js → index-g3te5ey1.js} +2 -1
- package/dist/{index-7j3hkwya.js → index-kw4tbthz.js} +1 -1
- package/dist/{index-0k43evt0.js → index-rzdn6r10.js} +186 -60
- package/dist/{index-2t1gdma7.js → index-santcs4q.js} +1 -1
- package/dist/index.js +35 -8
- package/dist/lib/check-options.d.ts +70 -0
- package/dist/lib/extension-manager.d.ts +16 -1
- package/dist/lib/extension-scaffold.d.ts +15 -2
- package/dist/lib/extension-specifier.d.ts +8 -1
- package/dist/lib/manifest-config.d.ts +3 -1
- package/dist/lib/manifest-old-spellings.d.ts +32 -9
- package/dist/lib/markdown/math.d.ts +1 -1
- package/dist/lib/markdown/typography.d.ts +1 -0
- package/dist/lib/page-size.d.ts +12 -4
- package/dist/lib/plugin-vendor.d.ts +6 -0
- package/dist/lib/presets.d.ts +2 -2
- package/dist/lib/root-tokens.d.ts +2 -1
- package/dist/lib/style-resolver.d.ts +2 -1
- package/dist/lib/version-changes.d.ts +9 -3
- package/dist/{manifest.schema-0jgj0jt1.json → manifest.schema-5cm13vr3.json} +215 -5
- package/dist/{new-d61n5cn0.js → new-3xrnhzr8.js} +22 -15
- package/dist/{plugins-0hhw6s17.js → plugins-1ed7bbxn.js} +2 -2
- package/dist/{plugins-e0n46s6m.js → plugins-ar5wrek4.js} +4 -4
- package/dist/{preflight-fjayhjr5.js → preflight-shmd1cnr.js} +9 -9
- package/dist/{preview-h815jrfb.js → preview-dadmsstg.js} +9 -9
- package/dist/{publish-ft39zgma.js → publish-s7vb3q2y.js} +9 -9
- package/dist/render.js +43 -11
- package/dist/schema/manifest.types.d.ts +45 -7
- package/dist/{source-provider-j1w7byeq.js → source-provider-3g3yrn1f.js} +2 -2
- package/dist/{source-provider-tjaf303m.js → source-provider-azg9ywhb.js} +2 -2
- package/dist/{validate-b201dbrb.js → validate-0h3b5vq4.js} +9 -9
- package/package.json +1 -1
- /package/dist/{cli-y28j019d.js → cli-1dha1nxk.js} +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BUNDLED_EXTENSION_DETAILS,
|
|
2
3
|
EXTENSION_MANIFEST_FILENAME,
|
|
3
4
|
TWO_VERSIONS_OPEN,
|
|
4
5
|
bundledExtension,
|
|
@@ -11,10 +12,10 @@ import {
|
|
|
11
12
|
prettify,
|
|
12
13
|
readExtensionMeta,
|
|
13
14
|
slugify
|
|
14
|
-
} from "./cli-
|
|
15
|
+
} from "./cli-w6ywbxym.js";
|
|
15
16
|
import {
|
|
16
17
|
log
|
|
17
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-b8rmyy7t.js";
|
|
18
19
|
import {
|
|
19
20
|
UsageError
|
|
20
21
|
} from "./cli-d8xjns66.js";
|
|
@@ -37,7 +38,7 @@ import {
|
|
|
37
38
|
vendoredNpmPluginRoot,
|
|
38
39
|
vendoredNpmPluginRoots,
|
|
39
40
|
windowsPathKey
|
|
40
|
-
} from "./cli-
|
|
41
|
+
} from "./cli-1dha1nxk.js";
|
|
41
42
|
import {
|
|
42
43
|
__require
|
|
43
44
|
} from "./cli-37x76zdn.js";
|
|
@@ -79,10 +80,10 @@ async function withFetchTimeout(options, run) {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
// src/lib/extension-manager.ts
|
|
82
|
-
import { readdir, readFile as readFile5, rm as rm3, stat } from "node:fs/promises";
|
|
83
|
+
import { mkdir as mkdir3, readdir, readFile as readFile5, rm as rm3, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
83
84
|
import { existsSync as existsSync3 } from "node:fs";
|
|
84
85
|
import path4 from "node:path";
|
|
85
|
-
import { isSeq as isSeq2, isMap, isScalar, YAMLMap, Scalar } from "yaml";
|
|
86
|
+
import { isSeq as isSeq2, isMap as isMap3, isScalar, YAMLMap, Scalar } from "yaml";
|
|
86
87
|
|
|
87
88
|
// src/lib/manifest-doc.ts
|
|
88
89
|
import { existsSync as existsSync2 } from "node:fs";
|
|
@@ -145,7 +146,8 @@ var DTRPG_PRESET = {
|
|
|
145
146
|
},
|
|
146
147
|
validate: {
|
|
147
148
|
assets: {
|
|
148
|
-
maxImageSize: 1e7
|
|
149
|
+
maxImageSize: 1e7,
|
|
150
|
+
approvedFontFiles: []
|
|
149
151
|
},
|
|
150
152
|
pdf: {
|
|
151
153
|
minImageResolution: 300,
|
|
@@ -202,7 +204,8 @@ var BOOK_PRESET = {
|
|
|
202
204
|
},
|
|
203
205
|
validate: {
|
|
204
206
|
assets: {
|
|
205
|
-
maxImageSize: 1e7
|
|
207
|
+
maxImageSize: 1e7,
|
|
208
|
+
approvedFontFiles: []
|
|
206
209
|
},
|
|
207
210
|
pdf: {
|
|
208
211
|
minImageResolution: 300,
|
|
@@ -362,6 +365,124 @@ function applyDefaultPdfStrictChecks(config) {
|
|
|
362
365
|
return next;
|
|
363
366
|
}
|
|
364
367
|
|
|
368
|
+
// src/lib/manifest-old-spellings.ts
|
|
369
|
+
import { isMap as isMap2 } from "yaml";
|
|
370
|
+
|
|
371
|
+
// src/lib/check-options.ts
|
|
372
|
+
import { isMap } from "yaml";
|
|
373
|
+
var CHECK_OPTIONS = {
|
|
374
|
+
"pdf.print.ink-coverage": {
|
|
375
|
+
maxTac: { at: "ink.maxTac", kind: "number" },
|
|
376
|
+
tacTolerance: { at: "ink.tacTolerance", kind: "number" }
|
|
377
|
+
},
|
|
378
|
+
"pdf.print.page-size": {
|
|
379
|
+
tolerance: { at: "page.tolerance", kind: "number" }
|
|
380
|
+
},
|
|
381
|
+
"pdf.print.image-resolution": {
|
|
382
|
+
minImageResolution: { at: "validate.pdf.minImageResolution", kind: "number" }
|
|
383
|
+
},
|
|
384
|
+
"pdf.print.bleed": {
|
|
385
|
+
bleedSize: { at: "validate.pdf.bleedSize", kind: "number" }
|
|
386
|
+
},
|
|
387
|
+
"asset.image.file-size": {
|
|
388
|
+
maxImageSize: { at: "validate.assets.maxImageSize", kind: "number" }
|
|
389
|
+
},
|
|
390
|
+
"asset.font.approved-files": {
|
|
391
|
+
approvedFontFiles: { at: "validate.assets.approvedFontFiles", kind: "patterns" }
|
|
392
|
+
},
|
|
393
|
+
"heuristic.decoration.layer-count": {
|
|
394
|
+
maxDecorativeLayers: { at: "validate.heuristics.maxDecorativeLayers", kind: "number" }
|
|
395
|
+
},
|
|
396
|
+
"heuristic.whitespace.text-density": {
|
|
397
|
+
textDensityRange: { at: "validate.heuristics.textDensityRange", kind: "range" }
|
|
398
|
+
},
|
|
399
|
+
"heuristic.chunking.section-density": {
|
|
400
|
+
maxParagraphsPerSection: { at: "validate.heuristics.maxParagraphsPerSection", kind: "number" }
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
function optionForOldSpelling(at) {
|
|
404
|
+
for (const [id, options] of Object.entries(CHECK_OPTIONS)) {
|
|
405
|
+
for (const [option, spec] of Object.entries(options)) {
|
|
406
|
+
if (spec.at === at)
|
|
407
|
+
return { id, option };
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
function isPlainObject(v) {
|
|
413
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
414
|
+
}
|
|
415
|
+
var isAmount = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
416
|
+
var isRangeEnd = ([k, v]) => (k === "min" || k === "max") && isAmount(v);
|
|
417
|
+
var MUST_BE = {
|
|
418
|
+
number: "a number, 0 or more",
|
|
419
|
+
range: "`{ min, max }` (numbers, 0 or more)",
|
|
420
|
+
patterns: "a list of file patterns"
|
|
421
|
+
};
|
|
422
|
+
function fits(kind, value) {
|
|
423
|
+
if (kind === "number")
|
|
424
|
+
return isAmount(value);
|
|
425
|
+
if (kind === "range")
|
|
426
|
+
return isPlainObject(value) && Object.entries(value).every(isRangeEnd);
|
|
427
|
+
return Array.isArray(value) && value.every((p) => typeof p === "string");
|
|
428
|
+
}
|
|
429
|
+
function checked(id, option, kind, value) {
|
|
430
|
+
if (fits(kind, value))
|
|
431
|
+
return value;
|
|
432
|
+
throw new UsageError(`Manifest field \`checks.${id}.${option}\` must be ${MUST_BE[kind]}, got ${JSON.stringify(value)}.`);
|
|
433
|
+
}
|
|
434
|
+
function isCheckLevelInput(value) {
|
|
435
|
+
return typeof value === "boolean" || ["off", "on", "info", "warn", "warning", "error"].includes(value);
|
|
436
|
+
}
|
|
437
|
+
function readOldThreshold(at, value) {
|
|
438
|
+
const moved = optionForOldSpelling(at);
|
|
439
|
+
if (!moved)
|
|
440
|
+
return;
|
|
441
|
+
const { kind } = CHECK_OPTIONS[moved.id][moved.option];
|
|
442
|
+
if (fits(kind, value))
|
|
443
|
+
return { ...moved, value };
|
|
444
|
+
const kept = kind === "range" && isPlainObject(value) ? Object.entries(value).filter(isRangeEnd) : [];
|
|
445
|
+
return { ...moved, ...kept.length > 0 ? { value: Object.fromEntries(kept) } : {}, mustBe: MUST_BE[kind] };
|
|
446
|
+
}
|
|
447
|
+
function readCheckOptions(id, entry) {
|
|
448
|
+
const known = CHECK_OPTIONS[id] ?? {};
|
|
449
|
+
const out = {};
|
|
450
|
+
for (const [option, value] of Object.entries(entry)) {
|
|
451
|
+
if (option === "level" || value === null || value === undefined)
|
|
452
|
+
continue;
|
|
453
|
+
const spec = known[option];
|
|
454
|
+
if (!spec) {
|
|
455
|
+
const takes = Object.keys(known);
|
|
456
|
+
throw new UsageError(`Manifest field \`checks.${id}\` has no option \`${option}\`. ` + (takes.length > 0 ? `It takes \`level\` and ${takes.map((o) => `\`${o}\``).join(", ")}.` : "It takes only `level` (off, on, info, warn or error)."));
|
|
457
|
+
}
|
|
458
|
+
out[option] = checked(id, option, spec.kind, value);
|
|
459
|
+
}
|
|
460
|
+
return out;
|
|
461
|
+
}
|
|
462
|
+
function applyCheckOptions(config, options) {
|
|
463
|
+
for (const [id, values] of Object.entries(options)) {
|
|
464
|
+
for (const [option, value] of Object.entries(values)) {
|
|
465
|
+
const spec = CHECK_OPTIONS[id][option];
|
|
466
|
+
const keys = spec.at.split(".");
|
|
467
|
+
const leaf = keys.pop();
|
|
468
|
+
let node = config;
|
|
469
|
+
for (const key of keys)
|
|
470
|
+
node = node[key];
|
|
471
|
+
node[leaf] = spec.kind === "range" ? { ...node[leaf], ...value } : value;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function setCheckOption(doc, id, option, value) {
|
|
476
|
+
if (!isMap(doc.get("checks", true)))
|
|
477
|
+
doc.set("checks", doc.createNode({}));
|
|
478
|
+
const current = doc.getIn(["checks", id], true);
|
|
479
|
+
if (!isMap(current)) {
|
|
480
|
+
const level = doc.getIn(["checks", id]);
|
|
481
|
+
doc.setIn(["checks", id], doc.createNode(level === undefined || level === null ? {} : { level }));
|
|
482
|
+
}
|
|
483
|
+
doc.setIn(["checks", id, option], value);
|
|
484
|
+
}
|
|
485
|
+
|
|
365
486
|
// src/lib/manifest-old-spellings.ts
|
|
366
487
|
var SOURCE_TOOL_CHECKS = {
|
|
367
488
|
markdownlint: "source.markdownlint",
|
|
@@ -380,6 +501,7 @@ var FLAG_CHECKS = {
|
|
|
380
501
|
function isObject(v) {
|
|
381
502
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
382
503
|
}
|
|
504
|
+
var optionSpelling = (id, option, value) => `checks: { ${id}: { ${option}: ${JSON.stringify(value)} } }`;
|
|
383
505
|
function readOldSpellings(raw) {
|
|
384
506
|
const { source, lint, validate, ink, ...manifest } = raw;
|
|
385
507
|
const tolerance = isObject(raw.page) && "tolerance" in raw.page;
|
|
@@ -391,7 +513,32 @@ function readOldSpellings(raw) {
|
|
|
391
513
|
}
|
|
392
514
|
const renamed = [];
|
|
393
515
|
const dropped = [];
|
|
394
|
-
const
|
|
516
|
+
const unusable = [];
|
|
517
|
+
const levels = {};
|
|
518
|
+
const options = {};
|
|
519
|
+
const threshold = (at, value) => {
|
|
520
|
+
const read = readOldThreshold(at, value);
|
|
521
|
+
if (!read) {
|
|
522
|
+
dropped.push(at);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
if (value === null || value === undefined)
|
|
526
|
+
return;
|
|
527
|
+
if (read.value !== undefined) {
|
|
528
|
+
(options[read.id] ??= {})[read.option] = read.value;
|
|
529
|
+
renamed.push(`${at} -> ${optionSpelling(read.id, read.option, read.value)}`);
|
|
530
|
+
}
|
|
531
|
+
if (read.mustBe) {
|
|
532
|
+
const kept = read.value !== undefined ? `kept ${Object.keys(read.value).join(" and ")}, ignored the rest` : "ignored";
|
|
533
|
+
unusable.push(`${at}: ${JSON.stringify(value)} is not ${read.mustBe} — ${kept}`);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
const level = (at, value) => {
|
|
537
|
+
if (isCheckLevelInput(value))
|
|
538
|
+
return value;
|
|
539
|
+
unusable.push(`${at}: ${JSON.stringify(value)} is not off, on, info, warn or error — ignored`);
|
|
540
|
+
return;
|
|
541
|
+
};
|
|
395
542
|
if (isObject(source) && "files" in source) {
|
|
396
543
|
renamed.push("source.files -> chapters");
|
|
397
544
|
if (manifest.chapters === undefined)
|
|
@@ -400,18 +547,37 @@ function readOldSpellings(raw) {
|
|
|
400
547
|
if (isObject(validate)) {
|
|
401
548
|
for (const [id, entry] of Object.entries(validate.checks ?? {})) {
|
|
402
549
|
if (entry === false || isObject(entry) && entry.enabled === false)
|
|
403
|
-
|
|
404
|
-
else if (isObject(entry) &&
|
|
405
|
-
|
|
406
|
-
else
|
|
407
|
-
|
|
550
|
+
levels[id] = "off";
|
|
551
|
+
else if (isObject(entry) && entry.severity !== undefined && entry.severity !== null) {
|
|
552
|
+
levels[id] = level(`validate.checks.${id}.severity`, entry.severity) ?? "on";
|
|
553
|
+
} else
|
|
554
|
+
levels[id] = "on";
|
|
408
555
|
}
|
|
409
556
|
if (validate.checks !== undefined)
|
|
410
557
|
renamed.push("validate.checks -> checks");
|
|
558
|
+
}
|
|
559
|
+
if (isObject(lint)) {
|
|
560
|
+
for (const [id, value] of Object.entries(lint.rules ?? {})) {
|
|
561
|
+
const read = level(`lint.rules.${id}`, value);
|
|
562
|
+
if (read !== undefined)
|
|
563
|
+
levels[id] = read;
|
|
564
|
+
}
|
|
565
|
+
if (lint.rules !== undefined)
|
|
566
|
+
renamed.push("lint.rules -> checks");
|
|
567
|
+
if (lint.enabled === false) {
|
|
568
|
+
levels["source.stylelint"] = "off";
|
|
569
|
+
renamed.push("lint.enabled: false -> checks: { source.stylelint: off }");
|
|
570
|
+
} else if (lint.enabled !== undefined) {
|
|
571
|
+
dropped.push("lint.enabled");
|
|
572
|
+
}
|
|
573
|
+
if (lint.configPath !== undefined)
|
|
574
|
+
dropped.push("lint.configPath");
|
|
575
|
+
}
|
|
576
|
+
if (isObject(validate)) {
|
|
411
577
|
for (const [tool, value] of Object.entries(validate.source ?? {})) {
|
|
412
578
|
const id = SOURCE_TOOL_CHECKS[tool];
|
|
413
579
|
if (id && value === false) {
|
|
414
|
-
|
|
580
|
+
levels[id] = "off";
|
|
415
581
|
renamed.push(`validate.source.${tool}: false -> checks: { ${id}: off }`);
|
|
416
582
|
} else if (id && tool !== "stylelint" && typeof value === "string") {
|
|
417
583
|
dropped.push(`validate.source.${tool} (the config file is found by its usual name in the book's folder or a folder above it)`);
|
|
@@ -423,11 +589,14 @@ function readOldSpellings(raw) {
|
|
|
423
589
|
for (const [key, value] of Object.entries(validate[block] ?? {})) {
|
|
424
590
|
const flag = FLAG_CHECKS[`${block}.${key}`];
|
|
425
591
|
if (flag && typeof value === "boolean") {
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
592
|
+
const on = value === flag.trueMeansOn;
|
|
593
|
+
if (!on)
|
|
594
|
+
levels[flag.check] = "off";
|
|
595
|
+
else
|
|
596
|
+
levels[flag.check] ??= "on";
|
|
597
|
+
renamed.push(`validate.${block}.${key}: ${value} -> checks: { ${flag.check}: ${String(levels[flag.check])} }`);
|
|
429
598
|
} else {
|
|
430
|
-
|
|
599
|
+
threshold(`validate.${block}.${key}`, value);
|
|
431
600
|
}
|
|
432
601
|
}
|
|
433
602
|
}
|
|
@@ -435,32 +604,28 @@ function readOldSpellings(raw) {
|
|
|
435
604
|
dropped.push("validate.enabled (`gutterpress build --skip-pre-validate --skip-post-validate` skips validation for one build)");
|
|
436
605
|
}
|
|
437
606
|
}
|
|
438
|
-
if (isObject(
|
|
439
|
-
for (const [
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
if (lint.enabled === false) {
|
|
444
|
-
checks["source.stylelint"] = "off";
|
|
445
|
-
renamed.push("lint.enabled: false -> checks: { source.stylelint: off }");
|
|
446
|
-
} else if (lint.enabled !== undefined) {
|
|
447
|
-
dropped.push("lint.enabled");
|
|
448
|
-
}
|
|
449
|
-
if (lint.configPath !== undefined)
|
|
450
|
-
dropped.push("lint.configPath");
|
|
607
|
+
if (isObject(ink)) {
|
|
608
|
+
for (const [key, value] of Object.entries(ink))
|
|
609
|
+
threshold(`ink.${key}`, value);
|
|
610
|
+
} else if (ink !== undefined && ink !== null) {
|
|
611
|
+
dropped.push("ink");
|
|
451
612
|
}
|
|
452
|
-
if (ink !== undefined)
|
|
453
|
-
dropped.push("ink (the preset and the publish target set it)");
|
|
454
613
|
if (tolerance) {
|
|
455
|
-
const { tolerance:
|
|
614
|
+
const { tolerance: value, ...page } = raw.page;
|
|
456
615
|
manifest.page = page;
|
|
457
|
-
|
|
616
|
+
threshold("page.tolerance", value);
|
|
617
|
+
}
|
|
618
|
+
const ids = new Set([...Object.keys(levels), ...Object.keys(options)]);
|
|
619
|
+
if (ids.size > 0) {
|
|
620
|
+
const checks = { ...manifest.checks };
|
|
621
|
+
for (const id of ids)
|
|
622
|
+
checks[id] = mergeEntry(levels[id], options[id], manifest.checks?.[id]);
|
|
623
|
+
manifest.checks = checks;
|
|
458
624
|
}
|
|
459
|
-
if (Object.keys(checks).length > 0)
|
|
460
|
-
manifest.checks = { ...checks, ...manifest.checks };
|
|
461
625
|
const lines = [
|
|
462
626
|
...renamed.map((r) => ` ${r}`),
|
|
463
|
-
...dropped.map((d) => ` ${d} — no longer a setting, ignored`)
|
|
627
|
+
...dropped.map((d) => ` ${d} — no longer a setting, ignored`),
|
|
628
|
+
...unusable.map((u) => ` ${u}`)
|
|
464
629
|
];
|
|
465
630
|
if (lines.length > 0) {
|
|
466
631
|
warnOnce(`old-manifest-spellings:${lines.join("|")}`, "[gutterpress] manifest.yaml uses spellings 0.11.23 replaced. They still work in this " + `release; rewrite them before the next one:
|
|
@@ -469,6 +634,18 @@ function readOldSpellings(raw) {
|
|
|
469
634
|
}
|
|
470
635
|
return manifest;
|
|
471
636
|
}
|
|
637
|
+
function mergeEntry(level, options, own) {
|
|
638
|
+
const ownEntry = isObject(own) ? own : own === undefined ? {} : { level: own };
|
|
639
|
+
const merged = {
|
|
640
|
+
...level !== undefined ? { level } : {},
|
|
641
|
+
...options,
|
|
642
|
+
...ownEntry
|
|
643
|
+
};
|
|
644
|
+
if (ownEntry.level === undefined && level !== undefined)
|
|
645
|
+
merged.level = level;
|
|
646
|
+
const keys = Object.keys(merged);
|
|
647
|
+
return keys.length === 1 && keys[0] === "level" ? merged.level : merged;
|
|
648
|
+
}
|
|
472
649
|
|
|
473
650
|
// src/lib/manifest.ts
|
|
474
651
|
var MANIFEST_FILENAMES = [
|
|
@@ -577,7 +754,7 @@ function pluginsRemovedMessage(raw) {
|
|
|
577
754
|
` + (lines.length > 0 ? lines.join(`
|
|
578
755
|
`) : " - ./plugins/my-plugin.js");
|
|
579
756
|
}
|
|
580
|
-
function
|
|
757
|
+
function isPlainObject2(v) {
|
|
581
758
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
582
759
|
}
|
|
583
760
|
function mergeShape(cli, manifest, preset) {
|
|
@@ -586,7 +763,7 @@ function mergeShape(cli, manifest, preset) {
|
|
|
586
763
|
const presetValue = preset[key];
|
|
587
764
|
const manifestValue = manifest ? manifest[key] : undefined;
|
|
588
765
|
const cliValue = cli ? cli[key] : undefined;
|
|
589
|
-
out[key] =
|
|
766
|
+
out[key] = isPlainObject2(presetValue) ? mergeShape(cliValue, manifestValue, presetValue) : cliValue ?? manifestValue ?? presetValue;
|
|
590
767
|
}
|
|
591
768
|
return out;
|
|
592
769
|
}
|
|
@@ -634,7 +811,7 @@ function resolveCustomPage(c, m) {
|
|
|
634
811
|
}
|
|
635
812
|
var MARGIN_EDGES = ["top", "bottom", "inside", "outside"];
|
|
636
813
|
function validatePageMargin(margin, size) {
|
|
637
|
-
const edges =
|
|
814
|
+
const edges = isPlainObject2(margin) && Object.keys(margin).every((k) => MARGIN_EDGES.includes(k)) && MARGIN_EDGES.every((e) => isNonNegativePoints(margin[e]));
|
|
638
815
|
if (!edges) {
|
|
639
816
|
throw new UsageError("Manifest field `page.margin` must set all four edges in points (72pt = 1in), for example\n" + ` page:
|
|
640
817
|
margin:
|
|
@@ -691,7 +868,9 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
691
868
|
const page = preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m);
|
|
692
869
|
if (page.margin !== undefined && page.margin !== null)
|
|
693
870
|
validatePageMargin(page.margin, page);
|
|
694
|
-
|
|
871
|
+
const manifestChecks = resolveChecks(m.checks);
|
|
872
|
+
const cliChecks = resolveChecks(c.checks);
|
|
873
|
+
const config = {
|
|
695
874
|
title: c.title ?? m.title ?? "Document",
|
|
696
875
|
authors: c.authors ?? m.authors ?? [],
|
|
697
876
|
language: resolveLanguage(c.language ?? m.language),
|
|
@@ -701,35 +880,47 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
701
880
|
extensions,
|
|
702
881
|
targets: resolveTargets(c.targets ?? m.targets, preset.defaultTargets),
|
|
703
882
|
chapters: c.chapters ?? m.chapters ?? preset.chapters,
|
|
704
|
-
checks: { ...preset.checks, ...
|
|
883
|
+
checks: { ...preset.checks, ...manifestChecks.levels, ...cliChecks.levels },
|
|
705
884
|
pdfx: mergeShape(c.pdfx, m.pdfx, preset.pdfx),
|
|
706
885
|
print: mergeShape(c.print, m.print, preset.print),
|
|
707
886
|
page,
|
|
708
887
|
ink: structuredClone(preset.ink),
|
|
709
888
|
validate: structuredClone(preset.validate)
|
|
710
889
|
};
|
|
711
|
-
|
|
712
|
-
|
|
890
|
+
applyCheckOptions(config, manifestChecks.options);
|
|
891
|
+
applyCheckOptions(config, cliChecks.options);
|
|
892
|
+
return config;
|
|
893
|
+
}
|
|
894
|
+
function checkLevel(id, value) {
|
|
895
|
+
if (!isCheckLevelInput(value)) {
|
|
896
|
+
throw new UsageError(`Manifest field \`checks.${id}\` must be off, on, info, warn or error, got ${JSON.stringify(value)}.`);
|
|
897
|
+
}
|
|
898
|
+
if (value === false || value === "off")
|
|
899
|
+
return "off";
|
|
900
|
+
if (value === true || value === "on")
|
|
901
|
+
return "on";
|
|
902
|
+
return value === "warn" || value === "warning" ? "warning" : value;
|
|
903
|
+
}
|
|
904
|
+
function resolveChecks(input) {
|
|
905
|
+
const levels = {};
|
|
906
|
+
const options = {};
|
|
713
907
|
if (input === undefined || input === null)
|
|
714
|
-
return {};
|
|
715
|
-
if (!
|
|
908
|
+
return { levels, options };
|
|
909
|
+
if (!isPlainObject2(input)) {
|
|
716
910
|
throw new UsageError("Manifest field `checks` must map check ids to off, on, info, warn or error.");
|
|
717
911
|
}
|
|
718
|
-
const out = {};
|
|
719
912
|
for (const [id, value] of Object.entries(input)) {
|
|
720
|
-
if (value
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
out[id] = "on";
|
|
724
|
-
else if (value === "warn" || value === "warning")
|
|
725
|
-
out[id] = "warning";
|
|
726
|
-
else if (value === "info" || value === "error")
|
|
727
|
-
out[id] = value;
|
|
728
|
-
else {
|
|
729
|
-
throw new UsageError(`Manifest field \`checks.${id}\` must be off, on, info, warn or error, got ${JSON.stringify(value)}.`);
|
|
913
|
+
if (!isPlainObject2(value)) {
|
|
914
|
+
levels[id] = checkLevel(id, value);
|
|
915
|
+
continue;
|
|
730
916
|
}
|
|
917
|
+
if (value.level !== undefined && value.level !== null)
|
|
918
|
+
levels[id] = checkLevel(`${id}.level`, value.level);
|
|
919
|
+
const own = readCheckOptions(id, value);
|
|
920
|
+
if (Object.keys(own).length > 0)
|
|
921
|
+
options[id] = own;
|
|
731
922
|
}
|
|
732
|
-
return
|
|
923
|
+
return { levels, options };
|
|
733
924
|
}
|
|
734
925
|
|
|
735
926
|
// src/lib/manifest-doc.ts
|
|
@@ -1502,7 +1693,7 @@ function withMutationLock(projectDir, mutation) {
|
|
|
1502
1693
|
function entryUse(item) {
|
|
1503
1694
|
if (isScalar(item))
|
|
1504
1695
|
return typeof item.value === "string" ? item.value.trim() : null;
|
|
1505
|
-
if (
|
|
1696
|
+
if (isMap3(item)) {
|
|
1506
1697
|
const u = item.get("use");
|
|
1507
1698
|
return typeof u === "string" ? u.trim() : null;
|
|
1508
1699
|
}
|
|
@@ -1512,7 +1703,7 @@ function rawEntry(item) {
|
|
|
1512
1703
|
const use = entryUse(item);
|
|
1513
1704
|
if (!use)
|
|
1514
1705
|
return null;
|
|
1515
|
-
if (!
|
|
1706
|
+
if (!isMap3(item))
|
|
1516
1707
|
return { use, enabled: true };
|
|
1517
1708
|
const x = item.get("export");
|
|
1518
1709
|
return {
|
|
@@ -1685,13 +1876,13 @@ async function setExtensionEnabled(projectDir, use, enabled) {
|
|
|
1685
1876
|
throw new Error(`Extension "${use}" is not in the manifest.`);
|
|
1686
1877
|
const item = seq.items[idx];
|
|
1687
1878
|
if (enabled) {
|
|
1688
|
-
if (
|
|
1879
|
+
if (isMap3(item)) {
|
|
1689
1880
|
item.delete("enabled");
|
|
1690
1881
|
if (item.items.length === 1 && typeof item.get("use") === "string") {
|
|
1691
1882
|
seq.items[idx] = new Scalar(item.get("use"));
|
|
1692
1883
|
}
|
|
1693
1884
|
}
|
|
1694
|
-
} else if (
|
|
1885
|
+
} else if (isMap3(item)) {
|
|
1695
1886
|
item.set("enabled", false);
|
|
1696
1887
|
} else {
|
|
1697
1888
|
const map = new YAMLMap(doc.schema);
|
|
@@ -1734,7 +1925,7 @@ async function upsertEntry(projectDir, use, exportName) {
|
|
|
1734
1925
|
const idx = indexOfUse(seq, use);
|
|
1735
1926
|
if (idx >= 0) {
|
|
1736
1927
|
const item = seq.items[idx];
|
|
1737
|
-
if (
|
|
1928
|
+
if (isMap3(item)) {
|
|
1738
1929
|
item.set("use", use);
|
|
1739
1930
|
if (exportName)
|
|
1740
1931
|
item.set("export", exportName);
|
|
@@ -1991,6 +2182,46 @@ async function updateExtensions(projectDir, options = {}) {
|
|
|
1991
2182
|
}
|
|
1992
2183
|
return updated;
|
|
1993
2184
|
}
|
|
2185
|
+
var BUILT_IN_LOOKS = BUNDLED_EXTENSION_DETAILS.filter((b) => b.css !== undefined).map((b) => b.name);
|
|
2186
|
+
async function addBuiltInStyleSet(projectDir, id) {
|
|
2187
|
+
const look = bundledExtension(id);
|
|
2188
|
+
if (look?.css === undefined) {
|
|
2189
|
+
throw new Error(`Unknown built-in look "${id}" (one of: ${BUILT_IN_LOOKS.join(", ")}).`);
|
|
2190
|
+
}
|
|
2191
|
+
const css = look.css;
|
|
2192
|
+
return withMutationLock(projectDir, async () => {
|
|
2193
|
+
const dest = path4.join(projectDir, EXTENSIONS_DIR, id);
|
|
2194
|
+
if (!existsSync3(dest)) {
|
|
2195
|
+
await mkdir3(dest, { recursive: true });
|
|
2196
|
+
const pkg = {
|
|
2197
|
+
name: id,
|
|
2198
|
+
description: look.description,
|
|
2199
|
+
author: "gutterpress",
|
|
2200
|
+
keywords: ["gutterpress", "gutterpress-look"],
|
|
2201
|
+
gutterpress: { styles: ["theme.css"] }
|
|
2202
|
+
};
|
|
2203
|
+
await writeFile2(path4.join(dest, EXTENSION_MANIFEST_FILENAME), `${JSON.stringify(pkg, null, 2)}
|
|
2204
|
+
`, "utf8");
|
|
2205
|
+
await writeFile2(path4.join(dest, "theme.css"), css, "utf8");
|
|
2206
|
+
}
|
|
2207
|
+
const use = `./${EXTENSIONS_DIR}/${id}`;
|
|
2208
|
+
await loadPlugin(extensionConfigFor({ use, kind: "path", name: use }), projectDir);
|
|
2209
|
+
const { doc, file } = await loadManifestDoc(projectDir);
|
|
2210
|
+
const seq = ensureSeq(doc, "extensions");
|
|
2211
|
+
if (indexOfUse(seq, use) < 0) {
|
|
2212
|
+
const at = indexOfUse(seq, id);
|
|
2213
|
+
const item = at < 0 ? undefined : seq.items[at];
|
|
2214
|
+
if (isMap3(item))
|
|
2215
|
+
item.set("use", use);
|
|
2216
|
+
else if (at >= 0)
|
|
2217
|
+
seq.items[at] = new Scalar(use);
|
|
2218
|
+
else
|
|
2219
|
+
seq.add(new Scalar(use));
|
|
2220
|
+
await writeManifestDoc(file, doc);
|
|
2221
|
+
}
|
|
2222
|
+
return await describeExtension(projectDir, use);
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
1994
2225
|
async function uniqueExtensionId(projectDir, base) {
|
|
1995
2226
|
const slug = slugify(base) || "extension";
|
|
1996
2227
|
let candidate = slug;
|
|
@@ -2117,4 +2348,4 @@ async function restoreForCommand(dir, options) {
|
|
|
2117
2348
|
log.warn(problem);
|
|
2118
2349
|
}
|
|
2119
2350
|
|
|
2120
|
-
export { PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, npmRegistryUrl, ensureProjectGitignore, listProjectExtensions, setExtensionEnabled, removeExtension, addExtension, checkExtensionUpdates, updateExtensions, uniqueExtensionId, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
2351
|
+
export { PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, setCheckOption, MANIFEST_FILENAMES, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, npmRegistryUrl, ensureProjectGitignore, listProjectExtensions, setExtensionEnabled, removeExtension, addExtension, checkExtensionUpdates, updateExtensions, BUILT_IN_LOOKS, addBuiltInStyleSet, uniqueExtensionId, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "gutterpress",
|
|
4
|
-
version: "0.11.23
|
|
4
|
+
version: "0.11.23",
|
|
5
5
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
6
6
|
author: "itlackey",
|
|
7
7
|
license: "MPL-2.0",
|
|
@@ -1218,7 +1218,7 @@ import { fileURLToPath } from "node:url";
|
|
|
1218
1218
|
var favicon_default = "./favicon-272ga6y0.ico";
|
|
1219
1219
|
|
|
1220
1220
|
// src/assets/manifest.schema.json
|
|
1221
|
-
var manifest_schema_default = "./manifest.schema-
|
|
1221
|
+
var manifest_schema_default = "./manifest.schema-5cm13vr3.json";
|
|
1222
1222
|
|
|
1223
1223
|
// src/assets/preview/scripts/preview-interface.js
|
|
1224
1224
|
var preview_interface_default = "./preview-interface-0xdh0r5b.js";
|