diff --git a/.changeset/sixty-cows-hang.md b/.changeset/sixty-cows-hang.md new file mode 100644 index 000000000..f4d53c15a --- /dev/null +++ b/.changeset/sixty-cows-hang.md @@ -0,0 +1,7 @@ +--- +"@logto/cli": minor +--- + +add `translate sync-keys` command + +This command is helpful for syncing keys from one language to another. Run `logto translate sync-keys --help` for details. diff --git a/package.json b/package.json index e17c2b8a8..8e0595e89 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "start:dev": "pnpm -r --parallel --filter=!@logto/integration-tests --filter \"!./packages/connectors/connector-*\" dev", "start": "cd packages/core && NODE_ENV=production node .", "cli": "logto", + "changeset": "changeset", "alteration": "logto db alt", "connectors:build": "pnpm -r --filter \"./packages/connectors/connector-*\" build", "//": "# `changeset version` won't run version lifecycle scripts, see https://github.com/changesets/changesets/issues/860", @@ -22,7 +23,7 @@ "ci:test": "pnpm -r --parallel --workspace-concurrency=0 test:ci" }, "devDependencies": { - "@changesets/cli": "^2.25.0", + "@changesets/cli": "^2.26.2", "@commitlint/cli": "^17.6.6", "@commitlint/config-conventional": "^17.6.6", "@commitlint/types": "^17.4.4", diff --git a/packages/cli/package.json b/packages/cli/package.json index 2b9fb1d7a..27dc75dda 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -69,6 +69,7 @@ "slonik-interceptor-preset": "^1.2.10", "slonik-sql-tag-raw": "^1.1.4", "tar": "^6.1.11", + "typescript": "^5.0.0", "yargs": "^17.6.0", "zod": "^3.20.2" }, @@ -86,8 +87,7 @@ "jest": "^29.5.0", "lint-staged": "^13.0.0", "prettier": "^3.0.0", - "sinon": "^15.0.0", - "typescript": "^5.0.0" + "sinon": "^15.0.0" }, "eslintConfig": { "extends": "@silverhand", diff --git a/packages/cli/src/commands/translate/index.ts b/packages/cli/src/commands/translate/index.ts index d302ead0f..a06c15627 100644 --- a/packages/cli/src/commands/translate/index.ts +++ b/packages/cli/src/commands/translate/index.ts @@ -3,6 +3,7 @@ import type { CommandModule } from 'yargs'; import create from './create.js'; import listTags from './list-tags.js'; +import syncKeys from './sync-keys/index.js'; import sync from './sync.js'; const translate: CommandModule = { @@ -18,6 +19,7 @@ const translate: CommandModule = { .command(create) .command(listTags) .command(sync) + .command(syncKeys) .demandCommand(1), handler: noop, }; diff --git a/packages/cli/src/commands/translate/sync-keys/index.ts b/packages/cli/src/commands/translate/sync-keys/index.ts new file mode 100644 index 000000000..63352ec85 --- /dev/null +++ b/packages/cli/src/commands/translate/sync-keys/index.ts @@ -0,0 +1,115 @@ +import { execFile } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { promisify } from 'node:util'; + +import { isLanguageTag } from '@logto/language-kit'; +import ora from 'ora'; +import { type CommandModule } from 'yargs'; + +import { consoleLog } from '../../../utils.js'; +import { inquireInstancePath } from '../../connector/utils.js'; + +import { praseLocaleFiles, syncPhraseKeysAndFileStructure } from './utils.js'; + +const execPromise = promisify(execFile); + +const syncKeys: CommandModule< + { path?: string }, + { path?: string; baseline: string; target: string; skipLint?: boolean; package: string } +> = { + command: ['sync-keys', 'sk'], + describe: [ + 'Sync nested object keys and the file structure from baseline to target.', + 'If a key is missing in the target, it will be added with a comment to indicate that the phrase is untranslated;', + 'If a key is missing in the baseline, it will be removed from the target;', + 'If a key exists in both the baseline and the target, the value of the target will be used.', + ].join(' '), + builder: (yargs) => + yargs + .option('baseline', { + alias: 'b', + type: 'string', + describe: 'The baseline language tag', + default: 'en', + }) + .option('package', { + alias: 'pkg', + type: 'string', + describe: 'The package name of the phrases, one of `phrases` or `phrases-ui`', + default: 'phrases', + }) + .option('target', { + alias: 't', + type: 'string', + describe: 'The target language tag, or `all` to sync all languages', + }) + .option('skip-lint', { + alias: 's', + type: 'boolean', + describe: 'Skip running `eslint --fix` for locales after syncing', + }) + .demandOption(['baseline', 'target']), + handler: async ({ + path: inputPath, + baseline: baselineTag, + target: targetTag, + skipLint, + package: packageName, + }) => { + if (!isLanguageTag(baselineTag)) { + consoleLog.fatal('Invalid baseline language tag'); + } + + if (targetTag !== 'all' && !isLanguageTag(targetTag)) { + consoleLog.fatal('Invalid target language tag'); + } + + if (baselineTag === targetTag) { + consoleLog.fatal('Baseline and target cannot be the same'); + } + + if (packageName !== 'phrases' && packageName !== 'phrases-ui') { + consoleLog.fatal('Invalid package name, expected `phrases` or `phrases-ui`'); + } + + const instancePath = await inquireInstancePath(inputPath); + const phrasesPath = path.join(instancePath, 'packages', packageName); + const localesPath = path.join(phrasesPath, 'src/locales'); + const entrypoint = path.join(localesPath, baselineTag.toLowerCase(), 'index.ts'); + const baseline = praseLocaleFiles(entrypoint); + const targetLocales = + targetTag === 'all' ? fs.readdirSync(localesPath) : [targetTag.toLowerCase()]; + + /* eslint-disable no-await-in-loop */ + for (const target of targetLocales) { + if (target === baselineTag) { + continue; + } + + const spinner = ora({ + text: `Syncing object keys and file structure from ${baselineTag} to ${target}`, + }).start(); + const targetDirectory = path.join(localesPath, target); + + await syncPhraseKeysAndFileStructure(baseline, target, targetDirectory); + + spinner.succeed(`Synced object keys and file structure from ${baselineTag} to ${target}`); + } + /* eslint-enable no-await-in-loop */ + + if (!skipLint) { + const spinner = ora({ + text: 'Running `eslint --fix` for locales', + }).start(); + await execPromise( + 'pnpm', + ['eslint', '--ext', '.ts', path.relative(phrasesPath, localesPath), '--fix'], + { cwd: phrasesPath } + ); + spinner.succeed('Ran `eslint --fix` for locales'); + } + }, +}; + +export default syncKeys; diff --git a/packages/cli/src/commands/translate/sync-keys/utils.ts b/packages/cli/src/commands/translate/sync-keys/utils.ts new file mode 100644 index 000000000..126e32c73 --- /dev/null +++ b/packages/cli/src/commands/translate/sync-keys/utils.ts @@ -0,0 +1,330 @@ +import { readFileSync, existsSync } from 'node:fs'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +import { trySafe } from '@silverhand/essentials'; +import ts from 'typescript'; + +import { consoleLog } from '../../../utils.js'; + +type FileStructure = { + [key: string]: { filePath?: string; structure: FileStructure }; +}; + +type NestedPhraseObject = { + [key: string]: string | NestedPhraseObject; +}; + +type ParsedTuple = readonly [NestedPhraseObject, FileStructure]; + +/** + * Given a entrypoint file path of a language, parse the nested object of + * phrases and the file structure. + * + * @example + * Given the following file: + * + * ```ts + * import errors from './errors/index.js'; + * + * const translation = { + * page_title: 'Anwendungen', + * errors, + * }; + * ``` + * + * The returned object will be: + * + * ```ts + * { + * page_title: 'Anwendungen', + * errors: { + * page_not_found: 'Seite nicht gefunden', + * }, + * } + * ``` + * + * And the file structure will be: + * + * ```ts + * { + * errors: { + * filePath: './errors/index.js', + * structure: {}, + * }, + * } + * ``` + * + * @param filePath The entrypoint file path of a language + * + * @returns A tuple of the nested object of phrases and the file structure + * + */ +export const praseLocaleFiles = (filePath: string): ParsedTuple => { + const content = readFileSync(filePath, 'utf8'); + const ast = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true); + const importIdentifierPath = new Map(); + + const traverseNode = ( + node: ts.Node, + nestedObject: NestedPhraseObject, + fileStructure: FileStructure + ) => { + /** + * Handle property assignment in object literal expression: + * + * - Shorthand property assignments (e.g. `{ errors }`) are treated as import + * - Property assignments will be categorized per its initializer: + * - Object literal expressions (e.g. `{ errors: { page_not_found: 'Page not found' } }`) + * will be treated as nested object + * - String literals (e.g. `{ page_title: 'Applications' }`) or no substitution template + * literals (e.g. `{ page_title: `Applications` }`) will be treated as string + * - Others are not supported, and will exit with error + */ + const handleProperty = (property: ts.ObjectLiteralElementLike) => { + // Treat shorthand property assignment as import + if (ts.isShorthandPropertyAssignment(property)) { + const key = property.name.getText(); + const importPath = importIdentifierPath.get(key); + + if (!importPath) { + consoleLog.fatal(`Cannot find import path for ${key} in ${filePath}`); + } + + const resolvedPath = path.resolve(path.dirname(filePath), importPath); + + // Recursively parse the nested object from the imported file + const [phrases, structure] = praseLocaleFiles(resolvedPath); + + // eslint-disable-next-line @silverhand/fp/no-mutation + nestedObject[key] = phrases; + // eslint-disable-next-line @silverhand/fp/no-mutation + fileStructure[key] = { + filePath: importPath, + structure, + }; + } + + if (ts.isPropertyAssignment(property)) { + const key = property.name.getText(); + + // Nested object, recursively parse it + if (ts.isObjectLiteralExpression(property.initializer)) { + const [phrases, structure] = traverseNode(property.initializer, {}, {}); + // eslint-disable-next-line @silverhand/fp/no-mutation + nestedObject[key] = phrases; + // eslint-disable-next-line @silverhand/fp/no-mutation + fileStructure[key] = { structure }; + } else if ( + ts.isStringLiteral(property.initializer) || + ts.isNoSubstitutionTemplateLiteral(property.initializer) + ) { + const value = property.initializer.getText(); + // eslint-disable-next-line @silverhand/fp/no-mutation + nestedObject[key] = value; + } else { + consoleLog.fatal('Unsupported property:', property); + } + } + }; + + if (ts.isImportDeclaration(node)) { + const importPath = node.moduleSpecifier.getText().slice(1, -1).replace('.js', '.ts'); + const importIdentifier = node.importClause?.getText(); + + // Assuming only default import is used + if (importIdentifier) { + importIdentifierPath.set(importIdentifier, importPath); + } + } else if (ts.isObjectLiteralExpression(node)) { + for (const property of node.properties) { + handleProperty(property); + } + } else { + node.forEachChild((child) => { + traverseNode(child, nestedObject, fileStructure); + }); + } + + return [nestedObject, fileStructure] as const; + }; + + return traverseNode(ast, {}, {}); +}; + +const getIdentifier = (filePath: string) => { + const filename = path.basename(filePath, '.ts'); + return (filename === 'index' ? path.basename(path.dirname(filePath)) : filename).replaceAll( + '-', + '_' + ); +}; + +/** Traverse the file structure and return an array of imports in the current file. */ +const getCurrentFileImports = (fileStructure: FileStructure) => { + const imports = new Set<[string, string]>(); + + for (const [key, value] of Object.entries(fileStructure)) { + // If the key has a file path, treat it as an import and stop traversing + // since it's pointing to another file + if (value.filePath) { + imports.add([key, value.filePath]); + } + // Otherwise, recursively traverse the nested object + else { + for (const importEntry of getCurrentFileImports(value.structure)) { + imports.add(importEntry); + } + } + } + + return [...imports]; +}; + +/** + * Recursively traverse the nested object of phrases and the file structure of + * the baseline language, and generate the target language directory with the + * same file structure. + * + * Values of the nested object will be replaced with the values of the target + * language if the key exists; otherwise, the value of the baseline language + * will be used. + * + * @param baseline The baseline language tuple + * @param targetObject The target language nested object + * @param targetFilePath The target language entrypoint file path + * @param isRoot Whether the target file is the root entrypoint + */ +/* eslint-disable no-await-in-loop */ +const traverseNode = async ( + baseline: ParsedTuple, + targetObject: NestedPhraseObject, + targetFilePath: string, + isRoot = false +) => { + const [, baselineStructure] = baseline; + const targetDirectory = path.dirname(targetFilePath); + + await fs.mkdir(targetDirectory, { recursive: true }); + await fs.writeFile(targetFilePath, '', { flag: 'w+' }); + + if (isRoot) { + await fs.appendFile(targetFilePath, "import type { LocalePhrase } from '../../types.js';\n\n"); + } + + // Write imports first + const baselineEntries = getCurrentFileImports(baselineStructure); + for (const [key, value] of baselineEntries + .slice() + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB))) { + const importPath = path.join(targetDirectory, value); + await fs.appendFile( + targetFilePath, + `import ${key} from './${path + .relative(targetDirectory, importPath) + .replace('.ts', '.js')}';\n` + ); + } + + // Add a newline between imports and the object + if (baselineEntries.length > 0) { + await fs.appendFile(targetFilePath, '\n'); + } + + // Write the object + const identifier = getIdentifier(targetFilePath); + await fs.appendFile(targetFilePath, `const ${identifier} = {\n`); + + // Recursively traverse the nested object of phrases and the file structure + // of the baseline language + const traverseObject = async ( + baseline: ParsedTuple, + targetObject: NestedPhraseObject, + tabSize: number + ) => { + const [baselineObject, baselineStructure] = baseline; + + for (const [key, value] of Object.entries(baselineObject)) { + const existingValue = targetObject[key]; + + if (typeof value === 'string') { + // If the key exists in the target language and the value is a string, use + // the value of the target language; otherwise, use the value of the + // baseline language and add a comment to indicate that the phrase is + // untranslated to help identify missing translations. + await (typeof existingValue === 'string' + ? fs.appendFile(targetFilePath, `${' '.repeat(tabSize)}${key}: ${existingValue},\n`) + : fs.appendFile( + targetFilePath, + `${' '.repeat(tabSize)}${key}: ${value}, // UNTRANSLATED\n` + )); + } + // Not a string, treat it as a nested object or an import + else { + const keyStructure = baselineStructure[key]; + + // If the key has a file structure, treat it as an import + if (keyStructure?.filePath) { + await fs.appendFile(targetFilePath, `${' '.repeat(tabSize)}${key},\n`); + + await traverseNode( + [value, keyStructure.structure], + typeof existingValue === 'object' ? existingValue : {}, + path.join(targetDirectory, keyStructure.filePath) + ); + } + // Otherwise, treat it as a nested object. + else { + await fs.appendFile(targetFilePath, `${' '.repeat(tabSize)}${key}: {\n`); + await traverseObject( + [value, keyStructure?.structure ?? {}], + typeof existingValue === 'object' ? existingValue : {}, + tabSize + 2 + ); + await fs.appendFile(targetFilePath, `${' '.repeat(tabSize)}},\n`); + } + } + } + }; + + await traverseObject(baseline, targetObject, 2); + + await (isRoot + ? fs.appendFile(targetFilePath, '} satisfies LocalePhrase;\n\n') + : fs.appendFile(targetFilePath, '};\n\n')); + await fs.appendFile(targetFilePath, `export default Object.freeze(${identifier});\n`); +}; +/* eslint-enable no-await-in-loop */ + +export const syncPhraseKeysAndFileStructure = async ( + baseline: ParsedTuple, + targetLocale: string, + targetDirectory: string +) => { + const targetEntrypoint = path.join(targetDirectory, 'index.ts'); + const isTargetLocaleExist = existsSync(targetEntrypoint); + const targetObject = isTargetLocaleExist ? praseLocaleFiles(targetEntrypoint)[0] : {}; + const backupDirectory = targetDirectory + '.bak'; + + if (isTargetLocaleExist) { + await fs.rename(targetDirectory, backupDirectory); + } else { + consoleLog.warn(`Cannot find ${targetLocale} entrypoint, creating one`); + } + + await trySafe( + traverseNode(baseline, targetObject, path.join(targetDirectory, 'index.ts'), true), + (error) => { + consoleLog.plain(); + consoleLog.error(error); + consoleLog.plain(); + consoleLog.fatal( + `Failed to sync keys for ${targetLocale}, the backup is at ${backupDirectory} for recovery` + ); + } + ); + + if (isTargetLocaleExist) { + await fs.rm(backupDirectory, { recursive: true }); + } +}; diff --git a/packages/phrases/package.json b/packages/phrases/package.json index 8f91e6686..12d34d2c0 100644 --- a/packages/phrases/package.json +++ b/packages/phrases/package.json @@ -48,7 +48,10 @@ "typescript": "^5.0.0" }, "eslintConfig": { - "extends": "@silverhand" + "extends": "@silverhand", + "rules": { + "no-template-curly-in-string": "off" + } }, "prettier": "@silverhand/eslint-config/.prettierrc" } diff --git a/packages/phrases/src/locales/de/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/de/translation/admin-console/subscription/index.ts index 3e550008e..010ab3158 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/subscription/index.ts @@ -24,7 +24,6 @@ const subscription = { upgrade_pro: 'Pro upgraden', update_payment: 'Zahlung aktualisieren', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Es wurde ein Zahlungsproblem festgestellt. Der Betrag von ${{price, number}} für den vorherigen Zyklus kann nicht verarbeitet werden. Aktualisieren Sie die Zahlung, um eine Aussetzung des Logto-Dienstes zu vermeiden.', downgrade: 'Herabstufen', current: 'Aktuell', diff --git a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts index 8a9bcee58..ac77ea58b 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Ihre monatlich aktiven Benutzer (MAU) werden in 3 Stufen unterteilt, basierend darauf, wie oft sie sich während des Abrechnungszeitraums anmelden. Jede Stufe hat einen anderen Preis pro MAU-Einheit.', unlimited: 'Unbegrenzt', contact: 'Kontakt', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mo', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} Tag', days_other: '{{count, number}} Tage', diff --git a/packages/phrases/src/locales/en/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/en/translation/admin-console/subscription/index.ts index af00f6c09..091276fc9 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/subscription/index.ts @@ -24,7 +24,6 @@ const subscription = { upgrade_pro: 'Upgrade Pro', update_payment: 'Update payment', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Payment issue detected. Unable to process ${{price, number}} for previous cycle. Update payment to avoid Logto service suspension.', downgrade: 'Downgrade', current: 'Current', diff --git a/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-table.ts index a12260e6a..2e47ecf2f 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Your monthly active users (MAU) are divided into 3 tiers based on how often they log in during the billing cycle. Each tier has a different price per MAU unit.', unlimited: 'Unlimited', contact: 'Contact', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mo', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} day', days_other: '{{count, number}} days', diff --git a/packages/phrases/src/locales/es/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/es/translation/admin-console/subscription/index.ts index 3128aeec2..6039930fb 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: 'Actualizar a Pro', update_payment: 'Actualizar pago', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Se ha detectado un problema de pago. No se puede procesar ${ {price, number}} para el ciclo anterior. Actualice el pago para evitar la suspensión del servicio Logto.', downgrade: 'Degradar', current: 'Actual', diff --git a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts index 049fec11a..9b6efbf49 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Sus usuarios activos mensuales (MAU) se dividen en 3 niveles según la frecuencia con la que inician sesión durante el ciclo de facturación. Cada nivel tiene un precio diferente por unidad de MAU.', unlimited: 'Ilimitado', contact: 'Contacto', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mes', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} día', days_other: '{{count, number}} días', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/fr/translation/admin-console/subscription/index.ts index 11d9a5968..ec6752a16 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/subscription/index.ts @@ -26,7 +26,6 @@ const subscription = { upgrade_pro: 'Passer au Plan Professionnel', update_payment: 'Mettre à jour le paiement', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Problème de paiement détecté. Impossible de traiter ${{price, number}} pour le cycle précédent. Mettez à jour le paiement pour éviter la suspension du service Logto.', downgrade: 'Passer à un Plan Inférieur', current: 'Actuel', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts index 82529f3a8..82a76d71d 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Vos utilisateurs actifs mensuels (MAU) sont répartis en 3 niveaux en fonction de la fréquence à laquelle ils se connectent pendant le cycle de facturation. Chaque niveau a un prix différent par unité MAU.', unlimited: 'Illimité', contact: 'Contact', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mo', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} jour', days_other: '{{count, number}} jours', diff --git a/packages/phrases/src/locales/it/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/it/translation/admin-console/subscription/index.ts index 7b33c88c9..45d77f0f2 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: "Esegui l'upgrade a Pro", update_payment: 'Aggiorna pagamento', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Rilevato un problema di pagamento. Impossibile elaborare ${{price, number}} per il ciclo precedente. Aggiorna il pagamento per evitare la sospensione del servizio Logto.', downgrade: 'Degrado', current: 'Attuale', diff --git a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts index 38cfe0479..9b436010b 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { "* I vostri utenti attivi mensili (MAU) sono divisi in 3 livelli in base a quante volte effettuano l'accesso durante il ciclo di fatturazione. Ogni livello ha un prezzo diverso per unità MAU.", unlimited: 'Illimitato', contact: 'Contatta', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mese', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} giorno', days_other: '{{count, number}} giorni', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/ja/translation/admin-console/subscription/index.ts index 882ed05e0..8a70a302f 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: 'プロプランにアップグレード', update_payment: '支払いを更新する', payment_error: - // eslint-disable-next-line no-template-curly-in-string '支払いに問題が発生しました。前回のサイクルで ${{price, number}} を処理できませんでした。Logtoのサービス停止を回避するために支払いを更新してください。', downgrade: 'ダウングレード', current: '現在', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts index b803fe1a6..3503f17d2 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* 月間アクティブユーザー(MAU)は、請求サイクル中のログイン頻度に基づいて3つの階層に分かれます。各階層ごとに異なるMAU単価が適用されます。', unlimited: '無制限', contact: 'お問い合わせ', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mo', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}}日', days_other: '{{count, number}}日', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/ko/translation/admin-console/subscription/index.ts index 52a534517..5ac19e235 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/subscription/index.ts @@ -24,7 +24,6 @@ const subscription = { upgrade_pro: '프로 업그레이드', update_payment: '결제 정보 업데이트', payment_error: - // eslint-disable-next-line no-template-curly-in-string '결제 문제가 발생했습니다. 이전 주기에 ${{price, number}}을(를) 처리할 수 없습니다. Logto 서비스 중단을 피하기 위해 결제를 업데이트하세요.', downgrade: '다운그레이드', current: '현재', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts index 78d916a37..44a3e67df 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* 월간 활성 사용자(MAU)는 청구 주기 동안 로그인 빈도에 따라 3단계로 나뉩니다. 각 단계마다 달리 책정되는 MAU 단가가 있습니다.', unlimited: '무제한', contact: '문의', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/월', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} 일', days_other: '{{count, number}} 일', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/index.ts index ff8d6b94b..8c9783dfe 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: 'Uaktualnij do Pro', update_payment: 'Zaktualizuj płatność', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Wykryto problem z płatnością. Nie można przetworzyć ${{price, number}} za poprzedni cykl. Zaktualizuj płatność, aby uniknąć zawieszenia usługi Logto.', downgrade: 'Zdegradować', current: 'Obecnie', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts index 11f946fef..cbda2e545 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Aktywni użytkownicy miesięcznie (MAU) są podzieleni na 3 poziomy w zależności od częstotliwości logowania się w okresie rozliczeniowym. Każdy poziom ma inną cenę za jednostkę MAU.', unlimited: 'Nieograniczone', contact: 'Kontakt', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mies.', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} dzień', days_other: '{{count, number}} dni', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts index 2828d8899..d58f3cfad 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Seus usuários ativos mensais (MAU) são divididos em 3 níveis com base em quantas vezes eles fazem login durante o ciclo de faturamento. Cada nível tem um preço diferente por unidade de MAU.', unlimited: 'Ilimitado', contact: 'Contato', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mês', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} dia', days_other: '{{count, number}} dias', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/index.ts index b20206b08..3879e65f9 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: 'Atualizar para Pro', update_payment: 'Atualizar pagamento', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Problema de pagamento detectado. Não é possível processar ${{price, number}} para o ciclo anterior. Atualize o pagamento para evitar a suspensão do serviço Logto.', downgrade: 'Downgrade', current: 'Atual', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts index e44ccdb20..b42999225 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Os seus utilizadores ativos mensais (MAU) são divididos em 3 níveis com base na frequência com que iniciam sessão durante o ciclo de faturação. Cada nível tem um preço diferente por unidade de MAU.', unlimited: 'Ilimitado', contact: 'Contactar', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/mês', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} dia', days_other: '{{count, number}} dias', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/ru/translation/admin-console/subscription/index.ts index 85ba546bb..04d716b1b 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/subscription/index.ts @@ -24,7 +24,6 @@ const subscription = { upgrade_pro: 'Повысить уровень до Pro', update_payment: 'Обновить платеж', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Обнаружена ошибка платежа. Невозможно обработать сумму ${{price, number}} за предыдущий цикл. Обновите платежную информацию, чтобы избежать блокировки сервиса Logto.', downgrade: 'Понизить уровень', current: 'Текущий', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts index 2cca3f6b5..d16e274ba 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Ваши активные пользователи в месяц (MAU) разделены на 3 уровня в зависимости от того, как часто они входят в систему в течение биллингового периода. Каждый уровень имеет свою стоимость за единицу MAU.', unlimited: 'Неограниченно', contact: 'Связаться', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/мес.', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} день', days_other: '{{count, number}} дней', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/index.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/index.ts index 1fdea8444..fcc5f8e29 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/index.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/index.ts @@ -25,7 +25,6 @@ const subscription = { upgrade_pro: "Pro'ya yükselt", update_payment: 'Ödemeyi Güncelle', payment_error: - // eslint-disable-next-line no-template-curly-in-string 'Ödeme hatası tespit edildi. Önceki döngü için ${{price, number}} işlenemedi. Logto hizmeti askıya alınmasını önlemek için ödemeleri güncelleyin.', downgrade: 'Düşür', current: 'Mevcut', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts index b75ae6f70..3bedda937 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* Aylık etkin kullanıcılarınız (MAU), faturalandırma dönemi boyunca ne sıklıkla oturum açtıklarına göre 3 düzeye ayrılır. Her düzeyin farklı bir MAU birim fiyatı vardır.', unlimited: 'Sınırsız', contact: 'İletişim', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/ay', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}} gün', days_other: '{{count, number}} gün', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts index 6455db28a..72b095978 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* 您的每月活跃用户(MAU)根据在结算周期内登录的频率分为3个层级。每个层级的MAU单价不同。', unlimited: '无限制', contact: '联系', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/月', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}}天', days_other: '{{count, number}}天', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts index 5a4bfc2eb..f025f83b0 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* 您的每月活躍用戶(MAU)將根據在結算週期內登錄的頻率分為3個層級。每個層級都有不同的MAU單價。', unlimited: '無限制', contact: '聯絡', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/月', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}}天', days_other: '{{count, number}}天', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts index 82230a209..2344bce40 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts @@ -59,9 +59,9 @@ const quota_table = { '* 您的每月活躍使用者(MAU)將根據在結算週期內登錄的頻率分為3個層級。每個層級都有不同的MAU單價。', unlimited: '無限制', contact: '聯絡', - // eslint-disable-next-line no-template-curly-in-string + monthly_price: '${{value, number}}/月', - // eslint-disable-next-line no-template-curly-in-string + mau_price: '${{value, number}}/MAU', days_one: '{{count, number}}天', days_other: '{{count, number}}天', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef07b7918..2bc703622 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,8 +13,8 @@ importers: version: link:packages/cli devDependencies: '@changesets/cli': - specifier: ^2.25.0 - version: 2.25.0 + specifier: ^2.26.2 + version: 2.26.2 '@commitlint/cli': specifier: ^17.6.6 version: 17.6.6 @@ -181,6 +181,9 @@ importers: tar: specifier: ^6.1.11 version: 6.1.11 + typescript: + specifier: ^5.0.0 + version: 5.0.2 yargs: specifier: ^17.6.0 version: 17.6.0 @@ -230,9 +233,6 @@ importers: sinon: specifier: ^15.0.0 version: 15.0.0 - typescript: - specifier: ^5.0.0 - version: 5.0.2 packages/connectors/connector-alipay-native: dependencies: @@ -6248,14 +6248,14 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@changesets/apply-release-plan@6.1.1: - resolution: {integrity: sha512-LaQiP/Wf0zMVR0HNrLQAjz3rsNsr0d/RlnP6Ef4oi8VafOwnY1EoWdK4kssuUJGgNgDyHpomS50dm8CU3D7k7g==} + /@changesets/apply-release-plan@6.1.4: + resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} dependencies: '@babel/runtime': 7.21.0 - '@changesets/config': 2.2.0 + '@changesets/config': 2.3.1 '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 1.5.0 - '@changesets/types': 5.2.0 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -6263,47 +6263,47 @@ packages: outdent: 0.5.0 prettier: 2.8.4 resolve-from: 5.0.0 - semver: 5.7.2 + semver: 7.5.4 dev: true - /@changesets/assemble-release-plan@5.2.2: - resolution: {integrity: sha512-B1qxErQd85AeZgZFZw2bDKyOfdXHhG+X5S+W3Da2yCem8l/pRy4G/S7iOpEcMwg6lH8q2ZhgbZZwZ817D+aLuQ==} + /@changesets/assemble-release-plan@5.2.4: + resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/types': 5.2.0 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 - semver: 5.7.2 + semver: 7.5.4 dev: true - /@changesets/changelog-git@0.1.13: - resolution: {integrity: sha512-zvJ50Q+EUALzeawAxax6nF2WIcSsC5PwbuLeWkckS8ulWnuPYx8Fn/Sjd3rF46OzeKA8t30loYYV6TIzp4DIdg==} + /@changesets/changelog-git@0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 dev: true - /@changesets/cli@2.25.0: - resolution: {integrity: sha512-Svu5KD2enurVHGEEzCRlaojrHjVYgF9srmMP9VQSy9c1TspX6C9lDPpulsSNIjYY9BuU/oiWpjBgR7RI9eQiAA==} + /@changesets/cli@2.26.2: + resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} hasBin: true dependencies: - '@babel/runtime': 7.19.4 - '@changesets/apply-release-plan': 6.1.1 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/changelog-git': 0.1.13 - '@changesets/config': 2.2.0 + '@babel/runtime': 7.21.0 + '@changesets/apply-release-plan': 6.1.4 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/changelog-git': 0.1.14 + '@changesets/config': 2.3.1 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 - '@changesets/get-release-plan': 3.0.15 - '@changesets/git': 1.5.0 + '@changesets/get-dependents-graph': 1.3.6 + '@changesets/get-release-plan': 3.0.17 + '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 - '@changesets/write': 0.2.1 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@changesets/write': 0.2.3 '@manypkg/get-packages': 1.1.3 '@types/is-ci': 3.0.0 - '@types/semver': 6.2.3 + '@types/semver': 7.5.0 ansi-colors: 4.1.3 chalk: 2.4.2 enquirer: 2.3.6 @@ -6316,19 +6316,19 @@ packages: p-limit: 2.3.0 preferred-pm: 3.0.3 resolve-from: 5.0.0 - semver: 5.7.1 + semver: 7.5.4 spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 4.1.6 dev: true - /@changesets/config@2.2.0: - resolution: {integrity: sha512-GGaokp3nm5FEDk/Fv2PCRcQCOxGKKPRZ7prcMqxEr7VSsG75MnChQE8plaW1k6V8L2bJE+jZWiRm19LbnproOw==} + /@changesets/config@2.3.1: + resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} dependencies: '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.4 + '@changesets/get-dependents-graph': 1.3.6 '@changesets/logger': 0.0.5 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 @@ -6340,25 +6340,25 @@ packages: extendable-error: 0.1.7 dev: true - /@changesets/get-dependents-graph@1.3.4: - resolution: {integrity: sha512-+C4AOrrFY146ydrgKOo5vTZfj7vetNu1tWshOID+UjPUU9afYGDXI8yLnAeib1ffeBXV3TuGVcyphKpJ3cKe+A==} + /@changesets/get-dependents-graph@1.3.6: + resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 - semver: 5.7.2 + semver: 7.5.4 dev: true - /@changesets/get-release-plan@3.0.15: - resolution: {integrity: sha512-W1tFwxE178/en+zSj/Nqbc3mvz88mcdqUMJhRzN1jDYqN3QI4ifVaRF9mcWUU+KI0gyYEtYR65tour690PqTcA==} + /@changesets/get-release-plan@3.0.17: + resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} dependencies: '@babel/runtime': 7.21.0 - '@changesets/assemble-release-plan': 5.2.2 - '@changesets/config': 2.2.0 - '@changesets/pre': 1.0.13 - '@changesets/read': 0.5.8 - '@changesets/types': 5.2.0 + '@changesets/assemble-release-plan': 5.2.4 + '@changesets/config': 2.3.1 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 dev: true @@ -6366,14 +6366,15 @@ packages: resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} dev: true - /@changesets/git@1.5.0: - resolution: {integrity: sha512-Xo8AT2G7rQJSwV87c8PwMm6BAc98BnufRMsML7m7Iw8Or18WFvFmxqG5aOL5PBvhgq9KrKvaeIBNIymracSuHg==} + /@changesets/git@2.0.0: + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 + micromatch: 4.0.5 spawndamnit: 2.0.0 dev: true @@ -6383,31 +6384,31 @@ packages: chalk: 2.4.2 dev: true - /@changesets/parse@0.3.15: - resolution: {integrity: sha512-3eDVqVuBtp63i+BxEWHPFj2P1s3syk0PTrk2d94W9JD30iG+OER0Y6n65TeLlY8T2yB9Fvj6Ev5Gg0+cKe/ZUA==} + /@changesets/parse@0.3.16: + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} dependencies: - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 js-yaml: 3.14.1 dev: true - /@changesets/pre@1.0.13: - resolution: {integrity: sha512-jrZc766+kGZHDukjKhpBXhBJjVQMied4Fu076y9guY1D3H622NOw8AQaLV3oQsDtKBTrT2AUFjt9Z2Y9Qx+GfA==} + /@changesets/pre@1.0.14: + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 dev: true - /@changesets/read@0.5.8: - resolution: {integrity: sha512-eYaNfxemgX7f7ELC58e7yqQICW5FB7V+bd1lKt7g57mxUrTveYME+JPaBPpYx02nP53XI6CQp6YxnR9NfmFPKw==} + /@changesets/read@0.5.9: + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} dependencies: '@babel/runtime': 7.21.0 - '@changesets/git': 1.5.0 + '@changesets/git': 2.0.0 '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.15 - '@changesets/types': 5.2.0 + '@changesets/parse': 0.3.16 + '@changesets/types': 5.2.1 chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -6417,15 +6418,15 @@ packages: resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} dev: true - /@changesets/types@5.2.0: - resolution: {integrity: sha512-km/66KOqJC+eicZXsm2oq8A8bVTSpkZJ60iPV/Nl5Z5c7p9kk8xxh6XGRTlnludHldxOOfudhnDN2qPxtHmXzA==} + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} dev: true - /@changesets/write@0.2.1: - resolution: {integrity: sha512-KUd49nt2fnYdGixIqTi1yVE1nAoZYUMdtB3jBfp77IMqjZ65hrmZE5HdccDlTeClZN0420ffpnfET3zzeY8pdw==} + /@changesets/write@0.2.3: + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} dependencies: '@babel/runtime': 7.21.0 - '@changesets/types': 5.2.0 + '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 2.8.4 @@ -9731,14 +9732,14 @@ packages: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} dev: true - /@types/semver@6.2.3: - resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} - dev: true - /@types/semver@7.3.12: resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==} dev: true + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + dev: true + /@types/serve-static@1.13.10: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: @@ -11471,14 +11472,6 @@ packages: dependencies: ms: 2.1.2 - /decamelize-keys@1.1.0: - resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} - engines: {node: '>=0.10.0'} - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - dev: true - /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -12844,7 +12837,7 @@ packages: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 dev: true @@ -13094,7 +13087,7 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.12 + fast-glob: 3.3.0 ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 @@ -15766,7 +15759,7 @@ packages: dependencies: '@types/minimist': 1.2.2 camelcase-keys: 6.2.2 - decamelize-keys: 1.1.0 + decamelize-keys: 1.1.1 hard-rejection: 2.1.0 minimist-options: 4.1.0 normalize-package-data: 2.5.0 @@ -18597,11 +18590,6 @@ packages: /semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - /semver@5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: true - /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -19897,7 +19885,7 @@ packages: smartwrap: 2.0.2 strip-ansi: 6.0.1 wcwidth: 1.0.1 - yargs: 17.7.1 + yargs: 17.7.2 dev: true /tunnel@0.0.6: