@vivliostyle/cli
Version:
Save the pdf file via headless browser and Vivliostyle.
1,484 lines (1,459 loc) • 37.9 kB
JavaScript
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