From 5d343a067cd8d87fe2d6042792f5d34b1aa980f9 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Fri, 16 Aug 2024 17:37:13 +0800 Subject: [PATCH] Implement PDF and EPUB renderers Implement basic compilation and formatting for PDF and EPUB formats. --- packages/cli/.gitignore | 2 +- packages/cli/src/commands.ts | 6 + .../cli/src/modules/bind/bind.controller.ts | 8 +- packages/core/.gitignore | 2 +- packages/core/package.json | 9 +- packages/core/src/common.ts | 31 +- packages/core/src/compilers/archive/index.ts | 10 +- packages/core/src/compilers/dir/index.ts | 174 ++++ packages/core/src/compilers/path/index.ts | 66 -- packages/core/src/formats/epub/index.ts | 9 +- packages/core/src/formats/epub/packaging.ts | 78 ++ .../core/src/formats/epub/xml-definitions.ts | 190 ++++ packages/core/src/formats/pdf/compiling.ts | 53 ++ packages/core/src/formats/pdf/index.ts | 16 +- packages/core/src/formats/pdf/rendering.ts | 26 + packages/core/src/index.ts | 25 +- packages/core/test/compilers/path.test.ts | 4 +- packages/sandboxes/astro/astro.config.mjs | 7 +- packages/sandboxes/astro/package.json | 1 + .../sandboxes/astro/patchouli.binding.json | 10 + packages/sandboxes/astro/patchouli.book.json | 2 - .../src/content/appendices/01-appendix.md | 5 + .../src/content/chapters/01-introduction.md | 5 + .../astro/src/content/chapters/02-next.md | 5 + .../astro/src/content/chapters/03-final.md | 5 + .../astro/src/content/special/foreword.md | 5 + packages/sandboxes/astro/src/env.d.ts | 1 + .../src/pages/appendices/[...slug].astro | 26 + .../astro/src/pages/chapters/[...slug].astro | 26 + .../sandboxes/astro/src/pages/foreword.astro | 16 + .../sandboxes/astro/src/pages/index.astro | 6 +- .../sandboxes/astro/src/pages/title.astro | 17 + pnpm-lock.yaml | 879 +++++++++++++++++- 33 files changed, 1593 insertions(+), 132 deletions(-) create mode 100644 packages/core/src/compilers/dir/index.ts delete mode 100644 packages/core/src/compilers/path/index.ts create mode 100644 packages/core/src/formats/epub/packaging.ts create mode 100644 packages/core/src/formats/epub/xml-definitions.ts create mode 100644 packages/core/src/formats/pdf/compiling.ts create mode 100644 packages/core/src/formats/pdf/rendering.ts create mode 100644 packages/sandboxes/astro/patchouli.binding.json create mode 100644 packages/sandboxes/astro/src/content/appendices/01-appendix.md create mode 100644 packages/sandboxes/astro/src/content/chapters/01-introduction.md create mode 100644 packages/sandboxes/astro/src/content/chapters/02-next.md create mode 100644 packages/sandboxes/astro/src/content/chapters/03-final.md create mode 100644 packages/sandboxes/astro/src/content/special/foreword.md create mode 100644 packages/sandboxes/astro/src/pages/appendices/[...slug].astro create mode 100644 packages/sandboxes/astro/src/pages/chapters/[...slug].astro create mode 100644 packages/sandboxes/astro/src/pages/foreword.astro create mode 100644 packages/sandboxes/astro/src/pages/title.astro diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore index 53992de..ea1438f 100644 --- a/packages/cli/.gitignore +++ b/packages/cli/.gitignore @@ -103,5 +103,5 @@ dist # TernJS port file .tern-port - +types/ .npmrc diff --git a/packages/cli/src/commands.ts b/packages/cli/src/commands.ts index e3297c3..1907012 100644 --- a/packages/cli/src/commands.ts +++ b/packages/cli/src/commands.ts @@ -12,6 +12,12 @@ export const addCommands = (cli: Cli) => { describe: 'Binds a collection of static Web assets into a book.', handler: bindController.bindBook, options: { + 'sourceType': { + alias: 's', + describe: 'The kind of source that will be supplied when binding the book.', + type: 'string', + default: 'dir', + }, 'format': { alias: 'f', describe: 'The format of the output.', diff --git a/packages/cli/src/modules/bind/bind.controller.ts b/packages/cli/src/modules/bind/bind.controller.ts index a5b5f7f..20cf808 100644 --- a/packages/cli/src/modules/bind/bind.controller.ts +++ b/packages/cli/src/modules/bind/bind.controller.ts @@ -18,6 +18,11 @@ export class BindControllerImpl implements BindController { readonly bindBook: CommandHandler = async (params) => { if (!params.interactive) { const checkArgs = params.args as Record; + const checkSourceType = checkArgs.sourceType ?? checkArgs.source ?? checkArgs.s; + if (typeof checkSourceType === 'undefined') { + params.logger.error('Missing required argument: sourceType'); + return -1; + } const checkFormat = checkArgs.format ?? checkArgs.f; if (typeof checkFormat === 'undefined') { params.logger.error('Missing required argument: format'); @@ -30,12 +35,13 @@ export class BindControllerImpl implements BindController { } } - const { inputPath: inputPathRaw, f, format = f, o, outputPath = o } = params.args; + const { inputPath: inputPathRaw, f, format = f, o, outputPath = o, s, source = s, sourceType = source, } = params.args; const inputPath = inputPathRaw ?? process.cwd(); try { const response = await this.bindService.bindBook({ input: { + sourceType, path: inputPath, }, output: { diff --git a/packages/core/.gitignore b/packages/core/.gitignore index 53992de..ea1438f 100644 --- a/packages/core/.gitignore +++ b/packages/core/.gitignore @@ -103,5 +103,5 @@ dist # TernJS port file .tern-port - +types/ .npmrc diff --git a/packages/core/package.json b/packages/core/package.json index 90b31c0..212b4db 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -16,6 +16,7 @@ "pridepack" ], "devDependencies": { + "@types/archiver": "^6.0.2", "@types/node": "^20.12.7", "pridepack": "2.6.0", "tslib": "^2.6.2", @@ -65,6 +66,12 @@ "*": {} }, "dependencies": { - "valibot": "^0.30.0" + "archiver": "^7.0.1", + "glob": "^11.0.0", + "mime": "^4.0.4", + "pdf-lib": "^1.17.1", + "puppeteer-html-pdf": "^4.0.8", + "valibot": "^0.30.0", + "xml-js": "^1.6.11" } } diff --git a/packages/core/src/common.ts b/packages/core/src/common.ts index 3e7a3a8..fa74e5d 100644 --- a/packages/core/src/common.ts +++ b/packages/core/src/common.ts @@ -1,8 +1,8 @@ import * as v from 'valibot'; -export const inputSchema = v.object({}, v.unknown()); +const commonInputSchema = v.object({}); -export type Input = v.Output; +export type CommonInput = v.Output; export const BOOK_FILENAME = 'patchouli.book.json' as const; @@ -12,7 +12,12 @@ export const bindingFileBaseSchema = v.object({ generatorType: v.string(), generatorConfigFilePath: v.optional(v.string()), generatorDistDirectory: v.string(), - pageOrdering: v.array(v.string()), // allow blobs on page ordering + pageFileExtensions: v.array(v.string()), + pageOrdering: v.optional( + v.array( + v.string() + ) + ), // allow blobs on page ordering // ahh so that's why I added this comment, so we can add the generated files in binding }); export const bookFileSchema = v.object({ @@ -26,3 +31,23 @@ export const bookFileSchema = v.object({ subjects: v.optional(v.array(v.string())), rights: v.optional(v.string()), }); + +export type Book = v.Output; + +export type Binding = v.Output; + +export interface BookManifestItem { + id: string; + href: string; + path?: string; + buffer?: Buffer; + type?: string; + properties?: string; +} + +export interface BookData { + metadata: Book; + manifest: BookManifestItem[]; + spine: BookManifestItem['id'][]; + binding: Binding; +} diff --git a/packages/core/src/compilers/archive/index.ts b/packages/core/src/compilers/archive/index.ts index 7d3f597..d48a454 100644 --- a/packages/core/src/compilers/archive/index.ts +++ b/packages/core/src/compilers/archive/index.ts @@ -1,14 +1,15 @@ import * as v from 'valibot'; -import {Input} from '../../common'; +import {CommonInput} from '../../common'; export const name = 'archive' as const; -const inputSchema = v.object({ +export const inputSchema = v.object({ + sourceType: v.literal(name), blob: v.blob(), type: v.string(), }); -interface ArchiveInput extends Input, v.Output {} +interface ArchiveInput extends CommonInput, v.Output {} export class InvalidArchiveTypeError extends Error {} @@ -24,7 +25,8 @@ const extractTar = () => { }; -export const compileFromInput = async (input: T) => { +export const compileFromInput = async (inputRaw: T) => { + const input = inputRaw as unknown as ArchiveInput; switch (input.type) { // TODO get files from archive type case 'zip': { diff --git a/packages/core/src/compilers/dir/index.ts b/packages/core/src/compilers/dir/index.ts new file mode 100644 index 0000000..b7f45a8 --- /dev/null +++ b/packages/core/src/compilers/dir/index.ts @@ -0,0 +1,174 @@ +import {readdir, stat, readFile} from 'fs/promises'; +import {resolve} from 'path'; +import {glob} from 'glob'; +import * as v from 'valibot'; +import { + Binding, + BINDING_FILENAME, + Book, + BOOK_FILENAME, BookData, + bookFileSchema, + BookManifestItem, + CommonInput, +} from '../../common'; +import { randomUUID } from 'crypto'; + +export const name = 'dir' as const; + +export const inputSchema = v.object({ + sourceType: v.literal(name), + path: v.string(), +}); + +interface DirInput extends CommonInput, v.Output {} + +export class InvalidInputPathError extends Error {} + +const getBookFile = async (bookFilePath: string, packageJsonFilePath: string): Promise => { + const bookFileString = await readFile(bookFilePath, 'utf-8'); + const bookFileRaw = JSON.parse(bookFileString); + + const packageJsonFileString = await readFile(packageJsonFilePath, 'utf-8'); + const packageJson = JSON.parse(packageJsonFileString); + + const bookFile = { + ...bookFileRaw, + id: bookFileRaw.id ?? randomUUID(), + publisher: bookFileRaw.publisher ?? '@modal-sh/patchouli', + description: bookFileRaw.description ?? packageJson.description, + rights: bookFileRaw.rights ?? packageJson.copyright, + }; + + return await v.parseAsync(bookFileSchema, bookFile); +}; + +const getBindingFile = async (bindingFilePath: string, defaultBinding: Binding): Promise => { + const bindingFileString = await readFile(bindingFilePath, 'utf-8'); + const bindingFileRaw = JSON.parse(bindingFileString); + + return { + ...defaultBinding, + ...bindingFileRaw, + }; +}; + +const getItems = async (dir: string, prefix = ''): Promise => { + const thisDirFiles = await readdir(dir); + + const items = await Promise.all( + thisDirFiles.map(async (p) => { + const thisPath = resolve(dir, p); + const s = await stat(thisPath); + if (s.isDirectory()) { + return getItems(thisPath, p); + } + + const href = [prefix, p].filter((s) => s.trim()).join('/'); + const [idRaw] = href.split('.'); + const id = idRaw.replace(/\//g, '-'); + + return [ + { + id, + href, + path: thisPath, + }, + ]; + }) + ); + + return items.flat(); +}; + +const getSpine = async (binding: Binding) => { + const { + pageOrdering, + generatorDistDirectory, + pageFileExtensions, + } = binding; + + if (!Array.isArray(pageOrdering)) { + // get glob of HTML pages + return []; + } + + const directoryNormalized = generatorDistDirectory.replace(/\\/g, '/'); + const extensionsGlobFragment = pageFileExtensions.join(','); + + const pagesPaths = await Promise.all( + pageOrdering.map( + async (globString) => { + switch (globString) { + case 'index': + case 'title': + return glob(`${directoryNormalized}/${globString}{${extensionsGlobFragment}`); + case 'toc': + return []; // TODO check if TOC is pre-generated or there is a directive to generate a TOC + default: + break; + } + + if (globString.startsWith('pages:')) { + const [prefix, ...etcGlobStrArr] = globString.split(':'); + const globStrPath = etcGlobStrArr.join(':'); + switch (prefix) { + case 'pages': { + const thePagesPath = await glob(`${directoryNormalized}/${globStrPath}{${extensionsGlobFragment}}`); + return thePagesPath.sort((a, b) => a.localeCompare(b)); + } + } + } + + return []; + } + ) + ); + + return pagesPaths.flat(); +}; + +export const compileFromInput = async (inputRaw: T): Promise => { + const input = inputRaw as unknown as DirInput; + const files = await readdir(input.path); + if (!files.includes(BOOK_FILENAME)) { + throw new InvalidInputPathError(`Path does not contain a "${BOOK_FILENAME}" file.`); + } + + const bookFilePath = resolve(input.path, BOOK_FILENAME); + const packageJsonFilePath = resolve(input.path, 'package.json'); + const bookFile = await getBookFile(bookFilePath, packageJsonFilePath); + + const defaultBinding: Binding = { + generatorType: 'static', + generatorDistDirectory: resolve(input.path, 'dist'), + pageFileExtensions: ['.html', '.htm', '.xhtml'], + }; + + const bindingFilePath = resolve(input.path, BINDING_FILENAME); + const bindingFile: Binding = files.includes(BINDING_FILENAME) + ? await getBindingFile(bindingFilePath, defaultBinding) + : defaultBinding; + + const isAstro = files.includes('astro.config.mjs'); + if (isAstro) { + bindingFile.generatorType = 'astro'; + bindingFile.generatorConfigFilePath = resolve(input.path, 'astro.config.mjs'); + const { default: config } = await import('file:///' + bindingFile.generatorConfigFilePath); + bindingFile.generatorDistDirectory = resolve(input.path, config.outDir ?? 'dist'); + if (typeof bindingFile.pageOrdering !== 'object') { + bindingFile.pageOrdering = []; // if we want to have a custom ordering, e.g. last minute changes + } + } + + const spine = await getSpine(bindingFile); + const manifest = await getItems( + bindingFile.generatorDistDirectory + ); + + return { + metadata: bookFile, + manifest, + spine, + binding: bindingFile, + }; +}; diff --git a/packages/core/src/compilers/path/index.ts b/packages/core/src/compilers/path/index.ts deleted file mode 100644 index fbfdceb..0000000 --- a/packages/core/src/compilers/path/index.ts +++ /dev/null @@ -1,66 +0,0 @@ -import {readdir, stat, readFile} from 'fs/promises'; -import {resolve} from 'path'; -import * as v from 'valibot'; -import {BINDING_FILENAME, bindingFileBaseSchema, BOOK_FILENAME, bookFileSchema, Input} from '../../common'; - -export const name = 'path' as const; - -const inputSchema = v.object({ - path: v.string(), -}); - -interface PathInput extends Input, v.Output {} - -const readPath = async (path: string, rootPath = path, readFiles = []) => { - const files = await readdir(path); - - // TODO get the buffers on the tree - //console.log(files); -}; - -export class InvalidInputPathError extends Error {} - -type Book = v.Output; - -type Binding = v.Output; - -const getBookFile = async (bookFilePath: string): Promise => { - const bookFileString = await readFile(bookFilePath, 'utf-8'); - const bookFileRaw = JSON.parse(bookFileString); - return await v.parseAsync(bookFileSchema, bookFileRaw); -}; - -const getBindingFile = async (bindingFilePath: string, defaultBinding: Binding) => { - const bindingFileString = await readFile(bindingFilePath, 'utf-8'); - const bindingFileRaw = JSON.parse(bindingFileString); - - return { - ...defaultBinding, - ...bindingFileRaw, - }; -}; - -export const compileFromInput = async (input: T) => { - const files = await readdir(input.path); - if (!files.includes(BOOK_FILENAME)) { - throw new InvalidInputPathError(`Path does not contain a "${BOOK_FILENAME}" file.`); - } - - const bookFilePath = resolve(input.path, BOOK_FILENAME); - const bookFile = await getBookFile(bookFilePath); - - const defaultBinding = { - generatorType: 'static', - // TODO should make the dist directory related to book file when getting contents - generatorDistDirectory: resolve(input.path, 'dist'), - }; - - const bindingFilePath = resolve(input.path, BINDING_FILENAME); - const bindingFile = files.includes(BINDING_FILENAME) - ? await getBindingFile(bindingFilePath, defaultBinding) - : defaultBinding; - - return [ - - ]; -}; diff --git a/packages/core/src/formats/epub/index.ts b/packages/core/src/formats/epub/index.ts index d08ff07..d532c64 100644 --- a/packages/core/src/formats/epub/index.ts +++ b/packages/core/src/formats/epub/index.ts @@ -1,7 +1,10 @@ -import {Input} from '../../common'; +import {BookData} from '../../common'; +import {createEpubArchive, prepareEpubContents} from './packaging'; export const name = 'epub' as const; -export const bindBook = async (input: T) => { - return Buffer.from(input.path + ' ' + name); +export const bindBook = async (bookPackage: U) => { + const data = await prepareEpubContents(bookPackage); + + return await createEpubArchive(data); }; diff --git a/packages/core/src/formats/epub/packaging.ts b/packages/core/src/formats/epub/packaging.ts new file mode 100644 index 0000000..cd252d4 --- /dev/null +++ b/packages/core/src/formats/epub/packaging.ts @@ -0,0 +1,78 @@ +import {Readable} from 'stream'; +import {BookData} from '../../common'; +import {prepareEpubContainerContents, prepareEpubRootfileContents} from './xml-definitions'; +import {createReadStream} from 'fs'; +import assert from 'assert'; +import archiver from 'archiver'; + +interface EpubArchiveDatum { + path: string; + data: Buffer | Readable; +} + +export const prepareEpubContents = async (bookPackage: U): Promise => { + const baseDir = 'EPUB'; + const rootFilePath = `${baseDir}/content.opf`; + const rootFileContents = await prepareEpubRootfileContents(bookPackage); + return [ + { + path: 'mimetype', + data: Buffer.from('application/epub+zip'), + }, + { + path: 'META-INF/container.xml', + data: Buffer.from(prepareEpubContainerContents(rootFilePath)) + }, + { + path: rootFilePath, + data: Buffer.from(rootFileContents), + }, + ...bookPackage.manifest.map((entry) => { + if (typeof entry.path === 'string') { + const finalPath = entry.path.slice(bookPackage.binding.generatorDistDirectory.length ?? 0); + return { + path: `${baseDir}/${finalPath}`, + data: createReadStream(entry.path), + }; + } + + assert(entry.buffer instanceof Buffer); + return { + path: `${baseDir}/${entry.href}`, + data: entry.buffer, + }; + }), + ]; +}; + +export const createEpubArchive = async (data: EpubArchiveDatum[]): Promise => { + const archive = archiver('zip', { + zlib: { + level: 9, + }, + }); + + return new Promise(async (resolve, reject) => { + let b = Buffer.from(''); + + archive.on('data', (c) => { + b = Buffer.concat([b, c]); + }); + + archive.on('end', () => { + resolve(b); + }); + + archive.on('error', (err) => { + reject(err); + }); + + data.forEach((entry) => { + archive.append(entry.data, { + name: entry.path, + }); + }); + + await archive.finalize(); + }); +}; diff --git a/packages/core/src/formats/epub/xml-definitions.ts b/packages/core/src/formats/epub/xml-definitions.ts new file mode 100644 index 0000000..ef93b1e --- /dev/null +++ b/packages/core/src/formats/epub/xml-definitions.ts @@ -0,0 +1,190 @@ +import {js2xml} from 'xml-js'; +import {BookData} from '../../common'; + +export const prepareEpubContainerContents = (rootFilePath: string) => { + return js2xml({ + _declaration: { + _attributes: { + version: '1.0', + encoding: 'utf-8', + }, + }, + container: { + _attributes: { + xmlns: 'urn:oasis:names:tc:opendocument:xmlns:container', + version: '1.0', + }, + rootfiles: { + rootfile: { + _attributes: { + 'full-path': rootFilePath, + 'media-type': 'application/oebps-package+xml', + } + } + } + } + }, { + compact: true, + }); +}; + +export const prepareEpubRootfileContents = async (bookPackage: U) => { + const { default: mime } = await import('mime'); // ESM import, convert to CJS for compatibility + const uniqueIdentifierName = 'BookID'; + return js2xml({ + declaration: { + attributes: { + version: '1.0', + encoding: 'utf-8', + }, + }, + elements: [ + { + type: 'element', + name: 'package', + attributes: { + xmlns: 'http://www.idpf.org/2007/opf', + 'xmlns:dc': 'http://purl.org/dc/elements/1.1/', + version: '3.0', + 'unique-identifier': uniqueIdentifierName, + }, + elements: [ + { + type: 'element', + name: 'metadata', + elements: [ + { + type: 'element', + name: 'dc:identifier', + attributes: { + id: uniqueIdentifierName, + }, + elements: [ + { + type: 'text', + text: bookPackage.metadata.id, + }, + ], + }, + typeof bookPackage.metadata.isbn !== 'undefined' + ? { + type: 'element', + name: 'dc:identifier', + elements: [ + { + type: 'text', + text: bookPackage.metadata.isbn, + }, + ], + } + : undefined, + { + type: 'element', + name: 'dc:title', + elements: [ + { + type: 'text', + text: bookPackage.metadata.title, + }, + ], + }, + typeof bookPackage.metadata.publisher !== 'undefined' + ? { + type: 'element', + name: 'dc:publisher', + elements: [ + { + type: 'text', + text: bookPackage.metadata.publisher, + }, + ], + } + : undefined, + { + type: 'element', + name: 'dc:creator', + elements: [ + { + type: 'text', + text: bookPackage.metadata.creator, + }, + ], + }, + ...(bookPackage.metadata.contributors ?? []).map((c) => ({ + type: 'element', + name: 'dc:contributor', + elements: [ + { + type: 'text', + text: c, + }, + ], + })), + typeof bookPackage.metadata.description !== 'undefined' + ? { + type: 'element', + name: 'dc:description', + elements: [ + { + type: 'text', + text: bookPackage.metadata.description, + }, + ], + } + : undefined, + ...(bookPackage.metadata.subjects ?? []).map((c) => ({ + type: 'element', + name: 'dc:subject', + elements: [ + { + type: 'text', + text: c, + }, + ], + })), + typeof bookPackage.metadata.rights !== 'undefined' + ? { + type: 'element', + name: 'dc:rights', + elements: [ + { + type: 'text', + text: bookPackage.metadata.rights, + }, + ], + } + : undefined, + ] + .filter((s) => typeof s !== 'undefined'), + }, + { + type: 'element', + name: 'manifest', + elements: bookPackage.manifest.map((e) => ({ + type: 'element', + name: 'item', + attributes: { + id: e.id, + href: e.href, + 'media-type': mime.getType(e.href), + }, + })), + }, + { + type: 'element', + name: 'spine', + elements: bookPackage.spine.map((e) => ({ + type: 'element', + name: 'itemref', + attributes: { + idref: bookPackage.manifest.find((m) => m.href === e || m.path === e)?.id, + }, + })), + }, + ], + }, + ], + }, { + compact: false, + }); +}; diff --git a/packages/core/src/formats/pdf/compiling.ts b/packages/core/src/formats/pdf/compiling.ts new file mode 100644 index 0000000..2f9e1aa --- /dev/null +++ b/packages/core/src/formats/pdf/compiling.ts @@ -0,0 +1,53 @@ +import {PDFDocument} from 'pdf-lib'; +import {Book} from '../../common'; + +export const compilePdfBuffers = async (buffers: Buffer[]) => { + const documents = await buffers.reduce( + async (previousPromise, e) => { + const p = await previousPromise; + const d = await PDFDocument.load(e, { + updateMetadata: false, + }); + return [ + ...p, + d, + ]; + }, + Promise.resolve([] as PDFDocument[]) + ); + return await documents.reduce( + async (thePdfDocPromise, dd) => { + const thePdfDoc = await thePdfDocPromise; + const c = await thePdfDoc.copyPages(dd, dd.getPageIndices()); + c.forEach((page) => { + thePdfDoc.addPage(page); + }); + return thePdfDoc; + }, + PDFDocument.create(), + ); +}; + +export const addPdfViewerPreferences = (pdfDoc: PDFDocument) => { + const viewerPrefs = pdfDoc.catalog.getOrCreateViewerPreferences(); + viewerPrefs.setHideToolbar(false); + viewerPrefs.setHideMenubar(false); + viewerPrefs.setDisplayDocTitle(true); + return pdfDoc; +}; + +export const addPdfMetadata = (pdfDoc: PDFDocument, metadata: Book) => { + pdfDoc.setTitle(metadata.title, { showInWindowTitleBar: true }); + pdfDoc.setAuthor([metadata.creator, ...(metadata.contributors ?? [])].join(', ')); + if (Array.isArray(metadata.subjects)) { + pdfDoc.setSubject(metadata.subjects.join(', ')); + } + pdfDoc.setCreator('@modal-sh/patchouli'); + const defaultProducer = pdfDoc.getProducer(); + pdfDoc.setProducer(['puppeteer-html-pdf (https://github.com/ultimateakash/puppeteer-html-pdf)', defaultProducer].join(', ')); + const now = new Date(); + pdfDoc.setCreationDate(now); + pdfDoc.setModificationDate(now); + // TODO add language data + return pdfDoc; +}; diff --git a/packages/core/src/formats/pdf/index.ts b/packages/core/src/formats/pdf/index.ts index 637abd8..fab80f4 100644 --- a/packages/core/src/formats/pdf/index.ts +++ b/packages/core/src/formats/pdf/index.ts @@ -1,7 +1,17 @@ -import {Input} from '../../common'; +import {BookData} from '../../common'; +import {renderFilesAsPdf} from './rendering'; +import {addPdfMetadata, addPdfViewerPreferences, compilePdfBuffers} from './compiling'; export const name = 'pdf' as const; -export const bindBook = async (input: T) => { - return Buffer.from(input.path + ' ' + name); +export const bindBook = async (input: T) => { + const buffers = await renderFilesAsPdf(input.spine); + // TODO how to generate TOC? + // https://github.com/Hopding/pdf-lib/issues/123 + // https://github.com/Hopding/pdf-lib/issues/1257 + const compiledDocument = await compilePdfBuffers(buffers); + const documentWithMetadata = addPdfMetadata(compiledDocument, input.metadata); + const documentWithViewerPreferences = addPdfViewerPreferences(documentWithMetadata);; + const buffer = await documentWithViewerPreferences.save(); + return Buffer.from(buffer); }; diff --git a/packages/core/src/formats/pdf/rendering.ts b/packages/core/src/formats/pdf/rendering.ts new file mode 100644 index 0000000..bb63115 --- /dev/null +++ b/packages/core/src/formats/pdf/rendering.ts @@ -0,0 +1,26 @@ +import PuppeteerHTMLPDF from 'puppeteer-html-pdf'; +import {BookData} from '../../common'; + +export const renderFilesAsPdf = async (spine: BookData['spine']) => { + const pdf = new PuppeteerHTMLPDF(); + await pdf.setOptions({ + preferCSSPageSize: true, + headless: true, + }); + + return await spine.reduce( + async (previousPromise, e, i, ee) => { + const previousBuffers = await previousPromise; + process.stdout.write(`Rendering file ${i + 1} of ${ee.length}...`); + await pdf.initializeBrowser(); + const thisPdf = await pdf.create(`file:///${e}`); + await pdf.closeBrowser(); + process.stdout.write('Done!\n'); + return [ + ...previousBuffers, + thisPdf + ]; + }, + Promise.resolve([] as Buffer[]) + ); +}; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 86ae5a3..5c2cbad 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,11 +2,12 @@ import * as v from 'valibot'; import assert from 'assert'; import * as PdfFormat from './formats/pdf'; import * as EpubFormat from './formats/epub'; -import * as PathCompiler from './compilers/path'; -import {inputSchema} from './common'; +import * as DirCompiler from './compilers/dir'; +import * as ArchiveCompiler from './compilers/archive'; const AVAILABLE_COMPILERS = [ - PathCompiler, + ArchiveCompiler, + DirCompiler, ]; const AVAILABLE_FORMATS = [ @@ -16,18 +17,11 @@ const AVAILABLE_FORMATS = [ const optionsSchema = v.object( { - input: v.merge( - [ - inputSchema, - v.object({ - sourceType: v.picklist(AVAILABLE_COMPILERS.map((f) => f.name)), - }) - ], - v.unknown(), - ), + input: v.union(AVAILABLE_COMPILERS.map((c) => c.inputSchema)), output: v.object( { format: v.picklist(AVAILABLE_FORMATS.map((f) => f.name)), + path: v.string(), }, v.unknown(), ), @@ -41,12 +35,13 @@ export interface BindFunction { (options: T): Promise; } +// TODO add options to include blank pages to ensure chapters' first pages are in the right side of the book export const bindBook: BindFunction = async (options: BindFunctionOptions): Promise => { const { input, output, } = await v.parseAsync(optionsSchema, options); const selectedCompiler = AVAILABLE_COMPILERS.find((c) => c.name === input.sourceType); - + assert(typeof selectedCompiler !== 'undefined'); + const bookPackage = await selectedCompiler.compileFromInput(input); const selectedFormat = AVAILABLE_FORMATS.find((f) => f.name === output.format); assert(typeof selectedFormat !== 'undefined'); - - return selectedFormat.bindBook(input); + return selectedFormat.bindBook(bookPackage); }; diff --git a/packages/core/test/compilers/path.test.ts b/packages/core/test/compilers/path.test.ts index 4700dd6..abdb4e4 100644 --- a/packages/core/test/compilers/path.test.ts +++ b/packages/core/test/compilers/path.test.ts @@ -7,7 +7,7 @@ import { Mock, afterEach, } from 'vitest'; import { readFile, readdir } from 'fs/promises'; -import { compileFromInput } from '../../src/compilers/path'; +import { compileFromInput } from '../../src/compilers/dir'; vi.mock('fs/promises'); @@ -26,7 +26,7 @@ const completeBookFile = { rights: '© copyright notice or get from package.json LICENSE' }; -describe('path compiler', () => { +describe('dir compiler', () => { let mockReaddir: Mock; beforeEach(() => { mockReaddir = readdir as Mock; diff --git a/packages/sandboxes/astro/astro.config.mjs b/packages/sandboxes/astro/astro.config.mjs index 882e651..65b3637 100644 --- a/packages/sandboxes/astro/astro.config.mjs +++ b/packages/sandboxes/astro/astro.config.mjs @@ -1,4 +1,9 @@ import { defineConfig } from 'astro/config'; // https://astro.build/config -export default defineConfig({}); +export default defineConfig({ + output: 'static', + build: { + format: 'file' + }, +}); diff --git a/packages/sandboxes/astro/package.json b/packages/sandboxes/astro/package.json index f121631..fe11add 100644 --- a/packages/sandboxes/astro/package.json +++ b/packages/sandboxes/astro/package.json @@ -1,6 +1,7 @@ { "name": "@modal-sh/patchouli-sandbox-astro", "type": "module", + "description": "Package JSON description", "version": "0.0.1", "scripts": { "dev": "astro dev", diff --git a/packages/sandboxes/astro/patchouli.binding.json b/packages/sandboxes/astro/patchouli.binding.json new file mode 100644 index 0000000..7bb5d26 --- /dev/null +++ b/packages/sandboxes/astro/patchouli.binding.json @@ -0,0 +1,10 @@ +{ + "pageOrdering": [ + "index", + "title", + "toc", + "pages:foreword", + "pages:chapters/**", + "pages:appendices/**" + ] +} diff --git a/packages/sandboxes/astro/patchouli.book.json b/packages/sandboxes/astro/patchouli.book.json index e4f34c9..f8e4a08 100644 --- a/packages/sandboxes/astro/patchouli.book.json +++ b/packages/sandboxes/astro/patchouli.book.json @@ -1,11 +1,9 @@ { "title": "Astro Sandbox", - "publisher": "", "creator": "John Doe", "contributors": [ "Jane Doe" ], - "description": "Retrieve from package.json", "subjects": [ "A subject of the publication", "Another subject of the publication" diff --git a/packages/sandboxes/astro/src/content/appendices/01-appendix.md b/packages/sandboxes/astro/src/content/appendices/01-appendix.md new file mode 100644 index 0000000..6cbe503 --- /dev/null +++ b/packages/sandboxes/astro/src/content/appendices/01-appendix.md @@ -0,0 +1,5 @@ +--- +title: Appendix +--- + +Appendix. diff --git a/packages/sandboxes/astro/src/content/chapters/01-introduction.md b/packages/sandboxes/astro/src/content/chapters/01-introduction.md new file mode 100644 index 0000000..d95913f --- /dev/null +++ b/packages/sandboxes/astro/src/content/chapters/01-introduction.md @@ -0,0 +1,5 @@ +--- +title: Introduction +--- + +Hello! This is chapter 1. diff --git a/packages/sandboxes/astro/src/content/chapters/02-next.md b/packages/sandboxes/astro/src/content/chapters/02-next.md new file mode 100644 index 0000000..e454adf --- /dev/null +++ b/packages/sandboxes/astro/src/content/chapters/02-next.md @@ -0,0 +1,5 @@ +--- +title: Next +--- + +This is the next chapter. diff --git a/packages/sandboxes/astro/src/content/chapters/03-final.md b/packages/sandboxes/astro/src/content/chapters/03-final.md new file mode 100644 index 0000000..64884a4 --- /dev/null +++ b/packages/sandboxes/astro/src/content/chapters/03-final.md @@ -0,0 +1,5 @@ +--- +title: Final +--- + +This is the final chapter. diff --git a/packages/sandboxes/astro/src/content/special/foreword.md b/packages/sandboxes/astro/src/content/special/foreword.md new file mode 100644 index 0000000..304936c --- /dev/null +++ b/packages/sandboxes/astro/src/content/special/foreword.md @@ -0,0 +1,5 @@ +--- +title: Foreword +--- + +This is a foreword. diff --git a/packages/sandboxes/astro/src/env.d.ts b/packages/sandboxes/astro/src/env.d.ts index f964fe0..acef35f 100644 --- a/packages/sandboxes/astro/src/env.d.ts +++ b/packages/sandboxes/astro/src/env.d.ts @@ -1 +1,2 @@ +/// /// diff --git a/packages/sandboxes/astro/src/pages/appendices/[...slug].astro b/packages/sandboxes/astro/src/pages/appendices/[...slug].astro new file mode 100644 index 0000000..b145ed5 --- /dev/null +++ b/packages/sandboxes/astro/src/pages/appendices/[...slug].astro @@ -0,0 +1,26 @@ +--- +import { getCollection } from 'astro:content'; + +export const getStaticPaths = async () => { + const entries = await getCollection('appendices'); + return entries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} + +const { entry } = Astro.props; +const { Content } = await entry.render(); +--- + + + + + + + + {entry.data.title} + + + + + diff --git a/packages/sandboxes/astro/src/pages/chapters/[...slug].astro b/packages/sandboxes/astro/src/pages/chapters/[...slug].astro new file mode 100644 index 0000000..fb246b3 --- /dev/null +++ b/packages/sandboxes/astro/src/pages/chapters/[...slug].astro @@ -0,0 +1,26 @@ +--- +import { getCollection } from 'astro:content'; + +export const getStaticPaths = async () => { + const entries = await getCollection('chapters'); + return entries.map(entry => ({ + params: { slug: entry.slug }, props: { entry }, + })); +} + +const { entry } = Astro.props; +const { Content } = await entry.render(); +--- + + + + + + + + {entry.data.title} + + + + + diff --git a/packages/sandboxes/astro/src/pages/foreword.astro b/packages/sandboxes/astro/src/pages/foreword.astro new file mode 100644 index 0000000..9dfc0fe --- /dev/null +++ b/packages/sandboxes/astro/src/pages/foreword.astro @@ -0,0 +1,16 @@ +--- +import { title } from '../../patchouli.book.json'; +--- + + + + + + + + Foreword - {title} + + +

