mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(cli): translate sync-keys
command (#4265)
* feat(cli): `translate sync-keys` command * refactor(cli): use promise and add comments * refactor(phrases): fix lint errors * refactor(cli): fix bugs and add changeset
This commit is contained in:
parent
fe54bbafe2
commit
fde330a8b3
34 changed files with 570 additions and 135 deletions
7
.changeset/sixty-cows-hang.md
Normal file
7
.changeset/sixty-cows-hang.md
Normal file
|
@ -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.
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
115
packages/cli/src/commands/translate/sync-keys/index.ts
Normal file
115
packages/cli/src/commands/translate/sync-keys/index.ts
Normal file
|
@ -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;
|
330
packages/cli/src/commands/translate/sync-keys/utils.ts
Normal file
330
packages/cli/src/commands/translate/sync-keys/utils.ts
Normal file
|
@ -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<string, string>();
|
||||
|
||||
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 });
|
||||
}
|
||||
};
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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: '現在',
|
||||
|
|
|
@ -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}}日',
|
||||
|
|
|
@ -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: '현재',
|
||||
|
|
|
@ -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}} 일',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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: 'Текущий',
|
||||
|
|
|
@ -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}} дней',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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}}天',
|
||||
|
|
|
@ -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}}天',
|
||||
|
|
|
@ -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}}天',
|
||||
|
|
168
pnpm-lock.yaml
168
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:
|
||||
|
|
Loading…
Reference in a new issue