gutterpress 0.10.10 → 0.10.11
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 +20 -6
- package/dist/api/index.js +1 -1
- package/dist/{audit-nx0rxyqs.js → audit-ebbbhpx7.js} +3 -3
- package/dist/{build-7dgk1b9z.js → build-zrajk3s2.js} +3 -3
- package/dist/checks/source/markdownlint.d.ts +16 -0
- package/dist/{cli-4vyra9eq.js → cli-36r50yr3.js} +1 -1
- package/dist/{cli-m7v5z501.js → cli-gxq7yz5f.js} +1 -1
- package/dist/{cli-jcemen7j.js → cli-hz44te1m.js} +131 -57
- package/dist/cli.js +14 -14
- package/dist/{doctor-07rfg847.js → doctor-78qft9g7.js} +2 -2
- package/dist/engine/shared/cdp.d.ts +6 -2
- package/dist/{ext-6twv1x6c.js → ext-3g1mk8mb.js} +3 -3
- package/dist/{index-xs2g04p2.js → index-03cqyyyk.js} +381 -305
- package/dist/index.js +1 -1
- package/dist/lib/markdownlint-fix.d.ts +7 -0
- package/dist/lib/validation-exec.d.ts +6 -0
- package/dist/{lint-j60awn0r.js → lint-va95zh6j.js} +3 -3
- package/dist/{new-j8q6paaz.js → new-3ex11eyq.js} +3 -3
- package/dist/{preflight-w9predag.js → preflight-q8w6dnjh.js} +3 -3
- package/dist/{preview-keecv833.js → preview-azatsrtp.js} +3 -3
- package/dist/{publish-mjrvdxpc.js → publish-5tqzepkb.js} +3 -3
- package/dist/render.js +1 -1
- package/dist/{validate-cn6jsndb.js → validate-rp613ejg.js} +9 -4
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
gitScopeFor,
|
|
25
25
|
hasPendingChanges,
|
|
26
26
|
hasUncommittedChanges,
|
|
27
|
+
listWorkdirChanges,
|
|
27
28
|
resolveGitAuthor,
|
|
28
29
|
resolveLogger,
|
|
29
30
|
snapshotStagingMarkerPath,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
} from "./index-y01v2fe0.js";
|
|
33
34
|
import {
|
|
34
35
|
detectProjectSource,
|
|
36
|
+
repoSubPath,
|
|
35
37
|
syncRemoteFor
|
|
36
38
|
} from "./index-v5mp7a6q.js";
|
|
37
39
|
import {
|
|
@@ -1469,7 +1471,7 @@ function attachDataAttrs(token, kind, name, attrs) {
|
|
|
1469
1471
|
continue;
|
|
1470
1472
|
if (k === "class" || k === "id" || k === "template" || k === "region")
|
|
1471
1473
|
continue;
|
|
1472
|
-
token.attrSet(`data-${k}`, v);
|
|
1474
|
+
token.attrSet(k.startsWith("data-") ? k : `data-${k}`, v);
|
|
1473
1475
|
}
|
|
1474
1476
|
}
|
|
1475
1477
|
var DECLARED_NAME_RE = /^[a-z][a-z0-9-]*$/;
|
|
@@ -4839,7 +4841,7 @@ import git from "isomorphic-git";
|
|
|
4839
4841
|
// package.json
|
|
4840
4842
|
var package_default = {
|
|
4841
4843
|
name: "gutterpress",
|
|
4842
|
-
version: "0.10.
|
|
4844
|
+
version: "0.10.11",
|
|
4843
4845
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
4844
4846
|
author: "itlackey",
|
|
4845
4847
|
license: "MPL-2.0",
|
|
@@ -5112,64 +5114,32 @@ async function writeBuildFingerprint(input) {
|
|
|
5112
5114
|
import { existsSync as existsSync10 } from "node:fs";
|
|
5113
5115
|
import { dirname as dirname4, join as join4, resolve as resolve8 } from "node:path";
|
|
5114
5116
|
|
|
5115
|
-
// src/
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
}
|
|
5123
|
-
function
|
|
5124
|
-
|
|
5125
|
-
const
|
|
5126
|
-
|
|
5127
|
-
if (r.detail)
|
|
5128
|
-
log.info(` ${r.detail}`);
|
|
5129
|
-
}
|
|
5130
|
-
for (const r of report.warnings) {
|
|
5131
|
-
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
5132
|
-
log.warn(`${loc}${r.message}`);
|
|
5133
|
-
if (r.detail)
|
|
5134
|
-
log.warn(` ${r.detail}`);
|
|
5135
|
-
}
|
|
5136
|
-
for (const r of report.errors) {
|
|
5137
|
-
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
5138
|
-
log.error(`${loc}${r.message}`);
|
|
5139
|
-
if (r.detail)
|
|
5140
|
-
log.error(` ${r.detail}`);
|
|
5141
|
-
}
|
|
5142
|
-
const { summary } = report;
|
|
5143
|
-
if (summary.errors > 0) {
|
|
5144
|
-
log.error(`VALIDATION FAILED (${summary.errors} error${summary.errors > 1 ? "s" : ""})`);
|
|
5145
|
-
} else if (summary.warnings > 0) {
|
|
5146
|
-
log.warn("VALIDATION PASSED (with warnings)");
|
|
5147
|
-
} else {
|
|
5148
|
-
log.success("VALIDATION PASSED");
|
|
5117
|
+
// src/lib/markdownlint-fix.ts
|
|
5118
|
+
import { readFile as readFile10, writeFile as writeFile5 } from "node:fs/promises";
|
|
5119
|
+
import { applyFixes } from "markdownlint";
|
|
5120
|
+
import { lint as lint2 } from "markdownlint/sync";
|
|
5121
|
+
|
|
5122
|
+
// src/checks/source/config-file.ts
|
|
5123
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
5124
|
+
import { resolve as resolve5 } from "node:path";
|
|
5125
|
+
function findConfigFile(inputDir, names, explicit) {
|
|
5126
|
+
if (explicit) {
|
|
5127
|
+
const p = resolve5(inputDir, explicit);
|
|
5128
|
+
return existsSync6(p) ? p : null;
|
|
5149
5129
|
}
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
function formatJson(report) {
|
|
5155
|
-
console.log(JSON.stringify({
|
|
5156
|
-
results: report.results,
|
|
5157
|
-
summary: report.summary,
|
|
5158
|
-
passed: report.passed
|
|
5159
|
-
}, null, 2));
|
|
5160
|
-
}
|
|
5161
|
-
function formatLocation(file, line, column) {
|
|
5162
|
-
if (!file)
|
|
5163
|
-
return "";
|
|
5164
|
-
let loc = `${file}`;
|
|
5165
|
-
if (line != null) {
|
|
5166
|
-
loc += `:${line}`;
|
|
5167
|
-
if (column != null)
|
|
5168
|
-
loc += `:${column}`;
|
|
5130
|
+
for (const name of names) {
|
|
5131
|
+
const p = resolve5(inputDir, name);
|
|
5132
|
+
if (existsSync6(p))
|
|
5133
|
+
return p;
|
|
5169
5134
|
}
|
|
5170
|
-
return
|
|
5135
|
+
return null;
|
|
5171
5136
|
}
|
|
5172
5137
|
|
|
5138
|
+
// src/checks/source/markdownlint.ts
|
|
5139
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
5140
|
+
import { lint } from "markdownlint/sync";
|
|
5141
|
+
import { parse as parseYaml2 } from "yaml";
|
|
5142
|
+
|
|
5173
5143
|
// src/checks/registry.ts
|
|
5174
5144
|
var checks = new Map;
|
|
5175
5145
|
function registerCheck(check) {
|
|
@@ -5235,15 +5205,205 @@ function selectorToRegex(selector) {
|
|
|
5235
5205
|
return new RegExp(`^${escaped}$`);
|
|
5236
5206
|
}
|
|
5237
5207
|
|
|
5208
|
+
// src/checks/source/markdownlint.ts
|
|
5209
|
+
var CONFIG_NAMES = [
|
|
5210
|
+
".markdownlint.yaml",
|
|
5211
|
+
".markdownlint.yml",
|
|
5212
|
+
".markdownlint.json",
|
|
5213
|
+
".markdownlint.jsonc",
|
|
5214
|
+
".markdownlint-cli2.yaml",
|
|
5215
|
+
".markdownlint-cli2.jsonc"
|
|
5216
|
+
];
|
|
5217
|
+
function stripJsonComments(s) {
|
|
5218
|
+
return s.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
5219
|
+
}
|
|
5220
|
+
async function loadConfig(configPath) {
|
|
5221
|
+
const raw = await readFile9(configPath, "utf8");
|
|
5222
|
+
let parsed;
|
|
5223
|
+
if (configPath.endsWith(".json")) {
|
|
5224
|
+
parsed = JSON.parse(raw);
|
|
5225
|
+
} else if (configPath.endsWith(".jsonc")) {
|
|
5226
|
+
parsed = JSON.parse(stripJsonComments(raw));
|
|
5227
|
+
} else {
|
|
5228
|
+
parsed = parseYaml2(raw);
|
|
5229
|
+
}
|
|
5230
|
+
if (parsed && typeof parsed === "object") {
|
|
5231
|
+
const obj = parsed;
|
|
5232
|
+
if (obj.config && typeof obj.config === "object") {
|
|
5233
|
+
return obj.config;
|
|
5234
|
+
}
|
|
5235
|
+
return obj;
|
|
5236
|
+
}
|
|
5237
|
+
return {};
|
|
5238
|
+
}
|
|
5239
|
+
var MARKDOWNLINT_CHECK_ID = "source.markdownlint";
|
|
5240
|
+
var check = {
|
|
5241
|
+
id: MARKDOWNLINT_CHECK_ID,
|
|
5242
|
+
name: "Markdownlint",
|
|
5243
|
+
description: "Runs markdownlint with project config to validate Markdown files",
|
|
5244
|
+
category: "source",
|
|
5245
|
+
phase: "pre-build",
|
|
5246
|
+
async run(ctx) {
|
|
5247
|
+
const sourceConfig = ctx.config.validate.source;
|
|
5248
|
+
if (sourceConfig.markdownlint === false)
|
|
5249
|
+
return [];
|
|
5250
|
+
const files = ctx.markdownFiles;
|
|
5251
|
+
if (!files || files.length === 0)
|
|
5252
|
+
return [];
|
|
5253
|
+
const configPath = typeof sourceConfig.markdownlint === "string" ? sourceConfig.markdownlint : null;
|
|
5254
|
+
const resolvedConfig = findConfigFile(ctx.inputDir, CONFIG_NAMES, configPath);
|
|
5255
|
+
if (!resolvedConfig && !configPath)
|
|
5256
|
+
return [];
|
|
5257
|
+
const config = resolvedConfig ? await loadConfig(resolvedConfig) : { default: true };
|
|
5258
|
+
const results = lint({ files, config });
|
|
5259
|
+
const out = [];
|
|
5260
|
+
for (const [file, violations] of Object.entries(results)) {
|
|
5261
|
+
if (!Array.isArray(violations))
|
|
5262
|
+
continue;
|
|
5263
|
+
for (const v of violations) {
|
|
5264
|
+
out.push({
|
|
5265
|
+
checkId: check.id,
|
|
5266
|
+
severity: "warning",
|
|
5267
|
+
message: `${v.ruleDescription} (${v.ruleNames.join("/")})`,
|
|
5268
|
+
file,
|
|
5269
|
+
line: v.lineNumber,
|
|
5270
|
+
column: v.errorRange?.[0],
|
|
5271
|
+
code: v.ruleNames[0]
|
|
5272
|
+
});
|
|
5273
|
+
}
|
|
5274
|
+
}
|
|
5275
|
+
return out;
|
|
5276
|
+
}
|
|
5277
|
+
};
|
|
5278
|
+
registerCheck(check);
|
|
5279
|
+
|
|
5280
|
+
// src/lib/markdownlint-fix.ts
|
|
5281
|
+
async function uncommittedAmong(inputDir, files) {
|
|
5282
|
+
const source = await detectProjectSource(inputDir);
|
|
5283
|
+
if (source.type !== "local-git-folder")
|
|
5284
|
+
return [];
|
|
5285
|
+
const repoRoot = source.repoRoot;
|
|
5286
|
+
let changed;
|
|
5287
|
+
try {
|
|
5288
|
+
const { adds } = await listWorkdirChanges(repoRoot);
|
|
5289
|
+
changed = new Set(adds);
|
|
5290
|
+
} catch {
|
|
5291
|
+
return [];
|
|
5292
|
+
}
|
|
5293
|
+
return files.filter((file) => changed.has(repoSubPath(repoRoot, file)));
|
|
5294
|
+
}
|
|
5295
|
+
async function applyMarkdownlintFixes(ctx) {
|
|
5296
|
+
const sourceConfig = ctx.config.validate.source;
|
|
5297
|
+
if (sourceConfig.markdownlint === false) {
|
|
5298
|
+
log.warn("--fix: source.markdownlint is disabled for this project — no files were fixed.");
|
|
5299
|
+
return [];
|
|
5300
|
+
}
|
|
5301
|
+
const files = ctx.markdownFiles;
|
|
5302
|
+
if (!files || files.length === 0) {
|
|
5303
|
+
log.warn("--fix: no markdown files to fix.");
|
|
5304
|
+
return [];
|
|
5305
|
+
}
|
|
5306
|
+
const configPath = typeof sourceConfig.markdownlint === "string" ? sourceConfig.markdownlint : null;
|
|
5307
|
+
const resolvedConfig = findConfigFile(ctx.inputDir, CONFIG_NAMES, configPath);
|
|
5308
|
+
if (!resolvedConfig && !configPath) {
|
|
5309
|
+
log.warn(`--fix: no markdownlint config found in ${ctx.inputDir} (looked for ${CONFIG_NAMES.join(", ")}) — no files were fixed.`);
|
|
5310
|
+
return [];
|
|
5311
|
+
}
|
|
5312
|
+
const config = resolvedConfig ? await loadConfig(resolvedConfig) : { default: true };
|
|
5313
|
+
const results = lint2({ files, config });
|
|
5314
|
+
const pending = [];
|
|
5315
|
+
for (const [file, violations] of Object.entries(results)) {
|
|
5316
|
+
if (!Array.isArray(violations) || violations.length === 0)
|
|
5317
|
+
continue;
|
|
5318
|
+
const before = await readFile10(file, "utf8");
|
|
5319
|
+
const after = applyFixes(before, violations);
|
|
5320
|
+
if (after !== before)
|
|
5321
|
+
pending.push({ file, content: after });
|
|
5322
|
+
}
|
|
5323
|
+
if (pending.length === 0) {
|
|
5324
|
+
log.warn("--fix: no mechanically fixable markdownlint violations found.");
|
|
5325
|
+
return [];
|
|
5326
|
+
}
|
|
5327
|
+
const dirty = await uncommittedAmong(ctx.inputDir, pending.map((p) => p.file));
|
|
5328
|
+
for (const { file, content } of pending) {
|
|
5329
|
+
await writeFile5(file, content, "utf8");
|
|
5330
|
+
}
|
|
5331
|
+
log.warn(`--fix: rewrote ${pending.length} file(s):`);
|
|
5332
|
+
for (const { file } of pending)
|
|
5333
|
+
log.warn(` ${file}`);
|
|
5334
|
+
if (dirty.length > 0) {
|
|
5335
|
+
log.warn(`--fix: ${dirty.length} of those already had uncommitted changes and were rewritten anyway: ${dirty.join(", ")}`);
|
|
5336
|
+
}
|
|
5337
|
+
return pending.map((p) => p.file);
|
|
5338
|
+
}
|
|
5339
|
+
|
|
5340
|
+
// src/checks/formatter.ts
|
|
5341
|
+
function formatReport(report, format = "text") {
|
|
5342
|
+
if (format === "json") {
|
|
5343
|
+
formatJson(report);
|
|
5344
|
+
} else {
|
|
5345
|
+
formatText(report);
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
function formatText(report) {
|
|
5349
|
+
for (const r of report.infos) {
|
|
5350
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
5351
|
+
log.info(`${loc}${r.message}`);
|
|
5352
|
+
if (r.detail)
|
|
5353
|
+
log.info(` ${r.detail}`);
|
|
5354
|
+
}
|
|
5355
|
+
for (const r of report.warnings) {
|
|
5356
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
5357
|
+
log.warn(`${loc}${r.message}`);
|
|
5358
|
+
if (r.detail)
|
|
5359
|
+
log.warn(` ${r.detail}`);
|
|
5360
|
+
}
|
|
5361
|
+
for (const r of report.errors) {
|
|
5362
|
+
const loc = targetPrefix(r.target) + formatLocation(r.file, r.line, r.column);
|
|
5363
|
+
log.error(`${loc}${r.message}`);
|
|
5364
|
+
if (r.detail)
|
|
5365
|
+
log.error(` ${r.detail}`);
|
|
5366
|
+
}
|
|
5367
|
+
const { summary } = report;
|
|
5368
|
+
if (summary.errors > 0) {
|
|
5369
|
+
log.error(`VALIDATION FAILED (${summary.errors} error${summary.errors > 1 ? "s" : ""})`);
|
|
5370
|
+
} else if (summary.warnings > 0) {
|
|
5371
|
+
log.warn("VALIDATION PASSED (with warnings)");
|
|
5372
|
+
} else {
|
|
5373
|
+
log.success("VALIDATION PASSED");
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
function targetPrefix(target) {
|
|
5377
|
+
return target ? `[${target}] ` : "";
|
|
5378
|
+
}
|
|
5379
|
+
function formatJson(report) {
|
|
5380
|
+
console.log(JSON.stringify({
|
|
5381
|
+
results: report.results,
|
|
5382
|
+
summary: report.summary,
|
|
5383
|
+
passed: report.passed
|
|
5384
|
+
}, null, 2));
|
|
5385
|
+
}
|
|
5386
|
+
function formatLocation(file, line, column) {
|
|
5387
|
+
if (!file)
|
|
5388
|
+
return "";
|
|
5389
|
+
let loc = `${file}`;
|
|
5390
|
+
if (line != null) {
|
|
5391
|
+
loc += `:${line}`;
|
|
5392
|
+
if (column != null)
|
|
5393
|
+
loc += `:${column}`;
|
|
5394
|
+
}
|
|
5395
|
+
return `${loc}: `;
|
|
5396
|
+
}
|
|
5397
|
+
|
|
5238
5398
|
// src/checks/policy.ts
|
|
5239
5399
|
var INSPECT_FAILED_CODE = "inspect-failed";
|
|
5240
|
-
function isCheckEnabled(
|
|
5241
|
-
const entry = config.validate.checks[
|
|
5400
|
+
function isCheckEnabled(check2, config) {
|
|
5401
|
+
const entry = config.validate.checks[check2.id];
|
|
5242
5402
|
if (entry === false)
|
|
5243
5403
|
return false;
|
|
5244
5404
|
if (typeof entry === "object" && entry.enabled === false)
|
|
5245
5405
|
return false;
|
|
5246
|
-
if (
|
|
5406
|
+
if (check2.enabledWhen && !check2.enabledWhen(config))
|
|
5247
5407
|
return false;
|
|
5248
5408
|
return true;
|
|
5249
5409
|
}
|
|
@@ -5280,7 +5440,7 @@ function inspectionFailed(checkId, message, extra = {}) {
|
|
|
5280
5440
|
}
|
|
5281
5441
|
|
|
5282
5442
|
// src/lib/pdf-inspect.ts
|
|
5283
|
-
import { stat, readFile as
|
|
5443
|
+
import { stat, readFile as readFile11 } from "node:fs/promises";
|
|
5284
5444
|
import { getDocumentProxy } from "unpdf";
|
|
5285
5445
|
import * as pdfjs from "unpdf/pdfjs";
|
|
5286
5446
|
function getOps(mod) {
|
|
@@ -5335,7 +5495,7 @@ async function loadPdf(path7) {
|
|
|
5335
5495
|
}
|
|
5336
5496
|
if (hit)
|
|
5337
5497
|
destroyEntry(hit);
|
|
5338
|
-
const docPromise =
|
|
5498
|
+
const docPromise = readFile11(path7).then((buf) => getDocumentProxy(new Uint8Array(buf)));
|
|
5339
5499
|
docCache.delete(path7);
|
|
5340
5500
|
docCache.set(path7, { mtimeMs: st.mtimeMs, size: st.size, doc: docPromise });
|
|
5341
5501
|
evictLru();
|
|
@@ -5533,12 +5693,12 @@ function getOpPass(doc) {
|
|
|
5533
5693
|
return p;
|
|
5534
5694
|
}
|
|
5535
5695
|
function getImagePixelSize(page, name, timeoutMs = 2000) {
|
|
5536
|
-
return new Promise((
|
|
5696
|
+
return new Promise((resolve6) => {
|
|
5537
5697
|
let done = false;
|
|
5538
5698
|
const finish = (v) => {
|
|
5539
5699
|
if (!done) {
|
|
5540
5700
|
done = true;
|
|
5541
|
-
|
|
5701
|
+
resolve6(v);
|
|
5542
5702
|
}
|
|
5543
5703
|
};
|
|
5544
5704
|
const t = setTimeout(() => finish(null), timeoutMs);
|
|
@@ -5594,7 +5754,7 @@ async function isLoadable(doc) {
|
|
|
5594
5754
|
}
|
|
5595
5755
|
|
|
5596
5756
|
// src/checks/pdf/qpdf-structure.ts
|
|
5597
|
-
var
|
|
5757
|
+
var check2 = {
|
|
5598
5758
|
id: "pdf.structure.qpdf",
|
|
5599
5759
|
name: "PDF Structure",
|
|
5600
5760
|
description: "Validates the PDF parses and every page is traversable",
|
|
@@ -5606,16 +5766,16 @@ var check = {
|
|
|
5606
5766
|
const doc = await loadPdf(ctx.pdfPath);
|
|
5607
5767
|
if (!doc || !await isLoadable(doc)) {
|
|
5608
5768
|
return [
|
|
5609
|
-
inspectionFailed(
|
|
5769
|
+
inspectionFailed(check2.id, "PDF could not be fully parsed — possible structural issues.", { file: ctx.pdfPath })
|
|
5610
5770
|
];
|
|
5611
5771
|
}
|
|
5612
5772
|
return [];
|
|
5613
5773
|
}
|
|
5614
5774
|
};
|
|
5615
|
-
registerCheck(
|
|
5775
|
+
registerCheck(check2);
|
|
5616
5776
|
|
|
5617
5777
|
// src/checks/pdf/page-size.ts
|
|
5618
|
-
var
|
|
5778
|
+
var check3 = {
|
|
5619
5779
|
id: "pdf.print.page-size",
|
|
5620
5780
|
name: "Page Size",
|
|
5621
5781
|
description: "Validates PDF page dimensions match expected size from config",
|
|
@@ -5627,7 +5787,7 @@ var check2 = {
|
|
|
5627
5787
|
const doc = await loadPdf(ctx.pdfPath);
|
|
5628
5788
|
if (!doc) {
|
|
5629
5789
|
return [
|
|
5630
|
-
inspectionFailed(
|
|
5790
|
+
inspectionFailed(check3.id, "Could not parse PDF page size.", {
|
|
5631
5791
|
file: ctx.pdfPath
|
|
5632
5792
|
})
|
|
5633
5793
|
];
|
|
@@ -5637,7 +5797,7 @@ var check2 = {
|
|
|
5637
5797
|
const { width, height, tolerance } = ctx.config.page;
|
|
5638
5798
|
if (Math.abs(size.w - width) >= tolerance || Math.abs(size.h - height) >= tolerance) {
|
|
5639
5799
|
return [
|
|
5640
|
-
finding(
|
|
5800
|
+
finding(check3.id, {
|
|
5641
5801
|
severity: "error",
|
|
5642
5802
|
message: `Page size mismatch: expected ~${width}x${height} pts, got ${Math.round(size.w)}x${Math.round(size.h)} pts.`,
|
|
5643
5803
|
file: ctx.pdfPath
|
|
@@ -5647,7 +5807,7 @@ var check2 = {
|
|
|
5647
5807
|
return [];
|
|
5648
5808
|
}
|
|
5649
5809
|
};
|
|
5650
|
-
registerCheck(
|
|
5810
|
+
registerCheck(check3);
|
|
5651
5811
|
|
|
5652
5812
|
// src/checks/pdf/pdfx-structure.ts
|
|
5653
5813
|
function isObject(value) {
|
|
@@ -5757,7 +5917,7 @@ function getPdfxMetadataIssues(objects, flavor) {
|
|
|
5757
5917
|
}
|
|
5758
5918
|
|
|
5759
5919
|
// src/checks/pdf/pdfx-markers.ts
|
|
5760
|
-
var
|
|
5920
|
+
var check4 = {
|
|
5761
5921
|
id: "pdf.print.pdfx-markers",
|
|
5762
5922
|
name: "PDF/X Markers",
|
|
5763
5923
|
description: "Checks PDF/X OutputIntent structure via qpdf JSON",
|
|
@@ -5776,27 +5936,27 @@ var check3 = {
|
|
|
5776
5936
|
const objects = parseQpdfObjectsJson(stdout);
|
|
5777
5937
|
if (!objects) {
|
|
5778
5938
|
return [
|
|
5779
|
-
inspectionFailed(
|
|
5939
|
+
inspectionFailed(check4.id, "Unable to parse qpdf JSON output for PDF/X checks.", { file: ctx.pdfPath })
|
|
5780
5940
|
];
|
|
5781
5941
|
}
|
|
5782
|
-
return getPdfxOutputIntentIssues(objects).map((message) => finding(
|
|
5942
|
+
return getPdfxOutputIntentIssues(objects).map((message) => finding(check4.id, {
|
|
5783
5943
|
severity: "error",
|
|
5784
5944
|
message,
|
|
5785
5945
|
file: ctx.pdfPath
|
|
5786
5946
|
}));
|
|
5787
5947
|
} catch {
|
|
5788
5948
|
return [
|
|
5789
|
-
inspectionFailed(
|
|
5949
|
+
inspectionFailed(check4.id, "Failed to inspect PDF objects with qpdf for PDF/X markers.", { file: ctx.pdfPath })
|
|
5790
5950
|
];
|
|
5791
5951
|
}
|
|
5792
5952
|
}
|
|
5793
5953
|
};
|
|
5794
|
-
registerCheck(
|
|
5954
|
+
registerCheck(check4);
|
|
5795
5955
|
|
|
5796
5956
|
// src/lib/pdf-parse.ts
|
|
5797
|
-
import { readFile as
|
|
5957
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
5798
5958
|
async function readPdfBytes(pdfPath) {
|
|
5799
|
-
return
|
|
5959
|
+
return readFile12(pdfPath, "latin1");
|
|
5800
5960
|
}
|
|
5801
5961
|
function parseInkCov(out) {
|
|
5802
5962
|
const lines = out.split(/\r?\n/).filter((l) => l.includes("CMYK"));
|
|
@@ -5844,7 +6004,7 @@ async function getPerPageInkCoverage(pdfPath) {
|
|
|
5844
6004
|
}
|
|
5845
6005
|
|
|
5846
6006
|
// src/checks/pdf/color-spaces.ts
|
|
5847
|
-
var
|
|
6007
|
+
var check5 = {
|
|
5848
6008
|
id: "pdf.print.color-spaces",
|
|
5849
6009
|
name: "Color Spaces",
|
|
5850
6010
|
description: "Checks for forbidden color spaces (DeviceRGB, Lab, Separation, DeviceN)",
|
|
@@ -5857,7 +6017,7 @@ var check4 = {
|
|
|
5857
6017
|
const results = [];
|
|
5858
6018
|
if (/\/DeviceRGB/.test(bytes)) {
|
|
5859
6019
|
results.push({
|
|
5860
|
-
checkId:
|
|
6020
|
+
checkId: check5.id,
|
|
5861
6021
|
severity: "error",
|
|
5862
6022
|
message: "DeviceRGB found (interior must be CMYK or grayscale only).",
|
|
5863
6023
|
file: ctx.pdfPath
|
|
@@ -5865,7 +6025,7 @@ var check4 = {
|
|
|
5865
6025
|
}
|
|
5866
6026
|
if (/\/Lab\b/.test(bytes)) {
|
|
5867
6027
|
results.push({
|
|
5868
|
-
checkId:
|
|
6028
|
+
checkId: check5.id,
|
|
5869
6029
|
severity: "error",
|
|
5870
6030
|
message: "Lab color space found (not allowed).",
|
|
5871
6031
|
file: ctx.pdfPath
|
|
@@ -5873,7 +6033,7 @@ var check4 = {
|
|
|
5873
6033
|
}
|
|
5874
6034
|
if (/\/Separation/.test(bytes)) {
|
|
5875
6035
|
results.push({
|
|
5876
|
-
checkId:
|
|
6036
|
+
checkId: check5.id,
|
|
5877
6037
|
severity: "error",
|
|
5878
6038
|
message: "Spot color (Separation) found (not allowed).",
|
|
5879
6039
|
file: ctx.pdfPath
|
|
@@ -5881,7 +6041,7 @@ var check4 = {
|
|
|
5881
6041
|
}
|
|
5882
6042
|
if (/\/DeviceN/.test(bytes)) {
|
|
5883
6043
|
results.push({
|
|
5884
|
-
checkId:
|
|
6044
|
+
checkId: check5.id,
|
|
5885
6045
|
severity: "error",
|
|
5886
6046
|
message: "Spot color (DeviceN) found (not allowed).",
|
|
5887
6047
|
file: ctx.pdfPath
|
|
@@ -5890,10 +6050,10 @@ var check4 = {
|
|
|
5890
6050
|
return results;
|
|
5891
6051
|
}
|
|
5892
6052
|
};
|
|
5893
|
-
registerCheck(
|
|
6053
|
+
registerCheck(check5);
|
|
5894
6054
|
|
|
5895
6055
|
// src/checks/pdf/embedded-fonts.ts
|
|
5896
|
-
var
|
|
6056
|
+
var check6 = {
|
|
5897
6057
|
id: "pdf.print.embedded-fonts",
|
|
5898
6058
|
name: "Embedded Fonts",
|
|
5899
6059
|
description: "Verifies all fonts in the PDF are embedded",
|
|
@@ -5909,7 +6069,7 @@ var check5 = {
|
|
|
5909
6069
|
if (fonts.length === 0) {
|
|
5910
6070
|
return [
|
|
5911
6071
|
{
|
|
5912
|
-
checkId:
|
|
6072
|
+
checkId: check6.id,
|
|
5913
6073
|
severity: "warning",
|
|
5914
6074
|
message: "No fonts detected (unexpected).",
|
|
5915
6075
|
file: ctx.pdfPath,
|
|
@@ -5922,7 +6082,7 @@ var check5 = {
|
|
|
5922
6082
|
const names = notEmbedded.map((f) => f.name);
|
|
5923
6083
|
return [
|
|
5924
6084
|
{
|
|
5925
|
-
checkId:
|
|
6085
|
+
checkId: check6.id,
|
|
5926
6086
|
severity: "error",
|
|
5927
6087
|
message: `Not all fonts are embedded (${names.join(", ")}). Check @font-face and Chromium output.`,
|
|
5928
6088
|
file: ctx.pdfPath,
|
|
@@ -5934,10 +6094,10 @@ var check5 = {
|
|
|
5934
6094
|
return [];
|
|
5935
6095
|
}
|
|
5936
6096
|
};
|
|
5937
|
-
registerCheck(
|
|
6097
|
+
registerCheck(check6);
|
|
5938
6098
|
|
|
5939
6099
|
// src/checks/pdf/ink-coverage.ts
|
|
5940
|
-
var
|
|
6100
|
+
var check7 = {
|
|
5941
6101
|
id: "pdf.print.ink-coverage",
|
|
5942
6102
|
name: "Ink Coverage (TAC)",
|
|
5943
6103
|
description: "Checks total area coverage (TAC) against maximum ink limits",
|
|
@@ -5951,7 +6111,7 @@ var check6 = {
|
|
|
5951
6111
|
if (!inkResult.ok) {
|
|
5952
6112
|
return [
|
|
5953
6113
|
{
|
|
5954
|
-
checkId:
|
|
6114
|
+
checkId: check7.id,
|
|
5955
6115
|
severity: "warning",
|
|
5956
6116
|
message: "Ink coverage could not be measured",
|
|
5957
6117
|
file: ctx.pdfPath,
|
|
@@ -5976,7 +6136,7 @@ var check6 = {
|
|
|
5976
6136
|
}
|
|
5977
6137
|
return [
|
|
5978
6138
|
{
|
|
5979
|
-
checkId:
|
|
6139
|
+
checkId: check7.id,
|
|
5980
6140
|
severity: "warning",
|
|
5981
6141
|
message: `Total ink coverage too high on ${offending.length} page(s) (max ${maxTac.toFixed(1)}%, recommended <=${ctx.config.ink.maxTac}%)`,
|
|
5982
6142
|
file: ctx.pdfPath,
|
|
@@ -6000,10 +6160,10 @@ var check6 = {
|
|
|
6000
6160
|
];
|
|
6001
6161
|
}
|
|
6002
6162
|
};
|
|
6003
|
-
registerCheck(
|
|
6163
|
+
registerCheck(check7);
|
|
6004
6164
|
|
|
6005
6165
|
// src/checks/pdf/rasterized-pages.ts
|
|
6006
|
-
var
|
|
6166
|
+
var check8 = {
|
|
6007
6167
|
id: "pdf.print.rasterized-pages",
|
|
6008
6168
|
name: "Rasterized Pages",
|
|
6009
6169
|
description: "Detects pages that appear to be fully rasterized (CSS filters, blend modes, transparency)",
|
|
@@ -6043,7 +6203,7 @@ var check7 = {
|
|
|
6043
6203
|
rasterizedPages.sort((a, b) => a - b);
|
|
6044
6204
|
return [
|
|
6045
6205
|
{
|
|
6046
|
-
checkId:
|
|
6206
|
+
checkId: check8.id,
|
|
6047
6207
|
severity: "warning",
|
|
6048
6208
|
message: `Possible rasterized pages detected: ${rasterizedPages.join(", ")}`,
|
|
6049
6209
|
file: ctx.pdfPath,
|
|
@@ -6054,10 +6214,10 @@ var check7 = {
|
|
|
6054
6214
|
];
|
|
6055
6215
|
}
|
|
6056
6216
|
};
|
|
6057
|
-
registerCheck(
|
|
6217
|
+
registerCheck(check8);
|
|
6058
6218
|
|
|
6059
6219
|
// src/checks/pdf/bookmarks.ts
|
|
6060
|
-
var
|
|
6220
|
+
var check9 = {
|
|
6061
6221
|
id: "pdf.nav.bookmarks",
|
|
6062
6222
|
name: "Bookmarks",
|
|
6063
6223
|
description: "Checks for PDF outline (bookmarks) tree",
|
|
@@ -6071,14 +6231,14 @@ var check8 = {
|
|
|
6071
6231
|
const doc = await loadPdf(ctx.pdfPath);
|
|
6072
6232
|
if (!doc) {
|
|
6073
6233
|
return [
|
|
6074
|
-
inspectionFailed(
|
|
6234
|
+
inspectionFailed(check9.id, "Could not inspect PDF for bookmarks.", {
|
|
6075
6235
|
file: ctx.pdfPath
|
|
6076
6236
|
})
|
|
6077
6237
|
];
|
|
6078
6238
|
}
|
|
6079
6239
|
if (await getOutlineCount(doc) === 0) {
|
|
6080
6240
|
return [
|
|
6081
|
-
finding(
|
|
6241
|
+
finding(check9.id, {
|
|
6082
6242
|
severity: "warning",
|
|
6083
6243
|
message: "PDF does not contain bookmarks (outline tree).",
|
|
6084
6244
|
file: ctx.pdfPath
|
|
@@ -6088,10 +6248,10 @@ var check8 = {
|
|
|
6088
6248
|
return [];
|
|
6089
6249
|
}
|
|
6090
6250
|
};
|
|
6091
|
-
registerCheck(
|
|
6251
|
+
registerCheck(check9);
|
|
6092
6252
|
|
|
6093
6253
|
// src/checks/pdf/toc-links.ts
|
|
6094
|
-
var
|
|
6254
|
+
var check10 = {
|
|
6095
6255
|
id: "pdf.nav.toc-links",
|
|
6096
6256
|
name: "TOC Links",
|
|
6097
6257
|
description: "Detects link annotations on TOC pages",
|
|
@@ -6106,7 +6266,7 @@ var check9 = {
|
|
|
6106
6266
|
if (!doc) {
|
|
6107
6267
|
return [
|
|
6108
6268
|
{
|
|
6109
|
-
checkId:
|
|
6269
|
+
checkId: check10.id,
|
|
6110
6270
|
severity: "warning",
|
|
6111
6271
|
message: "Could not inspect PDF for TOC links.",
|
|
6112
6272
|
file: ctx.pdfPath
|
|
@@ -6117,7 +6277,7 @@ var check9 = {
|
|
|
6117
6277
|
if (!hasLinks) {
|
|
6118
6278
|
return [
|
|
6119
6279
|
{
|
|
6120
|
-
checkId:
|
|
6280
|
+
checkId: check10.id,
|
|
6121
6281
|
severity: "warning",
|
|
6122
6282
|
message: "No link annotations found in PDF (expected for TOC).",
|
|
6123
6283
|
file: ctx.pdfPath
|
|
@@ -6127,10 +6287,10 @@ var check9 = {
|
|
|
6127
6287
|
return [];
|
|
6128
6288
|
}
|
|
6129
6289
|
};
|
|
6130
|
-
registerCheck(
|
|
6290
|
+
registerCheck(check10);
|
|
6131
6291
|
|
|
6132
6292
|
// src/checks/pdf/cross-refs.ts
|
|
6133
|
-
var
|
|
6293
|
+
var check11 = {
|
|
6134
6294
|
id: "pdf.nav.cross-refs",
|
|
6135
6295
|
name: "Cross References",
|
|
6136
6296
|
description: "Counts and verifies internal link annotations",
|
|
@@ -6143,7 +6303,7 @@ var check10 = {
|
|
|
6143
6303
|
if (!doc) {
|
|
6144
6304
|
return [
|
|
6145
6305
|
{
|
|
6146
|
-
checkId:
|
|
6306
|
+
checkId: check11.id,
|
|
6147
6307
|
severity: "info",
|
|
6148
6308
|
message: "Could not inspect PDF for cross-references.",
|
|
6149
6309
|
file: ctx.pdfPath
|
|
@@ -6153,7 +6313,7 @@ var check10 = {
|
|
|
6153
6313
|
const linkCount = await countLinkAnnotations(doc);
|
|
6154
6314
|
return [
|
|
6155
6315
|
{
|
|
6156
|
-
checkId:
|
|
6316
|
+
checkId: check11.id,
|
|
6157
6317
|
severity: "info",
|
|
6158
6318
|
message: `PDF contains ${linkCount} internal link annotation${linkCount !== 1 ? "s" : ""}.`,
|
|
6159
6319
|
file: ctx.pdfPath
|
|
@@ -6161,10 +6321,10 @@ var check10 = {
|
|
|
6161
6321
|
];
|
|
6162
6322
|
}
|
|
6163
6323
|
};
|
|
6164
|
-
registerCheck(
|
|
6324
|
+
registerCheck(check11);
|
|
6165
6325
|
|
|
6166
6326
|
// src/checks/pdf/page-labels.ts
|
|
6167
|
-
var
|
|
6327
|
+
var check12 = {
|
|
6168
6328
|
id: "pdf.nav.page-labels",
|
|
6169
6329
|
name: "Page Labels",
|
|
6170
6330
|
description: "Verifies PDF page labels / folio numbering",
|
|
@@ -6179,7 +6339,7 @@ var check11 = {
|
|
|
6179
6339
|
const labels = await getPageLabels(doc);
|
|
6180
6340
|
return [
|
|
6181
6341
|
{
|
|
6182
|
-
checkId:
|
|
6342
|
+
checkId: check12.id,
|
|
6183
6343
|
severity: "info",
|
|
6184
6344
|
message: labels && labels.length > 0 ? "PDF contains page labels." : "PDF does not contain explicit page labels.",
|
|
6185
6345
|
file: ctx.pdfPath
|
|
@@ -6187,10 +6347,10 @@ var check11 = {
|
|
|
6187
6347
|
];
|
|
6188
6348
|
}
|
|
6189
6349
|
};
|
|
6190
|
-
registerCheck(
|
|
6350
|
+
registerCheck(check12);
|
|
6191
6351
|
|
|
6192
6352
|
// src/checks/pdf/image-resolution.ts
|
|
6193
|
-
var
|
|
6353
|
+
var check13 = {
|
|
6194
6354
|
id: "pdf.print.image-resolution",
|
|
6195
6355
|
name: "Image Resolution",
|
|
6196
6356
|
description: "Checks DPI of images embedded in the PDF",
|
|
@@ -6217,7 +6377,7 @@ var check12 = {
|
|
|
6217
6377
|
lowResPages.sort((a, b) => a - b);
|
|
6218
6378
|
return [
|
|
6219
6379
|
{
|
|
6220
|
-
checkId:
|
|
6380
|
+
checkId: check13.id,
|
|
6221
6381
|
severity: "warning",
|
|
6222
6382
|
message: `Low-resolution images (below ${minDpi} DPI) found on pages: ${lowResPages.join(", ")}`,
|
|
6223
6383
|
file: ctx.pdfPath
|
|
@@ -6227,10 +6387,10 @@ var check12 = {
|
|
|
6227
6387
|
return [];
|
|
6228
6388
|
}
|
|
6229
6389
|
};
|
|
6230
|
-
registerCheck(
|
|
6390
|
+
registerCheck(check13);
|
|
6231
6391
|
|
|
6232
6392
|
// src/checks/pdf/transparency.ts
|
|
6233
|
-
var
|
|
6393
|
+
var check14 = {
|
|
6234
6394
|
id: "pdf.print.transparency",
|
|
6235
6395
|
name: "Transparency",
|
|
6236
6396
|
description: "Checks for transparency markers (/Transparency, /SMask, /BM) in the PDF",
|
|
@@ -6252,7 +6412,7 @@ var check13 = {
|
|
|
6252
6412
|
if (found.length > 0) {
|
|
6253
6413
|
return [
|
|
6254
6414
|
{
|
|
6255
|
-
checkId:
|
|
6415
|
+
checkId: check14.id,
|
|
6256
6416
|
severity: "warning",
|
|
6257
6417
|
message: `Transparency detected in PDF: ${found.join(", ")}. This may cause issues with some printers.`,
|
|
6258
6418
|
file: ctx.pdfPath
|
|
@@ -6262,7 +6422,7 @@ var check13 = {
|
|
|
6262
6422
|
return [];
|
|
6263
6423
|
}
|
|
6264
6424
|
};
|
|
6265
|
-
registerCheck(
|
|
6425
|
+
registerCheck(check14);
|
|
6266
6426
|
|
|
6267
6427
|
// src/checks/pdf/bleed.ts
|
|
6268
6428
|
function findBox(bytes, box) {
|
|
@@ -6272,7 +6432,7 @@ function findBox(bytes, box) {
|
|
|
6272
6432
|
return null;
|
|
6273
6433
|
return [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])];
|
|
6274
6434
|
}
|
|
6275
|
-
var
|
|
6435
|
+
var check15 = {
|
|
6276
6436
|
id: "pdf.print.bleed",
|
|
6277
6437
|
name: "Bleed Box",
|
|
6278
6438
|
description: "Compares MediaBox vs TrimBox/BleedBox to verify bleed area",
|
|
@@ -6286,7 +6446,7 @@ var check14 = {
|
|
|
6286
6446
|
const bytes = await readPdfBytes(ctx.pdfPath).catch(() => "");
|
|
6287
6447
|
if (!bytes) {
|
|
6288
6448
|
return [
|
|
6289
|
-
inspectionFailed(
|
|
6449
|
+
inspectionFailed(check15.id, "Could not inspect PDF for bleed boxes.", {
|
|
6290
6450
|
file: ctx.pdfPath
|
|
6291
6451
|
})
|
|
6292
6452
|
];
|
|
@@ -6296,14 +6456,14 @@ var check14 = {
|
|
|
6296
6456
|
const bleed = findBox(bytes, "BleedBox");
|
|
6297
6457
|
if (!media) {
|
|
6298
6458
|
return [
|
|
6299
|
-
inspectionFailed(
|
|
6459
|
+
inspectionFailed(check15.id, "Could not parse MediaBox from PDF.", {
|
|
6300
6460
|
file: ctx.pdfPath
|
|
6301
6461
|
})
|
|
6302
6462
|
];
|
|
6303
6463
|
}
|
|
6304
6464
|
if (!trim && !bleed) {
|
|
6305
6465
|
return [
|
|
6306
|
-
finding(
|
|
6466
|
+
finding(check15.id, {
|
|
6307
6467
|
severity: "warning",
|
|
6308
6468
|
message: "No TrimBox or BleedBox found. Bleed area cannot be verified.",
|
|
6309
6469
|
file: ctx.pdfPath
|
|
@@ -6316,7 +6476,7 @@ var check14 = {
|
|
|
6316
6476
|
const bleedSize = ctx.config.validate.pdf.bleedSize;
|
|
6317
6477
|
if (mediaW - trimW < bleedSize * 2 * 0.9) {
|
|
6318
6478
|
return [
|
|
6319
|
-
finding(
|
|
6479
|
+
finding(check15.id, {
|
|
6320
6480
|
severity: "warning",
|
|
6321
6481
|
message: `Bleed area appears insufficient. Expected at least ${bleedSize}pt on each side.`,
|
|
6322
6482
|
file: ctx.pdfPath
|
|
@@ -6327,10 +6487,10 @@ var check14 = {
|
|
|
6327
6487
|
return [];
|
|
6328
6488
|
}
|
|
6329
6489
|
};
|
|
6330
|
-
registerCheck(
|
|
6490
|
+
registerCheck(check15);
|
|
6331
6491
|
|
|
6332
6492
|
// src/checks/pdf/pdfx-metadata.ts
|
|
6333
|
-
var
|
|
6493
|
+
var check16 = {
|
|
6334
6494
|
id: "pdf.print.pdfx-metadata",
|
|
6335
6495
|
name: "PDF/X Metadata",
|
|
6336
6496
|
description: "Verifies PDF/X DOCINFO metadata via qpdf JSON",
|
|
@@ -6349,118 +6509,26 @@ var check15 = {
|
|
|
6349
6509
|
const objects = parseQpdfObjectsJson(stdout);
|
|
6350
6510
|
if (!objects) {
|
|
6351
6511
|
return [
|
|
6352
|
-
inspectionFailed(
|
|
6512
|
+
inspectionFailed(check16.id, "Unable to parse qpdf JSON output for PDF/X metadata checks.", { file: ctx.pdfPath })
|
|
6353
6513
|
];
|
|
6354
6514
|
}
|
|
6355
|
-
return getPdfxMetadataIssues(objects, ctx.config.pdfx.flavor).map((message) => finding(
|
|
6515
|
+
return getPdfxMetadataIssues(objects, ctx.config.pdfx.flavor).map((message) => finding(check16.id, {
|
|
6356
6516
|
severity: "error",
|
|
6357
6517
|
message,
|
|
6358
6518
|
file: ctx.pdfPath
|
|
6359
6519
|
}));
|
|
6360
6520
|
} catch {
|
|
6361
6521
|
return [
|
|
6362
|
-
inspectionFailed(
|
|
6522
|
+
inspectionFailed(check16.id, "Failed to inspect PDF objects with qpdf for PDF/X metadata.", { file: ctx.pdfPath })
|
|
6363
6523
|
];
|
|
6364
6524
|
}
|
|
6365
6525
|
}
|
|
6366
6526
|
};
|
|
6367
|
-
registerCheck(check15);
|
|
6368
|
-
|
|
6369
|
-
// src/checks/source/markdownlint.ts
|
|
6370
|
-
import { readFile as readFile11 } from "node:fs/promises";
|
|
6371
|
-
import { lint } from "markdownlint/sync";
|
|
6372
|
-
import { parse as parseYaml2 } from "yaml";
|
|
6373
|
-
|
|
6374
|
-
// src/checks/source/config-file.ts
|
|
6375
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
6376
|
-
import { resolve as resolve5 } from "node:path";
|
|
6377
|
-
function findConfigFile(inputDir, names, explicit) {
|
|
6378
|
-
if (explicit) {
|
|
6379
|
-
const p = resolve5(inputDir, explicit);
|
|
6380
|
-
return existsSync6(p) ? p : null;
|
|
6381
|
-
}
|
|
6382
|
-
for (const name of names) {
|
|
6383
|
-
const p = resolve5(inputDir, name);
|
|
6384
|
-
if (existsSync6(p))
|
|
6385
|
-
return p;
|
|
6386
|
-
}
|
|
6387
|
-
return null;
|
|
6388
|
-
}
|
|
6389
|
-
|
|
6390
|
-
// src/checks/source/markdownlint.ts
|
|
6391
|
-
var CONFIG_NAMES = [
|
|
6392
|
-
".markdownlint.yaml",
|
|
6393
|
-
".markdownlint.yml",
|
|
6394
|
-
".markdownlint.json",
|
|
6395
|
-
".markdownlint.jsonc",
|
|
6396
|
-
".markdownlint-cli2.yaml",
|
|
6397
|
-
".markdownlint-cli2.jsonc"
|
|
6398
|
-
];
|
|
6399
|
-
function stripJsonComments(s) {
|
|
6400
|
-
return s.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
6401
|
-
}
|
|
6402
|
-
async function loadConfig(configPath) {
|
|
6403
|
-
const raw = await readFile11(configPath, "utf8");
|
|
6404
|
-
let parsed;
|
|
6405
|
-
if (configPath.endsWith(".json")) {
|
|
6406
|
-
parsed = JSON.parse(raw);
|
|
6407
|
-
} else if (configPath.endsWith(".jsonc")) {
|
|
6408
|
-
parsed = JSON.parse(stripJsonComments(raw));
|
|
6409
|
-
} else {
|
|
6410
|
-
parsed = parseYaml2(raw);
|
|
6411
|
-
}
|
|
6412
|
-
if (parsed && typeof parsed === "object") {
|
|
6413
|
-
const obj = parsed;
|
|
6414
|
-
if (obj.config && typeof obj.config === "object") {
|
|
6415
|
-
return obj.config;
|
|
6416
|
-
}
|
|
6417
|
-
return obj;
|
|
6418
|
-
}
|
|
6419
|
-
return {};
|
|
6420
|
-
}
|
|
6421
|
-
var check16 = {
|
|
6422
|
-
id: "source.markdownlint",
|
|
6423
|
-
name: "Markdownlint",
|
|
6424
|
-
description: "Runs markdownlint with project config to validate Markdown files",
|
|
6425
|
-
category: "source",
|
|
6426
|
-
phase: "pre-build",
|
|
6427
|
-
async run(ctx) {
|
|
6428
|
-
const sourceConfig = ctx.config.validate.source;
|
|
6429
|
-
if (sourceConfig.markdownlint === false)
|
|
6430
|
-
return [];
|
|
6431
|
-
const files = ctx.markdownFiles;
|
|
6432
|
-
if (!files || files.length === 0)
|
|
6433
|
-
return [];
|
|
6434
|
-
const configPath = typeof sourceConfig.markdownlint === "string" ? sourceConfig.markdownlint : null;
|
|
6435
|
-
const resolvedConfig = findConfigFile(ctx.inputDir, CONFIG_NAMES, configPath);
|
|
6436
|
-
if (!resolvedConfig && !configPath)
|
|
6437
|
-
return [];
|
|
6438
|
-
const config = resolvedConfig ? await loadConfig(resolvedConfig) : { default: true };
|
|
6439
|
-
const results = lint({ files, config });
|
|
6440
|
-
const out = [];
|
|
6441
|
-
for (const [file, violations] of Object.entries(results)) {
|
|
6442
|
-
if (!Array.isArray(violations))
|
|
6443
|
-
continue;
|
|
6444
|
-
for (const v of violations) {
|
|
6445
|
-
out.push({
|
|
6446
|
-
checkId: check16.id,
|
|
6447
|
-
severity: "warning",
|
|
6448
|
-
message: `${v.ruleDescription} (${v.ruleNames.join("/")})`,
|
|
6449
|
-
file,
|
|
6450
|
-
line: v.lineNumber,
|
|
6451
|
-
column: v.errorRange?.[0],
|
|
6452
|
-
code: v.ruleNames[0]
|
|
6453
|
-
});
|
|
6454
|
-
}
|
|
6455
|
-
}
|
|
6456
|
-
return out;
|
|
6457
|
-
}
|
|
6458
|
-
};
|
|
6459
6527
|
registerCheck(check16);
|
|
6460
6528
|
|
|
6461
6529
|
// src/checks/source/htmlhint.ts
|
|
6462
6530
|
import { existsSync as existsSync7 } from "node:fs";
|
|
6463
|
-
import { readFile as
|
|
6531
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
6464
6532
|
import htmlhint from "htmlhint";
|
|
6465
6533
|
var { HTMLHint } = htmlhint;
|
|
6466
6534
|
var CONFIG_NAMES2 = [".htmlhintrc"];
|
|
@@ -6480,8 +6548,8 @@ var check17 = {
|
|
|
6480
6548
|
const resolvedConfig = findConfigFile(ctx.inputDir, CONFIG_NAMES2, configPath);
|
|
6481
6549
|
if (!resolvedConfig && !configPath)
|
|
6482
6550
|
return [];
|
|
6483
|
-
const ruleset = resolvedConfig ? JSON.parse(await
|
|
6484
|
-
const html = await
|
|
6551
|
+
const ruleset = resolvedConfig ? JSON.parse(await readFile13(resolvedConfig, "utf8")) : HTMLHint.defaultRuleset;
|
|
6552
|
+
const html = await readFile13(ctx.htmlPath, "utf8");
|
|
6485
6553
|
const messages = HTMLHint.verify(html, ruleset);
|
|
6486
6554
|
return messages.map((m) => ({
|
|
6487
6555
|
checkId: check17.id,
|
|
@@ -6496,7 +6564,7 @@ var check17 = {
|
|
|
6496
6564
|
registerCheck(check17);
|
|
6497
6565
|
|
|
6498
6566
|
// src/checks/source/stylelint.ts
|
|
6499
|
-
import { readFile as
|
|
6567
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
6500
6568
|
|
|
6501
6569
|
// src/lib/printsafe.ts
|
|
6502
6570
|
import postcss2 from "postcss";
|
|
@@ -6772,7 +6840,7 @@ var check18 = {
|
|
|
6772
6840
|
for (const file of files) {
|
|
6773
6841
|
let css;
|
|
6774
6842
|
try {
|
|
6775
|
-
css = await
|
|
6843
|
+
css = await readFile14(file, "utf8");
|
|
6776
6844
|
} catch (err) {
|
|
6777
6845
|
results.push({
|
|
6778
6846
|
checkId: check18.id,
|
|
@@ -6799,12 +6867,12 @@ var check18 = {
|
|
|
6799
6867
|
registerCheck(check18);
|
|
6800
6868
|
|
|
6801
6869
|
// src/checks/source/css-ownership.ts
|
|
6802
|
-
import { readFile as
|
|
6870
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
6803
6871
|
import postcss3 from "postcss";
|
|
6804
6872
|
import { parse as parseYaml3 } from "yaml";
|
|
6805
6873
|
var CONFIG_NAMES3 = [".gutterpress/css-contract.yaml", ".gutterpress/css-contract.yml"];
|
|
6806
6874
|
async function loadContract(configPath) {
|
|
6807
|
-
const raw = await
|
|
6875
|
+
const raw = await readFile15(configPath, "utf8");
|
|
6808
6876
|
const parsed = parseYaml3(raw);
|
|
6809
6877
|
if (parsed && typeof parsed === "object")
|
|
6810
6878
|
return parsed;
|
|
@@ -6955,7 +7023,7 @@ var check19 = {
|
|
|
6955
7023
|
continue;
|
|
6956
7024
|
let css;
|
|
6957
7025
|
try {
|
|
6958
|
-
css = await
|
|
7026
|
+
css = await readFile15(absFile, "utf8");
|
|
6959
7027
|
} catch {
|
|
6960
7028
|
continue;
|
|
6961
7029
|
}
|
|
@@ -7001,7 +7069,7 @@ import { existsSync as existsSync8 } from "node:fs";
|
|
|
7001
7069
|
import { dirname as dirname3, resolve as resolve6 } from "node:path";
|
|
7002
7070
|
|
|
7003
7071
|
// src/checks/source/local-ref-parser.ts
|
|
7004
|
-
import { readFile as
|
|
7072
|
+
import { readFile as readFile16 } from "node:fs/promises";
|
|
7005
7073
|
function newlineOffsets(content) {
|
|
7006
7074
|
const offsets = [];
|
|
7007
7075
|
for (let i = 0;i < content.length; i++)
|
|
@@ -7070,7 +7138,7 @@ async function* renderedLocalRefs(ctx, checkId, results) {
|
|
|
7070
7138
|
for (const file of files) {
|
|
7071
7139
|
let refs;
|
|
7072
7140
|
try {
|
|
7073
|
-
refs = collectRenderedLocalRefs(await
|
|
7141
|
+
refs = collectRenderedLocalRefs(await readFile16(file, "utf8"));
|
|
7074
7142
|
} catch {
|
|
7075
7143
|
results.push(inspectionFailed(checkId, `Could not read source file: ${file}`, { file }));
|
|
7076
7144
|
continue;
|
|
@@ -7421,7 +7489,7 @@ var check21 = {
|
|
|
7421
7489
|
registerCheck(check21);
|
|
7422
7490
|
|
|
7423
7491
|
// src/checks/source/accessibility-alt-text.ts
|
|
7424
|
-
import { readFile as
|
|
7492
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
7425
7493
|
var check22 = {
|
|
7426
7494
|
id: "source.accessibility.alt-text",
|
|
7427
7495
|
name: "Image Alt Text",
|
|
@@ -7435,7 +7503,7 @@ var check22 = {
|
|
|
7435
7503
|
const results = [];
|
|
7436
7504
|
for (const file of files) {
|
|
7437
7505
|
try {
|
|
7438
|
-
const content = await
|
|
7506
|
+
const content = await readFile17(file, "utf8");
|
|
7439
7507
|
const lines = content.split(`
|
|
7440
7508
|
`);
|
|
7441
7509
|
let inFence = false;
|
|
@@ -7479,7 +7547,7 @@ function extractImageAlts(line) {
|
|
|
7479
7547
|
registerCheck(check22);
|
|
7480
7548
|
|
|
7481
7549
|
// src/checks/source/accessibility-heading-order.ts
|
|
7482
|
-
import { readFile as
|
|
7550
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
7483
7551
|
var check23 = {
|
|
7484
7552
|
id: "source.accessibility.heading-order",
|
|
7485
7553
|
name: "Heading Order",
|
|
@@ -7493,7 +7561,7 @@ var check23 = {
|
|
|
7493
7561
|
const results = [];
|
|
7494
7562
|
for (const file of files) {
|
|
7495
7563
|
try {
|
|
7496
|
-
const content = await
|
|
7564
|
+
const content = await readFile18(file, "utf8");
|
|
7497
7565
|
const lines = content.split(`
|
|
7498
7566
|
`);
|
|
7499
7567
|
let inFence = false;
|
|
@@ -7529,7 +7597,7 @@ var check23 = {
|
|
|
7529
7597
|
registerCheck(check23);
|
|
7530
7598
|
|
|
7531
7599
|
// src/checks/source/layout-markers.ts
|
|
7532
|
-
import { readFile as
|
|
7600
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
7533
7601
|
var check24 = {
|
|
7534
7602
|
id: "source.markdown.layout-markers",
|
|
7535
7603
|
name: "Layout Markers",
|
|
@@ -7547,7 +7615,7 @@ var check24 = {
|
|
|
7547
7615
|
const md = createMarkdownRenderer(plugins);
|
|
7548
7616
|
for (const file of files) {
|
|
7549
7617
|
try {
|
|
7550
|
-
const content = await
|
|
7618
|
+
const content = await readFile19(file, "utf8");
|
|
7551
7619
|
const env = {};
|
|
7552
7620
|
md.render(content, env);
|
|
7553
7621
|
for (const w of env.layoutWarnings ?? []) {
|
|
@@ -7569,7 +7637,7 @@ var check24 = {
|
|
|
7569
7637
|
registerCheck(check24);
|
|
7570
7638
|
|
|
7571
7639
|
// src/checks/source/merge-markers.ts
|
|
7572
|
-
import { readFile as
|
|
7640
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
7573
7641
|
import path8 from "node:path";
|
|
7574
7642
|
|
|
7575
7643
|
// src/checks/asset/extensions.ts
|
|
@@ -7611,7 +7679,7 @@ var check25 = {
|
|
|
7611
7679
|
for (const file of textFiles) {
|
|
7612
7680
|
let content;
|
|
7613
7681
|
try {
|
|
7614
|
-
content = await
|
|
7682
|
+
content = await readFile20(file, "utf8");
|
|
7615
7683
|
} catch {
|
|
7616
7684
|
results.push(inspectionFailed(check25.id, `Could not read source file: ${file}`, { file }));
|
|
7617
7685
|
continue;
|
|
@@ -7674,7 +7742,7 @@ registerCheck(check25);
|
|
|
7674
7742
|
import { stat as stat3 } from "node:fs/promises";
|
|
7675
7743
|
|
|
7676
7744
|
// src/lib/image-inspect.ts
|
|
7677
|
-
import { stat as stat2, readFile as
|
|
7745
|
+
import { stat as stat2, readFile as readFile21 } from "node:fs/promises";
|
|
7678
7746
|
var DEFAULT_DPI = 72;
|
|
7679
7747
|
var cache = new Map;
|
|
7680
7748
|
async function inspectImage(path9) {
|
|
@@ -7689,7 +7757,7 @@ async function inspectImage(path9) {
|
|
|
7689
7757
|
return hit.info;
|
|
7690
7758
|
let info2 = null;
|
|
7691
7759
|
try {
|
|
7692
|
-
const buf = await
|
|
7760
|
+
const buf = await readFile21(path9);
|
|
7693
7761
|
info2 = parseImage(buf);
|
|
7694
7762
|
} catch {
|
|
7695
7763
|
info2 = null;
|
|
@@ -8249,7 +8317,7 @@ var check33 = {
|
|
|
8249
8317
|
registerCheck(check33);
|
|
8250
8318
|
|
|
8251
8319
|
// src/checks/heuristic/section-density.ts
|
|
8252
|
-
import { readFile as
|
|
8320
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
8253
8321
|
var check34 = {
|
|
8254
8322
|
id: "heuristic.chunking.section-density",
|
|
8255
8323
|
name: "Section Density",
|
|
@@ -8266,7 +8334,7 @@ var check34 = {
|
|
|
8266
8334
|
const results = [];
|
|
8267
8335
|
for (const file of files) {
|
|
8268
8336
|
try {
|
|
8269
|
-
const content = await
|
|
8337
|
+
const content = await readFile22(file, "utf8");
|
|
8270
8338
|
const lines = content.split(`
|
|
8271
8339
|
`);
|
|
8272
8340
|
let currentSectionStart = 0;
|
|
@@ -8765,6 +8833,14 @@ async function executeValidation(args) {
|
|
|
8765
8833
|
only,
|
|
8766
8834
|
skip
|
|
8767
8835
|
};
|
|
8836
|
+
if (args.fix) {
|
|
8837
|
+
const selected = selectChecks(runnerOptions, config).checks;
|
|
8838
|
+
if (selected.some((check37) => check37.id === MARKDOWNLINT_CHECK_ID)) {
|
|
8839
|
+
await applyMarkdownlintFixes(context);
|
|
8840
|
+
} else {
|
|
8841
|
+
log.warn(`--fix: ${MARKDOWNLINT_CHECK_ID} is not part of this run — no files were fixed.`);
|
|
8842
|
+
}
|
|
8843
|
+
}
|
|
8768
8844
|
const runs = planRuns({ manifest, baseConfig: config, targetIds, pdfPath, categories, only });
|
|
8769
8845
|
const reports = [];
|
|
8770
8846
|
const toolResults = [];
|
|
@@ -9243,7 +9319,7 @@ async function runBuild(opts) {
|
|
|
9243
9319
|
import path11 from "path";
|
|
9244
9320
|
import { tmpdir as tmpdir2 } from "os";
|
|
9245
9321
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
9246
|
-
import { readdir as readdir5, readFile as
|
|
9322
|
+
import { readdir as readdir5, readFile as readFile23, writeFile as writeFile6 } from "node:fs/promises";
|
|
9247
9323
|
|
|
9248
9324
|
// src/utils/file-utils.ts
|
|
9249
9325
|
import { promises as fs3 } from "fs";
|
|
@@ -9753,7 +9829,7 @@ async function cleanupOrphanTempDirs() {
|
|
|
9753
9829
|
const dir = path11.join(TEMP_DIR_BASE, entry);
|
|
9754
9830
|
const pidFile = path11.join(dir, PID_FILE_NAME);
|
|
9755
9831
|
try {
|
|
9756
|
-
const raw = await
|
|
9832
|
+
const raw = await readFile23(pidFile, "utf8");
|
|
9757
9833
|
const pid = parseInt(raw.trim(), 10);
|
|
9758
9834
|
if (!isProcessAlive(pid)) {
|
|
9759
9835
|
debug(`Removing orphan temp dir ${dir} (pid ${pid} not alive)`);
|
|
@@ -9768,7 +9844,7 @@ async function initializePreviewDirectories() {
|
|
|
9768
9844
|
const tempDir = path11.join(TEMP_DIR_BASE, tempDirSuffix);
|
|
9769
9845
|
await mkdir4(tempDir);
|
|
9770
9846
|
debug(`Created temporary directory: ${tempDir}`);
|
|
9771
|
-
await
|
|
9847
|
+
await writeFile6(path11.join(tempDir, PID_FILE_NAME), `${process.pid}
|
|
9772
9848
|
`, "utf8");
|
|
9773
9849
|
return tempDir;
|
|
9774
9850
|
}
|
|
@@ -9859,7 +9935,7 @@ function createServerState(inputPath, tempDir, config, options) {
|
|
|
9859
9935
|
import http from "node:http";
|
|
9860
9936
|
import net from "node:net";
|
|
9861
9937
|
import { createHash as createHash6, randomUUID } from "node:crypto";
|
|
9862
|
-
import { readFile as
|
|
9938
|
+
import { readFile as readFile24, stat as stat4 } from "node:fs/promises";
|
|
9863
9939
|
import path13 from "path";
|
|
9864
9940
|
import { WebSocket, WebSocketServer } from "ws";
|
|
9865
9941
|
|
|
@@ -10177,7 +10253,7 @@ async function serveStatic(absPath, res, cacheControl = "no-store", extraHeaders
|
|
|
10177
10253
|
}
|
|
10178
10254
|
let data;
|
|
10179
10255
|
try {
|
|
10180
|
-
data = await
|
|
10256
|
+
data = await readFile24(filePath);
|
|
10181
10257
|
} catch {
|
|
10182
10258
|
res.writeHead(404);
|
|
10183
10259
|
res.end("Not Found");
|
|
@@ -10227,7 +10303,7 @@ async function serveRevalidatedStatic(req, absPath, res, validators) {
|
|
|
10227
10303
|
let data;
|
|
10228
10304
|
if (!validator || validator.stamp !== stamp) {
|
|
10229
10305
|
try {
|
|
10230
|
-
data = await
|
|
10306
|
+
data = await readFile24(absPath);
|
|
10231
10307
|
} catch {
|
|
10232
10308
|
await serveStatic(absPath, res);
|
|
10233
10309
|
return;
|
|
@@ -10568,7 +10644,7 @@ async function startPreviewServer(options) {
|
|
|
10568
10644
|
import { platform, arch, release } from "node:os";
|
|
10569
10645
|
|
|
10570
10646
|
// src/lib/remote-auth/token-store.ts
|
|
10571
|
-
import { chmod, mkdir as mkdir5, readFile as
|
|
10647
|
+
import { chmod, mkdir as mkdir5, readFile as readFile25, rename as rename2, writeFile as writeFile7 } from "node:fs/promises";
|
|
10572
10648
|
import os3 from "node:os";
|
|
10573
10649
|
import path14 from "node:path";
|
|
10574
10650
|
function credentialHostKey(hostOrUrl) {
|
|
@@ -10612,7 +10688,7 @@ class FileTokenStore {
|
|
|
10612
10688
|
async read() {
|
|
10613
10689
|
let raw;
|
|
10614
10690
|
try {
|
|
10615
|
-
raw = await
|
|
10691
|
+
raw = await readFile25(this.filePath, "utf8");
|
|
10616
10692
|
} catch (e) {
|
|
10617
10693
|
if (e?.code === "ENOENT") {
|
|
10618
10694
|
return { version: 1, credentials: {} };
|
|
@@ -10624,7 +10700,7 @@ class FileTokenStore {
|
|
|
10624
10700
|
if (parsed && typeof parsed === "object" && parsed.credentials)
|
|
10625
10701
|
return parsed;
|
|
10626
10702
|
} catch {
|
|
10627
|
-
await
|
|
10703
|
+
await writeFile7(`${this.filePath}.corrupt`, raw, {
|
|
10628
10704
|
encoding: "utf8",
|
|
10629
10705
|
mode: 384
|
|
10630
10706
|
}).catch(() => {});
|
|
@@ -10634,7 +10710,7 @@ class FileTokenStore {
|
|
|
10634
10710
|
async write(data) {
|
|
10635
10711
|
await mkdir5(path14.dirname(this.filePath), { recursive: true });
|
|
10636
10712
|
const tmpPath = `${this.filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
10637
|
-
await
|
|
10713
|
+
await writeFile7(tmpPath, JSON.stringify(data, null, 2), {
|
|
10638
10714
|
encoding: "utf8",
|
|
10639
10715
|
mode: 384
|
|
10640
10716
|
});
|
|
@@ -10812,14 +10888,14 @@ async function getSystemDiagnostics() {
|
|
|
10812
10888
|
};
|
|
10813
10889
|
}
|
|
10814
10890
|
// src/lib/project-scaffold.ts
|
|
10815
|
-
import { access, copyFile, cp as cp3, mkdir as mkdir9, readdir as readdir6, readFile as
|
|
10891
|
+
import { access, copyFile, cp as cp3, mkdir as mkdir9, readdir as readdir6, readFile as readFile29, stat as stat6, writeFile as writeFile8 } from "node:fs/promises";
|
|
10816
10892
|
import { constants as FS, existsSync as existsSync13 } from "node:fs";
|
|
10817
10893
|
import path18 from "node:path";
|
|
10818
10894
|
|
|
10819
10895
|
// src/lib/manifest-doc.ts
|
|
10820
10896
|
import { existsSync as existsSync11 } from "node:fs";
|
|
10821
10897
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
10822
|
-
import { mkdir as mkdir6, open, readFile as
|
|
10898
|
+
import { mkdir as mkdir6, open, readFile as readFile26, rename as rename3, rm as rm2 } from "node:fs/promises";
|
|
10823
10899
|
import path15 from "node:path";
|
|
10824
10900
|
import { parseDocument, isSeq, YAMLSeq } from "yaml";
|
|
10825
10901
|
function resolveManifestPath(projectDir) {
|
|
@@ -10830,7 +10906,7 @@ async function loadManifestDoc(projectDir) {
|
|
|
10830
10906
|
const file = resolveManifestPath(projectDir);
|
|
10831
10907
|
let text = "";
|
|
10832
10908
|
try {
|
|
10833
|
-
text = await
|
|
10909
|
+
text = await readFile26(file, "utf8");
|
|
10834
10910
|
} catch (error2) {
|
|
10835
10911
|
if (error2.code !== "ENOENT")
|
|
10836
10912
|
throw error2;
|
|
@@ -10877,7 +10953,7 @@ function scalarString(item) {
|
|
|
10877
10953
|
}
|
|
10878
10954
|
|
|
10879
10955
|
// src/lib/extension-manager.ts
|
|
10880
|
-
import { cp as cp2, mkdir as mkdir8, readFile as
|
|
10956
|
+
import { cp as cp2, mkdir as mkdir8, readFile as readFile28, rm as rm4, stat as stat5 } from "node:fs/promises";
|
|
10881
10957
|
import { existsSync as existsSync12 } from "node:fs";
|
|
10882
10958
|
import path17 from "node:path";
|
|
10883
10959
|
import { isSeq as isSeq2, isMap, isScalar, YAMLMap, Scalar } from "yaml";
|
|
@@ -10890,7 +10966,7 @@ import {
|
|
|
10890
10966
|
mkdir as mkdir7,
|
|
10891
10967
|
mkdtemp as mkdtemp2,
|
|
10892
10968
|
open as open2,
|
|
10893
|
-
readFile as
|
|
10969
|
+
readFile as readFile27,
|
|
10894
10970
|
realpath as realpath2,
|
|
10895
10971
|
rename as rename4,
|
|
10896
10972
|
rm as rm3
|
|
@@ -11288,7 +11364,7 @@ async function readInstalledManifest(packageDir, selected) {
|
|
|
11288
11364
|
const info2 = await lstat2(packageJsonPath);
|
|
11289
11365
|
if (!info2.isFile() || info2.isSymbolicLink())
|
|
11290
11366
|
throw new Error("not a regular file");
|
|
11291
|
-
manifest = object3(JSON.parse(await
|
|
11367
|
+
manifest = object3(JSON.parse(await readFile27(packageJsonPath, "utf8")));
|
|
11292
11368
|
} catch (error2) {
|
|
11293
11369
|
throw new SecurityInstallError(`Downloaded ${selected.name}@${selected.version} has no valid package.json (${error2 instanceof Error ? error2.message : String(error2)}).`);
|
|
11294
11370
|
}
|
|
@@ -12060,7 +12136,7 @@ async function readExtensionCss(projectDir, use) {
|
|
|
12060
12136
|
throw new Error(`Extension "${use}" declares no stylesheets.`);
|
|
12061
12137
|
const parts = [];
|
|
12062
12138
|
for (const sheet of sheets)
|
|
12063
|
-
parts.push(await
|
|
12139
|
+
parts.push(await readFile28(sheet, "utf8"));
|
|
12064
12140
|
return parts.join(`
|
|
12065
12141
|
|
|
12066
12142
|
`);
|
|
@@ -12187,7 +12263,7 @@ async function scaffoldProject(options) {
|
|
|
12187
12263
|
await copyFile(tplManifest, path18.join(projectDir, MANIFEST_FILENAMES[0]));
|
|
12188
12264
|
await copyFile(tplChapter, path18.join(projectDir, "chapter-01.md"));
|
|
12189
12265
|
await mkdir9(path18.join(projectDir, "styles"), { recursive: true });
|
|
12190
|
-
await
|
|
12266
|
+
await writeFile8(path18.join(projectDir, "styles", "book.css"), starterOverridesCss(starterThemeId), "utf8");
|
|
12191
12267
|
}
|
|
12192
12268
|
} catch (e) {
|
|
12193
12269
|
throw new CreateProjectErrorImpl("scaffold-io", `Could not create the project files: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -12302,7 +12378,7 @@ async function adoptFolder(options) {
|
|
|
12302
12378
|
const bookCssPath = path18.join(dir, "styles", "book.css");
|
|
12303
12379
|
const hadOwnStylesheet = existsSync13(bookCssPath);
|
|
12304
12380
|
if (!hadOwnStylesheet) {
|
|
12305
|
-
await
|
|
12381
|
+
await writeFile8(bookCssPath, starterOverridesCss(themeId), "utf8");
|
|
12306
12382
|
}
|
|
12307
12383
|
const filesYaml = mdFiles.map((f) => ` - "${escapeYamlScalar(f)}"`).join(`
|
|
12308
12384
|
`);
|
|
@@ -12318,7 +12394,7 @@ ${filesYaml}
|
|
|
12318
12394
|
styles:
|
|
12319
12395
|
- styles/book.css
|
|
12320
12396
|
`;
|
|
12321
|
-
await
|
|
12397
|
+
await writeFile8(path18.join(dir, MANIFEST_FILENAMES[0]), manifest, "utf8");
|
|
12322
12398
|
await mkdir9(path18.join(dir, "assets"), { recursive: true });
|
|
12323
12399
|
if (!hadOwnStylesheet) {
|
|
12324
12400
|
await addBuiltInStyleSet(dir, themeId);
|
|
@@ -12361,10 +12437,10 @@ async function ensureGitignoreHasDist(projectDir) {
|
|
|
12361
12437
|
const gitignorePath = path18.join(projectDir, ".gitignore");
|
|
12362
12438
|
let existing = null;
|
|
12363
12439
|
try {
|
|
12364
|
-
existing = await
|
|
12440
|
+
existing = await readFile29(gitignorePath, "utf8");
|
|
12365
12441
|
} catch {}
|
|
12366
12442
|
if (existing === null) {
|
|
12367
|
-
await
|
|
12443
|
+
await writeFile8(gitignorePath, `dist/
|
|
12368
12444
|
`, "utf8");
|
|
12369
12445
|
return;
|
|
12370
12446
|
}
|
|
@@ -12374,14 +12450,14 @@ async function ensureGitignoreHasDist(projectDir) {
|
|
|
12374
12450
|
return;
|
|
12375
12451
|
const needsLeadingNewline = existing.length > 0 && !existing.endsWith(`
|
|
12376
12452
|
`);
|
|
12377
|
-
await
|
|
12453
|
+
await writeFile8(gitignorePath, existing + (needsLeadingNewline ? `
|
|
12378
12454
|
` : "") + `dist/
|
|
12379
12455
|
`, "utf8");
|
|
12380
12456
|
}
|
|
12381
12457
|
async function firstSourceFile(manifestPath) {
|
|
12382
12458
|
let text;
|
|
12383
12459
|
try {
|
|
12384
|
-
text = await
|
|
12460
|
+
text = await readFile29(manifestPath, "utf8");
|
|
12385
12461
|
} catch {
|
|
12386
12462
|
return;
|
|
12387
12463
|
}
|
|
@@ -12393,14 +12469,14 @@ async function firstSourceFile(manifestPath) {
|
|
|
12393
12469
|
return m ? m[1].trim() : undefined;
|
|
12394
12470
|
}
|
|
12395
12471
|
async function fillTemplateFile(filePath, substitutions) {
|
|
12396
|
-
let text = await
|
|
12472
|
+
let text = await readFile29(filePath, "utf8");
|
|
12397
12473
|
for (const [token, value] of Object.entries(substitutions)) {
|
|
12398
12474
|
text = text.split(token).join(value);
|
|
12399
12475
|
}
|
|
12400
|
-
await
|
|
12476
|
+
await writeFile8(filePath, text, "utf8");
|
|
12401
12477
|
}
|
|
12402
12478
|
// src/lib/extension-scaffold.ts
|
|
12403
|
-
import { access as access2, mkdir as mkdir10, readFile as
|
|
12479
|
+
import { access as access2, mkdir as mkdir10, readFile as readFile30, writeFile as writeFile9 } from "node:fs/promises";
|
|
12404
12480
|
import { constants as FS2 } from "node:fs";
|
|
12405
12481
|
import path19 from "node:path";
|
|
12406
12482
|
var EXTENSION_KINDS = ["plugin", "theme"];
|
|
@@ -12517,9 +12593,9 @@ async function scaffoldExtension(options) {
|
|
|
12517
12593
|
const src = await getAssetPath(`extension-templates/${kind}/${assetName}`);
|
|
12518
12594
|
const dest = path19.join(extensionDir, relDest);
|
|
12519
12595
|
await mkdir10(path19.dirname(dest), { recursive: true });
|
|
12520
|
-
const text = await
|
|
12596
|
+
const text = await readFile30(src, "utf8");
|
|
12521
12597
|
const table = relDest.endsWith(".json") ? jsonSafe : plain;
|
|
12522
|
-
await
|
|
12598
|
+
await writeFile9(dest, substitute(text, table), "utf8");
|
|
12523
12599
|
written.push(relDest);
|
|
12524
12600
|
}
|
|
12525
12601
|
} catch (e) {
|
|
@@ -12543,7 +12619,7 @@ function substitute(text, table) {
|
|
|
12543
12619
|
return out;
|
|
12544
12620
|
}
|
|
12545
12621
|
// src/lib/project-templates.ts
|
|
12546
|
-
import { cp as cp4, mkdir as mkdir11, readFile as
|
|
12622
|
+
import { cp as cp4, mkdir as mkdir11, readFile as readFile31, readdir as readdir7, stat as stat7, writeFile as writeFile10 } from "node:fs/promises";
|
|
12547
12623
|
import { constants as FS3, existsSync as existsSync14 } from "node:fs";
|
|
12548
12624
|
import { access as access3 } from "node:fs/promises";
|
|
12549
12625
|
import path20 from "node:path";
|
|
@@ -12555,7 +12631,7 @@ var BUILT_IN_TEMPLATE_IDS = [
|
|
|
12555
12631
|
];
|
|
12556
12632
|
async function readTemplateChoices(manifestPath) {
|
|
12557
12633
|
try {
|
|
12558
|
-
const text = await
|
|
12634
|
+
const text = await readFile31(manifestPath, "utf8");
|
|
12559
12635
|
const doc = parseDocument2(text);
|
|
12560
12636
|
const out = {};
|
|
12561
12637
|
const preset = doc.get("preset");
|
|
@@ -12724,7 +12800,7 @@ async function saveProjectAsTemplate(options) {
|
|
|
12724
12800
|
const shared = manifestName ? await reconcileSharedRefs(dir, projectDir, options.sharedRefs ?? "vendor") : { vendoredRefs: [], excludedRefs: [] };
|
|
12725
12801
|
if (manifestName)
|
|
12726
12802
|
await retokeniseManifest(path20.join(dir, manifestName));
|
|
12727
|
-
await
|
|
12803
|
+
await writeFile10(path20.join(dir, TEMPLATE_META_FILE), JSON.stringify({ label: name }, null, 2), "utf8");
|
|
12728
12804
|
return {
|
|
12729
12805
|
id,
|
|
12730
12806
|
label: name,
|
|
@@ -12737,12 +12813,12 @@ async function saveProjectAsTemplate(options) {
|
|
|
12737
12813
|
async function retokeniseManifest(manifestPath) {
|
|
12738
12814
|
let text;
|
|
12739
12815
|
try {
|
|
12740
|
-
text = await
|
|
12816
|
+
text = await readFile31(manifestPath, "utf8");
|
|
12741
12817
|
} catch {
|
|
12742
12818
|
return;
|
|
12743
12819
|
}
|
|
12744
12820
|
text = text.replace(/^title:\s*.*$/m, 'title: "{{TITLE}}"').replace(/^(authors:[^\n]*\n[ \t]*-[ \t]*).*$/m, '$1"{{AUTHOR}}"');
|
|
12745
|
-
await
|
|
12821
|
+
await writeFile10(manifestPath, text, "utf8");
|
|
12746
12822
|
}
|
|
12747
12823
|
async function listCustomTemplates(templatesRoot) {
|
|
12748
12824
|
let entries;
|
|
@@ -12758,7 +12834,7 @@ async function listCustomTemplates(templatesRoot) {
|
|
|
12758
12834
|
const dir = path20.join(templatesRoot, entry.name);
|
|
12759
12835
|
let label = prettify(entry.name);
|
|
12760
12836
|
try {
|
|
12761
|
-
const meta = JSON.parse(await
|
|
12837
|
+
const meta = JSON.parse(await readFile31(path20.join(dir, TEMPLATE_META_FILE), "utf8"));
|
|
12762
12838
|
if (typeof meta.label === "string" && meta.label)
|
|
12763
12839
|
label = meta.label;
|
|
12764
12840
|
} catch {}
|
|
@@ -12784,7 +12860,7 @@ async function importTemplateFromFolder(options) {
|
|
|
12784
12860
|
return saveProjectAsTemplate({ projectDir: sourceDir, name, templatesRoot });
|
|
12785
12861
|
}
|
|
12786
12862
|
// src/lib/snippets.ts
|
|
12787
|
-
import { readdir as readdir8, readFile as
|
|
12863
|
+
import { readdir as readdir8, readFile as readFile32, writeFile as writeFile11, mkdir as mkdir12, rm as rm5 } from "node:fs/promises";
|
|
12788
12864
|
import path21 from "node:path";
|
|
12789
12865
|
var SNIPPETS_DIR = "snippets";
|
|
12790
12866
|
var PLACEHOLDER_RE = /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g;
|
|
@@ -12826,7 +12902,7 @@ async function scanSnippetFiles(dir) {
|
|
|
12826
12902
|
continue;
|
|
12827
12903
|
let body = "";
|
|
12828
12904
|
try {
|
|
12829
|
-
body = await
|
|
12905
|
+
body = await readFile32(path21.join(dir, fileName), "utf8");
|
|
12830
12906
|
} catch {
|
|
12831
12907
|
continue;
|
|
12832
12908
|
}
|
|
@@ -12844,7 +12920,7 @@ async function listSnippets(projectDir) {
|
|
|
12844
12920
|
return files.map((file) => ({ ...file, source: { kind: "project" } }));
|
|
12845
12921
|
}
|
|
12846
12922
|
async function readSnippet(projectDir, fileName) {
|
|
12847
|
-
return
|
|
12923
|
+
return readFile32(resolveSnippetPath(projectDir, fileName), "utf8");
|
|
12848
12924
|
}
|
|
12849
12925
|
async function saveSnippet(projectDir, name, body) {
|
|
12850
12926
|
const stem = slugify(name);
|
|
@@ -12853,7 +12929,7 @@ async function saveSnippet(projectDir, name, body) {
|
|
|
12853
12929
|
const fileName = `${stem}.md`;
|
|
12854
12930
|
const dir = path21.join(projectDir, SNIPPETS_DIR);
|
|
12855
12931
|
await mkdir12(dir, { recursive: true });
|
|
12856
|
-
await
|
|
12932
|
+
await writeFile11(resolveSnippetPath(projectDir, fileName), body, "utf8");
|
|
12857
12933
|
return { name, fileName, variables: extractVariables(body), source: { kind: "project" } };
|
|
12858
12934
|
}
|
|
12859
12935
|
async function deleteSnippet(projectDir, fileName) {
|
|
@@ -12903,11 +12979,11 @@ async function readExtensionSnippet(projectDir, source, fileName) {
|
|
|
12903
12979
|
if (!dir) {
|
|
12904
12980
|
throw new Error(`Extension "${source.ref}" does not declare a usable snippets folder.`);
|
|
12905
12981
|
}
|
|
12906
|
-
return
|
|
12982
|
+
return readFile32(resolveSafeChildFile(dir, fileName), "utf8");
|
|
12907
12983
|
}
|
|
12908
12984
|
// src/lib/extension-import.ts
|
|
12909
12985
|
import { existsSync as existsSync15 } from "node:fs";
|
|
12910
|
-
import { cp as cp5, mkdir as mkdir13, mkdtemp as mkdtemp3, readFile as
|
|
12986
|
+
import { cp as cp5, mkdir as mkdir13, mkdtemp as mkdtemp3, readFile as readFile33, rm as rm6, writeFile as writeFile12 } from "node:fs/promises";
|
|
12911
12987
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
12912
12988
|
import path22 from "node:path";
|
|
12913
12989
|
import { unzipSync } from "fflate";
|
|
@@ -12980,7 +13056,7 @@ async function finalizeExtensionImport(projectDir, sourceDir, relPaths, fallback
|
|
|
12980
13056
|
if (!existsSync15(cssPath)) {
|
|
12981
13057
|
throw new Error("A theme must contain a theme.css file.");
|
|
12982
13058
|
}
|
|
12983
|
-
const css = await
|
|
13059
|
+
const css = await readFile33(cssPath, "utf8");
|
|
12984
13060
|
const { reject, warnings: printFindings } = classifyThemeCssFindings(checkCss(css, "theme.css"));
|
|
12985
13061
|
if (reject) {
|
|
12986
13062
|
throw new Error(`theme.css could not be parsed — ${reject.message}`);
|
|
@@ -13008,7 +13084,7 @@ async function finalizeExtensionImport(projectDir, sourceDir, relPaths, fallback
|
|
|
13008
13084
|
for (let i = 0;i < extraSheets.length; i++) {
|
|
13009
13085
|
const rel = extraSheets[i];
|
|
13010
13086
|
const sheetPath = extraSheetPaths[i];
|
|
13011
|
-
const sheetCss = await
|
|
13087
|
+
const sheetCss = await readFile33(sheetPath, "utf8");
|
|
13012
13088
|
const { reject: sheetReject, warnings: sheetFindings } = classifyThemeCssFindings(checkCss(sheetCss, rel));
|
|
13013
13089
|
if (sheetReject) {
|
|
13014
13090
|
throw new Error(`${rel} could not be parsed — ${sheetReject.message}`);
|
|
@@ -13041,14 +13117,14 @@ async function completeLandedManifest(dest, id, meta, metaExists) {
|
|
|
13041
13117
|
let pkg = {};
|
|
13042
13118
|
if (metaExists) {
|
|
13043
13119
|
try {
|
|
13044
|
-
const parsed = JSON.parse(await
|
|
13120
|
+
const parsed = JSON.parse(await readFile33(file, "utf8"));
|
|
13045
13121
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
13046
13122
|
pkg = parsed;
|
|
13047
13123
|
}
|
|
13048
13124
|
} catch {}
|
|
13049
13125
|
}
|
|
13050
13126
|
const gutterpress = pkg.gutterpress && typeof pkg.gutterpress === "object" && !Array.isArray(pkg.gutterpress) ? pkg.gutterpress : {};
|
|
13051
|
-
await
|
|
13127
|
+
await writeFile12(file, JSON.stringify({
|
|
13052
13128
|
...pkg,
|
|
13053
13129
|
name: typeof pkg.name === "string" && pkg.name.trim() ? pkg.name : id,
|
|
13054
13130
|
gutterpress: { ...gutterpress, styles: ["theme.css"] }
|
|
@@ -13113,7 +13189,7 @@ async function importExtensionFromZip(projectDir, archive) {
|
|
|
13113
13189
|
}
|
|
13114
13190
|
relPaths.push(rel);
|
|
13115
13191
|
await mkdir13(path22.dirname(dest), { recursive: true });
|
|
13116
|
-
await
|
|
13192
|
+
await writeFile12(dest, data);
|
|
13117
13193
|
}
|
|
13118
13194
|
return await finalizeExtensionImport(projectDir, tmp, relPaths, root || "imported-look");
|
|
13119
13195
|
} finally {
|
|
@@ -13128,8 +13204,8 @@ async function importExtensionFromCssText(projectDir, css, name) {
|
|
|
13128
13204
|
const displayName = name.trim() || "Imported theme";
|
|
13129
13205
|
const tmp = await mkdtemp3(path22.join(tmpdir3(), "gutterpress-theme-"));
|
|
13130
13206
|
try {
|
|
13131
|
-
await
|
|
13132
|
-
await
|
|
13207
|
+
await writeFile12(path22.join(tmp, "theme.css"), css, "utf8");
|
|
13208
|
+
await writeFile12(path22.join(tmp, EXTENSION_MANIFEST_FILENAME), JSON.stringify({ name: slugify(displayName, "look"), gutterpress: { styles: ["theme.css"] } }, null, 2), "utf8");
|
|
13133
13209
|
const result = await finalizeExtensionImport(projectDir, tmp, ["theme.css", EXTENSION_MANIFEST_FILENAME], displayName);
|
|
13134
13210
|
result.warnings.unshift({
|
|
13135
13211
|
code: "no-theme-json",
|
|
@@ -13143,11 +13219,11 @@ async function importExtensionFromCssText(projectDir, css, name) {
|
|
|
13143
13219
|
async function importExtensionFromFile(projectDir, filePath) {
|
|
13144
13220
|
const ext = path22.extname(filePath).toLowerCase();
|
|
13145
13221
|
if (ext === ".zip") {
|
|
13146
|
-
const buf = await
|
|
13222
|
+
const buf = await readFile33(filePath);
|
|
13147
13223
|
return importExtensionFromZip(projectDir, new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength));
|
|
13148
13224
|
}
|
|
13149
13225
|
if (ext === ".css") {
|
|
13150
|
-
const css = await
|
|
13226
|
+
const css = await readFile33(filePath, "utf8");
|
|
13151
13227
|
return importExtensionFromCssText(projectDir, css, prettify(path22.basename(filePath, ".css")));
|
|
13152
13228
|
}
|
|
13153
13229
|
throw new Error("Choose a .zip extension package or a .css stylesheet.");
|
|
@@ -13212,7 +13288,7 @@ async function importExtensionFromUrl(projectDir, url) {
|
|
|
13212
13288
|
assertLooksLikeCss(css, trimmed);
|
|
13213
13289
|
const tmp = await mkdtemp3(path22.join(tmpdir3(), "gutterpress-ext-"));
|
|
13214
13290
|
try {
|
|
13215
|
-
await
|
|
13291
|
+
await writeFile12(path22.join(tmp, "theme.css"), css, "utf8");
|
|
13216
13292
|
const gp = meta.gutterpress && typeof meta.gutterpress === "object" && !Array.isArray(meta.gutterpress) ? meta.gutterpress : {};
|
|
13217
13293
|
const finalMeta = {
|
|
13218
13294
|
name: typeof meta.name === "string" && meta.name || slugify(baseName, "look"),
|
|
@@ -13224,7 +13300,7 @@ async function importExtensionFromUrl(projectDir, url) {
|
|
|
13224
13300
|
preview: typeof gp.preview === "string" ? gp.preview : null
|
|
13225
13301
|
}
|
|
13226
13302
|
};
|
|
13227
|
-
await
|
|
13303
|
+
await writeFile12(path22.join(tmp, EXTENSION_MANIFEST_FILENAME), JSON.stringify(finalMeta, null, 2), "utf8");
|
|
13228
13304
|
return await finalizeExtensionImport(projectDir, tmp, ["theme.css", EXTENSION_MANIFEST_FILENAME], baseName);
|
|
13229
13305
|
} finally {
|
|
13230
13306
|
await rm6(tmp, { recursive: true, force: true });
|
|
@@ -14680,7 +14756,7 @@ async function diagnoseProjectRemote(projectDir, options = {}) {
|
|
|
14680
14756
|
import git6 from "isomorphic-git";
|
|
14681
14757
|
|
|
14682
14758
|
// src/lib/remote-auth/converge-merge.ts
|
|
14683
|
-
import { mkdir as mkdir15, unlink as unlink3, writeFile as
|
|
14759
|
+
import { mkdir as mkdir15, unlink as unlink3, writeFile as writeFile13 } from "node:fs/promises";
|
|
14684
14760
|
import path24 from "node:path";
|
|
14685
14761
|
import git5 from "isomorphic-git";
|
|
14686
14762
|
import diff3Merge from "diff3";
|
|
@@ -14730,7 +14806,7 @@ async function readBlobOrNull(dir, cache2, oid, filepath) {
|
|
|
14730
14806
|
async function writeTreeFile(dir, filepath, content) {
|
|
14731
14807
|
const abs = path24.join(dir, filepath);
|
|
14732
14808
|
await mkdir15(path24.dirname(abs), { recursive: true });
|
|
14733
|
-
await
|
|
14809
|
+
await writeFile13(abs, content);
|
|
14734
14810
|
}
|
|
14735
14811
|
async function bothAddedPaths(dir, cache2, ourTip, theirTip, allowUnrelated) {
|
|
14736
14812
|
const bases = await git5.findMergeBase({ fs: gitFs, dir, cache: cache2, oids: [ourTip, theirTip] });
|
|
@@ -15248,7 +15324,7 @@ ${tail}` : ""}`);
|
|
|
15248
15324
|
};
|
|
15249
15325
|
|
|
15250
15326
|
// src/lib/publish/providers/guided.ts
|
|
15251
|
-
import { copyFile as copyFile2, mkdir as mkdir16, writeFile as
|
|
15327
|
+
import { copyFile as copyFile2, mkdir as mkdir16, writeFile as writeFile14 } from "node:fs/promises";
|
|
15252
15328
|
import path25 from "node:path";
|
|
15253
15329
|
async function stageGuidedPackage(req, providerId, listingLines) {
|
|
15254
15330
|
const packageDir = path25.join(path25.dirname(req.artifact.path), "publish", providerId);
|
|
@@ -15266,7 +15342,7 @@ async function stageGuidedPackage(req, providerId, listingLines) {
|
|
|
15266
15342
|
""
|
|
15267
15343
|
].join(`
|
|
15268
15344
|
`);
|
|
15269
|
-
await
|
|
15345
|
+
await writeFile14(path25.join(packageDir, "LISTING.md"), sheet, "utf8");
|
|
15270
15346
|
return packageDir;
|
|
15271
15347
|
}
|
|
15272
15348
|
|
|
@@ -15329,7 +15405,7 @@ var drivethrurpgProvider = {
|
|
|
15329
15405
|
};
|
|
15330
15406
|
|
|
15331
15407
|
// src/lib/publish/providers/gdrive.ts
|
|
15332
|
-
import { mkdtemp as mkdtemp4, readFile as
|
|
15408
|
+
import { mkdtemp as mkdtemp4, readFile as readFile34, readdir as readdir10, rm as rm8, stat as stat9, writeFile as writeFile15 } from "node:fs/promises";
|
|
15333
15409
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
15334
15410
|
import path26 from "node:path";
|
|
15335
15411
|
import { Zip, ZipDeflate } from "fflate";
|
|
@@ -15721,12 +15797,12 @@ async function collectZipEntries(root, dir, out, onWarn) {
|
|
|
15721
15797
|
await collectZipEntries(root, full, out, onWarn);
|
|
15722
15798
|
} else if (entry.isFile()) {
|
|
15723
15799
|
const rel = path26.relative(root, full).split(path26.sep).join("/");
|
|
15724
|
-
out[rel] = await
|
|
15800
|
+
out[rel] = await readFile34(full);
|
|
15725
15801
|
} else if (entry.isSymbolicLink()) {
|
|
15726
15802
|
const resolved = await stat9(full).catch(() => null);
|
|
15727
15803
|
if (resolved?.isFile()) {
|
|
15728
15804
|
const rel = path26.relative(root, full).split(path26.sep).join("/");
|
|
15729
|
-
out[rel] = await
|
|
15805
|
+
out[rel] = await readFile34(full);
|
|
15730
15806
|
} else if (resolved?.isDirectory()) {
|
|
15731
15807
|
await collectZipEntries(root, full, out, onWarn);
|
|
15732
15808
|
} else {
|
|
@@ -15737,7 +15813,7 @@ async function collectZipEntries(root, dir, out, onWarn) {
|
|
|
15737
15813
|
}
|
|
15738
15814
|
}
|
|
15739
15815
|
}
|
|
15740
|
-
async function zipHtmlExport(exportDir, title, onWarn, writeArchiveImpl =
|
|
15816
|
+
async function zipHtmlExport(exportDir, title, onWarn, writeArchiveImpl = writeFile15) {
|
|
15741
15817
|
const entries = {};
|
|
15742
15818
|
await collectZipEntries(exportDir, exportDir, entries, onWarn);
|
|
15743
15819
|
const fileName = `${bookSlug(title)}-website.zip`;
|
|
@@ -15841,7 +15917,7 @@ var gdriveProvider = {
|
|
|
15841
15917
|
};
|
|
15842
15918
|
|
|
15843
15919
|
// src/lib/publish/butler.ts
|
|
15844
|
-
import { chmod as chmod2, mkdir as mkdir17, stat as stat10, writeFile as
|
|
15920
|
+
import { chmod as chmod2, mkdir as mkdir17, stat as stat10, writeFile as writeFile16 } from "node:fs/promises";
|
|
15845
15921
|
import path27 from "node:path";
|
|
15846
15922
|
import { unzipSync as unzipSync2 } from "fflate";
|
|
15847
15923
|
var BUTLER_DOWNLOAD_TIMEOUT_MS = 300000;
|
|
@@ -15908,7 +15984,7 @@ async function ensureButler(deps) {
|
|
|
15908
15984
|
if (name.endsWith("/"))
|
|
15909
15985
|
continue;
|
|
15910
15986
|
const target = path27.join(cacheDir, path27.basename(name));
|
|
15911
|
-
await
|
|
15987
|
+
await writeFile16(target, data);
|
|
15912
15988
|
if (path27.basename(name) === butlerBinaryName()) {
|
|
15913
15989
|
await chmod2(target, 493).catch(() => {});
|
|
15914
15990
|
foundBinary = true;
|
|
@@ -16543,7 +16619,7 @@ async function disconnectPublishCredential(key, deps, options = {}) {
|
|
|
16543
16619
|
}
|
|
16544
16620
|
}
|
|
16545
16621
|
// src/lib/publish/selections.ts
|
|
16546
|
-
import { chmod as chmod3, mkdir as mkdir18, readFile as
|
|
16622
|
+
import { chmod as chmod3, mkdir as mkdir18, readFile as readFile35, writeFile as writeFile17 } from "node:fs/promises";
|
|
16547
16623
|
import path29 from "node:path";
|
|
16548
16624
|
class PublishSelectionsStore {
|
|
16549
16625
|
filePath;
|
|
@@ -16553,7 +16629,7 @@ class PublishSelectionsStore {
|
|
|
16553
16629
|
}
|
|
16554
16630
|
async read() {
|
|
16555
16631
|
try {
|
|
16556
|
-
const raw = await
|
|
16632
|
+
const raw = await readFile35(this.filePath, "utf8");
|
|
16557
16633
|
const parsed = JSON.parse(raw);
|
|
16558
16634
|
if (parsed && typeof parsed === "object") {
|
|
16559
16635
|
return {
|
|
@@ -16567,7 +16643,7 @@ class PublishSelectionsStore {
|
|
|
16567
16643
|
}
|
|
16568
16644
|
async write(data) {
|
|
16569
16645
|
await mkdir18(path29.dirname(this.filePath), { recursive: true });
|
|
16570
|
-
await
|
|
16646
|
+
await writeFile17(this.filePath, JSON.stringify(data, null, 2), {
|
|
16571
16647
|
encoding: "utf8",
|
|
16572
16648
|
mode: 384
|
|
16573
16649
|
});
|
|
@@ -16669,4 +16745,4 @@ async function setPublishProviderConfig(projectDir, providerId, values) {
|
|
|
16669
16745
|
await writeManifestDoc(file, doc);
|
|
16670
16746
|
return settingsFromDoc(doc);
|
|
16671
16747
|
}
|
|
16672
|
-
export { DEFAULT_NPM_REGISTRY, npmRegistryUrl, PLUGINS_DIR, BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, SYNC_SNAPSHOT_MESSAGE, log, resolveActiveStyles, listProjectStyles, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, loadPluginsWithCss,
|
|
16748
|
+
export { DEFAULT_NPM_REGISTRY, npmRegistryUrl, PLUGINS_DIR, BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, SYNC_SNAPSHOT_MESSAGE, log, resolveActiveStyles, listProjectStyles, EXTENSION_MANIFEST_FILENAME, readExtensionMeta, extensionStyleList, extensionEntry, extensionCarries, pathEscapesFolder, assertExtensionContained, resolveExtension, loadPluginsWithCss, getChecks, getCheckById, resolveCheckSelectors, formatReport, ruleRemoteUrls, ruleRiskyProps, ruleSyntax, rulePageContainment, checkCss, inspectImage, runChecks, checkToolAvailability, reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, defaultConfigDir, FileTokenStore, extractUrlCredential, getSystemDiagnostics, EXTENSIONS_DIR, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, sameExtension, listProjectExtensions, describeExtension, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listBuiltInStyleSets, addBuiltInStyleSet, validateProjectExtensions, readExtensionCss, slugifyProjectName, escapeYamlScalar, scaffoldProject, adoptFolder, EXTENSION_KINDS, RESERVED_PREFIX, resolveExtensionPrefix, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, listBuiltInTemplates, saveProjectAsTemplate, listCustomTemplates, importTemplateFromFolder, SNIPPETS_DIR, extractVariables, substituteVariables, listSnippets, readSnippet, saveSnippet, deleteSnippet, listMergedSnippets, readExtensionSnippet, importExtensionFromFile, importExtensionFromUrl, MAX_SEARCH_BYTES, SEARCH_KEYWORDS, searchNpmExtensions, setManifestFields, readManifestFields, setActiveStyles, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, AUTO_SYNC_PUSH_INTERVAL_MINUTES, autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, resolveGitHubClientId, GITHUB_HOST, GitHubAuthProvider, GDRIVE_HOST, resolveGoogleClientId, resolveGoogleClientSecret, GOOGLE_NOT_CONFIGURED_MESSAGE, requireGoogleClientCredentials, pkceChallengeFromVerifier, GoogleAuthProvider, revokeGoogleCredential, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listGitHubRepositories, listRepoBooks, listGitHubBranches, sanitizeCloneFolderName, cloneRepository, isSshRemoteUrl, testRemoteAccess, knownForgeTokenUrl, connectGenericHost, parseRemoteOrigin, forgeKindForHost, diagnoseProjectRemote, syncProject, refreshRemoteCopies, listPublishProviders, publishProviderFor, resolvePublishFormat, resolvePublishRequest, runPublish, connectPublishProvider, disconnectPublishCredential, PublishSelectionsStore, readPublishSettings, setPublishProviderConfig };
|