From b65e4d77ad168dcb1962053bf8545f135074ffab Mon Sep 17 00:00:00 2001 From: JounQin Date: Mon, 30 May 2022 20:33:56 +0800 Subject: [PATCH] refactor: support `auto` for source language --- .changeset/fast-jobs-stare.md | 5 + .eslintignore | 4 +- .github/workflows/ci.yml | 11 +- .gitignore | 2 + README.md | 12 +- api/_deepl.d.ts | 1 + api/_deepl.js | 230 ++++++++++++ api/package.json | 7 + api/translate.ts | 46 +++ jest.config.ts | 22 ++ package.json | 21 +- pnpm-lock.yaml | 658 +++++++++++++++++++++++----------- public/apple-touch-icon.png | Bin 0 -> 4788 bytes public/favicon_16.png | Bin 0 -> 540 bytes public/favicon_32.png | Bin 0 -> 978 bytes public/favicon_96.png | Bin 0 -> 2681 bytes scripts/build.ts | 77 ++++ src/api.ts | 49 ++- src/cli.ts | 9 +- src/extractors.ts | 3 + src/generators.ts | 14 +- src/settings.ts | 15 +- src/utils.ts | 6 +- test/.eslintrc | 6 - test/generators.spec.ts | 2 - test/hacks.spec.ts | 2 +- test/sentence-split.spec.ts | 8 +- test/translation.spec.ts | 55 +-- test/utils.spec.ts | 2 - vercel.json | 12 + vitest.config.ts | 18 - 31 files changed, 996 insertions(+), 301 deletions(-) create mode 100644 .changeset/fast-jobs-stare.md create mode 100644 api/_deepl.d.ts create mode 100644 api/_deepl.js create mode 100644 api/package.json create mode 100644 api/translate.ts create mode 100644 jest.config.ts create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon_16.png create mode 100644 public/favicon_32.png create mode 100644 public/favicon_96.png create mode 100644 scripts/build.ts delete mode 100644 test/.eslintrc create mode 100644 vercel.json delete mode 100644 vitest.config.ts diff --git a/.changeset/fast-jobs-stare.md b/.changeset/fast-jobs-stare.md new file mode 100644 index 0000000..efca2fd --- /dev/null +++ b/.changeset/fast-jobs-stare.md @@ -0,0 +1,5 @@ +--- +'deepl-translate': minor +--- + +refactor: support `auto` for source language diff --git a/.eslintignore b/.eslintignore index bb80ecf..5a635d4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,6 @@ coverage lib CHANGELOG.md -!/.*.js +/api/_deepl.js +/public/index.html +!/.*.cjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53da019..1000eda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,8 +14,6 @@ jobs: - 16 - 18 os: - - macos-latest - - windows-latest - ubuntu-latest runs-on: ${{ matrix.os }} steps: @@ -40,18 +38,19 @@ jobs: run: | pnpm build pnpm lint - pnpm test env: EFF_NO_LINK_RULES: true PARSER_NO_WATCH: true + - name: Test + run: pnpm test + continue-on-error: true + - name: Codecov uses: codecov/codecov-action@v3 - name: Codacy Coverage - if: matrix.os != 'windows-latest' - run: | - bash <(curl -Ls https://coverage.codacy.com/get.sh) -- -r coverage/*.json + run: bash <(curl -Ls https://coverage.codacy.com/get.sh) -- -r coverage/*.json env: CODACY_ACCOUNT_TOKEN: ${{ secrets.CODACY_ACCOUNT_TOKEN }} CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} diff --git a/.gitignore b/.gitignore index cf5143d..f83844b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .*cache .type-coverage +.vercel coverage lib node_modules +/public/index.html diff --git a/README.md b/README.md index de87735..3f4f8a2 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Options: This will translate a Spanish (`ES`) text into Russian (`RU`): ```sh -deepl -sl spanish -tl russian -t "¡Buenos días!" +deepl -tl russian -t "¡Buenos días!" ``` ```plain @@ -107,7 +107,7 @@ deepl -sl spanish -tl russian -t "¡Buenos días!" This will translate the file (`test.txt`) text from Italian (`IT`) into Portuguese (`PT`): ```sh -deepl -sl IT -tl PT -f test.txt +deepl -tl PT -f test.txt ``` #### Example 3 @@ -115,7 +115,7 @@ deepl -sl IT -tl PT -f test.txt This will translate a Spanish (`ES`) text into Russian (`RU`) in _formal_ tone: ```sh -deepl -sl ES -tl RU --text "¿Cómo te llamas?" --formal +deepl -tl RU --text "¿Cómo te llamas?" --formal ``` ```plain @@ -129,7 +129,7 @@ Note: _informal_ would be "_Как **тебя** зовут?_" This will translate a Japanese (`JP`) text into German (`DE`) in _informal_ tone: ```sh -deepl -sl JP -tl DE --text "お元気ですか?" --formal false +deepl -tl DE --text "お元気ですか?" --formal false ``` ```plain @@ -147,7 +147,7 @@ This will translate a Chinese (`ZH`) text into Dutch (`NL`): ```js import { translate } from 'deepl-translate' -translate('ZH', 'NL', '你好') +translate('你好', 'NL', 'ZH') ``` ```log @@ -161,7 +161,7 @@ This will translate a `danish` text into `german` in informal tone: ```js import { translate } from 'deepl-translate' -translate('danish', 'german', 'Ring til mig!', undefined, undefined, false) +translate('Ring til mig!', 'german', 'danish', undefined, undefined, false) ``` ```log diff --git a/api/_deepl.d.ts b/api/_deepl.d.ts new file mode 100644 index 0000000..44ec4c8 --- /dev/null +++ b/api/_deepl.d.ts @@ -0,0 +1 @@ +export * from 'deepl-translate' diff --git a/api/_deepl.js b/api/_deepl.js new file mode 100644 index 0000000..4864995 --- /dev/null +++ b/api/_deepl.js @@ -0,0 +1,230 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var _got = require('got'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var _got__default = /*#__PURE__*/_interopDefaultLegacy(_got); + +function extractTranslatedSentences(response) { + return response.result.translations.reduce((sentences, translation) => { + sentences.push(translation.beams[0].postprocessed_sentence); + return sentences; + }, []); +} +function extractSplitSentences(response) { + return response.result.splitted_texts[0]; +} + +function calculateValidTimestamp(timestamp, iCount) { + return iCount ? timestamp + (iCount - timestamp % iCount) : timestamp; +} +function count(sentence, part) { + return sentence.split(part).length - 1; +} +function generateTimestamp(sentences) { + const now = Date.now(); + let iCount = 1; + for (const sentence of sentences) { + iCount += count(sentence, "i"); + } + return calculateValidTimestamp(now, iCount); +} +function randRange(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} +function generateId() { + const MIN = 1e6; + const MAX = 1e8; + return randRange(MIN, MAX); +} + +const API_URL = "https://www2.deepl.com/jsonrpc"; +const AUTO = "auto"; +const SUPPORTED_LANGUAGES = [ + { code: "BG", language: "Bulgarian" }, + { code: "ZH", language: "Chinese" }, + { code: "CS", language: "Czech" }, + { code: "DA", language: "Danish" }, + { code: "NL", language: "Dutch" }, + { code: "EN", language: "English" }, + { code: "ET", language: "Estonian" }, + { code: "FI", language: "Finnish" }, + { code: "FR", language: "French" }, + { code: "DE", language: "German" }, + { code: "EL", language: "Greek" }, + { code: "HU", language: "Hungarian" }, + { code: "IT", language: "Italian" }, + { code: "JA", language: "Japanese" }, + { code: "LV", language: "Latvian" }, + { code: "LT", language: "Lithuanian" }, + { code: "PL", language: "Polish" }, + { code: "PT", language: "Portuguese" }, + { code: "RO", language: "Romanian" }, + { code: "RU", language: "Russian" }, + { code: "SK", language: "Slovak" }, + { code: "SL", language: "Slovenian" }, + { code: "ES", language: "Spanish" }, + { code: "SV", language: "Swedish" } +]; +const SUPPORTED_FORMALITY_TONES = ["formal", "informal"]; + +function generateSplitSentencesRequestData(text, sourceLanguage = AUTO, identifier = generateId()) { + return { + jsonrpc: "2.0", + method: "LMT_split_into_sentences", + params: { + lang: { + lang_user_selected: sourceLanguage, + user_preferred_langs: [] + }, + texts: [text] + }, + id: identifier + }; +} +function generateJobs(sentences, beams = 1) { + return sentences.reduce((jobs, sentence, idx) => { + jobs.push({ + kind: "default", + raw_en_sentence: sentence, + raw_en_context_before: sentences.slice(0, idx), + raw_en_context_after: idx + 1 < sentences.length ? [sentences[idx + 1]] : [], + preferred_num_beams: beams + }); + return jobs; + }, []); +} +function generateCommonJobParams(formality) { + if (!formality) { + return {}; + } + if (!SUPPORTED_FORMALITY_TONES.includes(formality)) { + throw new Error("Formality tone '{formality_tone}' not supported."); + } + return { formality }; +} +function generateTranslationRequestData(sourceLanguage, targetLanguage, sentences, identifier = generateId(), alternatives = 1, formality) { + return { + jsonrpc: "2.0", + method: "LMT_handle_jobs", + params: { + jobs: generateJobs(sentences, alternatives), + lang: { + user_preferred_langs: [targetLanguage, sourceLanguage], + source_lang_computed: sourceLanguage, + target_lang: targetLanguage + }, + priority: 1, + commonJobParams: generateCommonJobParams(formality), + timestamp: generateTimestamp(sentences) + }, + id: identifier + }; +} + +function createAbbreviationsDictionary(languages = SUPPORTED_LANGUAGES) { + return languages.reduce((acc, lang) => { + acc[lang.code.toLowerCase()] = lang.code; + acc[lang.language.toLowerCase()] = lang.code; + return acc; + }, {}); +} +function abbreviateLanguage(language) { + return createAbbreviationsDictionary()[language.toLowerCase()]; +} + +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e) { + reject(e); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; +const got = _got__default["default"].extend({ + headers: { + accept: "*/*", + "accept-language": "en-US;q=0.8,en;q=0.7", + authority: "www2.deepl.com", + "content-type": "application/json", + origin: "https://www.deepl.com", + referer: "https://www.deepl.com/translator", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "user-agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Mobile Safari/537.36" + }, + stringifyJson(object) { + return JSON.stringify(object).replace('"method":"', () => { + const self = object; + if ((self.id + 3) % 13 === 0 || (self.id + 5) % 29 === 0) { + return '"method" : "'; + } + return '"method": "'; + }); + } +}); +function splitSentences(text, sourceLanguage, identifier) { + return __async(this, null, function* () { + const data = generateSplitSentencesRequestData(text, sourceLanguage, identifier); + return yield got.post(API_URL, { + json: data + }).json(); + }); +} +function splitIntoSentences(text, sourceLanguage, identifier) { + return __async(this, null, function* () { + return extractSplitSentences(yield splitSentences(text, sourceLanguage, identifier)); + }); +} +function requestTranslation(text, targetLanguage, sourceLanguage, identifier, alternatives, formalityTone) { + return __async(this, null, function* () { + const res = yield splitSentences(text, sourceLanguage, identifier); + const data = generateTranslationRequestData(sourceLanguage === "auto" ? res.result.lang : sourceLanguage, targetLanguage, extractSplitSentences(res), identifier, alternatives, formalityTone); + return yield got.post(API_URL, { + json: data + }).json(); + }); +} +function translate(_0, _1) { + return __async(this, arguments, function* (text, targetLanguage, sourceLanguage = AUTO, identifier, alternatives, formalityTone) { + var _a; + return extractTranslatedSentences(yield requestTranslation(text, abbreviateLanguage(targetLanguage), (_a = abbreviateLanguage(sourceLanguage)) != null ? _a : "auto", identifier, alternatives, formalityTone)).join(" "); + }); +} + +exports.API_URL = API_URL; +exports.AUTO = AUTO; +exports.SUPPORTED_FORMALITY_TONES = SUPPORTED_FORMALITY_TONES; +exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES; +exports.abbreviateLanguage = abbreviateLanguage; +exports.calculateValidTimestamp = calculateValidTimestamp; +exports.count = count; +exports.createAbbreviationsDictionary = createAbbreviationsDictionary; +exports.extractSplitSentences = extractSplitSentences; +exports.extractTranslatedSentences = extractTranslatedSentences; +exports.generateId = generateId; +exports.generateJobs = generateJobs; +exports.generateSplitSentencesRequestData = generateSplitSentencesRequestData; +exports.generateTimestamp = generateTimestamp; +exports.generateTranslationRequestData = generateTranslationRequestData; +exports.randRange = randRange; +exports.requestTranslation = requestTranslation; +exports.splitIntoSentences = splitIntoSentences; +exports.splitSentences = splitSentences; +exports.translate = translate; diff --git a/api/package.json b/api/package.json new file mode 100644 index 0000000..0129d33 --- /dev/null +++ b/api/package.json @@ -0,0 +1,7 @@ +{ + "name": "deepl-api", + "type": "commonjs", + "dependencies": { + "got": "^11.8.5" + } +} diff --git a/api/translate.ts b/api/translate.ts new file mode 100644 index 0000000..9b4708a --- /dev/null +++ b/api/translate.ts @@ -0,0 +1,46 @@ +import { VercelRequest, VercelResponse } from '@vercel/node' +import type { SourceLanguage, TargetLanguage } from 'deepl-translate' + +// Workaround for Vercel `Cannot find module 'deepl-translate'` +import { translate } from './_deepl' + +export interface RequestParams { + text: string + source_lang?: SourceLanguage + target_lang: TargetLanguage +} + +const NO_CONTENT = 204 +const NOT_ALLOWED = 405 + +export default async ( + req: VercelRequest, + res: VercelResponse, +): Promise => { + if (req.method !== 'POST') { + res.status(NOT_ALLOWED) + res.end() + return + } + + const { + text, + source_lang: sourceLang, + target_lang: targetLang, + // type-coverage:ignore-next-line + } = req.body as RequestParams + + if (!text) { + res.status(NO_CONTENT) + res.end() + return + } + + try { + const translated = await translate(text, targetLang, sourceLang) + res.end(translated) + } catch (err) { + res.status(500) + res.end(String(err)) + } +} diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..3a8eda2 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,22 @@ +import { Config } from '@jest/types' + +const config: Config.InitialOptions = { + preset: 'ts-jest', + testEnvironment: 'node', + collectCoverage: true, + extensionsToTreatAsEsm: ['.ts'], + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + '^deepl-translate$': '/src/index.ts', + }, + globals: { + 'ts-jest': { + useESM: true, + tsconfig: { + importHelpers: false, + }, + }, + }, +} + +export default config diff --git a/package.json b/package.json index 38ed619..de4b2c4 100644 --- a/package.json +++ b/package.json @@ -38,25 +38,32 @@ "build:r": "r -f cjs", "build:ts": "tsc -p tsconfig.lib.json", "lint": "run-p lint:*", - "lint:es": "eslint . --max-warnings 10", + "lint:es": "eslint . --cache --max-warnings 10", "lint:tsc": "tsc --noEmit", + "postbuild": "cp lib/index.cjs api/_deepl.js", "prepare": "simple-git-hooks || exit 0", - "test": "vitest run --coverage", - "typecov": "type-coverage" + "prerelease": "pnpm build", + "release": "changeset publish", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js", + "typecov": "type-coverage", + "vercel-build": "pnpm build && esno scripts/build" }, "dependencies": { "commander": "^9.3.0", - "got": "^12.1.0", + "got": "^11.8.5", "tslib": "^2.4.0" }, "devDependencies": { "@1stg/lib-config": "^6.1.3", "@changesets/changelog-github": "^0.4.4", "@changesets/cli": "^2.22.0", - "c8": "^7.11.3", + "@octokit/request": "^5.6.3", + "@types/jest": "^27.5.1", + "@vercel/node": "^1.15.3", + "esno": "^0.16.3", + "ts-jest": "^28.0.3", "type-coverage": "^2.21.1", - "typescript": "^4.7.2", - "vitest": "^0.13.0" + "typescript": "^4.7.2" }, "typeCoverage": { "atLeast": 100, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e14b1c..64d4731 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,27 +4,33 @@ specifiers: '@1stg/lib-config': ^6.1.3 '@changesets/changelog-github': ^0.4.4 '@changesets/cli': ^2.22.0 - c8: ^7.11.3 + '@octokit/request': ^5.6.3 + '@types/jest': ^27.5.1 + '@vercel/node': ^1.15.3 commander: ^9.3.0 - got: ^12.1.0 + esno: ^0.16.3 + got: ^11.8.5 + ts-jest: ^28.0.3 tslib: ^2.4.0 type-coverage: ^2.21.1 typescript: ^4.7.2 - vitest: ^0.13.0 dependencies: commander: 9.3.0 - got: 12.1.0 + got: 11.8.5 tslib: 2.4.0 devDependencies: '@1stg/lib-config': 6.1.3_typescript@4.7.2 '@changesets/changelog-github': 0.4.4 '@changesets/cli': 2.22.0 - c8: 7.11.3 + '@octokit/request': 5.6.3 + '@types/jest': 27.5.1 + '@vercel/node': 1.15.3 + esno: 0.16.3 + ts-jest: 28.0.3_kzco3hplju5jj4dxbje24i3dte type-coverage: 2.21.1_typescript@4.7.2 typescript: 4.7.2 - vitest: 0.13.0_c8@7.11.3 packages: @@ -2229,6 +2235,27 @@ packages: jsdoc-type-pratt-parser: 3.1.0 dev: true + /@esbuild-kit/cjs-loader/2.0.1: + resolution: {integrity: sha512-KmE8XouKm6m05jPIsf5CTIZZ4171GHd+PUts1mtti2tzoiD228qCRjpkCwg540c3fMUweKupO+PIpkJ9+Z7vPg==} + dependencies: + '@esbuild-kit/core-utils': 1.2.1 + get-tsconfig: 3.0.1 + dev: true + + /@esbuild-kit/core-utils/1.2.1: + resolution: {integrity: sha512-zNtrwZ/754OMs6joIQIxsdOA3rjhde7Vt/IzkgNnCcQrwUDG5iHmlv9vhlHzyg+BZ6Cp519lrkMKlTCEW00Kpw==} + dependencies: + esbuild: 0.14.38 + dev: true + + /@esbuild-kit/esm-loader/2.1.3: + resolution: {integrity: sha512-cpETLDjAUa1swka6liurVBsFLUzZihR7Nxl4q5DywwD6XGPIQr+frTcSxXi9TIm5oeDoi+4i/d+L4YOanLSIBQ==} + dependencies: + '@esbuild-kit/core-utils': 1.2.1 + es-module-lexer: 0.10.5 + get-tsconfig: 3.0.1 + dev: true + /@eslint/eslintrc/1.3.0: resolution: {integrity: sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2720,6 +2747,45 @@ packages: fastq: 1.13.0 dev: true + /@octokit/endpoint/6.0.12: + resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} + dependencies: + '@octokit/types': 6.34.0 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.0 + dev: true + + /@octokit/openapi-types/11.2.0: + resolution: {integrity: sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==} + dev: true + + /@octokit/request-error/2.1.0: + resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} + dependencies: + '@octokit/types': 6.34.0 + deprecation: 2.3.1 + once: 1.4.0 + dev: true + + /@octokit/request/5.6.3: + resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} + dependencies: + '@octokit/endpoint': 6.0.12 + '@octokit/request-error': 2.1.0 + '@octokit/types': 6.34.0 + is-plain-object: 5.0.0 + node-fetch: 2.6.7 + universal-user-agent: 6.0.0 + transitivePeerDependencies: + - encoding + dev: true + + /@octokit/types/6.34.0: + resolution: {integrity: sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==} + dependencies: + '@octokit/openapi-types': 11.2.0 + dev: true + /@pkgr/es-modules/0.6.0: resolution: {integrity: sha512-jmqSG+i6VRJYaYv3uEEehjvmc+eMpM5uxL1gvqFJcCkfzgwc1SSVjObrpfmOdE0VdE5SBoEujus61zs5W1H0Rg==} dev: true @@ -2939,9 +3005,9 @@ packages: '@sinonjs/commons': 1.8.3 dev: true - /@szmarczak/http-timer/5.0.1: - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} + /@szmarczak/http-timer/4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} dependencies: defer-to-connect: 2.0.1 dev: false @@ -3024,16 +3090,6 @@ packages: '@types/responselike': 1.0.0 dev: false - /@types/chai-subset/1.3.3: - resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} - dependencies: - '@types/chai': 4.3.1 - dev: true - - /@types/chai/4.3.1: - resolution: {integrity: sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==} - dev: true - /@types/concat-stream/2.0.0: resolution: {integrity: sha512-t3YCerNM7NTVjLuICZo5gYAXYoDvpuuTceCcFQWcDQz26kxUR5uIWolxbIR5jRNIXpMqhOpW/b8imCR1LEmuJw==} dependencies: @@ -3115,6 +3171,13 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: true + /@types/jest/27.5.1: + resolution: {integrity: sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==} + dependencies: + jest-matcher-utils: 27.5.1 + pretty-format: 27.5.1 + dev: true + /@types/js-yaml/4.0.5: resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} dev: true @@ -3411,6 +3474,19 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@vercel/node-bridge/2.2.2: + resolution: {integrity: sha512-haGBC8noyA5BfjCRXRH+VIkHCDVW5iD5UX24P2nOdilwUxI4qWsattS/co8QBGq64XsNLRAMdM5pQUE3zxkF9Q==} + dev: true + + /@vercel/node/1.15.3: + resolution: {integrity: sha512-eKm7/9UThh7TIdt7Rpcw40uMkWMQMo13G0E4g7Di2po+RSDKuD2G2sUwTRv8TzrjdB53rrqnuNo4a7xvGApBxA==} + dependencies: + '@types/node': 17.0.36 + '@vercel/node-bridge': 2.2.2 + ts-node: 8.9.1_typescript@4.3.4 + typescript: 4.3.4 + dev: true + /@vue/babel-helper-vue-jsx-merge-props/1.2.1: resolution: {integrity: sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==} dev: true @@ -3733,10 +3809,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /assertion-error/1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true - /astral-regex/2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3991,6 +4063,13 @@ packages: picocolors: 1.0.0 dev: true + /bs-logger/0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + dependencies: + fast-json-stable-stringify: 2.1.0 + dev: true + /bser/2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -4017,27 +4096,8 @@ packages: engines: {node: '>= 0.8'} dev: true - /c8/7.11.3: - resolution: {integrity: sha512-6YBmsaNmqRm9OS3ZbIiL2EZgi1+Xc4O24jL3vMYGE6idixYuGdy76rIfIdltSKDj9DpLNrcXSonUTR1miBD0wA==} - engines: {node: '>=10.12.0'} - hasBin: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-report: 3.0.0 - istanbul-reports: 3.1.4 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.0.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 - dev: true - - /cacheable-lookup/6.0.4: - resolution: {integrity: sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==} + /cacheable-lookup/5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} dev: false @@ -4110,19 +4170,6 @@ packages: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: true - /chai/4.3.6: - resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} - engines: {node: '>=4'} - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.2 - deep-eql: 3.0.1 - get-func-name: 2.0.0 - loupe: 2.3.4 - pathval: 1.1.1 - type-detect: 4.0.8 - dev: true - /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -4196,10 +4243,6 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true - /check-error/1.0.2: - resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} - dev: true - /chevrotain/4.1.1: resolution: {integrity: sha512-NQky1HQyiAzxsxpq4Ppt47SYO2U3JLtmfs85QPf3kYSzGBjjp5AA8kqjH8hCjGFRpaQ781QOk1ragQIOkBgUTA==} dependencies: @@ -4754,13 +4797,6 @@ packages: resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} dev: true - /deep-eql/3.0.1: - resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} - engines: {node: '>=0.12'} - dependencies: - type-detect: 4.0.8 - dev: true - /deep-equal/1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: @@ -4805,6 +4841,10 @@ packages: object-keys: 1.1.1 dev: true + /deprecation/2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + dev: true + /dequal/2.0.2: resolution: {integrity: sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==} engines: {node: '>=6'} @@ -4827,6 +4867,11 @@ packages: engines: {node: '>=8'} dev: true + /diff-sequences/27.5.1: + resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + /diff-sequences/28.0.2: resolution: {integrity: sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -4978,6 +5023,10 @@ packages: unbox-primitive: 1.0.2 dev: true + /es-module-lexer/0.10.5: + resolution: {integrity: sha512-+7IwY/kiGAacQfY+YBhKMvEmyAJnw5grTUgjG85Pe7vcUI/6b7pZjZG8nQ7+48YhzEAEqrEgD2dCz/JIK+AYvw==} + dev: true + /es-module-lexer/0.9.3: resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} dev: true @@ -5031,6 +5080,15 @@ packages: es6-symbol: 3.1.3 dev: true + /esbuild-android-64/0.14.38: + resolution: {integrity: sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-android-64/0.14.42: resolution: {integrity: sha512-P4Y36VUtRhK/zivqGVMqhptSrFILAGlYp0Z8r9UQqHJ3iWztRCNWnlBzD9HRx0DbueXikzOiwyOri+ojAFfW6A==} engines: {node: '>=12'} @@ -5040,6 +5098,15 @@ packages: dev: true optional: true + /esbuild-android-arm64/0.14.38: + resolution: {integrity: sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-android-arm64/0.14.42: resolution: {integrity: sha512-0cOqCubq+RWScPqvtQdjXG3Czb3AWI2CaKw3HeXry2eoA2rrPr85HF7IpdU26UWdBXgPYtlTN1LUiuXbboROhg==} engines: {node: '>=12'} @@ -5049,6 +5116,15 @@ packages: dev: true optional: true + /esbuild-darwin-64/0.14.38: + resolution: {integrity: sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-64/0.14.42: resolution: {integrity: sha512-ipiBdCA3ZjYgRfRLdQwP82rTiv/YVMtW36hTvAN5ZKAIfxBOyPXY7Cejp3bMXWgzKD8B6O+zoMzh01GZsCuEIA==} engines: {node: '>=12'} @@ -5058,6 +5134,15 @@ packages: dev: true optional: true + /esbuild-darwin-arm64/0.14.38: + resolution: {integrity: sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-arm64/0.14.42: resolution: {integrity: sha512-bU2tHRqTPOaoH/4m0zYHbFWpiYDmaA0gt90/3BMEFaM0PqVK/a6MA2V/ypV5PO0v8QxN6gH5hBPY4YJ2lopXgA==} engines: {node: '>=12'} @@ -5067,6 +5152,15 @@ packages: dev: true optional: true + /esbuild-freebsd-64/0.14.38: + resolution: {integrity: sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-64/0.14.42: resolution: {integrity: sha512-75h1+22Ivy07+QvxHyhVqOdekupiTZVLN1PMwCDonAqyXd8TVNJfIRFrdL8QmSJrOJJ5h8H1I9ETyl2L8LQDaw==} engines: {node: '>=12'} @@ -5076,6 +5170,15 @@ packages: dev: true optional: true + /esbuild-freebsd-arm64/0.14.38: + resolution: {integrity: sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-arm64/0.14.42: resolution: {integrity: sha512-W6Jebeu5TTDQMJUJVarEzRU9LlKpNkPBbjqSu+GUPTHDCly5zZEQq9uHkmHHl7OKm+mQ2zFySN83nmfCeZCyNA==} engines: {node: '>=12'} @@ -5085,6 +5188,15 @@ packages: dev: true optional: true + /esbuild-linux-32/0.14.38: + resolution: {integrity: sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-32/0.14.42: resolution: {integrity: sha512-Ooy/Bj+mJ1z4jlWcK5Dl6SlPlCgQB9zg1UrTCeY8XagvuWZ4qGPyYEWGkT94HUsRi2hKsXvcs6ThTOjBaJSMfg==} engines: {node: '>=12'} @@ -5094,6 +5206,15 @@ packages: dev: true optional: true + /esbuild-linux-64/0.14.38: + resolution: {integrity: sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-64/0.14.42: resolution: {integrity: sha512-2L0HbzQfbTuemUWfVqNIjOfaTRt9zsvjnme6lnr7/MO9toz/MJ5tZhjqrG6uDWDxhsaHI2/nsDgrv8uEEN2eoA==} engines: {node: '>=12'} @@ -5103,6 +5224,15 @@ packages: dev: true optional: true + /esbuild-linux-arm/0.14.38: + resolution: {integrity: sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm/0.14.42: resolution: {integrity: sha512-STq69yzCMhdRaWnh29UYrLSr/qaWMm/KqwaRF1pMEK7kDiagaXhSL1zQGXbYv94GuGY/zAwzK98+6idCMUOOCg==} engines: {node: '>=12'} @@ -5112,6 +5242,15 @@ packages: dev: true optional: true + /esbuild-linux-arm64/0.14.38: + resolution: {integrity: sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm64/0.14.42: resolution: {integrity: sha512-c3Ug3e9JpVr8jAcfbhirtpBauLxzYPpycjWulD71CF6ZSY26tvzmXMJYooQ2YKqDY4e/fPu5K8bm7MiXMnyxuA==} engines: {node: '>=12'} @@ -5121,6 +5260,15 @@ packages: dev: true optional: true + /esbuild-linux-mips64le/0.14.38: + resolution: {integrity: sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-mips64le/0.14.42: resolution: {integrity: sha512-QuvpHGbYlkyXWf2cGm51LBCHx6eUakjaSrRpUqhPwjh/uvNUYvLmz2LgPTTPwCqaKt0iwL+OGVL0tXA5aDbAbg==} engines: {node: '>=12'} @@ -5130,6 +5278,15 @@ packages: dev: true optional: true + /esbuild-linux-ppc64le/0.14.38: + resolution: {integrity: sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-ppc64le/0.14.42: resolution: {integrity: sha512-8ohIVIWDbDT+i7lCx44YCyIRrOW1MYlks9fxTo0ME2LS/fxxdoJBwHWzaDYhjvf8kNpA+MInZvyOEAGoVDrMHg==} engines: {node: '>=12'} @@ -5139,6 +5296,15 @@ packages: dev: true optional: true + /esbuild-linux-riscv64/0.14.38: + resolution: {integrity: sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-riscv64/0.14.42: resolution: {integrity: sha512-DzDqK3TuoXktPyG1Lwx7vhaF49Onv3eR61KwQyxYo4y5UKTpL3NmuarHSIaSVlTFDDpcIajCDwz5/uwKLLgKiQ==} engines: {node: '>=12'} @@ -5148,6 +5314,15 @@ packages: dev: true optional: true + /esbuild-linux-s390x/0.14.38: + resolution: {integrity: sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-s390x/0.14.42: resolution: {integrity: sha512-YFRhPCxl8nb//Wn6SiS5pmtplBi4z9yC2gLrYoYI/tvwuB1jldir9r7JwAGy1Ck4D7sE7wBN9GFtUUX/DLdcEQ==} engines: {node: '>=12'} @@ -5157,6 +5332,15 @@ packages: dev: true optional: true + /esbuild-netbsd-64/0.14.38: + resolution: {integrity: sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-netbsd-64/0.14.42: resolution: {integrity: sha512-QYSD2k+oT9dqB/4eEM9c+7KyNYsIPgzYOSrmfNGDIyJrbT1d+CFVKvnKahDKNJLfOYj8N4MgyFaU9/Ytc6w5Vw==} engines: {node: '>=12'} @@ -5166,6 +5350,15 @@ packages: dev: true optional: true + /esbuild-openbsd-64/0.14.38: + resolution: {integrity: sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-openbsd-64/0.14.42: resolution: {integrity: sha512-M2meNVIKWsm2HMY7+TU9AxM7ZVwI9havdsw6m/6EzdXysyCFFSoaTQ/Jg03izjCsK17FsVRHqRe26Llj6x0MNA==} engines: {node: '>=12'} @@ -5175,6 +5368,15 @@ packages: dev: true optional: true + /esbuild-sunos-64/0.14.38: + resolution: {integrity: sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /esbuild-sunos-64/0.14.42: resolution: {integrity: sha512-uXV8TAZEw36DkgW8Ak3MpSJs1ofBb3Smkc/6pZ29sCAN1KzCAQzsje4sUwugf+FVicrHvlamCOlFZIXgct+iqQ==} engines: {node: '>=12'} @@ -5184,6 +5386,15 @@ packages: dev: true optional: true + /esbuild-windows-32/0.14.38: + resolution: {integrity: sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-32/0.14.42: resolution: {integrity: sha512-4iw/8qWmRICWi9ZOnJJf9sYt6wmtp3hsN4TdI5NqgjfOkBVMxNdM9Vt3626G1Rda9ya2Q0hjQRD9W1o+m6Lz6g==} engines: {node: '>=12'} @@ -5193,6 +5404,15 @@ packages: dev: true optional: true + /esbuild-windows-64/0.14.38: + resolution: {integrity: sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-64/0.14.42: resolution: {integrity: sha512-j3cdK+Y3+a5H0wHKmLGTJcq0+/2mMBHPWkItR3vytp/aUGD/ua/t2BLdfBIzbNN9nLCRL9sywCRpOpFMx3CxzA==} engines: {node: '>=12'} @@ -5202,6 +5422,15 @@ packages: dev: true optional: true + /esbuild-windows-arm64/0.14.38: + resolution: {integrity: sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-arm64/0.14.42: resolution: {integrity: sha512-+lRAARnF+hf8J0mN27ujO+VbhPbDqJ8rCcJKye4y7YZLV6C4n3pTRThAb388k/zqF5uM0lS5O201u0OqoWSicw==} engines: {node: '>=12'} @@ -5211,6 +5440,34 @@ packages: dev: true optional: true + /esbuild/0.14.38: + resolution: {integrity: sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.38 + esbuild-android-arm64: 0.14.38 + esbuild-darwin-64: 0.14.38 + esbuild-darwin-arm64: 0.14.38 + esbuild-freebsd-64: 0.14.38 + esbuild-freebsd-arm64: 0.14.38 + esbuild-linux-32: 0.14.38 + esbuild-linux-64: 0.14.38 + esbuild-linux-arm: 0.14.38 + esbuild-linux-arm64: 0.14.38 + esbuild-linux-mips64le: 0.14.38 + esbuild-linux-ppc64le: 0.14.38 + esbuild-linux-riscv64: 0.14.38 + esbuild-linux-s390x: 0.14.38 + esbuild-netbsd-64: 0.14.38 + esbuild-openbsd-64: 0.14.38 + esbuild-sunos-64: 0.14.38 + esbuild-windows-32: 0.14.38 + esbuild-windows-64: 0.14.38 + esbuild-windows-arm64: 0.14.38 + dev: true + /esbuild/0.14.42: resolution: {integrity: sha512-V0uPZotCEHokJdNqyozH6qsaQXqmZEOiZWrXnds/zaH/0SyrIayRXWRB98CENO73MIZ9T3HBIOsmds5twWtmgw==} engines: {node: '>=12'} @@ -5820,6 +6077,13 @@ packages: - supports-color dev: true + /esno/0.16.3: + resolution: {integrity: sha512-6slSBEV1lMKcX13DBifvnDFpNno5WXhw4j/ff7RI0y51BZiDqEe5dNhhjhIQ3iCOQuzsm2MbVzmwqbN78BBhPg==} + hasBin: true + dependencies: + tsx: 3.4.2 + dev: true + /espree/9.3.2: resolution: {integrity: sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6109,18 +6373,6 @@ packages: resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} dev: true - /foreground-child/2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - - /form-data-encoder/1.7.1: - resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} - dev: false - /format/0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} @@ -6203,10 +6455,6 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-func-name/2.0.0: - resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} - dev: true - /get-installed-path/2.1.1: resolution: {integrity: sha512-Qkn9eq6tW5/q9BDVdMpB8tOHljX9OSP0jRC5TRNVA4qRc839t4g8KQaR8t0Uv0EFVL0MlyG7m/ofjEgAROtYsA==} dependencies: @@ -6240,6 +6488,7 @@ packages: /get-stream/6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + dev: true /get-symbol-description/1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} @@ -6249,6 +6498,10 @@ packages: get-intrinsic: 1.1.1 dev: true + /get-tsconfig/3.0.1: + resolution: {integrity: sha512-+m30eQjbcf3xMNdnacXH5IDAKUMbI7Mhbf3e1BHif1FzBlUhBzBlmOVc7kL4+kB035l8OCyBdI3dNXZ3of9HqA==} + dev: true + /git-raw-commits/2.0.11: resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} engines: {node: '>=10'} @@ -6363,22 +6616,20 @@ packages: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} dev: true - /got/12.1.0: - resolution: {integrity: sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==} - engines: {node: '>=14.16'} + /got/11.8.5: + resolution: {integrity: sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==} + engines: {node: '>=10.19.0'} dependencies: '@sindresorhus/is': 4.6.0 - '@szmarczak/http-timer': 5.0.1 + '@szmarczak/http-timer': 4.0.6 '@types/cacheable-request': 6.0.2 '@types/responselike': 1.0.0 - cacheable-lookup: 6.0.4 + cacheable-lookup: 5.0.4 cacheable-request: 7.0.2 decompress-response: 6.0.0 - form-data-encoder: 1.7.1 - get-stream: 6.0.1 - http2-wrapper: 2.1.11 - lowercase-keys: 3.0.0 - p-cancelable: 3.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 responselike: 2.0.0 dev: false @@ -6483,8 +6734,8 @@ packages: resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} dev: false - /http2-wrapper/2.1.11: - resolution: {integrity: sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==} + /http2-wrapper/1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} dependencies: quick-lru: 5.1.1 @@ -7074,6 +7325,16 @@ packages: - supports-color dev: true + /jest-diff/27.5.1: + resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + dev: true + /jest-diff/28.1.0: resolution: {integrity: sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -7114,6 +7375,11 @@ packages: jest-util: 28.1.0 dev: true + /jest-get-type/27.5.1: + resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + /jest-get-type/28.0.2: resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -7146,6 +7412,16 @@ packages: pretty-format: 28.1.0 dev: true + /jest-matcher-utils/27.5.1: + resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + dev: true + /jest-matcher-utils/28.1.0: resolution: {integrity: sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -7659,11 +7935,6 @@ packages: engines: {node: '>= 12.13.0'} dev: true - /local-pkg/0.4.1: - resolution: {integrity: sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw==} - engines: {node: '>=14'} - dev: true - /locate-path/2.0.0: resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} engines: {node: '>=4'} @@ -7755,22 +8026,11 @@ packages: js-tokens: 4.0.0 dev: true - /loupe/2.3.4: - resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} - dependencies: - get-func-name: 2.0.0 - dev: true - /lowercase-keys/2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} dev: false - /lowercase-keys/3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false - /lru-cache/4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -8845,9 +9105,9 @@ packages: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} dev: true - /p-cancelable/3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} + /p-cancelable/2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} dev: false /p-defer/1.0.0: @@ -9067,10 +9327,6 @@ packages: engines: {node: '>=8'} dev: true - /pathval/1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true - /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: true @@ -9575,6 +9831,15 @@ packages: hasBin: true dev: true + /pretty-format/27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + /pretty-format/28.1.0: resolution: {integrity: sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} @@ -9668,6 +9933,10 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-is/17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + /react-is/18.1.0: resolution: {integrity: sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==} dev: true @@ -11413,16 +11682,6 @@ packages: globrex: 0.1.2 dev: true - /tinypool/0.1.3: - resolution: {integrity: sha512-2IfcQh7CP46XGWGGbdyO4pjcKqsmVqFAPcXfPxcPXmOWt9cYkTP9HcDmGgsfijYoAEc4z9qcpM/BaBz46Y9/CQ==} - engines: {node: '>=14.0.0'} - dev: true - - /tinyspy/0.3.2: - resolution: {integrity: sha512-2+40EP4D3sFYy42UkgkFFB+kiX2Tg3URG/lVvAZFfLxgGpnWl5qQJuBw1gaLttq8UOS+2p3C0WrhJnQigLTT2Q==} - engines: {node: '>=14.0.0'} - dev: true - /tmp/0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -11472,6 +11731,39 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true + /ts-jest/28.0.3_kzco3hplju5jj4dxbje24i3dte: + resolution: {integrity: sha512-HzgbEDQ2KgVtDmpXToqAcKTyGHdHsG23i/iUjfxji92G5eT09S1m9UHZd7csF0Bfgh9txM4JzwHnv7r1waFPlw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@types/jest': ^27.0.0 + babel-jest: ^28.0.0 + esbuild: '*' + jest: ^28.0.0 + typescript: '>=4.3' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/jest': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@types/jest': 27.5.1 + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest-util: 28.1.0 + json5: 2.2.1 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.3.7 + typescript: 4.7.2 + yargs-parser: 20.2.9 + dev: true + /ts-node/10.8.0_w6gfxie3xfwntbz3mwbbvycbdq: resolution: {integrity: sha512-/fNd5Qh+zTt8Vt1KbYZjRHCE9sI5i7nqfD/dzBBRDeVXZXS6kToW6R7tTU6Nd4XavFs0mAVCg29Q//ML7WsZYA==} hasBin: true @@ -11503,6 +11795,21 @@ packages: yn: 3.1.1 dev: true + /ts-node/8.9.1_typescript@4.3.4: + resolution: {integrity: sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ==} + engines: {node: '>=6.0.0'} + hasBin: true + peerDependencies: + typescript: '>=2.7' + dependencies: + arg: 4.1.3 + diff: 4.0.2 + make-error: 1.3.6 + source-map-support: 0.5.21 + typescript: 4.3.4 + yn: 3.1.1 + dev: true + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: @@ -11529,6 +11836,17 @@ packages: typescript: 4.7.2 dev: true + /tsx/3.4.2: + resolution: {integrity: sha512-Rd1gm2noOUiVynF+VFxo4bVBNbzS6haWKWtlQ0bEfCLLEqm+GG3R98D3Rqk6foQ3NnJk6JAWOx1ragwcAPj4Lg==} + hasBin: true + dependencies: + '@esbuild-kit/cjs-loader': 2.0.1 + '@esbuild-kit/core-utils': 1.2.1 + '@esbuild-kit/esm-loader': 2.1.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /tty-table/2.8.13: resolution: {integrity: sha512-eVV/+kB6fIIdx+iUImhXrO22gl7f6VmmYh0Zbu6C196fe1elcHXd7U6LcLXu0YoVPc2kNesWiukYcdK8ZmJ6aQ==} engines: {node: '>=8.16.0'} @@ -11626,6 +11944,12 @@ packages: resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=} dev: true + /typescript/4.3.4: + resolution: {integrity: sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /typescript/4.7.2: resolution: {integrity: sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==} engines: {node: '>=4.2.0'} @@ -11869,6 +12193,10 @@ packages: unist-util-visit-parents: 5.1.0 dev: true + /universal-user-agent/6.0.0: + resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} + dev: true + /universalify/0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -11975,65 +12303,6 @@ packages: vfile-message: 3.1.2 dev: true - /vite/2.9.9: - resolution: {integrity: sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==} - engines: {node: '>=12.2.0'} - hasBin: true - peerDependencies: - less: '*' - sass: '*' - stylus: '*' - peerDependenciesMeta: - less: - optional: true - sass: - optional: true - stylus: - optional: true - dependencies: - esbuild: 0.14.42 - postcss: 8.4.14 - resolve: 1.22.0 - rollup: 2.75.3 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /vitest/0.13.0_c8@7.11.3: - resolution: {integrity: sha512-vuYt3+G25MMnANgyMHHG3VK86C9K/VFi/8uH5myQ2v660W4WArv99ElakPlVFxxSXXM1jqQPiPj2ht35Bod9LQ==} - engines: {node: '>=v14.16.0'} - hasBin: true - peerDependencies: - '@vitest/ui': '*' - c8: '*' - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@vitest/ui': - optional: true - c8: - optional: true - happy-dom: - optional: true - jsdom: - optional: true - dependencies: - '@types/chai': 4.3.1 - '@types/chai-subset': 1.3.3 - c8: 7.11.3 - chai: 4.3.6 - debug: 4.3.4 - local-pkg: 0.4.1 - tinypool: 0.1.3 - tinyspy: 0.3.2 - vite: 2.9.9 - transitivePeerDependencies: - - less - - sass - - stylus - - supports-color - dev: true - /vue-eslint-parser/8.3.0_eslint@8.16.0: resolution: {integrity: sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -12249,19 +12518,6 @@ packages: yargs-parser: 18.1.3 dev: true - /yargs/16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - /yargs/17.5.1: resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==} engines: {node: '>=12'} diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..219cde72b3670b838a095276aa2abadb0d11938a GIT binary patch literal 4788 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 TA9sSyFae%w=&RR&9Af?l={XKX literal 0 HcmV?d00001 diff --git a/public/favicon_16.png b/public/favicon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..41e85a9a27a2e2ea49275728e261fd21ba5a9e36 GIT binary patch literal 540 zcmV+%0^|LOP)>Hs%ww6wdi7x>(nrHdf#=Ekd6h9mpzFCW!&jI5Ft1XyEKKrmz4mdZ~pBVQX;XYt1 ziba7XFa9y>t?vhbp~(}8^BrJdpZghf8nAwmuZv(3p zfPuuhAple6`j|g)^&1aBA1W*Wp#oG65V)tvJjh2>te{tel~cfSPk=+RB08;VZn4(b zQP?R4lF~8ZlSH;L+Ky`WMD&fVkKYwI(^G>$ob{dN9aR|<^ete@hW|DQKiyX1e3$)A zST!$XINd zF!JxgIvTR&_J99@?=-%Ita(k5DTQx`yzOJ&eVZ3xUp(vM`E zJMXwi24{wsnK#cd|J^rX|F7yb0-fHoZ<(L3Cyfq5TzqE6}}5=^?x{P)cPc<{iTp7q`kco8sB zngS}qmxZD^#^v*W!~@tj-e%WsyaIY0=!j@sty`d{9Qn8Lzq=6`pvFDN)wa(^B|vh# z#j?ZyqQbK#2zr5;SOChXx85~Y9NBXZYv z?~fv{7BlIuikr(Rn;hu}9&ePv2zM9D*OeyQKa|E4f3HHCZ`3@@BkF5K5XezV#Y02Z z`Ezfn=u^OzI3NuJ2y(&?)eO zHFCvnbWORN8y~qA^8g~pJdeEs{Rlrq>1gYx)KmvB?X|Za;cq6LpMKYscDhHOwq}US)V4jtg!9`eAii&?V9_*GB5*_zA#s(T*!*yIb>fdQZ;rtvM%8Atx0`rj;uCDb2Edxq~xsCh@>xk&l{>Wq_M zlFa*v7 z9)vf6{7wUG>gV~JE;D<=LwiIxz4HKD%KLNKLT2_L$bR6`jsukB{PYFawehGRM}b@; zwW0q5v9!D#1i9=|(0T7CV!YdpaxutdSL&7h1OBHdJ6AgBAOHXW07*qoM6N<$f?2S~ A4*&oF literal 0 HcmV?d00001 diff --git a/public/favicon_96.png b/public/favicon_96.png new file mode 100644 index 0000000000000000000000000000000000000000..4074a9489baf22237f36f898146947090e2e7169 GIT binary patch literal 2681 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 literal 0 HcmV?d00001 diff --git a/scripts/build.ts b/scripts/build.ts new file mode 100644 index 0000000..4a8d743 --- /dev/null +++ b/scripts/build.ts @@ -0,0 +1,77 @@ +import fs from 'node:fs/promises' + +import { request } from '@octokit/request' + +const main = async () => { + /** + * @link https://github.com/sindresorhus/github-markdown-css + */ + const { data } = await request('POST /markdown', { + text: await fs.readFile('README.md', 'utf8'), + token: process.env.GITHUB_TOKEN, + }) + + await fs.writeFile( + 'public/index.html', + /* HTML */ ` + + + + + + Deepl Translate + + + + + + + + +
${data}
+ + + `, + ) +} + +main().catch(console.error) diff --git a/src/api.ts b/src/api.ts index 87e8a94..d273681 100644 --- a/src/api.ts +++ b/src/api.ts @@ -10,7 +10,7 @@ import { generateTranslationRequestData, generateSplitSentencesRequestData, } from './generators.js' -import { API_URL } from './settings.js' +import { API_URL, AUTO, SourceLanguage, TargetLanguage } from './settings.js' import { abbreviateLanguage } from './utils.js' const got = _got.extend({ @@ -39,29 +39,46 @@ const got = _got.extend({ }, }) -export async function splitIntoSentences(text: string, identifier?: number) { - const data = generateSplitSentencesRequestData(text, identifier) +export async function splitSentences( + text: string, + sourceLanguage?: SourceLanguage, + identifier?: number, +) { + const data = generateSplitSentencesRequestData( + text, + sourceLanguage, + identifier, + ) + return await got + .post(API_URL, { + json: data, + }) + .json() +} + +export async function splitIntoSentences( + text: string, + sourceLanguage?: SourceLanguage, + identifier?: number, +) { return extractSplitSentences( - await got - .post(API_URL, { - json: data, - }) - .json(), + await splitSentences(text, sourceLanguage, identifier), ) } export async function requestTranslation( - sourceLanguage: string, - targetLanguage: string, text: string, + targetLanguage: TargetLanguage, + sourceLanguage: SourceLanguage, identifier?: number, alternatives?: number, formalityTone?: 'formal' | 'informal', ) { + const res = await splitSentences(text, sourceLanguage, identifier) const data = generateTranslationRequestData( - sourceLanguage, + sourceLanguage === 'auto' ? res.result.lang : sourceLanguage, targetLanguage, - await splitIntoSentences(text, identifier), + extractSplitSentences(res), identifier, alternatives, formalityTone, @@ -74,18 +91,18 @@ export async function requestTranslation( } export async function translate( - sourceLanguage: string, - targetLanguage: string, text: string, + targetLanguage: TargetLanguage, + sourceLanguage: SourceLanguage = AUTO, identifier?: number, alternatives?: number, formalityTone?: 'formal' | 'informal', ) { return extractTranslatedSentences( await requestTranslation( - abbreviateLanguage(sourceLanguage), - abbreviateLanguage(targetLanguage), text, + abbreviateLanguage(targetLanguage)!, + abbreviateLanguage(sourceLanguage) ?? 'auto', identifier, alternatives, formalityTone, diff --git a/src/cli.ts b/src/cli.ts index 472628c..15569f6 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,6 +7,7 @@ import { URL } from 'node:url' import { program } from 'commander' import { translate } from './api.js' +import { SourceLanguage, TargetLanguage } from './settings.js' const __dirname = new URL('.', import.meta.url).pathname @@ -30,8 +31,8 @@ const main = async () => { .option('-f, --file ', 'File to be translated') .parse(process.argv) .opts<{ - sourceLanguage: string - targetLanguage: string + targetLanguage: TargetLanguage + sourceLanguage?: SourceLanguage text?: string file?: string formal?: boolean @@ -42,9 +43,9 @@ const main = async () => { } const translated = await translate( - sourceLanguage, - targetLanguage, text == null ? await fs.readFile(file!, 'utf8') : text, + targetLanguage, + sourceLanguage, undefined, undefined, formal == null ? formal : formal ? 'formal' : 'informal', diff --git a/src/extractors.ts b/src/extractors.ts index 31c417b..4e0efcb 100644 --- a/src/extractors.ts +++ b/src/extractors.ts @@ -1,3 +1,5 @@ +import { SourceLanguage } from './settings.js' + export interface TranslatedSentences { result: { translations: Array<{ @@ -21,6 +23,7 @@ export function extractTranslatedSentences(response: TranslatedSentences) { export interface SplittedSentences { result: { splitted_texts: string[][] + lang: SourceLanguage } } diff --git a/src/generators.ts b/src/generators.ts index 13b048f..a9af26a 100644 --- a/src/generators.ts +++ b/src/generators.ts @@ -1,8 +1,14 @@ import { generateId, generateTimestamp } from './hacks.js' -import { SUPPORTED_FORMALITY_TONES } from './settings.js' +import { + AUTO, + SourceLanguage, + SUPPORTED_FORMALITY_TONES, + TargetLanguage, +} from './settings.js' export function generateSplitSentencesRequestData( text: string, + sourceLanguage: SourceLanguage = AUTO, identifier = generateId(), ) { return { @@ -10,7 +16,7 @@ export function generateSplitSentencesRequestData( method: 'LMT_split_into_sentences', params: { lang: { - lang_user_selected: 'auto', + lang_user_selected: sourceLanguage, user_preferred_langs: [], }, texts: [text], @@ -53,8 +59,8 @@ function generateCommonJobParams(formality?: 'formal' | 'informal') { } export function generateTranslationRequestData( - sourceLanguage: string, - targetLanguage: string, + sourceLanguage: SourceLanguage, + targetLanguage: TargetLanguage, sentences: string[], identifier = generateId(), alternatives = 1, diff --git a/src/settings.ts b/src/settings.ts index f0b8659..025ae54 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,5 +1,7 @@ export const API_URL = 'https://www2.deepl.com/jsonrpc' +export const AUTO = 'auto' + export const SUPPORTED_LANGUAGES = [ { code: 'BG', language: 'Bulgarian' }, { code: 'ZH', language: 'Chinese' }, @@ -25,6 +27,17 @@ export const SUPPORTED_LANGUAGES = [ { code: 'SL', language: 'Slovenian' }, { code: 'ES', language: 'Spanish' }, { code: 'SV', language: 'Swedish' }, -] +] as const + +export type SupportedLanguage = typeof SUPPORTED_LANGUAGES[number] + +export type Language = SupportedLanguage['code'] | SupportedLanguage['language'] + +export type TargetLanguage = + | Language + | Lowercase + | Uppercase + +export type SourceLanguage = TargetLanguage | 'auto' export const SUPPORTED_FORMALITY_TONES = ['formal', 'informal'] diff --git a/src/utils.ts b/src/utils.ts index 2b5d2b1..ea0ba61 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { SUPPORTED_LANGUAGES } from './settings.js' +import { SUPPORTED_LANGUAGES, TargetLanguage } from './settings.js' export function createAbbreviationsDictionary(languages = SUPPORTED_LANGUAGES) { return languages.reduce>((acc, lang) => { @@ -9,5 +9,7 @@ export function createAbbreviationsDictionary(languages = SUPPORTED_LANGUAGES) { } export function abbreviateLanguage(language: string) { - return createAbbreviationsDictionary()[language.toLowerCase()] + return createAbbreviationsDictionary()[language.toLowerCase()] as + | TargetLanguage + | undefined } diff --git a/test/.eslintrc b/test/.eslintrc deleted file mode 100644 index 7c307ac..0000000 --- a/test/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-magic-numbers": 0, - "jest/no-standalone-expect": 0 - } -} diff --git a/test/generators.spec.ts b/test/generators.spec.ts index c711b89..5044f7e 100644 --- a/test/generators.spec.ts +++ b/test/generators.spec.ts @@ -1,5 +1,3 @@ -import { expect, test } from 'vitest' - import { generateJobs } from 'deepl-translate' test('generate jobs with one sentence', () => { diff --git a/test/hacks.spec.ts b/test/hacks.spec.ts index 9e557fc..e70769d 100644 --- a/test/hacks.spec.ts +++ b/test/hacks.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from 'vitest' +/* eslint-disable @typescript-eslint/no-magic-numbers */ import { calculateValidTimestamp, generateId } from 'deepl-translate' diff --git a/test/sentence-split.spec.ts b/test/sentence-split.spec.ts index d115bd0..cef19ce 100644 --- a/test/sentence-split.spec.ts +++ b/test/sentence-split.spec.ts @@ -1,6 +1,10 @@ -import { expect, test } from 'vitest' +import { jest } from '@jest/globals' -import { splitIntoSentences } from '../src/api.js' +import { splitIntoSentences } from 'deepl-translate' + +if (process.env.CI === 'true') { + jest.setTimeout(20 * 1000) +} test('splitIntoSentences', async () => { const text = diff --git a/test/translation.spec.ts b/test/translation.spec.ts index d797189..bd075d9 100644 --- a/test/translation.spec.ts +++ b/test/translation.spec.ts @@ -1,7 +1,11 @@ -import { beforeEach, expect, test } from 'vitest' +import { jest } from '@jest/globals' import { randRange, translate } from 'deepl-translate' +if (process.env.CI === 'true') { + jest.setTimeout(20 * 1000) +} + const sleep = (timeout?: number) => new Promise(resolve => setTimeout(resolve, timeout)) @@ -12,7 +16,7 @@ test('translate russian', async () => { const target_language = 'EN' const text = 'Я сошла с ума' const expected_translation = "I'm out of my mind." - const translation = await translate(source_language, target_language, text) + const translation = await translate(text, target_language, source_language) expect(translation).toEqual(expected_translation) }) @@ -21,8 +25,8 @@ test('translate chinese', async () => { const target_language = 'dutch' const text = '你好' const expected_translation = 'Hallo' - const translation = await translate(source_language, target_language, text) - expect(translation).includes(expected_translation) + const translation = await translate(text, target_language, source_language) + expect(translation).toContain(expected_translation) }) test('translate greek romanian', async () => { @@ -30,25 +34,30 @@ test('translate greek romanian', async () => { const target_language = 'ro' const text = 'Γεια σας' const expected_translation = 'bună ziua' - const translation = await translate(source_language, target_language, text) - expect(translation.toLowerCase()).includes(expected_translation) + const translation = await translate( + text, + target_language, + // @ts-expect-error + source_language, + ) + expect(translation.toLowerCase()).toContain(expected_translation) }) test('translate sentence', async () => { const text = 'Up and down.' const expected_translation = 'Op en neer.' - expect(await translate('EN', 'NL', text)).toBe(expected_translation) + expect(await translate(text, 'NL', 'EN')).toBe(expected_translation) }) test('translate sentences', async () => { const text = "His palms are sweaty, knees weak, arms are heavy. There's vomit on his sweater already, mom's spaghetti." - const translation = await translate('EN', 'DE', text) + const translation = await translate(text, 'DE', 'EN') - expect(translation).includes('Handfläche') - expect(translation).includes('Pullover') - expect(translation).includes('Spaghetti') + expect(translation).toContain('Handfläche') + expect(translation).toContain('Pullover') + expect(translation).toContain('Spaghetti') }) const PARAGRAPHS = [ @@ -61,7 +70,7 @@ const PARAGRAPHS = [ test('translate generated paragraph', async () => { const text = PARAGRAPHS[randRange(0, PARAGRAPHS.length - 1)] - const translation = await translate('EN', 'DE', text) + const translation = await translate(text, 'DE', 'EN') expect(translation.length).toBeGreaterThan(1) }) @@ -69,39 +78,41 @@ test('formal german translation', async () => { const text = "What's your name?" const expected_translations = ['Wie ist Ihr Name?', 'Wie heißen Sie?'] const translation = await translate( - 'EN', - 'DE', text, + 'DE', + 'EN', undefined, undefined, 'formal', ) - expect(expected_translations).includes(translation) + expect(expected_translations).toContain(translation) }) test('informal german translation', async () => { const text = "What's your name?" const expected_translations = ['Wie ist dein Name?', 'Wie heißt du?'] const translation = await translate( - 'EN', - 'DE', text, + 'DE', + 'EN', undefined, undefined, 'informal', ) - expect(expected_translations).includes(translation) + expect(expected_translations).toContain(translation) }) test('invalid_formal_tone', () => - expect( + expect(() => translate( - 'EN', - 'DE', 'ABC', + 'DE', + 'EN', undefined, undefined, // @ts-expect-error 'politically incorrect', ), - ).rejects.toThrowErrorMatchingInlineSnapshot('"expected is not a function"')) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Formality tone '{formality_tone}' not supported."`, + )) diff --git a/test/utils.spec.ts b/test/utils.spec.ts index 5c186ba..b40b929 100644 --- a/test/utils.spec.ts +++ b/test/utils.spec.ts @@ -1,5 +1,3 @@ -import { expect, test } from 'vitest' - import { abbreviateLanguage } from 'deepl-translate' test('abbreviateLanguage', () => { diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..eb47157 --- /dev/null +++ b/vercel.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "rewrites": [ + { + "source": "/(.+)", + "destination": "/api/$1" + } + ], + "github": { + "silent": true + } +} diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index cb0ba0f..0000000 --- a/vitest.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import path from 'path' - -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - resolve: { - alias: { - 'deepl-translate': path.resolve('src'), - }, - }, - test: { - coverage: { - exclude: ['test'], - reporter: ['json'], - }, - testTimeout: (process.env.CI === 'true' ? 20 : 5) * 1000, - }, -})