UNPKG

@vivliostyle/cli

Version:

Save the pdf file via headless browser and Vivliostyle.

1,484 lines (1,459 loc) 37.9 kB
import { VivliostyleInlineConfig } from "./chunk-7GIJVX4M.js"; import { DEFAULT_BROWSER_VERSIONS, EMPTY_DATA_URI, languages } from "./chunk-OAFXM4ES.js"; // src/commands/cli-flags.ts import "commander"; import * as v from "valibot"; function createParserProgram({ setupProgram, parseArgs }) { return (argv) => { const program = setupProgram(); program.parse(argv); let options = program.opts(); options = parseArgs?.(options, program.args ?? []) || options; options = warnDeprecatedFlags(options); return v.parse(VivliostyleInlineConfig, options); }; } function setupConfigFromFlags(flags) { if (!flags.input) { if (flags.enableViewerStartPage) { return { tasks: [{ entry: [] }], inlineOptions: { input: { format: "webbook", entry: EMPTY_DATA_URI } } }; } else { throw new Error( "No input is set. Please set an appropriate entry or a Vivliostyle config file." ); } } return { tasks: [{ entry: [] }], inlineOptions: { ...flags } }; } function warnDeprecatedFlags(options) { const modifiedOptions = { ...options }; return modifiedOptions; } // src/util.ts import { codeFrameColumns } from "@babel/code-frame"; import { evaluate, parse as parse2 } from "@humanwhocodes/momoa"; import { Ajv } from "ajv"; import formatsPlugin from "ajv-formats"; import { XMLParser } from "fast-xml-parser"; import lcid from "lcid"; import StreamZip from "node-stream-zip"; import childProcess from "node:child_process"; import fs from "node:fs"; import os from "node:os"; import readline from "node:readline"; import util from "node:util"; import { osLocale } from "os-locale"; import { titleCase } from "title-case"; import tmp from "tmp"; import upath from "upath"; import { gray, red, redBright as redBright2 } from "yoctocolors"; // src/logger.ts import debug from "debug"; import { Console } from "node:console"; import yoctoSpinner from "yocto-spinner"; import { blueBright, greenBright, redBright, yellowBright } from "yoctocolors"; var isUnicodeSupported = process.platform !== "win32" || Boolean(process.env.WT_SESSION); var randomBookSymbol = ["\u{1F4D5}", "\u{1F4D7}", "\u{1F4D8}", "\u{1F4D9}"][Math.floor(Math.random() * 4)]; var spinnerFrames = isUnicodeSupported ? ["\u2581\u2581\u2571 ", "\u2581\u2551\u2581 ", "\u2572\u2581\u2581 ", "\u2581\u2581\u2581 ", "\u2581\u2581\u2581 ", "\u2581\u2581\u2581 "] : ["- ", "\\ ", "| ", "/ "]; var spinnerInterval = 80; var infoSymbol = blueBright("INFO"); var successSymbol = greenBright("SUCCESS"); var warnSymbol = yellowBright("WARN"); var errorSymbol = redBright("ERROR"); var Logger = class _Logger { /** * 0: silent 1: info 2: verbose 3: debug */ static #logLevel = 0; static #loggerInstance; static #nonBlockingLogPrinted = false; static #customLogger; static #logPrefix; static #stdin = process.stdin; static #stdout = process.stdout; static #stderr = process.stderr; static #signal; static debug = debug("vs-cli"); static get #console() { if (this.#customLogger) { return { ...this.#customLogger, log: () => { } }; } return new Console({ stdout: this.#stdout, stderr: this.#stderr }); } static get #spinner() { return this.#loggerInstance && this.#loggerInstance.#_spinner; } static get stdin() { return this.#stdin; } static get stdout() { return this.#stdout; } static get stderr() { return this.#stderr; } static get signal() { return this.#signal; } static get isInteractive() { return Boolean( !this.#customLogger && this.#stderr.isTTY && process.env.TERM !== "dumb" && !("CI" in process.env) && !import.meta.env?.VITEST && !debug.enabled("vs-cli") && // Prevent stream output in docker container so that not to spawn process !isInContainer() ); } static startLogging(text) { if (this.#logLevel === 0) { return; } if (!this.isInteractive) { this.logInfo(text); return; } if (this.#loggerInstance) { this.#loggerInstance.#_spinner.text = text; return this.#loggerInstance; } this.#loggerInstance = new _Logger(this.#stderr); this.#loggerInstance.#start(text); return this.#loggerInstance; } static suspendLogging(text) { if (this.#logLevel === 0) { return; } if (!this.#spinner || !this.isInteractive) { this.logInfo(text); return; } const currentMsg = this.#spinner?.text; this.logUpdate(currentMsg); this.#spinner.stop(`${infoSymbol} ${text} `); return { [Symbol.dispose]() { if (_Logger.isInteractive) { _Logger.#console.log(""); _Logger.#spinner?.start(currentMsg); _Logger.#nonBlockingLogPrinted = true; } } }; } static log(...messages) { if (this.#logLevel < 1) { return; } _Logger.#console.log(...messages); } static logUpdate(...messages) { if (!this.#spinner || !this.isInteractive) { this.logInfo(...messages); return; } this.#spinner.stop( this.#nonBlockingLogPrinted ? void 0 : `${infoSymbol} ${this.#spinner.text}` ); this.#spinner.start(messages.join(" ")); this.#nonBlockingLogPrinted = false; } static getMessage(message, symbol) { return !this.#customLogger && symbol ? `${symbol} ${message}` : message; } static #nonBlockingLog(logMethod, message) { if (!this.#spinner || !this.isInteractive) { if (this.#logPrefix) { message = `${this.#logPrefix} ${message}`; } this.#logLevel >= 3 ? this.debug(message) : this.#console[logMethod](message); return; } this.logUpdate(this.#spinner.text); this.#nonBlockingLogPrinted = true; this.#spinner.stop(message); this.#spinner.start(); } static logSuccess(...messages) { if (this.#logLevel < 1) { return; } this.#nonBlockingLog( "info", this.getMessage(messages.join(" "), successSymbol) ); } static logError(...messages) { if (this.#logLevel < 1) { return; } this.#nonBlockingLog( "error", this.getMessage(messages.join(" "), errorSymbol) ); } static logWarn(...messages) { if (this.#logLevel < 1) { return; } this.#nonBlockingLog( "warn", this.getMessage(messages.join(" "), warnSymbol) ); } static logInfo(...messages) { if (this.#logLevel < 1) { return; } this.#nonBlockingLog( "info", this.getMessage(messages.join(" "), infoSymbol) ); } static logVerbose(...messages) { if (this.#logLevel < 2) { return; } this.#nonBlockingLog("info", this.getMessage(messages.join(" "))); } static setLogOptions({ logLevel, logger, stdin, stdout, stderr, signal }) { if (logLevel) { this.#logLevel = { silent: 0, info: 1, verbose: 2, debug: 3 }[logLevel]; if (this.#logLevel >= 3) { debug.enable("vs-cli"); } } if (logger) { this.#customLogger = logger; } if (stdin) { this.#stdin = stdin; } if (stdout) { this.#stdout = stdout; } if (stderr) { this.#stderr = stderr; } if (signal) { this.#signal = signal; } } static setLogPrefix(prefix) { this.#logPrefix = prefix; } #_spinner; #_disposeSpinnerExitHandler; constructor(stream) { this.#_spinner = yoctoSpinner({ spinner: { frames: spinnerFrames, interval: spinnerInterval }, color: "gray", stream }); return this; } #start(text) { this.#_spinner.start(text); this.#_disposeSpinnerExitHandler = registerExitHandler( "Stopping spinner", () => { this.#_spinner.stop(); } ); } [Symbol.dispose]() { this.#_disposeSpinnerExitHandler?.(); this.#_spinner.stop( _Logger.#nonBlockingLogPrinted ? void 0 : `${infoSymbol} ${this.#_spinner.text}` ); _Logger.#loggerInstance = void 0; } }; // schemas/pub-manifest/module/bcp.schema.json var bcp_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/bcp.schema.json", title: "BCP47 Language tag", type: "string", pattern: "^((?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?:([A-Za-z]{2,3}(-(?:[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?:[A-Za-z]{4}))?(-(?:[A-Za-z]{2}|[0-9]{3}))?(-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?:[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?:x(-[A-Za-z0-9]{1,8})+))?)|(?:x(-[A-Za-z0-9]{1,8})+))$" }; // schemas/pub-manifest/module/context.schema.json var context_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/context.schema.json", title: "Publication Contexts", type: "array", items: [ { const: "https://schema.org" }, { const: "https://www.w3.org/ns/pub-context" } ], additionalItems: { anyOf: [ { type: "string" }, { type: "object", properties: { language: { $ref: "bcp.schema.json" }, direction: false }, required: ["language"] }, { type: "object", properties: { direction: { type: "string", enum: ["ltr", "rtl"] }, language: false }, required: ["direction"] }, { type: "object", properties: { language: { $ref: "bcp.schema.json" }, direction: { type: "string", enum: ["ltr", "rtl"] } }, required: ["language", "direction"] }, { type: "object", properties: { language: false, direction: false } } ] } }; // schemas/pub-manifest/module/contributor-object.schema.json var contributor_object_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/contributor-object.schema.json", title: "Contributor Object", type: "object", properties: { name: { $ref: "localizable.schema.json" }, id: { $ref: "url.schema.json" }, type: { oneOf: [ { type: "string", enum: ["Person", "Organization"], default: "Person" }, { type: "array", items: { type: "string" }, contains: { enum: ["Person", "Organization"] } } ] }, url: { $ref: "url.schema.json" }, identifier: { type: "array", items: { type: "string" } } }, required: ["name"] }; // schemas/pub-manifest/module/contributor.schema.json var contributor_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/contributor.schema.json", title: "Contributor", anyOf: [ { type: "string" }, { type: "array", items: { anyOf: [ { type: "string" }, { $ref: "contributor-object.schema.json" } ] } }, { $ref: "contributor-object.schema.json" } ] }; // schemas/pub-manifest/module/date.schema.json var date_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/date.schema.json", title: "Dates", type: "string", format: "date-time" }; // schemas/pub-manifest/module/duration.schema.json var duration_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/duration.schema.json", title: "Duration", type: "string", pattern: "^P(?!$)((\\d+Y)|(\\d+\\.\\d+Y$))?((\\d+M)|(\\d+\\.\\d+M$))?((\\d+W)|(\\d+\\.\\d+W$))?((\\d+D)|(\\d+\\.\\d+D$))?(T(?=\\d)((\\d+H)|(\\d+\\.\\d+H$))?((\\d+M)|(\\d+\\.\\d+M$))?(\\d+(\\.\\d+)?S)?)??$" }; // schemas/pub-manifest/module/item-lists.schema.json var item_lists_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/item-lists.schema.json", title: "Lists of ItemList", oneOf: [ { $ref: "ItemList.schema.json" }, { type: "array", items: { $ref: "ItemList.schema.json" } } ] }; // schemas/pub-manifest/module/ItemList.schema.json var ItemList_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/ItemList.schema.json", title: "schema.org ItemList object", type: "object", properties: { type: { oneOf: [ { type: "string", const: "ItemList" }, { type: "array", items: { type: "string" }, contains: { const: "ItemList" } } ] }, itemListElement: { type: ["array"], items: { type: "string" } } }, required: ["type", "itemListElement"] }; // schemas/pub-manifest/module/language.schema.json var language_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/language.schema.json", title: "Languages", oneOf: [ { $ref: "bcp.schema.json" }, { type: "array", items: { $ref: "bcp.schema.json" } } ] }; // schemas/pub-manifest/module/link.schema.json var link_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/link.schema.json", title: "Publication Links", type: "object", properties: { type: { oneOf: [ { type: "string", const: "LinkedResource" }, { type: "array", items: { type: "string" }, contains: { const: "LinkedResource" } } ] }, url: { $ref: "url.schema.json" }, encodingFormat: { type: "string" }, name: { $ref: "localizable.schema.json" }, description: { anyOf: [ { type: "string" }, { $ref: "localizable-object.schema.json" } ] }, rel: { type: ["string", "array"], items: { type: "string" } }, integrity: { type: "string" }, duration: { $ref: "duration.schema.json" }, alternate: { $ref: "resource.categorization.schema.json" } }, required: ["url"] }; // schemas/pub-manifest/module/localizable-object.schema.json var localizable_object_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/localizable-object.schema.json", title: "Localizable String Object", type: "object", properties: { value: { type: "string" }, language: { $ref: "bcp.schema.json" } }, required: ["value"] }; // schemas/pub-manifest/module/localizable.schema.json var localizable_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/localizable.schema.json", title: "Localizable String or Object", anyOf: [ { type: "string" }, { type: "array", items: { anyOf: [ { type: "string" }, { $ref: "localizable-object.schema.json" } ] } }, { $ref: "localizable-object.schema.json" } ] }; // schemas/pub-manifest/module/resource.categorization.schema.json var resource_categorization_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/resource.categorization.schema.json", title: "Resource Categorization", oneOf: [ { oneOf: [ { $ref: "url.schema.json" }, { $ref: "link.schema.json" } ] }, { type: "array", items: { anyOf: [ { $ref: "url.schema.json" }, { $ref: "link.schema.json" } ] }, uniqueItems: true } ] }; // schemas/pub-manifest/module/strings.schema.json var strings_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/strings.schema.json", title: "Unique strings", type: ["string", "array"], items: { type: "string" } }; // schemas/pub-manifest/module/url.schema.json var url_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/url.schema.json", title: "URL", type: "string", format: "uri-reference" }; // schemas/pub-manifest/module/urls.schema.json var urls_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/module/urls.schema.json", title: "URLs", oneOf: [ { type: "string", format: "uri-reference" }, { type: "array", items: { type: "string", format: "uri-reference" } } ] }; // schemas/pub-manifest/publication.schema.json var publication_schema_default = { $schema: "http://json-schema.org/draft-07/schema#", $id: "https://www.w3.org/ns/pub-schema/manifest/publication.schema.json", title: "Publication Manifest", type: "object", properties: { "@context": { $ref: "module/context.schema.json" }, type: { type: ["string", "array"], items: { type: "string" } }, conformsTo: { oneOf: [ { $ref: "module/url.schema.json" }, { type: "array", items: { $ref: "module/url.schema.json" } } ] }, id: { type: "string" }, abridged: { type: "boolean" }, accessMode: { $ref: "module/strings.schema.json" }, accessModeSufficient: { $ref: "module/item-lists.schema.json" }, accessibilityFeature: { $ref: "module/strings.schema.json" }, accessibilityHazard: { $ref: "module/strings.schema.json" }, accessibilitySummary: { $ref: "module/localizable.schema.json" }, artist: { $ref: "module/contributor.schema.json" }, author: { $ref: "module/contributor.schema.json" }, colorist: { $ref: "module/contributor.schema.json" }, contributor: { $ref: "module/contributor.schema.json" }, creator: { $ref: "module/contributor.schema.json" }, editor: { $ref: "module/contributor.schema.json" }, illustrator: { $ref: "module/contributor.schema.json" }, inker: { $ref: "module/contributor.schema.json" }, letterer: { $ref: "module/contributor.schema.json" }, penciler: { $ref: "module/contributor.schema.json" }, publisher: { $ref: "module/contributor.schema.json" }, readBy: { $ref: "module/contributor.schema.json" }, translator: { $ref: "module/contributor.schema.json" }, url: { $ref: "module/urls.schema.json" }, duration: { $ref: "module/duration.schema.json" }, inLanguage: { $ref: "module/language.schema.json" }, dateModified: { $ref: "module/date.schema.json" }, datePublished: { $ref: "module/date.schema.json" }, name: { $ref: "module/localizable.schema.json" }, readingOrder: { $ref: "module/resource.categorization.schema.json" }, resources: { $ref: "module/resource.categorization.schema.json" }, links: { $ref: "module/resource.categorization.schema.json" }, readingProgression: { type: "string", enum: ["ltr", "rtl"], default: "ltr" } }, required: ["@context", "conformsTo"] }; // src/schema/pub-manifest.ts var publicationSchemas = [ bcp_schema_default, context_schema_default, contributor_object_schema_default, contributor_schema_default, date_schema_default, duration_schema_default, item_lists_schema_default, ItemList_schema_default, language_schema_default, link_schema_default, localizable_object_schema_default, localizable_schema_default, resource_categorization_schema_default, strings_schema_default, url_schema_default, urls_schema_default, publication_schema_default ]; // src/util.ts var cwd = upath.normalize(process.cwd()); var execFile = util.promisify(childProcess.execFile); async function exec(command, args = [], options = {}) { const subprocess = await execFile(command, args, { ...options, encoding: "utf8" }); subprocess.stdout = subprocess.stdout.trim(); return subprocess; } var beforeExitHandlers = []; var exitHandlersRun = false; var registerExitHandler = (debugMessage, handler) => { const callback = () => { Logger.debug(debugMessage); return handler(); }; beforeExitHandlers.push(callback); return () => { const index = beforeExitHandlers.indexOf(callback); if (index !== -1) { return beforeExitHandlers.splice(index, 1)[0]; } }; }; async function runExitHandlers() { if (exitHandlersRun) return; exitHandlersRun = true; while (beforeExitHandlers.length) { try { await beforeExitHandlers.shift()?.(); } catch (e) { } } } var exitSignals = process.platform === "win32" ? ["exit"] : ["exit", "SIGINT", "SIGTERM"]; exitSignals.forEach((sig) => { process.once(sig, async (signal, exitCode) => { if (sig !== "exit") { await runExitHandlers(); } else { void runExitHandlers(); } if (process.exitCode === void 0) { process.exitCode = exitCode !== void 0 ? 128 + exitCode : Number(signal); } if (sig !== "exit") { process.exit(); } }); }); if (process.platform === "win32") { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.on("SIGINT", async () => { await runExitHandlers(); process.exit(130); }); registerExitHandler("Closing readline interface", () => { rl.close(); }); } var DetailError = class extends Error { detail; constructor(message, detail) { super(message); this.detail = detail; } }; function getFormattedError(err) { return err instanceof DetailError ? `${err.message} ${err.detail}` : err.stack || `${err.message}`; } function gracefulError(err) { console.log(`${redBright2("ERROR")} ${getFormattedError(err)} ${gray("If you think this is a bug, please report at https://github.com/vivliostyle/vivliostyle-cli/issues")}`); process.exit(1); } function readJSON(path) { try { return JSON.parse(fs.readFileSync(path, "utf8")); } catch (err) { return void 0; } } function statFileSync(filePath, { errorMessage = "Specified input does not exist" } = {}) { try { return fs.statSync(filePath); } catch (err) { if (err.code === "ENOENT") { throw new Error(`${errorMessage}: ${filePath}`); } throw err; } } async function inflateZip(filePath, dest) { return await new Promise((res, rej) => { try { const zip = new StreamZip({ file: filePath, storeEntries: true }); zip.on("error", (err) => { rej(err); }); zip.on("ready", async () => { await util.promisify(zip.extract)(null, dest); await util.promisify(zip.close)(); Logger.debug(`Unzipped ${filePath} to ${dest}`); res(); }); } catch (err) { rej(err); } }); } function useTmpDirectory() { return new Promise((res, rej) => { tmp.dir({ unsafeCleanup: true }, (err, path, clear) => { if (err) { return rej(err); } Logger.debug(`Created the temporary directory: ${path}`); if (import.meta.env?.VITEST) { return res([path, () => { }]); } const callback = () => { fs.rmSync(path, { force: true, recursive: true }); }; registerExitHandler( `Removing the temporary directory: ${path}`, callback ); res([path, callback]); }); }); } function touchTmpFile(path) { fs.mkdirSync(upath.dirname(path), { recursive: true }); fs.closeSync(fs.openSync(path, "a")); Logger.debug(`Created the temporary file: ${path}`); const callback = () => { fs.rmSync(path, { force: true, recursive: true }); }; registerExitHandler(`Removing the temporary file: ${path}`, callback); return callback; } function pathEquals(path1, path2) { return upath.relative(path1, path2) === ""; } function pathContains(parentPath, childPath) { const rel = upath.relative(parentPath, childPath); return rel !== "" && !rel.startsWith(".."); } function isValidUri(str) { return /^(https?|file|data):/i.test(str); } function cachedFn(fn) { let cache = null; return () => cache ?? (cache = fn()); } var isInContainer = cachedFn(function isInContainer2() { return fs.existsSync("/opt/vivliostyle-cli/.vs-cli-version"); }); var isRunningOnWSL = cachedFn(function isRunningOnWSL2() { return fs.existsSync("/proc/version") && fs.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft"); }); async function openEpub(epubPath, tmpDir) { await inflateZip(epubPath, tmpDir); Logger.debug(`Created the temporary EPUB directory: ${tmpDir}`); const deleteEpub = () => { fs.rmSync(tmpDir, { force: true, recursive: true }); }; registerExitHandler( `Removing the temporary EPUB directory: ${tmpDir}`, deleteEpub ); return deleteEpub; } function getDefaultEpubOpfPath(epubDir) { const containerXmlPath = upath.join(epubDir, "META-INF/container.xml"); const xmlParser = new XMLParser({ ignoreAttributes: false }); const { container } = xmlParser.parse( fs.readFileSync(containerXmlPath, "utf8") ); const rootfile = [container.rootfiles.rootfile].flat()[0]; const epubOpfPath = upath.join(epubDir, rootfile["@_full-path"]); return epubOpfPath; } function getEpubRootDir(epubOpfPath) { function traverse(dir) { const files = fs.readdirSync(dir); if (files.includes("META-INF") && pathEquals(epubOpfPath, getDefaultEpubOpfPath(dir))) { return dir; } const next = upath.dirname(dir); if (pathEquals(dir, next)) { return; } return traverse(next); } return traverse(upath.dirname(epubOpfPath)); } var getAjvValidatorFunction = (schema, refSchemas) => (obj) => { const ajv = new Ajv({ strict: false }); const addFormats = formatsPlugin; addFormats(ajv); if (refSchemas) { ajv.addSchema(refSchemas); } const validate = ajv.compile(schema); const valid = validate(obj); if (!valid) { throw validate.errors?.[0] || new Error(); } return true; }; var assertPubManifestSchema = getAjvValidatorFunction( publication_schema_default, publicationSchemas ); function parseJsonc(rawJsonc) { const ast = parse2(rawJsonc, { mode: "jsonc", ranges: false, tokens: false }); return evaluate(ast); } function prettifySchemaError(rawJsonc, issues) { const parsed = parse2(rawJsonc, { mode: "jsonc", ranges: false, tokens: false }); function traverse(issues2, depth) { return issues2.flatMap((issue) => { const p = issue.path?.length || 0; if (!issue.issues) { return [[[issue], depth + p]]; } return traverse(issue.issues, depth + p).map(([i, d]) => [ [issue, ...i], d ]); }); } const all = traverse(issues, 0); const maxDepth = Math.max(...all.map(([, d]) => d)); const issuesTraversed = all.find(([, d]) => d === maxDepth)[0]; let jsonValue = parsed.body; for (const p of issuesTraversed.flatMap((v2) => v2.path ?? [])) { let childValue; if (p.type === "object" && jsonValue.type === "Object") { childValue = jsonValue.members.find( (m) => m.name.type === "Identifier" && m.name.name === p.key || m.name.type === "String" && m.name.value === p.key )?.value; } if (p.type === "array" && jsonValue.type === "Array") { childValue = jsonValue.elements[p.key]?.value; } if (childValue) { jsonValue = childValue; } else { break; } } let message = `${red(issuesTraversed.at(-1).message)}`; if (jsonValue) { message += ` ${codeFrameColumns(rawJsonc, jsonValue.loc, { highlightCode: true })}`; } return message; } function writeFileIfChanged(filePath, content) { if (!fs.existsSync(filePath) || !fs.readFileSync(filePath).equals(content)) { fs.mkdirSync(upath.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, content); } } var cachedLocale; async function getOsLocale() { if (import.meta.env?.VITEST) { return process.env.TEST_LOCALE || "en"; } if (cachedLocale) { return cachedLocale; } let locale; if (process.platform === "win32") { const { stdout } = await exec("wmic", ["os", "get", "locale"]); const lcidCode = Number.parseInt(stdout.replace("Locale", ""), 16); locale = lcid.from(lcidCode); } if (process.platform === "darwin") { const results = await Promise.all([ exec("defaults", ["read", "-globalDomain", "AppleLocale"]).then( ({ stdout }) => stdout ), exec("locale", ["-a"]).then(({ stdout }) => stdout) ]); if (results[1].includes(results[0])) { locale = results[0]; } } if (locale) { locale = locale.replace(/_/, "-"); } else { locale = await osLocale(); } const langs = Object.keys(languages); locale = langs.includes(locale) ? locale : langs.includes(locale.split("-")[0]) ? locale.split("-")[0] : "en"; return cachedLocale = locale.replace(/_/, "-"); } function toTitleCase(input) { if (typeof input !== "string") { return input; } return titleCase( input.replace(/[\W_]/g, " ").replace(/\s+/g, " ").trim() ); } function debounce(func, wait, options = {}) { const leading = options.leading ?? false; const trailing = options.trailing ?? !leading; let timer = null; let pending = false; const invoke = (...args) => { pending = false; func(...args); }; return (...args) => { pending = true; if (timer) { clearTimeout(timer); } const callNow = leading && !timer; timer = setTimeout(() => { const shouldCall = trailing && pending && !(leading && callNow); timer = null; if (shouldCall) { invoke(...args); } else { pending = false; } }, wait); if (callNow) { invoke(...args); } }; } var getCacheDir = cachedFn(function getCacheDir2() { let osCacheDir; if (process.platform === "linux") { osCacheDir = process.env.XDG_CACHE_HOME || upath.join(os.homedir(), ".cache"); } else if (process.platform === "darwin") { osCacheDir = upath.join(os.homedir(), "Library", "Caches"); } else if (process.platform === "win32") { osCacheDir = process.env.LOCALAPPDATA || upath.join(os.homedir(), "AppData", "Local"); } else { throw new Error(`Unsupported platform: ${process.platform}`); } return upath.join(osCacheDir, "vivliostyle"); }); var detectBrowserPlatform = cachedFn(function detectBrowserPlatform2() { const platform = process.platform; const arch = process.arch; switch (platform) { case "darwin": return arch === "arm64" ? "mac_arm" : "mac"; case "linux": return arch === "arm64" ? "linux_arm" : "linux"; case "win32": return arch === "x64" || // Windows 11 for ARM supports x64 emulation arch === "arm64" && isWindows11(os.release()) ? "win64" : "win32"; default: return void 0; } }); function isWindows11(version) { const parts = version.split("."); if (parts.length > 2) { const major = parseInt(parts[0], 10); const minor = parseInt(parts[1], 10); const patch = parseInt(parts[2], 10); return major > 10 || major === 10 && minor > 0 || major === 10 && minor === 0 && patch >= 22e3; } return false; } var getDefaultBrowserTag = (browserType) => { if (import.meta.env?.VITEST) { return "100.0"; } const platform = detectBrowserPlatform(); return platform && DEFAULT_BROWSER_VERSIONS[browserType][platform]; }; function whichPm() { if (!process.env.npm_config_user_agent) { return "npm"; } const pmSpec = process.env.npm_config_user_agent.split(" ")[0]; const separatorPos = pmSpec.lastIndexOf("/"); const name = pmSpec.substring(0, separatorPos); return name; } // src/processor/asset.ts import { copy } from "fs-extra/esm"; import fs2 from "node:fs"; import picomatch from "picomatch"; import { glob } from "tinyglobby"; import upath2 from "upath"; var GlobMatcher = class { matcherConfig; #_matchers; constructor(matcherConfig) { this.matcherConfig = matcherConfig; this.#_matchers = matcherConfig.map( ({ patterns, ...options }) => picomatch(patterns, options) ); } match(test) { return this.#_matchers.some((matcher) => matcher(test)); } async glob(globOptions = {}) { return new Set( (await Promise.all( this.matcherConfig.map( (config) => glob({ ...config, ...globOptions }) ) )).flat() ); } }; function getIgnoreThemeDirectoryPatterns({ themesDir, cwd: cwd2 }) { return pathContains(cwd2, themesDir) ? [ `${upath2.relative(cwd2, themesDir)}/node_modules/*/example`, `${upath2.relative(cwd2, themesDir)}/node_modules/*/*/example` ] : []; } function getIgnoreAssetPatterns({ outputs, entries, cwd: cwd2 }) { return [ ...outputs.flatMap( ({ format, path: p }) => !pathContains(cwd2, p) ? [] : format === "webpub" ? upath2.join(upath2.relative(cwd2, p), "**") : upath2.relative(cwd2, p) ), ...entries.flatMap(({ template }) => { return template?.type === "file" && pathContains(cwd2, template.pathname) ? upath2.relative(cwd2, template.pathname) : []; }) ]; } function getWebPubResourceMatcher({ outputs, themesDir, entries, cwd: cwd2, manifestPath, copyAsset: { fileExtensions } }) { return new GlobMatcher([ { patterns: [ `**/${upath2.relative(cwd2, manifestPath)}`, "**/*.{html,htm,xhtml,xht}", `**/*.{${fileExtensions.join(",")}}` ], ignore: [ ...getIgnoreAssetPatterns({ cwd: cwd2, outputs, entries }), ...getIgnoreThemeDirectoryPatterns({ cwd: cwd2, themesDir }), // Ignore node_modules in the root directory "node_modules/**", // only include dotfiles starting with `.vs-` "**/.!(vs-*)/**" ], dot: true, cwd: cwd2 } ]); } function getAssetMatcher({ copyAsset: { fileExtensions, includes, excludes }, outputs, themesDir, entries, cwd: cwd2, ignore = [] }) { const ignorePatterns = [ ...ignore, ...excludes, ...getIgnoreAssetPatterns({ outputs, entries, cwd: cwd2 }) ]; return new GlobMatcher([ // Step 1: Glob files with an extension in `fileExtension` // Ignore files in node_modules directory, theme example files and files matched `excludes` { patterns: fileExtensions.map((ext) => `**/*.${ext}`), ignore: [ "**/node_modules/**", ...ignorePatterns, ...getIgnoreThemeDirectoryPatterns({ themesDir, cwd: cwd2 }) ], cwd: cwd2 }, // Step 2: Glob files matched with `includes` // Ignore only files matched `excludes` { patterns: includes, ignore: ignorePatterns, cwd: cwd2 } ]); } async function copyAssets({ entryContextDir, workspaceDir, copyAsset, outputs, themesDir, entries }) { if (pathEquals(entryContextDir, workspaceDir)) { return; } const relWorkspaceDir = upath2.relative(entryContextDir, workspaceDir); const assets = await getAssetMatcher({ copyAsset, cwd: entryContextDir, outputs, themesDir, entries, ignore: [ // don't copy workspace itself ...relWorkspaceDir ? [upath2.join(relWorkspaceDir, "**")] : [] ] }).glob({ followSymbolicLinks: true }); Logger.debug("assets", assets); for (const asset of assets) { const target = upath2.join(workspaceDir, asset); fs2.mkdirSync(upath2.dirname(target), { recursive: true }); await copy(upath2.resolve(entryContextDir, asset), target); } } export { createParserProgram, setupConfigFromFlags, cwd, exec, registerExitHandler, runExitHandlers, DetailError, getFormattedError, gracefulError, readJSON, statFileSync, useTmpDirectory, touchTmpFile, pathEquals, pathContains, isValidUri, isInContainer, isRunningOnWSL, openEpub, getDefaultEpubOpfPath, getEpubRootDir, assertPubManifestSchema, parseJsonc, prettifySchemaError, writeFileIfChanged, getOsLocale, toTitleCase, debounce, getCacheDir, detectBrowserPlatform, getDefaultBrowserTag, whichPm, isUnicodeSupported, randomBookSymbol, Logger, GlobMatcher, getWebPubResourceMatcher, getAssetMatcher, copyAssets }; //# sourceMappingURL=chunk-DBK27BAR.js.map