diff --git a/.gitignore b/.gitignore index 3978273..07c1495 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,6 @@ dist .pnp.* output/* -!output/.gitkeep \ No newline at end of file +!output/.gitkeep + +testdata/* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f7622f5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM node:latest + +ENV SUT=quiver-to-obsidian-exporter-1.1.0.tgz + +RUN apt-get update && apt-get install -y \ + less \ + && rm -rf /var/lib/apt/lists/* + +COPY testenv/.bashrc /root/.bashrc + +WORKDIR /app + +COPY $SUT /app + +RUN npm install -g /app/$SUT + +CMD ["/bin/bash"] diff --git a/README.md b/README.md index 36d6736..498a650 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,105 @@ -# Quiver Library Markdown exporter to Obsidian +# Export Quiver library to Obsidian markdown files -![npm](https://img.shields.io/npm/v/quiver-markdown-exporter) +![npm](https://img.shields.io/npm/v/quiver-to-obsidian-exporter) -A [Quiver](https://yliansoft.com/) markdown note exporter. I started to use Quiver around 2015 and 2016. But I quickly get back to Evernote. Recently I found [Obsidian](https://obsidian.md/) quite useful and migrated all of my notes to it. So I write this exporter to migrate my notes from Quiver to Obsidian. +The original repository can be found +[here](https://github.com/Yukaii/quiver-markdown-exporter) +This command line tool is built upon the excellent foundation of the original repository. +Thank you! -And my Quiver notes only use a subset of Quiver features, so I can't guarantee that the exported notes are the same as the ones in Quiver. But I hope it's enough for you to get started. +--- -Some working features: +This tool facilitates migration from Quiver to Obsidian. + I've enhanced its features and corrected several bugs, as the original functionality did not fully meet my needs. + + Please note that both the repository name and the command name have been changed for clarity. + +![App Concept Image](app-concept-image.png) +![App Running Image](app-running.png) + +[Quiver](https://yliansoft.com/) +[Obsidian](https://obsidian.md/) -- [Attachments](https://github.com/Yukaii/quiver-obsidian-markdown/blob/c13f42daa8af30268797b3d902ba9f844bc24873/src/quiver-markdown.mts#L24-L29) -- Images, [\[1\]](https://github.com/Yukaii/quiver-obsidian-markdown/blob/c13f42daa8af30268797b3d902ba9f844bc24873/src/quiver-markdown.mts#L32-L46), and [\[2\]](https://github.com/Yukaii/quiver-obsidian-markdown/blob/c13f42daa8af30268797b3d902ba9f844bc24873/src/quiver-markdown.mts#L95-L103A) -- [Diagrams and Markdown/Code block](https://github.com/Yukaii/quiver-obsidian-markdown/blob/c13f42daa8af30268797b3d902ba9f844bc24873/src/quiver-markdown.mts#L117-L120) ## Installation ```bash -npm install -g quiver-markdown-exporter +npm install -g quiver-to-obsidian-exporter ``` ## Usage ```bash Usage - $ quiver-markdown -o + $ qvr2obs -o -a + or + $ qvr2obs -o -a -n Options - --output, -o Output folder + --output, -o: Output folder + --attachmentFolderPolicy, -a: Attachment folder policy (vaultFolder, subfolderUnderVault, sameFolderAsEachFile, subfolderUnderEachFolder). 'subfolderUnderVault' and 'subfolderUnderEachFolder' require subfolder name. + --attachmentSubfolderName, -n: Specify the subfolder name if 'subfolderUnderVault' or 'subfolderUnderEachFolder' is selected as the attachmentFolderPolicy option. Examples - $ quiver-markdown MyLibrary.qvlibrary -o dist + $ qvr2obs MyNote.qvlibrary -o dest/MyNote -a vaultFolder + $ qvr2obs MyNote.qvlibrary -o dest/MyNote -a subfolderUnderVault -n _attachments +``` + + +## Changes from the Original + +### New Features + +* Output maintains the tree structure of the Quiver library (originally output was flat). +* Added support for all four Obsidian attachment folder policies. +* Converts tags, creation and modification times of notebooks into YAML front matter. +* Migrates Quiver notebooks while preserving their timestamps. +* Added a progress bar to display the transformation progress from Quiver to Obsidian. + +### Bug Fixes + +* Fixed an issue where image links in Markdown cells were not rendering in Obsidian. +* Sanitized characters in titles that are not allowed in Obsidian. +* Fixed LaTeX rendering issues to ensure correct display in Obsidian. + +### Minor Changes + +* Changed the timestamp formatter to `YYYY-MM-DD(ddd) HH:mm:ss`. +* Added a check for the existence of the qvlibrary file. +* Displays help text when executed without arguments. + +### For Developers + +* Added debug logging (controlled by the environment variable QUIVER_TO_OBSIDIAN_EXPORTER_LOGGING_VERBOSE). +* Created a Docker environment dedicated to testing. + + +## How to Test (For Developers) + +This testing procedure is designed for testing in a clean environment. +For routine testing, feel free to use your IDE of choice. + +1. Prepare the `testdata` folder: + In the testdata folder, place xxx.qvlibrary in the sources directory, for example, and also provide a destination folder, etc. and use it as the location for the -o option (-o testdata/destination/MyNote) +2. `yarn run build`. +3. `npm pack`. +4. `docker compose up -d --build`. +5. Enter the Docker container: + e.g. + ``` + docker exec -it quiver-to-obsidian-exporter-app-1 /bin/bash + ``` +6. Execute the command: + e.g. + ``` + qvr2obs testdata/source/MyNote.qvlibrary -o testdata/destination/MyNote -a subfolderUnderVault -n _attachments + ``` + +If needed, enable verbose logging for debugging: ``` +export QUIVER_TO_OBSIDIAN_EXPORTER_LOGGING_VERBOSE=true +``` + ## Contributing diff --git a/app-concept-image.png b/app-concept-image.png new file mode 100644 index 0000000..6657821 Binary files /dev/null and b/app-concept-image.png differ diff --git a/app-running.png b/app-running.png new file mode 100644 index 0000000..dc70dc0 Binary files /dev/null and b/app-running.png differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f157dd3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + app: + image: quiver-to-obsidian-exporter + build: + context: . + dockerfile: Dockerfile + volumes: + - ./testdata:/app/testdata + command: tail -f /dev/null diff --git a/package.json b/package.json index 3a7b664..66ff944 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,44 @@ { - "name": "quiver-markdown-exporter", - "version": "1.0.1", + "name": "quiver-to-obsidian-exporter", + "version": "1.1.0", "description": "Export Quiver library to Obsidian markdown files", + "repository": { + "type": "git", + "url": "https://github.com/blue-monk/quiver-to-obsidian-exporter" + }, + "homepage": "https://github.com/blue-monk/quiver-to-obsidian-exporter", "main": "dist/index.mjs", "files": [ "dist" ], "type": "module", "bin": { - "quiver-markdown": "dist/index.mjs" + "qvr2obs": "dist/index.mjs" + }, + "engines": { + "node": ">=21.7.3" }, "scripts": { - "build": "tsc", + "build": "rm -rf ./dist && tsc", "prepublishOnly": "npm run build" }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "devDependencies": { - "@types/node": "^17.0.32", - "@types/turndown": "^5.0.1", - "ts-node": "^10.7.0", - "typescript": "^4.8.0-dev.20220512" + "@types/node": "^20.12.7", + "@types/turndown": "^5.0.4", + "ts-node": "^10.9.2", + "typescript": "^5.4.5" }, "dependencies": { - "fast-glob": "^3.2.11", - "fs-extra": "^10.1.0", - "meow": "^10.1.2", - "turndown": "^7.1.1" + "chalk": "^5.3.0", + "cli-progress": "^3.12.0", + "dayjs": "^1.11.10", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "meow": "^13.2.0", + "turndown": "^7.1.3", + "utimes": "^5.2.1" } } diff --git a/src/assertions.mts b/src/assertions.mts new file mode 100644 index 0000000..7daabbc --- /dev/null +++ b/src/assertions.mts @@ -0,0 +1,20 @@ +import fs from "fs-extra"; + +import { getLogger } from './logger.mjs'; + + +const logger = getLogger(); + + +export function assertValidQvlibraryPath(qvlibraryPath: string) { + + if (!fs.existsSync(qvlibraryPath)) { + logger.error(`The specified qvlibraryPath does not exist. [qvlibraryPath=${qvlibraryPath}]`); + process.exit(2); + } + + if (!fs.statSync(qvlibraryPath).isDirectory()) { + logger.error(`The specified qvlibraryPath is not a directory. [qvlibraryPath=${qvlibraryPath}]`); + process.exit(2); + } +} diff --git a/src/extensions/String+Path.mts b/src/extensions/String+Path.mts new file mode 100644 index 0000000..743c403 --- /dev/null +++ b/src/extensions/String+Path.mts @@ -0,0 +1,18 @@ + + +declare global { + interface String { + lastPathComponent(): string; + } +} + + +if (!String.prototype.lastPathComponent) { + String.prototype.lastPathComponent = function () { + + const pathComponents = this.split('/'); + return pathComponents[pathComponents.length - 1]; + }; +} + +export {}; diff --git a/src/index.mts b/src/index.mts index 201694a..c7c06f1 100644 --- a/src/index.mts +++ b/src/index.mts @@ -1,34 +1,107 @@ #!/usr/bin/env node import meow from 'meow'; -import { convert } from './quiver-markdown.mjs'; -const cli = meow(` - Usage - $ quiver-markdown -o +import { getLogger } from './logger.mjs'; +import { assertValidQvlibraryPath } from './assertions.mjs'; +import { exportQvlibrary } from './quiver-to-obsidian-exporter.mjs'; +import { AttachmentFolderPolicy, createAttachmentFolderPolicyWithSubfolder, createAttachmentFolderPolicyWithoutSubfolder } from './migration-support/attachment-folder-treatment.mjs'; - Options - --output, -o Output folder - Examples - $ quiver-markdown MyLibrary.qvlibrary -o dist -`, { +const logger = getLogger(); + + +const helpText = ` +Usage + $ qvr2obs -o -a + or + $ qvr2obs -o -a -n + +Options + --output, -o: Output folder + --attachmentFolderPolicy, -a: Attachment folder policy (vaultFolder, subfolderUnderVault, sameFolderAsEachFile, subfolderUnderEachFolder). 'subfolderUnderVault' and 'subfolderUnderEachFolder' require subfolder name. + --attachmentSubfolderName, -n: Specify the subfolder name if 'subfolderUnderVault' or 'subfolderUnderEachFolder' is selected as the attachmentFolderPolicy option. + +Examples + $ qvr2obs MyNote.qvlibrary -o dest/MyNote -a vaultFolder + $ qvr2obs MyNote.qvlibrary -o dest/MyNote -a subfolderUnderVault -n _attachments +` + + +const args = process.argv.slice(2) +if (args.length === 0) { + meow(helpText, { importMeta: import.meta }).showHelp(); +} + +const cli = meow(helpText, { importMeta: import.meta, flags: { output: { type: 'string', - alias: 'o', + shortFlag: 'o', + isRequired: true, + }, + attachmentFolderPolicy: { + type: 'string', + choices: ['vaultFolder', 'subfolderUnderVault', 'sameFolderAsEachFile', 'subfolderUnderEachFolder'], + shortFlag: 'a', + isRequired: true, + }, + attachmentSubfolderName: { + type: 'string', + shortFlag: 'n', + isRequired: (flags, input) => { + return (flags.attachmentFolderPolicy as string)?.startsWith('subfolder'); + }, }, }, }); if (cli.input.length < 1) { - console.error('Please provide a qvlibrary file'); - process.exit(1); + logger.error('Please provide a qvlibrary file'); + cli.showHelp(); } if (!cli.flags.output) { - console.error('Please provide an output folder'); - process.exit(1); + logger.error('Please provide an output folder'); + cli.showHelp(); } -convert(cli.input[0], cli.flags.output); +if (cli.flags.attachmentFolderPolicy.startsWith('subfolder')) { + if (!cli.flags.attachmentSubfolderName) { + logger.error(`Please provide an Attachment subfolder name with -n option (Because you specified '${cli.flags.attachmentFolderPolicy}' with -i)`); + cli.showHelp(); + } +} +else { + if (cli.flags.attachmentSubfolderName) { + logger.error(`It is not necessary to specify Attachment subfolder name (Because you specified '${cli.flags.attachmentFolderPolicy}' with -i) (or is it a mistake in specifying attachmentFolderPolicy?)`); + cli.showHelp(); + } +} + + + +const qvlibraryPath = cli.input[0] +assertValidQvlibraryPath(qvlibraryPath); + +const outputPath = cli.flags.output + +const attachmentFolderPolicy = createAttachmentFolderPolicy(cli.flags.attachmentFolderPolicy, cli.flags.attachmentSubfolderName) +logger.info(`AttachmentFolderPolicy: { attachmentFolderPolicy=${cli.flags.attachmentFolderPolicy}, attachmentSubfolderName=${cli.flags.attachmentSubfolderName} }`); + +exportQvlibrary(qvlibraryPath, outputPath, attachmentFolderPolicy); + + +function createAttachmentFolderPolicy(policyType: string, subfolderName: string): AttachmentFolderPolicy { + + switch (policyType) { + case 'vaultFolder': + case 'sameFolderAsEachFile': + return createAttachmentFolderPolicyWithoutSubfolder(policyType); + case 'subfolderUnderVault': + case 'subfolderUnderEachFolder': + return createAttachmentFolderPolicyWithSubfolder(policyType, subfolderName); + default: + throw new Error(`Unknown policy type: ${policyType}`); + } +} diff --git a/src/logger.mts b/src/logger.mts new file mode 100644 index 0000000..3811ed5 --- /dev/null +++ b/src/logger.mts @@ -0,0 +1,68 @@ +import { parseBoolean } from './util/environment-variable-parser.mjs' + + +const isVerbose = parseBoolean(process.env.QUIVER_TO_OBSIDIAN_EXPORTER_LOGGING_VERBOSE); + + +type LogConfig = { + isVerbose: boolean; + toString(): string; +}; + +const logConfig: LogConfig = { + isVerbose: isVerbose, + toString: function() { + return `LogConfig: { isVerbose: ${this.isVerbose} }`; + } +}; + + +const createLogger = (config: LogConfig) => { + + if (config.isVerbose) { + console.log(`LogConfig=${config.toString()}`) + } + + return { + + error: (message: string) => console.error(message), + forceInfo: (message: string) => console.info(message), + + info: (message: string) => { + if (!config.isVerbose) return; + console.info(message) + }, + + debug: (message: string) => { + if (!config.isVerbose) return; + console.debug(message) + }, + + debugNotebookPathsByUUID: (notebookPathsByUUID: Map) => { + if (!config.isVerbose) return; + debugNotebookPathsByUUID(notebookPathsByUUID); + }, + + completed: () => { + console.info('') + console.info("🎉 The export of the Quiver library to the Obsidian Vault has been completed successfully.") + }, + }; +}; + + +const debugNotebookPathsByUUID = (notebookPathsByUUID: Map) => { + + console.debug(`==== contents of notebookPathsByUUID ====`); + notebookPathsByUUID.forEach((value, key) => { + console.debug(`Key: ${key}, Value: ${value}`); + }); +} + + +let loggerInstance = createLogger(logConfig); + +export const getLogger = () => { + return loggerInstance; +}; + diff --git a/src/migration-support/attachment-folder-treatment.mts b/src/migration-support/attachment-folder-treatment.mts new file mode 100644 index 0000000..eb2b316 --- /dev/null +++ b/src/migration-support/attachment-folder-treatment.mts @@ -0,0 +1,54 @@ +import pathlib from 'path' + + +const AttachmentFolderPolicyTypes = { + vaultFolder: "vaultFolder", + subfolderUnderVault: "subfolderUnderVault", + sameFolderAsEachFile: "sameFolderAsEachFile", + subfolderUnderEachFolder: "subfolderUnderEachFolder", +} as const; + +export type AttachmentFolderPolicy = + | { type: typeof AttachmentFolderPolicyTypes.vaultFolder } + | { + type: typeof AttachmentFolderPolicyTypes.subfolderUnderVault; + subfolderName: string; + } + | { type: typeof AttachmentFolderPolicyTypes.sameFolderAsEachFile } + | { + type: typeof AttachmentFolderPolicyTypes.subfolderUnderEachFolder; + subfolderName: string; + }; + + +export function createAttachmentFolderPolicyWithSubfolder( + type: + | typeof AttachmentFolderPolicyTypes.subfolderUnderVault + | typeof AttachmentFolderPolicyTypes.subfolderUnderEachFolder, + subfolderName: string +): AttachmentFolderPolicy { + return { type, subfolderName }; +} + +export function createAttachmentFolderPolicyWithoutSubfolder( + type: + | typeof AttachmentFolderPolicyTypes.vaultFolder + | typeof AttachmentFolderPolicyTypes.sameFolderAsEachFile +): AttachmentFolderPolicy { + return { type }; +} + + +export function calculateAttachmentFolderPath(rootPath: string, currentFolderPath: string, attachmentFolderPolicy: AttachmentFolderPolicy): string { + + switch (attachmentFolderPolicy.type) { + case AttachmentFolderPolicyTypes.vaultFolder: + return rootPath; + case AttachmentFolderPolicyTypes.subfolderUnderVault: + return pathlib.join(rootPath, attachmentFolderPolicy.subfolderName); + case AttachmentFolderPolicyTypes.sameFolderAsEachFile: + return currentFolderPath; + case AttachmentFolderPolicyTypes.subfolderUnderEachFolder: + return pathlib.join(currentFolderPath, attachmentFolderPolicy.subfolderName); + } +} diff --git a/src/migration-support/file-timestamp-cloner.mts b/src/migration-support/file-timestamp-cloner.mts new file mode 100644 index 0000000..9d8e769 --- /dev/null +++ b/src/migration-support/file-timestamp-cloner.mts @@ -0,0 +1,28 @@ +import { utimes } from 'utimes'; + +import { getLogger } from '../logger.mjs'; + + +const logger = getLogger(); + + +export function cloneTimestamp(fileName: string, quiverMeta: any) { + + try { + utimes(fileName, { + btime: Number(quiverMeta.created_at * 1000), + mtime: Number(quiverMeta.updated_at * 1000), + atime: Number(quiverMeta.updated_at * 1000), + }, function (err) { + if (err) { + logger.error(`Error occurred while updating the file timestamp. [err=${err}, file=${fileName}]`); + } else { + logger.debug(`The timestamp of the file has been updated successfully.`); + // logger.debug(`The timestamp of the file [${fileName}] has been updated successfully.`); + } + }); + } + catch (error) { + logger.error(error); + } +} diff --git a/src/quiver-markdown.mts b/src/quiver-markdown.mts deleted file mode 100644 index 57bb512..0000000 --- a/src/quiver-markdown.mts +++ /dev/null @@ -1,136 +0,0 @@ -import fg from 'fast-glob' -import fs from 'fs-extra' -import path from 'path' -import Turndown from 'turndown' - -let TurndownService: Turndown - -export function convert (qvlibrary: string, outputPath: string) { - const glob = path.join(qvlibrary, '*.qvnotebook') - const noteBooks = fg.sync(glob, { onlyDirectories: true }) - - TurndownService = new Turndown() - - // extend turndown link rule to replace quiver-file-url - TurndownService.addRule('quiver-file-url', { - filter: function (node, options) { - return ( - options.linkStyle === 'inlined' && - node.nodeName === 'A' && - node.getAttribute('href') && - node.getAttribute('href').startsWith('quiver-file-url/') - ) - }, - replacement: function (content, node: HTMLAnchorElement, options) { - const href = node.getAttribute('href') - const fileName = href.replace('quiver-file-url/', '') - - return `[[${fileName}]]` - } - }) - - TurndownService.addRule('quiver-file-url-image', { - filter: function (node, options) { - return ( - node.nodeName === 'IMG' && - node.getAttribute('src') && - node.getAttribute('src').startsWith('quiver-image-url/') - ) - }, - replacement: function (content, node: HTMLImageElement, options) { - const src = node.getAttribute('src') - const fileName = src.replace('quiver-image-url/', '') - - return `![[${fileName}]]` - } - }) - - for (const notebook of noteBooks) { - convertNotebook(notebook, outputPath) - } -} - - -export function convertNotebook (notebook: string, outputPath: string) { - const notebookMeta = JSON.parse(fs.readFileSync(path.join(notebook, 'meta.json'), 'utf8')) - - const glob = path.join(notebook, '*.qvnote') - const notes = fg.sync(glob, { onlyDirectories: true }) - - const notebookOutputPath = path.join(outputPath, notebookMeta.name) - const notebookResourcePath = path.join(notebookOutputPath, `./_resources`) - - fs.ensureDirSync(notebookOutputPath) - fs.ensureDirSync(notebookResourcePath) - - for (const note of notes) { - const { title, content } = convertNoteToMarkdown(note) - - const fileName = path.join(notebookOutputPath, `${title}.md`) - try { - fs.writeFileSync(fileName, content) - - const notebookResourceDir = path.join(note, 'resources') - if (fs.pathExistsSync(notebookResourceDir)) { - // copy every file under resources to notebook resource dir - const files = fg.sync(path.join(notebookResourceDir, '**/*')) - for (const file of files) { - const fileName = path.basename(file) - const dest = path.join(notebookResourcePath, fileName) - fs.copySync(file, dest) - } - } - } catch (e) { - console.error(e) - console.error(`Invalid file name ${fileName}`) - } - } -} - -const formatTime = (timestamp: number) => { - const date = new Date(timestamp) - return date.toLocaleString() -} - -function processMarkdownImage (markdown: string) { - return markdown.replaceAll(/(?:__|[*#])|\[(.*?)\]\((.*?)\)/g, (match, p1, p2) => { - if (p2?.startsWith('quiver-image-url/')) { - return `[[${p2.replace('quiver-image-url/', '')}]]` - } else { - return match - } - }) -} - -export function convertNoteToMarkdown (note: string): { title: string, content: string } { - const meta = JSON.parse(fs.readFileSync(path.join(note, 'meta.json'), 'utf8')) - const content = JSON.parse(fs.readFileSync(path.join(note, 'content.json'), 'utf8')) - - const tags = meta.tags.length > 0 ? meta.tags.map(t => `#${t}`).join(' ') + '\n\n' : '' - - const cellsToMarkdown = content.cells.map(cell => { - switch(cell.type) { - case 'text': - return TurndownService.turndown(cell.data) - case 'code': - return `\`\`\`${cell.language}\n${cell.data}\n\`\`\`` - case 'markdown': - return processMarkdownImage(cell.data) - case 'diagram': - return `\`\`\`${cell.diagramType}\n${cell.data}\n\`\`\`` - case 'latex': - return `$$\n${cell.data}\n$$` - default: - throw new Error(`Unknown cell type: ${cell.type}`) - } - }).join('\n\n') - - return { - title: meta.title, - content: `${tags}${cellsToMarkdown} - - Created At: ${formatTime(meta.created_at * 1000)} - Updated At: ${formatTime(meta.updated_at * 1000)} - ` - } -} diff --git a/src/quiver-to-obsidian-exporter.mts b/src/quiver-to-obsidian-exporter.mts new file mode 100644 index 0000000..06c5d64 --- /dev/null +++ b/src/quiver-to-obsidian-exporter.mts @@ -0,0 +1,173 @@ +import fg from 'fast-glob' +import fs from 'fs-extra' +import pathModule from 'path' +import * as cliProgress from 'cli-progress' +import chalk from 'chalk' + +import { getLogger } from './logger.mjs'; +import './extensions/String+Path.mjs'; +import { transformQuiverNoteToObsidian } from './quiver-to-obsidian-transform.mjs' +import { cloneTimestamp } from './migration-support/file-timestamp-cloner.mjs'; +import { AttachmentFolderPolicy, calculateAttachmentFolderPath } from './migration-support/attachment-folder-treatment.mjs' + + +const logger = getLogger(); + +const progressBar = new cliProgress.SingleBar({ + format: `${chalk.green('{bar}')} | ${chalk.hex('#00BFFF')('{percentage}%')} || ${chalk.yellow('{value}/{total}')} Notebooks || Duration: ${chalk.cyan('{duration_formatted}')}`, + barCompleteChar: '\u2588', // completely filled rectangle + barIncompleteChar: '\u2591', // thin rectangle + hideCursor: true +}, cliProgress.Presets.shades_classic); + +const Keys = { + children: 'children', +} as const; + + +export function exportQvlibrary(qvlibrary: string, outputPath: string, attachmentFolderPolicy: AttachmentFolderPolicy) { + + const glob = pathModule.join(qvlibrary, '*.qvnotebook') + const quiverNoteBooks = fg.sync(glob, { onlyDirectories: true }) + + logger.forceInfo('==> retrieving the qvnotebooks info under the qvlibrary.'); + const notebookPathsByUUID = quiverNoteBooks.reduce((acc: Map, path: string): Map => { + const fileName = path.lastPathComponent(); + const uuid = fileName.split('.')[0]; + return acc.set(uuid, path); + }, new Map()); + + logger.debugNotebookPathsByUUID(notebookPathsByUUID) + + logger.forceInfo(`==> processing the default fixed notebooks 'Inbox' and 'Trash' in Quiver.`); + ['Inbox', 'Trash'].forEach((fixedName: string) => { + const notebookPath = notebookPathsByUUID.get(fixedName); + convertNotebook(notebookPath, outputPath, [fixedName], attachmentFolderPolicy); + }); + + logger.forceInfo('==> retrieving the root meta.json, which stores the tree structure.'); + const treeMetaPath = pathModule.join(qvlibrary, 'meta.json'); + const treeMetaText = fs.readFileSync(treeMetaPath, 'utf8').toString(); + const treeMeta = JSON.parse(treeMetaText); + + const totalFileCount = totalNumberOfFile(treeMeta, notebookPathsByUUID); + logger.info(`totalFileCount=${totalFileCount}`); + + logger.forceInfo('==> traversing the folder tree structure to convert Quiver notebooks into Obsidian .md files.'); + progressBar.start(totalFileCount, 0); + const rootChildren = treeMeta[Keys.children]; + traverseFolderTree(rootChildren, 0, [], outputPath, notebookPathsByUUID, attachmentFolderPolicy); + + logger.info('==> Traversal of the folder tree structure has been completed.'); + progressBar.stop(); + logger.completed(); +} + +function totalNumberOfFile(treeMeta: any, notebooksByUUID: Map): number { + + const rootChildren = treeMeta[Keys.children]; + + return traverse(rootChildren, notebooksByUUID, 0); + + function traverse(children: [], notebooksByUUID: Map, fileCount: number): number { + + if (children === undefined) { return fileCount; } + + children.forEach((node) => { + + const uuid = node['uuid']; + + const notebookPath = notebooksByUUID.get(uuid); + if (notebookPath === undefined) { + return; + } + + fileCount++; + const notebookMeta = JSON.parse(fs.readFileSync(pathModule.join(notebookPath, 'meta.json'), 'utf8')); + fileCount = traverse(node[Keys.children], notebooksByUUID, fileCount); + }) + + return fileCount; + } +} + +function traverseFolderTree(children: [], depth: number, pathStack: string[], outputPath: string, notebooksByUUID: Map, attachmentFolderPolicy: AttachmentFolderPolicy) { + + logger.debug(" ".repeat(depth * 4) + 'traverseFolderTree called...'); + if (children === undefined) { return; } + + children.forEach((node) => { + + const uuid = node['uuid']; + logger.info(" ".repeat(depth * 4) + uuid); + + const notebookPath = notebooksByUUID.get(uuid); + if (notebookPath === undefined) { + return; + } + + logger.debug('==> retrieving the qvnotebook meta.json.'); + const notebookMeta = JSON.parse(fs.readFileSync(pathModule.join(notebookPath, 'meta.json'), 'utf8')); + + pathStack.push(notebookMeta.name); + progressBar.increment(); + convertNotebook(notebookPath, outputPath, pathStack, attachmentFolderPolicy); + traverseFolderTree(node[Keys.children], depth + 1, pathStack, outputPath, notebooksByUUID, attachmentFolderPolicy); + pathStack.pop(); + }) +} + +export function convertNotebook(quiverNotebook: string, outputPath: string, pathStack: string[], attachmentFolderPolicy: AttachmentFolderPolicy) { + + const glob = pathModule.join(quiverNotebook, '*.qvnote') + const quiverNotePaths = fg.sync(glob, { onlyDirectories: true }) + + const obsidianNoteDirPath = pathModule.join(outputPath, ...pathStack) + const obsidianAttachmentFolderPath = calculateAttachmentFolderPath(outputPath, obsidianNoteDirPath, attachmentFolderPolicy) + + for (const quiverNotePath of quiverNotePaths) { + const { title, content, quiverMeta } = transformQuiverNoteToObsidian(quiverNotePath) + outputNoteAndCopyResources({ quiverNotePath, quiverMeta }, { obsidianNoteDirPath, title, content, obsidianAttachmentFolderPath }) + } +} + +function outputNoteAndCopyResources(srcInfo: any, destInfo: any) { + + const { quiverNotePath, quiverMeta } = srcInfo + const { obsidianNoteDirPath, title, content, obsidianAttachmentFolderPath } = destInfo + + fs.ensureDirSync(obsidianNoteDirPath) + fs.ensureDirSync(obsidianAttachmentFolderPath) + + const destFilePath = pathModule.join(obsidianNoteDirPath, `${title}.md`) + + try { + fs.writeFileSync(destFilePath, content) + copyResources(quiverNotePath, obsidianAttachmentFolderPath) + } + catch (e) { + console.error(e) + console.error(`Invalid file name ${destFilePath}`) + } + + cloneTimestamp(destFilePath, quiverMeta); +} + +function copyResources(quiverNotePath: string, obsidianAttachmentFolderPath: string) { + + const notebookResourceDir = pathModule.join(quiverNotePath, 'resources') + + if (!fs.pathExistsSync(notebookResourceDir)) { + return + } + + // copy every file under resources to notebook resource dir + const files = fg.sync(pathModule.join(notebookResourceDir, '**/*')) + + for (const file of files) { + const fileName = pathModule.basename(file) + const dest = pathModule.join(obsidianAttachmentFolderPath, fileName) + fs.copySync(file, dest) + } +} + diff --git a/src/quiver-to-obsidian-transform.mts b/src/quiver-to-obsidian-transform.mts new file mode 100644 index 0000000..e94be3a --- /dev/null +++ b/src/quiver-to-obsidian-transform.mts @@ -0,0 +1,59 @@ +import fs from "fs-extra"; +import pathModule from "path"; + +import TurndownService from "./transform/turndown-service.mjs"; +import { formatTimestamp } from './transform/formatter.mjs'; +import { transformImageLinkOnMarkdown } from './transform/image-link-transform.mjs'; +import { sanitizeTitle } from './transform/title-sanitizer.mjs' + + +export function transformQuiverNoteToObsidian(quiverNotePath: string): { title: string; content: string; quiverMeta: any; } { + + const quiverMeta = JSON.parse(fs.readFileSync(pathModule.join(quiverNotePath, 'meta.json'), 'utf8')) + const quiverContent = JSON.parse(fs.readFileSync(pathModule.join(quiverNotePath, 'content.json'), 'utf8')) + + const transformedContent = quiverContent.cells.map(cell => { + switch (cell.type) { + case 'text': + return TurndownService.turndown(cell.data) + case 'code': + return `\`\`\`${cell.language}\n${cell.data}\n\`\`\`` + case 'markdown': + return transformImageLinkOnMarkdown(cell.data) + case 'diagram': + return `\`\`\`${cell.diagramType}\n${cell.data}\n\`\`\`` + case 'latex': + return `${cell.data}` + default: + throw new Error(`Unknown cell type: ${cell.type}`) + } + }).join('\n\n') + + return { + title: sanitizeTitle(quiverMeta.title), + content: makeObsidianContent(quiverMeta, transformedContent), + quiverMeta: quiverMeta, + } +} + +function makeObsidianContent(quiverMeta: any, transformedContent: any): string { + + const tags = quiverMeta.tags.length > 0 ? quiverMeta.tags.map((tag: string) => ` - ${tag}`).join('\n') : ''; + + return `${makeYamlFrontMatter(tags, quiverMeta)} + +${transformedContent} +`; +} + +function makeYamlFrontMatter(tags: string, quiverMeta: any): string { + + return `--- +tags: +${tags} +origin: Quiver +created-at: ${formatTimestamp(quiverMeta.created_at * 1000)} +updated-at: ${formatTimestamp(quiverMeta.updated_at * 1000)} +--- +`; +} diff --git a/src/transform/formatter.mts b/src/transform/formatter.mts new file mode 100644 index 0000000..2849ba4 --- /dev/null +++ b/src/transform/formatter.mts @@ -0,0 +1,8 @@ +import dayjs from "dayjs"; + + +export const formatTimestamp = (timestamp: number) => { + + return dayjs(timestamp) + .format('YYYY-MM-DD(ddd) HH:mm:ss') +} diff --git a/src/transform/image-link-transform.mts b/src/transform/image-link-transform.mts new file mode 100644 index 0000000..13cf4ec --- /dev/null +++ b/src/transform/image-link-transform.mts @@ -0,0 +1,12 @@ + + +export function transformImageLinkOnMarkdown(markdown: string) { + + return markdown.replaceAll(/(?:__|[*#])|\[(.*?)\]\((.*?)\)/g, (match, p1, p2) => { + if (p2?.startsWith('quiver-image-url/')) { + return `[[${p2.replace('quiver-image-url/', '').replace(/ *=(\d+x\d+)$/, '|$1')}]]`; + } else { + return match + } + }) +} diff --git a/src/transform/title-sanitizer.mts b/src/transform/title-sanitizer.mts new file mode 100644 index 0000000..cd6ee22 --- /dev/null +++ b/src/transform/title-sanitizer.mts @@ -0,0 +1,39 @@ + + +/** + * Sanitizes input string for use as an Obsidian note title. + * + * Removes or replaces characters that are not allowed in Obsidian titles. + * The following characters are not allowed in Obsidian titles: + * `/`, `:`, `\`, `#`, `^`, `[`, `]`, `|` + * + * @param title The original title string to be sanitized. + * @returns The sanitized title string. + */ +export function sanitizeTitle(title: string): string { + + return [ + [/\//g, "/"], + [/:/g, ":"], + [/\\/g, "¥"], + [/#/g, "#"], + [/\^/g, "~"], + [/\[/g, "["], + [/]/g, "]"], + [/\|/g, "|"], + ].reduce((title: string, pair: [RegExp, string]): string => { + return title.replace(pair[0], pair[1]); + }, sanitizeTime(sanitizeDate(title))); +} + +function sanitizeDate(title: string): string { + + const regExp = /(\d{4})\/(\d{2})\/(\d{2})/g; + return title.replace(regExp, "$1-$2-$3"); +} + +function sanitizeTime(title: string): string { + + const regExp = /(\d{2}):(\d{2}):(\d{2})/g; + return title.replace(regExp, "$1:$2:$3"); +} diff --git a/src/transform/turndown-service.mts b/src/transform/turndown-service.mts new file mode 100644 index 0000000..55a6ed3 --- /dev/null +++ b/src/transform/turndown-service.mts @@ -0,0 +1,40 @@ +import Turndown from 'turndown' + + +const TurndownService: Turndown = new Turndown() + +// extend turndown link rule to replace quiver-file-url +TurndownService.addRule('quiver-file-url', { + filter: function (node, options) { + return ( + options.linkStyle === 'inlined' && + node.nodeName === 'A' && + node.getAttribute('href') && + node.getAttribute('href').startsWith('quiver-file-url/') + ) + }, + replacement: function (content, node: HTMLAnchorElement, options) { + const href = node.getAttribute('href') + const fileName = href.replace('quiver-file-url/', '') + + return `[[${fileName}]]` + } +}) + +TurndownService.addRule('quiver-file-url-image', { + filter: function (node, options) { + return ( + node.nodeName === 'IMG' && + node.getAttribute('src') && + node.getAttribute('src').startsWith('quiver-image-url/') + ) + }, + replacement: function (content, node: HTMLImageElement, options) { + const src = node.getAttribute('src') + const fileName = src.replace('quiver-image-url/', '') + + return `![[${fileName}]]` + } +}) + +export default TurndownService diff --git a/src/util/environment-variable-parser.mts b/src/util/environment-variable-parser.mts new file mode 100644 index 0000000..b00a7a4 --- /dev/null +++ b/src/util/environment-variable-parser.mts @@ -0,0 +1,9 @@ + + +export function parseBoolean(envValue: string | undefined): boolean { + + if (!envValue) return false; + + const normalizedValue = envValue.toLowerCase(); + return normalizedValue === 'true' || normalizedValue === 'yes' || /^[1-9]\d*$/.test(normalizedValue); +} diff --git a/testenv/.bashrc b/testenv/.bashrc new file mode 100644 index 0000000..8299883 --- /dev/null +++ b/testenv/.bashrc @@ -0,0 +1,9 @@ +# .bashrc + +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi + +alias ll='ls -l --color=auto' +alias lla='ls -la --color=auto' +alias datef="date '+%Y-%m-%d %H:%M:%S'" diff --git a/tsconfig.json b/tsconfig.json index 93ae9cd..a6fc68f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { "outDir": "dist", - "module": "esnext", + "module": "NodeNext", "target": "ES2020", "esModuleInterop": true, - "moduleResolution": "Node", + "moduleResolution": "NodeNext", "lib": [ "ESNext", "DOM" diff --git a/yarn.lock b/yarn.lock index 052c05e..5e7cc5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,38 +2,45 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== - dependencies: - "@cspotcode/source-map-consumer" "0.8.0" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@mapbox/node-pre-gyp@^1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" + integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -76,25 +83,22 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== -"@types/minimist@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - -"@types/node@^17.0.32": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.32.tgz#51d59d7a90ef2d0ae961791e0900cad2393a0149" - integrity sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw== +"@types/node@^20.12.7": + version "20.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.7.tgz#04080362fa3dd6c5822061aa3124f5c152cff384" + integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== + dependencies: + undici-types "~5.26.4" -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/turndown@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/turndown/-/turndown-5.0.4.tgz#61fcdda2e539a86b1d40cb3277505f22ca76f014" + integrity sha512-28GI33lCCkU4SGH1GvjDhFgOVr+Tym4PXGBIU1buJUa6xQolniPArtUT+kv42RR2N9MsMLInkr904Aq+ESHBJg== -"@types/turndown@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/turndown/-/turndown-5.0.1.tgz#fcda7b02cda4c9d445be1440036df20f335b9387" - integrity sha512-N8Ad4e3oJxh9n9BiZx9cbe/0M3kqDpOTm2wzj13wdDUxDPjfjloWIJaquZzWE1cYTAHpjOH3rcTnXQdpEfS/SQ== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== acorn-walk@^8.1.1: version "8.2.0" @@ -106,22 +110,48 @@ acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== dependencies: - color-convert "^1.9.0" + delegates "^1.0.0" + readable-stream "^3.6.0" arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" braces@^3.0.2: version "3.0.2" @@ -130,64 +160,64 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -camelcase-keys@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-7.0.2.tgz#d048d8c69448745bb0de6fc4c1c52a30dfbe7252" - integrity sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg== - dependencies: - camelcase "^6.3.0" - map-obj "^4.1.0" - quick-lru "^5.1.1" - type-fest "^1.2.1" - -camelcase@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== +cli-progress@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.12.0.tgz#807ee14b66bcc086258e444ad0f19e7d42577942" + integrity sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A== dependencies: - color-name "1.1.3" + string-width "^4.2.3" -color-name@1.1.3: +color-support@^1.1.2: version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -decamelize-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= +dayjs@^1.11.10: + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== + +debug@4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" + ms "2.1.2" -decamelize@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -decamelize@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9" - integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA== +detect-libc@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== diff@^4.0.1: version "4.0.2" @@ -199,22 +229,15 @@ domino@^2.1.6: resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe" integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ== -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -fast-glob@^3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -236,27 +259,41 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== +fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" glob-parent@^5.1.2: version "5.1.2" @@ -265,57 +302,59 @@ glob-parent@^5.1.2: dependencies: is-glob "^4.0.1" +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: - function-bind "^1.1.1" + agent-base "6" + debug "4" -hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: - lru-cache "^6.0.0" - -indent-string@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" - integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + once "^1.3.0" + wrappy "1" -is-core-module@^2.5.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== - dependencies: - has "^1.0.3" +inherits@2, inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-glob@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -328,21 +367,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -352,23 +376,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -376,38 +383,22 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-obj@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -meow@^10.1.2: - version "10.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-10.1.2.tgz#62951cb69afa69594142c8250806bc30a3912e4d" - integrity sha512-zbuAlN+V/sXlbGchNS9WTWjUzeamwMt/BApKCJi7B0QyZstZaMx0n4Unll/fg0njGtMdC9UP5SAscvOCLYdM+Q== - dependencies: - "@types/minimist" "^1.2.2" - camelcase-keys "^7.0.0" - decamelize "^5.0.0" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.2" - read-pkg-up "^8.0.0" - redent "^4.0.0" - trim-newlines "^4.0.2" - type-fest "^1.2.2" - yargs-parser "^20.2.9" +meow@^13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f" + integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA== merge2@^1.3.0: version "1.4.1" @@ -422,58 +413,88 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" -min-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== +minipass@^3.0.0: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" + yallist "^4.0.0" + +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -normalize-package-data@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" + minipass "^3.0.0" + yallist "^4.0.0" -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + +node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: - yocto-queue "^0.1.0" + whatwg-url "^5.0.0" -p-locate@^5.0.0: +nopt@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== dependencies: - p-limit "^3.0.2" + abbrev "1" -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== picomatch@^2.3.1: version "2.3.1" @@ -485,43 +506,27 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -read-pkg-up@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-8.0.0.tgz#72f595b65e66110f43b052dd9af4de6b10534670" - integrity sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ== - dependencies: - find-up "^5.0.0" - read-pkg "^6.0.0" - type-fest "^1.0.1" - -read-pkg@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-6.0.0.tgz#a67a7d6a1c2b0c3cd6aa2ea521f40c458a4a504c" - integrity sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q== +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^3.0.2" - parse-json "^5.2.0" - type-fest "^1.0.1" - -redent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-4.0.0.tgz#0c0ba7caabb24257ab3bb7a4fd95dd1d5c5681f9" - integrity sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag== - dependencies: - indent-string "^5.0.0" - strip-indent "^4.0.0" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -529,52 +534,67 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -semver@^7.3.4: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== +semver@^6.0.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== - -strip-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" - integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== +semver@^7.3.5: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: - min-indent "^1.0.1" + lru-cache "^6.0.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +tar@^6.1.11: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" to-regex-range@^5.0.1: version "5.0.1" @@ -583,17 +603,17 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -trim-newlines@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.0.2.tgz#d6aaaf6a0df1b4b536d183879a6b939489808c7c" - integrity sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew== +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -ts-node@^10.7.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== dependencies: - "@cspotcode/source-map-support" "0.7.0" + "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" "@tsconfig/node12" "^1.0.7" "@tsconfig/node14" "^1.0.0" @@ -604,60 +624,80 @@ ts-node@^10.7.0: create-require "^1.1.0" diff "^4.0.1" make-error "^1.1.1" - v8-compile-cache-lib "^3.0.0" + v8-compile-cache-lib "^3.0.1" yn "3.1.1" -turndown@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/turndown/-/turndown-7.1.1.tgz#96992f2d9b40a1a03d3ea61ad31b5a5c751ef77f" - integrity sha512-BEkXaWH7Wh7e9bd2QumhfAXk5g34+6QUmmWx+0q6ThaVOLuLUqsnkq35HQ5SBHSaxjSfSM7US5o4lhJNH7B9MA== +turndown@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/turndown/-/turndown-7.1.3.tgz#2890eb76c603e66bf0c9e91526582b563065c57d" + integrity sha512-Z3/iJ6IWh8VBiACWQJaA5ulPQE5E1QwvBHj00uGzdQxdRnd8fh1DPqNOJqzQDu6DkOstORrtXzf/9adB+vMtEA== dependencies: domino "^2.1.6" -type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" - integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== +typescript@^5.4.5: + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== -typescript@^4.8.0-dev.20220512: - version "4.8.0-dev.20220512" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220512.tgz#2f9b96bc7acb0f4190bfe6f25dbab44416841e1b" - integrity sha512-GkLFx5zji3VXVFfOhhYuFbyNRrjzmokfpp8Yq15gzjNrMIqe/dgUIl1yzMDoY5nuB0ul2Tac1+4jeAWFVf6agg== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -v8-compile-cache-lib@^3.0.0: +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utimes@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/utimes/-/utimes-5.2.1.tgz#e87679f9d6406313431830de9fbcac74ac067170" + integrity sha512-6S5mCapmzcxetOD/2UEjL0GF5e4+gB07Dh8qs63xylw5ay4XuyW6iQs70FOJo/puf10LCkvhp4jYMQSDUBYEFg== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.11" + node-addon-api "^4.3.0" + +v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" + string-width "^1.0.2 || 2 || 3 || 4" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^20.2.9: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==