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,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
BUNDLED_EXTENSION_DETAILS,
|
|
3
3
|
EXTENSION_MANIFEST_FILENAME,
|
|
4
4
|
TWO_VERSIONS_OPEN,
|
|
5
5
|
bundledExtension,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
readExtensionMeta,
|
|
15
15
|
resolveExtension,
|
|
16
16
|
slugify
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-37cxffyb.js";
|
|
18
18
|
import {
|
|
19
19
|
BuildError,
|
|
20
20
|
EXIT_CODES,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
vendoredNpmPluginRoot,
|
|
33
33
|
vendoredNpmPluginRoots,
|
|
34
34
|
windowsPathKey
|
|
35
|
-
} from "./index-
|
|
35
|
+
} from "./index-g3te5ey1.js";
|
|
36
36
|
import {
|
|
37
37
|
__require
|
|
38
38
|
} from "./index-37x76zdn.js";
|
|
@@ -74,10 +74,10 @@ async function withFetchTimeout(options, run) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// src/lib/extension-manager.ts
|
|
77
|
-
import { readdir, readFile as readFile5, rm as rm3, stat } from "node:fs/promises";
|
|
77
|
+
import { mkdir as mkdir3, readdir, readFile as readFile5, rm as rm3, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
78
78
|
import { existsSync as existsSync3 } from "node:fs";
|
|
79
79
|
import path4 from "node:path";
|
|
80
|
-
import { isSeq as isSeq2, isMap, isScalar, YAMLMap, Scalar } from "yaml";
|
|
80
|
+
import { isSeq as isSeq2, isMap as isMap3, isScalar, YAMLMap, Scalar } from "yaml";
|
|
81
81
|
|
|
82
82
|
// src/lib/manifest-doc.ts
|
|
83
83
|
import { existsSync as existsSync2 } from "node:fs";
|
|
@@ -170,7 +170,8 @@ var DTRPG_PRESET = {
|
|
|
170
170
|
},
|
|
171
171
|
validate: {
|
|
172
172
|
assets: {
|
|
173
|
-
maxImageSize: 1e7
|
|
173
|
+
maxImageSize: 1e7,
|
|
174
|
+
approvedFontFiles: []
|
|
174
175
|
},
|
|
175
176
|
pdf: {
|
|
176
177
|
minImageResolution: 300,
|
|
@@ -227,7 +228,8 @@ var BOOK_PRESET = {
|
|
|
227
228
|
},
|
|
228
229
|
validate: {
|
|
229
230
|
assets: {
|
|
230
|
-
maxImageSize: 1e7
|
|
231
|
+
maxImageSize: 1e7,
|
|
232
|
+
approvedFontFiles: []
|
|
231
233
|
},
|
|
232
234
|
pdf: {
|
|
233
235
|
minImageResolution: 300,
|
|
@@ -387,6 +389,124 @@ function applyDefaultPdfStrictChecks(config) {
|
|
|
387
389
|
return next;
|
|
388
390
|
}
|
|
389
391
|
|
|
392
|
+
// src/lib/manifest-old-spellings.ts
|
|
393
|
+
import { isMap as isMap2 } from "yaml";
|
|
394
|
+
|
|
395
|
+
// src/lib/check-options.ts
|
|
396
|
+
import { isMap } from "yaml";
|
|
397
|
+
var CHECK_OPTIONS = {
|
|
398
|
+
"pdf.print.ink-coverage": {
|
|
399
|
+
maxTac: { at: "ink.maxTac", kind: "number" },
|
|
400
|
+
tacTolerance: { at: "ink.tacTolerance", kind: "number" }
|
|
401
|
+
},
|
|
402
|
+
"pdf.print.page-size": {
|
|
403
|
+
tolerance: { at: "page.tolerance", kind: "number" }
|
|
404
|
+
},
|
|
405
|
+
"pdf.print.image-resolution": {
|
|
406
|
+
minImageResolution: { at: "validate.pdf.minImageResolution", kind: "number" }
|
|
407
|
+
},
|
|
408
|
+
"pdf.print.bleed": {
|
|
409
|
+
bleedSize: { at: "validate.pdf.bleedSize", kind: "number" }
|
|
410
|
+
},
|
|
411
|
+
"asset.image.file-size": {
|
|
412
|
+
maxImageSize: { at: "validate.assets.maxImageSize", kind: "number" }
|
|
413
|
+
},
|
|
414
|
+
"asset.font.approved-files": {
|
|
415
|
+
approvedFontFiles: { at: "validate.assets.approvedFontFiles", kind: "patterns" }
|
|
416
|
+
},
|
|
417
|
+
"heuristic.decoration.layer-count": {
|
|
418
|
+
maxDecorativeLayers: { at: "validate.heuristics.maxDecorativeLayers", kind: "number" }
|
|
419
|
+
},
|
|
420
|
+
"heuristic.whitespace.text-density": {
|
|
421
|
+
textDensityRange: { at: "validate.heuristics.textDensityRange", kind: "range" }
|
|
422
|
+
},
|
|
423
|
+
"heuristic.chunking.section-density": {
|
|
424
|
+
maxParagraphsPerSection: { at: "validate.heuristics.maxParagraphsPerSection", kind: "number" }
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
function optionForOldSpelling(at) {
|
|
428
|
+
for (const [id, options] of Object.entries(CHECK_OPTIONS)) {
|
|
429
|
+
for (const [option, spec] of Object.entries(options)) {
|
|
430
|
+
if (spec.at === at)
|
|
431
|
+
return { id, option };
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
function isPlainObject(v) {
|
|
437
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
438
|
+
}
|
|
439
|
+
var isAmount = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
440
|
+
var isRangeEnd = ([k, v]) => (k === "min" || k === "max") && isAmount(v);
|
|
441
|
+
var MUST_BE = {
|
|
442
|
+
number: "a number, 0 or more",
|
|
443
|
+
range: "`{ min, max }` (numbers, 0 or more)",
|
|
444
|
+
patterns: "a list of file patterns"
|
|
445
|
+
};
|
|
446
|
+
function fits(kind, value) {
|
|
447
|
+
if (kind === "number")
|
|
448
|
+
return isAmount(value);
|
|
449
|
+
if (kind === "range")
|
|
450
|
+
return isPlainObject(value) && Object.entries(value).every(isRangeEnd);
|
|
451
|
+
return Array.isArray(value) && value.every((p) => typeof p === "string");
|
|
452
|
+
}
|
|
453
|
+
function checked(id, option, kind, value) {
|
|
454
|
+
if (fits(kind, value))
|
|
455
|
+
return value;
|
|
456
|
+
throw new UsageError(`Manifest field \`checks.${id}.${option}\` must be ${MUST_BE[kind]}, got ${JSON.stringify(value)}.`);
|
|
457
|
+
}
|
|
458
|
+
function isCheckLevelInput(value) {
|
|
459
|
+
return typeof value === "boolean" || ["off", "on", "info", "warn", "warning", "error"].includes(value);
|
|
460
|
+
}
|
|
461
|
+
function readOldThreshold(at, value) {
|
|
462
|
+
const moved = optionForOldSpelling(at);
|
|
463
|
+
if (!moved)
|
|
464
|
+
return;
|
|
465
|
+
const { kind } = CHECK_OPTIONS[moved.id][moved.option];
|
|
466
|
+
if (fits(kind, value))
|
|
467
|
+
return { ...moved, value };
|
|
468
|
+
const kept = kind === "range" && isPlainObject(value) ? Object.entries(value).filter(isRangeEnd) : [];
|
|
469
|
+
return { ...moved, ...kept.length > 0 ? { value: Object.fromEntries(kept) } : {}, mustBe: MUST_BE[kind] };
|
|
470
|
+
}
|
|
471
|
+
function readCheckOptions(id, entry) {
|
|
472
|
+
const known = CHECK_OPTIONS[id] ?? {};
|
|
473
|
+
const out = {};
|
|
474
|
+
for (const [option, value] of Object.entries(entry)) {
|
|
475
|
+
if (option === "level" || value === null || value === undefined)
|
|
476
|
+
continue;
|
|
477
|
+
const spec = known[option];
|
|
478
|
+
if (!spec) {
|
|
479
|
+
const takes = Object.keys(known);
|
|
480
|
+
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)."));
|
|
481
|
+
}
|
|
482
|
+
out[option] = checked(id, option, spec.kind, value);
|
|
483
|
+
}
|
|
484
|
+
return out;
|
|
485
|
+
}
|
|
486
|
+
function applyCheckOptions(config, options) {
|
|
487
|
+
for (const [id, values] of Object.entries(options)) {
|
|
488
|
+
for (const [option, value] of Object.entries(values)) {
|
|
489
|
+
const spec = CHECK_OPTIONS[id][option];
|
|
490
|
+
const keys = spec.at.split(".");
|
|
491
|
+
const leaf = keys.pop();
|
|
492
|
+
let node = config;
|
|
493
|
+
for (const key of keys)
|
|
494
|
+
node = node[key];
|
|
495
|
+
node[leaf] = spec.kind === "range" ? { ...node[leaf], ...value } : value;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function setCheckOption(doc, id, option, value) {
|
|
500
|
+
if (!isMap(doc.get("checks", true)))
|
|
501
|
+
doc.set("checks", doc.createNode({}));
|
|
502
|
+
const current = doc.getIn(["checks", id], true);
|
|
503
|
+
if (!isMap(current)) {
|
|
504
|
+
const level = doc.getIn(["checks", id]);
|
|
505
|
+
doc.setIn(["checks", id], doc.createNode(level === undefined || level === null ? {} : { level }));
|
|
506
|
+
}
|
|
507
|
+
doc.setIn(["checks", id, option], value);
|
|
508
|
+
}
|
|
509
|
+
|
|
390
510
|
// src/lib/manifest-old-spellings.ts
|
|
391
511
|
var SOURCE_TOOL_CHECKS = {
|
|
392
512
|
markdownlint: "source.markdownlint",
|
|
@@ -405,6 +525,7 @@ var FLAG_CHECKS = {
|
|
|
405
525
|
function isObject(v) {
|
|
406
526
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
407
527
|
}
|
|
528
|
+
var optionSpelling = (id, option, value) => `checks: { ${id}: { ${option}: ${JSON.stringify(value)} } }`;
|
|
408
529
|
function readOldSpellings(raw) {
|
|
409
530
|
const { source, lint, validate, ink, ...manifest } = raw;
|
|
410
531
|
const tolerance = isObject(raw.page) && "tolerance" in raw.page;
|
|
@@ -416,7 +537,32 @@ function readOldSpellings(raw) {
|
|
|
416
537
|
}
|
|
417
538
|
const renamed = [];
|
|
418
539
|
const dropped = [];
|
|
419
|
-
const
|
|
540
|
+
const unusable = [];
|
|
541
|
+
const levels = {};
|
|
542
|
+
const options = {};
|
|
543
|
+
const threshold = (at, value) => {
|
|
544
|
+
const read = readOldThreshold(at, value);
|
|
545
|
+
if (!read) {
|
|
546
|
+
dropped.push(at);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
if (value === null || value === undefined)
|
|
550
|
+
return;
|
|
551
|
+
if (read.value !== undefined) {
|
|
552
|
+
(options[read.id] ??= {})[read.option] = read.value;
|
|
553
|
+
renamed.push(`${at} -> ${optionSpelling(read.id, read.option, read.value)}`);
|
|
554
|
+
}
|
|
555
|
+
if (read.mustBe) {
|
|
556
|
+
const kept = read.value !== undefined ? `kept ${Object.keys(read.value).join(" and ")}, ignored the rest` : "ignored";
|
|
557
|
+
unusable.push(`${at}: ${JSON.stringify(value)} is not ${read.mustBe} — ${kept}`);
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
const level = (at, value) => {
|
|
561
|
+
if (isCheckLevelInput(value))
|
|
562
|
+
return value;
|
|
563
|
+
unusable.push(`${at}: ${JSON.stringify(value)} is not off, on, info, warn or error — ignored`);
|
|
564
|
+
return;
|
|
565
|
+
};
|
|
420
566
|
if (isObject(source) && "files" in source) {
|
|
421
567
|
renamed.push("source.files -> chapters");
|
|
422
568
|
if (manifest.chapters === undefined)
|
|
@@ -425,18 +571,37 @@ function readOldSpellings(raw) {
|
|
|
425
571
|
if (isObject(validate)) {
|
|
426
572
|
for (const [id, entry] of Object.entries(validate.checks ?? {})) {
|
|
427
573
|
if (entry === false || isObject(entry) && entry.enabled === false)
|
|
428
|
-
|
|
429
|
-
else if (isObject(entry) &&
|
|
430
|
-
|
|
431
|
-
else
|
|
432
|
-
|
|
574
|
+
levels[id] = "off";
|
|
575
|
+
else if (isObject(entry) && entry.severity !== undefined && entry.severity !== null) {
|
|
576
|
+
levels[id] = level(`validate.checks.${id}.severity`, entry.severity) ?? "on";
|
|
577
|
+
} else
|
|
578
|
+
levels[id] = "on";
|
|
433
579
|
}
|
|
434
580
|
if (validate.checks !== undefined)
|
|
435
581
|
renamed.push("validate.checks -> checks");
|
|
582
|
+
}
|
|
583
|
+
if (isObject(lint)) {
|
|
584
|
+
for (const [id, value] of Object.entries(lint.rules ?? {})) {
|
|
585
|
+
const read = level(`lint.rules.${id}`, value);
|
|
586
|
+
if (read !== undefined)
|
|
587
|
+
levels[id] = read;
|
|
588
|
+
}
|
|
589
|
+
if (lint.rules !== undefined)
|
|
590
|
+
renamed.push("lint.rules -> checks");
|
|
591
|
+
if (lint.enabled === false) {
|
|
592
|
+
levels["source.stylelint"] = "off";
|
|
593
|
+
renamed.push("lint.enabled: false -> checks: { source.stylelint: off }");
|
|
594
|
+
} else if (lint.enabled !== undefined) {
|
|
595
|
+
dropped.push("lint.enabled");
|
|
596
|
+
}
|
|
597
|
+
if (lint.configPath !== undefined)
|
|
598
|
+
dropped.push("lint.configPath");
|
|
599
|
+
}
|
|
600
|
+
if (isObject(validate)) {
|
|
436
601
|
for (const [tool, value] of Object.entries(validate.source ?? {})) {
|
|
437
602
|
const id = SOURCE_TOOL_CHECKS[tool];
|
|
438
603
|
if (id && value === false) {
|
|
439
|
-
|
|
604
|
+
levels[id] = "off";
|
|
440
605
|
renamed.push(`validate.source.${tool}: false -> checks: { ${id}: off }`);
|
|
441
606
|
} else if (id && tool !== "stylelint" && typeof value === "string") {
|
|
442
607
|
dropped.push(`validate.source.${tool} (the config file is found by its usual name in the book's folder or a folder above it)`);
|
|
@@ -448,11 +613,14 @@ function readOldSpellings(raw) {
|
|
|
448
613
|
for (const [key, value] of Object.entries(validate[block] ?? {})) {
|
|
449
614
|
const flag = FLAG_CHECKS[`${block}.${key}`];
|
|
450
615
|
if (flag && typeof value === "boolean") {
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
616
|
+
const on = value === flag.trueMeansOn;
|
|
617
|
+
if (!on)
|
|
618
|
+
levels[flag.check] = "off";
|
|
619
|
+
else
|
|
620
|
+
levels[flag.check] ??= "on";
|
|
621
|
+
renamed.push(`validate.${block}.${key}: ${value} -> checks: { ${flag.check}: ${String(levels[flag.check])} }`);
|
|
454
622
|
} else {
|
|
455
|
-
|
|
623
|
+
threshold(`validate.${block}.${key}`, value);
|
|
456
624
|
}
|
|
457
625
|
}
|
|
458
626
|
}
|
|
@@ -460,32 +628,28 @@ function readOldSpellings(raw) {
|
|
|
460
628
|
dropped.push("validate.enabled (`gutterpress build --skip-pre-validate --skip-post-validate` skips validation for one build)");
|
|
461
629
|
}
|
|
462
630
|
}
|
|
463
|
-
if (isObject(
|
|
464
|
-
for (const [
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if (lint.enabled === false) {
|
|
469
|
-
checks["source.stylelint"] = "off";
|
|
470
|
-
renamed.push("lint.enabled: false -> checks: { source.stylelint: off }");
|
|
471
|
-
} else if (lint.enabled !== undefined) {
|
|
472
|
-
dropped.push("lint.enabled");
|
|
473
|
-
}
|
|
474
|
-
if (lint.configPath !== undefined)
|
|
475
|
-
dropped.push("lint.configPath");
|
|
631
|
+
if (isObject(ink)) {
|
|
632
|
+
for (const [key, value] of Object.entries(ink))
|
|
633
|
+
threshold(`ink.${key}`, value);
|
|
634
|
+
} else if (ink !== undefined && ink !== null) {
|
|
635
|
+
dropped.push("ink");
|
|
476
636
|
}
|
|
477
|
-
if (ink !== undefined)
|
|
478
|
-
dropped.push("ink (the preset and the publish target set it)");
|
|
479
637
|
if (tolerance) {
|
|
480
|
-
const { tolerance:
|
|
638
|
+
const { tolerance: value, ...page } = raw.page;
|
|
481
639
|
manifest.page = page;
|
|
482
|
-
|
|
640
|
+
threshold("page.tolerance", value);
|
|
641
|
+
}
|
|
642
|
+
const ids = new Set([...Object.keys(levels), ...Object.keys(options)]);
|
|
643
|
+
if (ids.size > 0) {
|
|
644
|
+
const checks = { ...manifest.checks };
|
|
645
|
+
for (const id of ids)
|
|
646
|
+
checks[id] = mergeEntry(levels[id], options[id], manifest.checks?.[id]);
|
|
647
|
+
manifest.checks = checks;
|
|
483
648
|
}
|
|
484
|
-
if (Object.keys(checks).length > 0)
|
|
485
|
-
manifest.checks = { ...checks, ...manifest.checks };
|
|
486
649
|
const lines = [
|
|
487
650
|
...renamed.map((r) => ` ${r}`),
|
|
488
|
-
...dropped.map((d) => ` ${d} — no longer a setting, ignored`)
|
|
651
|
+
...dropped.map((d) => ` ${d} — no longer a setting, ignored`),
|
|
652
|
+
...unusable.map((u) => ` ${u}`)
|
|
489
653
|
];
|
|
490
654
|
if (lines.length > 0) {
|
|
491
655
|
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:
|
|
@@ -494,6 +658,43 @@ function readOldSpellings(raw) {
|
|
|
494
658
|
}
|
|
495
659
|
return manifest;
|
|
496
660
|
}
|
|
661
|
+
function mergeEntry(level, options, own) {
|
|
662
|
+
const ownEntry = isObject(own) ? own : own === undefined ? {} : { level: own };
|
|
663
|
+
const merged = {
|
|
664
|
+
...level !== undefined ? { level } : {},
|
|
665
|
+
...options,
|
|
666
|
+
...ownEntry
|
|
667
|
+
};
|
|
668
|
+
if (ownEntry.level === undefined && level !== undefined)
|
|
669
|
+
merged.level = level;
|
|
670
|
+
const keys = Object.keys(merged);
|
|
671
|
+
return keys.length === 1 && keys[0] === "level" ? merged.level : merged;
|
|
672
|
+
}
|
|
673
|
+
function rewriteOldThresholds(doc) {
|
|
674
|
+
const blocks = [["ink"], ["page"], ["validate", "assets"], ["validate", "pdf"], ["validate", "heuristics"]];
|
|
675
|
+
for (const block of blocks) {
|
|
676
|
+
const node = doc.getIn(block, true);
|
|
677
|
+
if (!isMap2(node))
|
|
678
|
+
continue;
|
|
679
|
+
for (const item of [...node.items]) {
|
|
680
|
+
const key = String(item.key?.value ?? item.key);
|
|
681
|
+
const value = item.value;
|
|
682
|
+
const js = value && typeof value === "object" && "toJSON" in value ? value.toJSON() : value;
|
|
683
|
+
const read = readOldThreshold([...block, key].join("."), js);
|
|
684
|
+
if (!read || js !== null && js !== undefined && read.mustBe)
|
|
685
|
+
continue;
|
|
686
|
+
if (js !== null && js !== undefined && doc.getIn(["checks", read.id, read.option]) === undefined) {
|
|
687
|
+
setCheckOption(doc, read.id, read.option, value);
|
|
688
|
+
}
|
|
689
|
+
node.delete(key);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
for (const block of [...blocks, ["validate"]]) {
|
|
693
|
+
const node = doc.getIn(block, true);
|
|
694
|
+
if (isMap2(node) && node.items.length === 0)
|
|
695
|
+
doc.deleteIn(block);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
497
698
|
|
|
498
699
|
// src/lib/manifest.ts
|
|
499
700
|
var MANIFEST_FILENAMES = [
|
|
@@ -612,7 +813,7 @@ function pluginsRemovedMessage(raw) {
|
|
|
612
813
|
` + (lines.length > 0 ? lines.join(`
|
|
613
814
|
`) : " - ./plugins/my-plugin.js");
|
|
614
815
|
}
|
|
615
|
-
function
|
|
816
|
+
function isPlainObject2(v) {
|
|
616
817
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
617
818
|
}
|
|
618
819
|
function mergeShape(cli, manifest, preset) {
|
|
@@ -621,7 +822,7 @@ function mergeShape(cli, manifest, preset) {
|
|
|
621
822
|
const presetValue = preset[key];
|
|
622
823
|
const manifestValue = manifest ? manifest[key] : undefined;
|
|
623
824
|
const cliValue = cli ? cli[key] : undefined;
|
|
624
|
-
out[key] =
|
|
825
|
+
out[key] = isPlainObject2(presetValue) ? mergeShape(cliValue, manifestValue, presetValue) : cliValue ?? manifestValue ?? presetValue;
|
|
625
826
|
}
|
|
626
827
|
return out;
|
|
627
828
|
}
|
|
@@ -669,7 +870,7 @@ function resolveCustomPage(c, m) {
|
|
|
669
870
|
}
|
|
670
871
|
var MARGIN_EDGES = ["top", "bottom", "inside", "outside"];
|
|
671
872
|
function validatePageMargin(margin, size) {
|
|
672
|
-
const edges =
|
|
873
|
+
const edges = isPlainObject2(margin) && Object.keys(margin).every((k) => MARGIN_EDGES.includes(k)) && MARGIN_EDGES.every((e) => isNonNegativePoints(margin[e]));
|
|
673
874
|
if (!edges) {
|
|
674
875
|
throw new UsageError("Manifest field `page.margin` must set all four edges in points (72pt = 1in), for example\n" + ` page:
|
|
675
876
|
margin:
|
|
@@ -726,7 +927,9 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
726
927
|
const page = preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m);
|
|
727
928
|
if (page.margin !== undefined && page.margin !== null)
|
|
728
929
|
validatePageMargin(page.margin, page);
|
|
729
|
-
|
|
930
|
+
const manifestChecks = resolveChecks(m.checks);
|
|
931
|
+
const cliChecks = resolveChecks(c.checks);
|
|
932
|
+
const config = {
|
|
730
933
|
title: c.title ?? m.title ?? "Document",
|
|
731
934
|
authors: c.authors ?? m.authors ?? [],
|
|
732
935
|
language: resolveLanguage(c.language ?? m.language),
|
|
@@ -736,35 +939,47 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
736
939
|
extensions,
|
|
737
940
|
targets: resolveTargets(c.targets ?? m.targets, preset.defaultTargets),
|
|
738
941
|
chapters: c.chapters ?? m.chapters ?? preset.chapters,
|
|
739
|
-
checks: { ...preset.checks, ...
|
|
942
|
+
checks: { ...preset.checks, ...manifestChecks.levels, ...cliChecks.levels },
|
|
740
943
|
pdfx: mergeShape(c.pdfx, m.pdfx, preset.pdfx),
|
|
741
944
|
print: mergeShape(c.print, m.print, preset.print),
|
|
742
945
|
page,
|
|
743
946
|
ink: structuredClone(preset.ink),
|
|
744
947
|
validate: structuredClone(preset.validate)
|
|
745
948
|
};
|
|
746
|
-
|
|
747
|
-
|
|
949
|
+
applyCheckOptions(config, manifestChecks.options);
|
|
950
|
+
applyCheckOptions(config, cliChecks.options);
|
|
951
|
+
return config;
|
|
952
|
+
}
|
|
953
|
+
function checkLevel(id, value) {
|
|
954
|
+
if (!isCheckLevelInput(value)) {
|
|
955
|
+
throw new UsageError(`Manifest field \`checks.${id}\` must be off, on, info, warn or error, got ${JSON.stringify(value)}.`);
|
|
956
|
+
}
|
|
957
|
+
if (value === false || value === "off")
|
|
958
|
+
return "off";
|
|
959
|
+
if (value === true || value === "on")
|
|
960
|
+
return "on";
|
|
961
|
+
return value === "warn" || value === "warning" ? "warning" : value;
|
|
962
|
+
}
|
|
963
|
+
function resolveChecks(input) {
|
|
964
|
+
const levels = {};
|
|
965
|
+
const options = {};
|
|
748
966
|
if (input === undefined || input === null)
|
|
749
|
-
return {};
|
|
750
|
-
if (!
|
|
967
|
+
return { levels, options };
|
|
968
|
+
if (!isPlainObject2(input)) {
|
|
751
969
|
throw new UsageError("Manifest field `checks` must map check ids to off, on, info, warn or error.");
|
|
752
970
|
}
|
|
753
|
-
const out = {};
|
|
754
971
|
for (const [id, value] of Object.entries(input)) {
|
|
755
|
-
if (value
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
out[id] = "on";
|
|
759
|
-
else if (value === "warn" || value === "warning")
|
|
760
|
-
out[id] = "warning";
|
|
761
|
-
else if (value === "info" || value === "error")
|
|
762
|
-
out[id] = value;
|
|
763
|
-
else {
|
|
764
|
-
throw new UsageError(`Manifest field \`checks.${id}\` must be off, on, info, warn or error, got ${JSON.stringify(value)}.`);
|
|
972
|
+
if (!isPlainObject2(value)) {
|
|
973
|
+
levels[id] = checkLevel(id, value);
|
|
974
|
+
continue;
|
|
765
975
|
}
|
|
976
|
+
if (value.level !== undefined && value.level !== null)
|
|
977
|
+
levels[id] = checkLevel(`${id}.level`, value.level);
|
|
978
|
+
const own = readCheckOptions(id, value);
|
|
979
|
+
if (Object.keys(own).length > 0)
|
|
980
|
+
options[id] = own;
|
|
766
981
|
}
|
|
767
|
-
return
|
|
982
|
+
return { levels, options };
|
|
768
983
|
}
|
|
769
984
|
|
|
770
985
|
// src/lib/manifest-doc.ts
|
|
@@ -1544,7 +1759,7 @@ function withMutationLock(projectDir, mutation) {
|
|
|
1544
1759
|
function entryUse(item) {
|
|
1545
1760
|
if (isScalar(item))
|
|
1546
1761
|
return typeof item.value === "string" ? item.value.trim() : null;
|
|
1547
|
-
if (
|
|
1762
|
+
if (isMap3(item)) {
|
|
1548
1763
|
const u = item.get("use");
|
|
1549
1764
|
return typeof u === "string" ? u.trim() : null;
|
|
1550
1765
|
}
|
|
@@ -1554,7 +1769,7 @@ function rawEntry(item) {
|
|
|
1554
1769
|
const use = entryUse(item);
|
|
1555
1770
|
if (!use)
|
|
1556
1771
|
return null;
|
|
1557
|
-
if (!
|
|
1772
|
+
if (!isMap3(item))
|
|
1558
1773
|
return { use, enabled: true };
|
|
1559
1774
|
const x = item.get("export");
|
|
1560
1775
|
return {
|
|
@@ -1727,13 +1942,13 @@ async function setExtensionEnabled(projectDir, use, enabled) {
|
|
|
1727
1942
|
throw new Error(`Extension "${use}" is not in the manifest.`);
|
|
1728
1943
|
const item = seq.items[idx];
|
|
1729
1944
|
if (enabled) {
|
|
1730
|
-
if (
|
|
1945
|
+
if (isMap3(item)) {
|
|
1731
1946
|
item.delete("enabled");
|
|
1732
1947
|
if (item.items.length === 1 && typeof item.get("use") === "string") {
|
|
1733
1948
|
seq.items[idx] = new Scalar(item.get("use"));
|
|
1734
1949
|
}
|
|
1735
1950
|
}
|
|
1736
|
-
} else if (
|
|
1951
|
+
} else if (isMap3(item)) {
|
|
1737
1952
|
item.set("enabled", false);
|
|
1738
1953
|
} else {
|
|
1739
1954
|
const map = new YAMLMap(doc.schema);
|
|
@@ -1799,7 +2014,7 @@ async function upsertEntry(projectDir, use, exportName) {
|
|
|
1799
2014
|
const idx = indexOfUse(seq, use);
|
|
1800
2015
|
if (idx >= 0) {
|
|
1801
2016
|
const item = seq.items[idx];
|
|
1802
|
-
if (
|
|
2017
|
+
if (isMap3(item)) {
|
|
1803
2018
|
item.set("use", use);
|
|
1804
2019
|
if (exportName)
|
|
1805
2020
|
item.set("export", exportName);
|
|
@@ -2060,13 +2275,53 @@ async function updateExtensions(projectDir, options = {}) {
|
|
|
2060
2275
|
return updated;
|
|
2061
2276
|
}
|
|
2062
2277
|
function listBundledExtensions() {
|
|
2063
|
-
return
|
|
2278
|
+
return BUNDLED_EXTENSION_DETAILS.map((b) => ({
|
|
2064
2279
|
use: b.name,
|
|
2065
2280
|
label: b.label,
|
|
2066
2281
|
description: b.description,
|
|
2067
2282
|
look: b.css !== undefined
|
|
2068
2283
|
}));
|
|
2069
2284
|
}
|
|
2285
|
+
var BUILT_IN_LOOKS = BUNDLED_EXTENSION_DETAILS.filter((b) => b.css !== undefined).map((b) => b.name);
|
|
2286
|
+
async function addBuiltInStyleSet(projectDir, id) {
|
|
2287
|
+
const look = bundledExtension(id);
|
|
2288
|
+
if (look?.css === undefined) {
|
|
2289
|
+
throw new Error(`Unknown built-in look "${id}" (one of: ${BUILT_IN_LOOKS.join(", ")}).`);
|
|
2290
|
+
}
|
|
2291
|
+
const css = look.css;
|
|
2292
|
+
return withMutationLock(projectDir, async () => {
|
|
2293
|
+
const dest = path4.join(projectDir, EXTENSIONS_DIR, id);
|
|
2294
|
+
if (!existsSync3(dest)) {
|
|
2295
|
+
await mkdir3(dest, { recursive: true });
|
|
2296
|
+
const pkg = {
|
|
2297
|
+
name: id,
|
|
2298
|
+
description: look.description,
|
|
2299
|
+
author: "gutterpress",
|
|
2300
|
+
keywords: ["gutterpress", "gutterpress-look"],
|
|
2301
|
+
gutterpress: { styles: ["theme.css"] }
|
|
2302
|
+
};
|
|
2303
|
+
await writeFile2(path4.join(dest, EXTENSION_MANIFEST_FILENAME), `${JSON.stringify(pkg, null, 2)}
|
|
2304
|
+
`, "utf8");
|
|
2305
|
+
await writeFile2(path4.join(dest, "theme.css"), css, "utf8");
|
|
2306
|
+
}
|
|
2307
|
+
const use = `./${EXTENSIONS_DIR}/${id}`;
|
|
2308
|
+
await loadPlugin(extensionConfigFor({ use, kind: "path", name: use }), projectDir);
|
|
2309
|
+
const { doc, file } = await loadManifestDoc(projectDir);
|
|
2310
|
+
const seq = ensureSeq(doc, "extensions");
|
|
2311
|
+
if (indexOfUse(seq, use) < 0) {
|
|
2312
|
+
const at = indexOfUse(seq, id);
|
|
2313
|
+
const item = at < 0 ? undefined : seq.items[at];
|
|
2314
|
+
if (isMap3(item))
|
|
2315
|
+
item.set("use", use);
|
|
2316
|
+
else if (at >= 0)
|
|
2317
|
+
seq.items[at] = new Scalar(use);
|
|
2318
|
+
else
|
|
2319
|
+
seq.add(new Scalar(use));
|
|
2320
|
+
await writeManifestDoc(file, doc);
|
|
2321
|
+
}
|
|
2322
|
+
return await describeExtension(projectDir, use);
|
|
2323
|
+
});
|
|
2324
|
+
}
|
|
2070
2325
|
async function uniqueExtensionId(projectDir, base) {
|
|
2071
2326
|
const slug = slugify(base) || "extension";
|
|
2072
2327
|
let candidate = slug;
|
|
@@ -2238,4 +2493,4 @@ async function restoreForCommand(dir, options) {
|
|
|
2238
2493
|
log.warn(problem);
|
|
2239
2494
|
}
|
|
2240
2495
|
|
|
2241
|
-
export { DEBOUNCE, UsageError, resolvePort, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, MARGIN_EDGES, validatePageMargin, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, scalarString, DEFAULT_NPM_REGISTRY, npmRegistryUrl, ensureProjectGitignore, sameExtension, listProjectExtensions, describeExtension, extensionConfigFor, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listNpmVersions, checkExtensionUpdates, updateExtensions, listBundledExtensions, uniqueExtensionId, validateProjectExtensions, readExtensionCss, readEntryCss, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
2496
|
+
export { DEBOUNCE, UsageError, resolvePort, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, setCheckOption, rewriteOldThresholds, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, MARGIN_EDGES, validatePageMargin, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, scalarString, DEFAULT_NPM_REGISTRY, npmRegistryUrl, ensureProjectGitignore, sameExtension, listProjectExtensions, describeExtension, extensionConfigFor, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listNpmVersions, checkExtensionUpdates, updateExtensions, listBundledExtensions, BUILT_IN_LOOKS, addBuiltInStyleSet, uniqueExtensionId, validateProjectExtensions, readExtensionCss, readEntryCss, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
@@ -697,7 +697,7 @@ import { fileURLToPath } from "node:url";
|
|
|
697
697
|
var favicon_default = "./favicon-272ga6y0.ico";
|
|
698
698
|
|
|
699
699
|
// src/assets/manifest.schema.json
|
|
700
|
-
var manifest_schema_default = "./manifest.schema-
|
|
700
|
+
var manifest_schema_default = "./manifest.schema-5cm13vr3.json";
|
|
701
701
|
|
|
702
702
|
// src/assets/preview/scripts/preview-interface.js
|
|
703
703
|
var preview_interface_default = "./preview-interface-0xdh0r5b.js";
|
|
@@ -3,6 +3,7 @@ import { lstat, readFile, realpath } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { exports as resolveExports } from "resolve.exports";
|
|
5
5
|
var EXTENSIONS_DIR = "extensions";
|
|
6
|
+
var PLUGINS_DIR = EXTENSIONS_DIR;
|
|
6
7
|
var LEGACY_PLUGINS_DIR = "plugins";
|
|
7
8
|
var VENDORED_NPM_DIR = "npm";
|
|
8
9
|
var NPM_SEGMENT = /^[a-z0-9][a-z0-9._~-]*$/;
|
|
@@ -206,4 +207,4 @@ async function resolveVendoredPluginInstallRoot(projectDir, expectedName, expect
|
|
|
206
207
|
return installRoot;
|
|
207
208
|
}
|
|
208
209
|
|
|
209
|
-
export { EXTENSIONS_DIR, LEGACY_PLUGINS_DIR, VENDORED_NPM_DIR, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginRoots, vendoredNpmPluginPackageDir, toPosixPath, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, safePackageTarget, resolvePackageEntry, resolveVendoredPluginInstallRoot };
|
|
210
|
+
export { EXTENSIONS_DIR, PLUGINS_DIR, LEGACY_PLUGINS_DIR, VENDORED_NPM_DIR, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginRoots, vendoredNpmPluginPackageDir, toPosixPath, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, safePackageTarget, resolvePackageEntry, resolveVendoredPluginInstallRoot };
|