Foreword

+ + diff --git a/packages/sandboxes/astro/src/pages/index.astro b/packages/sandboxes/astro/src/pages/index.astro index 2d14107..84e3dae 100644 --- a/packages/sandboxes/astro/src/pages/index.astro +++ b/packages/sandboxes/astro/src/pages/index.astro @@ -1,5 +1,5 @@ --- - +import { title } from '../../patchouli.book.json'; --- @@ -8,9 +8,9 @@ - Astro + {title} -

Astro

+

{title}

diff --git a/packages/sandboxes/astro/src/pages/title.astro b/packages/sandboxes/astro/src/pages/title.astro new file mode 100644 index 0000000..b6ca4d1 --- /dev/null +++ b/packages/sandboxes/astro/src/pages/title.astro @@ -0,0 +1,17 @@ +--- +import { title } from '../../patchouli.book.json'; +--- + + + + + + + + {title} + + +

{title}

+ Title Page + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 898ef0f..bac32b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,10 +45,31 @@ importers: packages/core: dependencies: + archiver: + specifier: ^7.0.1 + version: 7.0.1 + glob: + specifier: ^11.0.0 + version: 11.0.0 + mime: + specifier: ^4.0.4 + version: 4.0.4 + pdf-lib: + specifier: ^1.17.1 + version: 1.17.1 + puppeteer-html-pdf: + specifier: ^4.0.8 + version: 4.0.8(typescript@5.4.5) valibot: specifier: ^0.30.0 version: 0.30.0 + xml-js: + specifier: ^1.6.11 + version: 1.6.11 devDependencies: + '@types/archiver': + specifier: ^6.0.2 + version: 6.0.2 '@types/node': specifier: ^20.12.7 version: 20.12.7 @@ -876,6 +897,18 @@ packages: fast-deep-equal: 3.1.3 dev: false + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: false + /@jest/schemas@29.6.3: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -938,6 +971,42 @@ packages: engines: {node: '>=8'} dev: true + /@pdf-lib/standard-fonts@1.0.0: + resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==} + dependencies: + pako: 1.0.11 + dev: false + + /@pdf-lib/upng@1.0.1: + resolution: {integrity: sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==} + dependencies: + pako: 1.0.11 + dev: false + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: false + optional: true + + /@puppeteer/browsers@2.3.0: + resolution: {integrity: sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==} + engines: {node: '>=18'} + hasBin: true + dependencies: + debug: 4.3.6 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.4.0 + semver: 7.6.3 + tar-fs: 3.0.6 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + dev: false + /@rollup/rollup-android-arm-eabi@4.16.1: resolution: {integrity: sha512-92/y0TqNLRYOTXpm6Z7mnpvKAG9P7qmK7yJeRJSdzElNCUnsgbpAsGqerUboYRIQKzgfq4pWu9xVkgpWLfmNsw==} cpu: [arm] @@ -1058,6 +1127,16 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: false + + /@types/archiver@6.0.2: + resolution: {integrity: sha512-KmROQqbQzKGuaAbmK+ZcytkJ51+YqDa7NmbXjmtC5YBLSyQYo21YaUnQ3HbaPFKL1ooo6RQ6OPYPIDyxfpDDXw==} + dependencies: + '@types/readdir-glob': 1.1.5 + dev: true + /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: @@ -1127,6 +1206,12 @@ packages: dependencies: undici-types: 5.26.5 + /@types/readdir-glob@1.1.5: + resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} + dependencies: + '@types/node': 20.12.7 + dev: true + /@types/unist@2.0.10: resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} dev: false @@ -1145,6 +1230,14 @@ packages: '@types/yargs-parser': 21.0.3 dev: true + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + requiresBuild: true + dependencies: + '@types/node': 20.12.7 + dev: false + optional: true + /@ungap/structured-clone@1.2.0: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false @@ -1291,6 +1384,15 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + dev: false + /ajv-formats@2.1.1(ajv@8.12.0): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -1367,6 +1469,32 @@ packages: picomatch: 2.3.1 dev: false + /archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + dependencies: + glob: 10.4.5 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.21 + normalize-path: 3.0.0 + readable-stream: 4.5.2 + dev: false + + /archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + dependencies: + archiver-utils: 5.0.2 + async: 3.2.5 + buffer-crc32: 1.0.0 + readable-stream: 4.5.2 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + dev: false + /archy@1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: false @@ -1395,6 +1523,13 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: false + /astro@4.6.3(typescript@5.4.5): resolution: {integrity: sha512-p2zs1Gac+ysdc/yFCoc8pOXTZE5L9foAtmqUzUVL22WX68bYTRovd03GRs7J1MDpwzsl9kJtlK20ROpjyIFpNw==} engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} @@ -1477,6 +1612,10 @@ packages: - typescript dev: false + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: false + /atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -1503,25 +1642,28 @@ packages: resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} requiresBuild: true dev: false - optional: true /bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} dev: false - /bare-events@2.2.2: - resolution: {integrity: sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==} + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: false + + /bare-events@2.4.2: + resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==} requiresBuild: true dev: false optional: true - /bare-fs@2.2.3: - resolution: {integrity: sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==} + /bare-fs@2.3.1: + resolution: {integrity: sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==} requiresBuild: true dependencies: - bare-events: 2.2.2 - bare-path: 2.1.1 - streamx: 2.16.1 + bare-events: 2.4.2 + bare-path: 2.1.3 + bare-stream: 2.1.3 dev: false optional: true @@ -1531,14 +1673,22 @@ packages: dev: false optional: true - /bare-path@2.1.1: - resolution: {integrity: sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==} + /bare-path@2.1.3: + resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==} requiresBuild: true dependencies: bare-os: 2.2.1 dev: false optional: true + /bare-stream@2.1.3: + resolution: {integrity: sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==} + requiresBuild: true + dependencies: + streamx: 2.18.0 + dev: false + optional: true + /base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} dev: false @@ -1546,6 +1696,11 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + /basic-ftp@5.0.5: + resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + engines: {node: '>=10.0.0'} + dev: false + /binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1582,6 +1737,12 @@ packages: wrap-ansi: 8.1.0 dev: false + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -1600,6 +1761,15 @@ packages: update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: false + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: false + + /buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + dev: false + /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} requiresBuild: true @@ -1607,7 +1777,6 @@ packages: base64-js: 1.5.1 ieee754: 1.2.1 dev: false - optional: true /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -1620,6 +1789,11 @@ packages: engines: {node: '>=8'} dev: true + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: false + /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} @@ -1703,6 +1877,17 @@ packages: dev: false optional: true + /chromium-bidi@0.6.3(devtools-protocol@0.0.1312386): + resolution: {integrity: sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==} + peerDependencies: + devtools-protocol: '*' + dependencies: + devtools-protocol: 0.0.1312386 + mitt: 3.0.1 + urlpattern-polyfill: 10.0.0 + zod: 3.23.8 + dev: false + /ci-info@4.0.0: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} @@ -1790,6 +1975,17 @@ packages: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} dev: false + /compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.5.2 + dev: false + /confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} dev: true @@ -1815,6 +2011,40 @@ packages: engines: {node: '>= 0.6'} dev: false + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: false + + /cosmiconfig@9.0.0(typescript@5.4.5): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.4.5 + dev: false + + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + dev: false + + /crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + dependencies: + crc-32: 1.2.2 + readable-stream: 4.5.2 + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1834,6 +2064,11 @@ packages: hasBin: true dev: false + /data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + dev: false + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -1845,6 +2080,18 @@ packages: dependencies: ms: 2.1.2 + /debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + /decamelize@1.2.0: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} @@ -1879,6 +2126,15 @@ packages: dev: false optional: true + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: false + /degit@2.8.4: resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} engines: {node: '>=8.0.0'} @@ -1919,6 +2175,10 @@ packages: dequal: 2.0.3 dev: false + /devtools-protocol@0.0.1312386: + resolution: {integrity: sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==} + dev: false + /diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1980,13 +2240,23 @@ packages: dependencies: once: 1.4.0 dev: false - optional: true /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} dev: false + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: false + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: false + /es-module-lexer@1.5.0: resolution: {integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==} dev: false @@ -2065,17 +2335,39 @@ packages: engines: {node: '>=12'} dev: false + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: false + /esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true dev: false + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: false + /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: '@types/estree': 1.0.5 + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: false + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -2122,6 +2414,20 @@ packages: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: false + /extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.6 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + dev: false + /fast-content-type-parse@1.1.0: resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} dev: false @@ -2138,7 +2444,6 @@ packages: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} requiresBuild: true dev: false - optional: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -2207,6 +2512,12 @@ packages: reusify: 1.0.4 dev: false + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: false + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -2250,6 +2561,14 @@ packages: engines: {node: '>=8'} dev: false + /foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: false + /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -2261,6 +2580,15 @@ packages: dev: false optional: true + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: false + /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2294,10 +2622,29 @@ packages: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: false + /get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} + /get-uri@6.0.3: + resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.5 + data-uri-to-buffer: 6.0.2 + debug: 4.3.6 + fs-extra: 11.2.0 + transitivePeerDependencies: + - supports-color + dev: false + /git-config-path@2.0.0: resolution: {integrity: sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==} engines: {node: '>=4'} @@ -2320,6 +2667,31 @@ packages: is-glob: 4.0.3 dev: false + /glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + dev: false + + /glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.1 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 2.0.0 + dev: false + /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -2470,6 +2842,26 @@ packages: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} dev: false + /http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + dev: false + + /https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + dev: false + /human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -2477,6 +2869,14 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: false + /import-meta-resolve@4.0.0: resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} dev: false @@ -2492,11 +2892,23 @@ packages: /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + /ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + dev: false + /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} dev: false + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: false + /is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} requiresBuild: true @@ -2575,6 +2987,11 @@ packages: engines: {node: '>=12'} dev: false + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2594,9 +3011,30 @@ packages: is-inside-container: 1.0.0 dev: false + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: false + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + /jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + + /jackspeak@4.0.1: + resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} + engines: {node: 20 || >=22} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: false @@ -2620,12 +3058,20 @@ packages: argparse: 2.0.1 dev: false + /jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + dev: false + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true dev: false + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: false + /json-schema-ref-resolver@1.0.1: resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} dependencies: @@ -2646,6 +3092,14 @@ packages: resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} dev: false + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -2660,6 +3114,13 @@ packages: engines: {node: '>=6'} dev: false + /lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + dependencies: + readable-stream: 2.3.8 + dev: false + /license@1.0.3: resolution: {integrity: sha512-M3F6dUcor+vy4znXK5ULfTikeMWxSf/K2w7EUk5vbuZL4UAEN4zOmjh7d2UJ0/v9GYTOz13LNsLqPXJGu+A26w==} hasBin: true @@ -2683,6 +3144,10 @@ packages: set-cookie-parser: 2.6.0 dev: false + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: false + /load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -2714,6 +3179,10 @@ packages: p-locate: 5.0.0 dev: false + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + /log-symbols@5.1.0: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} @@ -2731,6 +3200,15 @@ packages: get-func-name: 2.0.2 dev: true + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + dev: false + + /lru-cache@11.0.0: + resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==} + engines: {node: 20 || >=22} + dev: false + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -2744,6 +3222,11 @@ packages: yallist: 4.0.0 dev: false + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: false + /magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} dependencies: @@ -3174,6 +3657,12 @@ packages: hasBin: true dev: false + /mime@4.0.4: + resolution: {integrity: sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==} + engines: {node: '>=16'} + hasBin: true + dev: false + /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -3189,12 +3678,42 @@ packages: dev: false optional: true + /minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: false + /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} requiresBuild: true dev: false optional: true + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + dev: false + + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: false + /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} requiresBuild: true @@ -3228,6 +3747,11 @@ packages: dev: false optional: true + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: false + /nlcst-to-string@3.1.1: resolution: {integrity: sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==} dependencies: @@ -3275,7 +3799,6 @@ packages: dependencies: wrappy: 1.0.2 dev: false - optional: true /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} @@ -3352,10 +3875,49 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + /pac-proxy-agent@7.0.2: + resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.1 + debug: 4.3.6 + get-uri: 6.0.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + dev: false + + /package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + dev: false + /package-json-type@1.0.3: resolution: {integrity: sha512-Bey4gdRuOwDbS8Fj1qA3/pTq5r8pqiI5E3tjSqCdhaLSsyGG364VFzXLTIexN5AaNGe/vgdBzLfoKdr7EVg2KQ==} dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: false + /parse-git-config@3.0.0: resolution: {integrity: sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==} engines: {node: '>=8'} @@ -3364,6 +3926,16 @@ packages: ini: 1.3.8 dev: true + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.24.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: false + /parse-latin@5.0.1: resolution: {integrity: sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==} dependencies: @@ -3398,6 +3970,22 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: false + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + dev: false + + /path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + dependencies: + lru-cache: 11.0.0 + minipass: 7.1.2 + dev: false + /path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} dev: false @@ -3410,6 +3998,19 @@ packages: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true + /pdf-lib@1.17.1: + resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==} + dependencies: + '@pdf-lib/standard-fonts': 1.0.0 + '@pdf-lib/upng': 1.0.1 + pako: 1.0.11 + tslib: 1.14.1 + dev: false + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: false + /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -3547,6 +4148,10 @@ packages: engines: {node: '>=6'} dev: false + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: false + /process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} dev: false @@ -3556,6 +4161,11 @@ packages: engines: {node: '>= 0.6.0'} dev: false + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: false + /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -3575,6 +4185,26 @@ packages: ipaddr.js: 1.9.1 dev: false + /proxy-agent@6.4.0: + resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.2 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} requiresBuild: true @@ -3582,13 +4212,55 @@ packages: end-of-stream: 1.4.4 once: 1.4.0 dev: false - optional: true /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: false + /puppeteer-core@22.15.0: + resolution: {integrity: sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==} + engines: {node: '>=18'} + dependencies: + '@puppeteer/browsers': 2.3.0 + chromium-bidi: 0.6.3(devtools-protocol@0.0.1312386) + debug: 4.3.6 + devtools-protocol: 0.0.1312386 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /puppeteer-html-pdf@4.0.8(typescript@5.4.5): + resolution: {integrity: sha512-UcNTZ6sdERr0PC9pwjhhkqbXGeBtNSxxfBCc3Cku7U+Z8xNEVLj4TFpq1/oYNknYXBijd8+aORZAQpLEvM5q2w==} + dependencies: + puppeteer: 22.15.0(typescript@5.4.5) + transitivePeerDependencies: + - bufferutil + - supports-color + - typescript + - utf-8-validate + dev: false + + /puppeteer@22.15.0(typescript@5.4.5): + resolution: {integrity: sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + dependencies: + '@puppeteer/browsers': 2.3.0 + cosmiconfig: 9.0.0(typescript@5.4.5) + devtools-protocol: 0.0.1312386 + puppeteer-core: 22.15.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - typescript + - utf-8-validate + dev: false + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: false @@ -3597,7 +4269,6 @@ packages: resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} requiresBuild: true dev: false - optional: true /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -3619,6 +4290,18 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: false + /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3638,6 +4321,12 @@ packages: string_decoder: 1.3.0 dev: false + /readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + dependencies: + minimatch: 5.1.6 + dev: false + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -3751,6 +4440,11 @@ packages: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: false + /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -3847,6 +4541,10 @@ packages: queue-microtask: 1.2.3 dev: false + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -3861,6 +4559,10 @@ packages: engines: {node: '>=10'} dev: false + /sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + dev: false + /section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} @@ -3885,6 +4587,12 @@ packages: lru-cache: 6.0.0 dev: false + /semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + dev: false + /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true @@ -3963,6 +4671,30 @@ packages: /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: false + + /socks-proxy-agent@8.0.4: + resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + dev: false + + /socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + dev: false + /sonic-boom@3.8.1: resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} dependencies: @@ -3973,6 +4705,13 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: false + optional: true + /space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} dev: false @@ -3986,6 +4725,10 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: false + /sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + dev: false + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true @@ -4000,16 +4743,16 @@ packages: dependencies: bl: 5.1.0 - /streamx@2.16.1: - resolution: {integrity: sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==} + /streamx@2.18.0: + resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==} requiresBuild: true dependencies: fast-fifo: 1.3.2 queue-tick: 1.0.1 + text-decoder: 1.1.1 optionalDependencies: - bare-events: 2.2.2 + bare-events: 2.4.2 dev: false - optional: true /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -4045,6 +4788,12 @@ packages: strip-ansi: 7.1.0 dev: false + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: false + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: @@ -4126,11 +4875,21 @@ packages: pump: 3.0.0 tar-stream: 3.1.7 optionalDependencies: - bare-fs: 2.2.3 - bare-path: 2.1.1 + bare-fs: 2.3.1 + bare-path: 2.1.3 dev: false optional: true + /tar-fs@3.0.6: + resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==} + dependencies: + pump: 3.0.0 + tar-stream: 3.1.7 + optionalDependencies: + bare-fs: 2.3.1 + bare-path: 2.1.3 + dev: false + /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} @@ -4150,9 +4909,15 @@ packages: dependencies: b4a: 1.6.6 fast-fifo: 1.3.2 - streamx: 2.16.1 + streamx: 2.18.0 + dev: false + + /text-decoder@1.1.1: + resolution: {integrity: sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==} + requiresBuild: true + dependencies: + b4a: 1.6.6 dev: false - optional: true /thread-stream@2.4.1: resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} @@ -4160,6 +4925,10 @@ packages: real-require: 0.2.0 dev: false + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: false + /tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} dev: true @@ -4212,9 +4981,12 @@ packages: typescript: 5.4.5 dev: false + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: false + /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: true /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -4259,6 +5031,13 @@ packages: resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} dev: true + /unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + dependencies: + buffer: 5.7.1 + through: 2.3.8 + dev: false + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -4384,6 +5163,11 @@ packages: unist-util-visit-parents: 6.0.1 dev: false + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: false + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -4401,6 +5185,10 @@ packages: punycode: 2.3.1 dev: false + /urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -4795,7 +5583,6 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} requiresBuild: true dev: false - optional: true /write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} @@ -4806,11 +5593,31 @@ packages: typedarray-to-buffer: 3.1.5 dev: true + /ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} engines: {node: '>=8'} dev: true + /xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + dependencies: + sax: 1.4.1 + dev: false + /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} dev: true @@ -4868,6 +5675,13 @@ packages: y18n: 5.0.8 yargs-parser: 21.1.1 + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: false + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -4877,6 +5691,15 @@ packages: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} + /zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.5.2 + dev: false + /zod-to-json-schema@3.23.0(zod@3.23.3): resolution: {integrity: sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==} peerDependencies: @@ -4889,6 +5712,10 @@ packages: resolution: {integrity: sha512-tPvq1B/2Yu/dh2uAIH2/BhUlUeLIUvAjr6dpL/75I0pCYefHgjhXk1o1Kob3kTU8C7yU1j396jFHlsVWFi9ogg==} dev: false + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false