gt 2.22.4 → 2.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/auth/errors.d.ts +1 -0
- package/dist/auth/errors.js +12 -2
- package/dist/auth/errors.js.map +1 -1
- package/dist/auth/interactiveLogin.d.ts +2 -0
- package/dist/auth/interactiveLogin.js +22 -0
- package/dist/auth/interactiveLogin.js.map +1 -0
- package/dist/auth/oauth.js +2 -2
- package/dist/auth/oauth.js.map +1 -1
- package/dist/cli/base.d.ts +22 -4
- package/dist/cli/base.js +328 -223
- package/dist/cli/base.js.map +1 -1
- package/dist/cli/commands/api.js +15 -16
- package/dist/cli/commands/api.js.map +1 -1
- package/dist/cli/node.js +1 -1
- package/dist/cli/node.js.map +1 -1
- package/dist/cli/react.js +1 -1
- package/dist/cli/react.js.map +1 -1
- package/dist/cli/vue.js +2 -2
- package/dist/cli/vue.js.map +1 -1
- package/dist/config/generateSettings.d.ts +2 -0
- package/dist/config/generateSettings.js +13 -6
- package/dist/config/generateSettings.js.map +1 -1
- package/dist/config/resolveConfig.js +0 -4
- package/dist/config/resolveConfig.js.map +1 -1
- package/dist/config/validateSettings.js +5 -4
- package/dist/config/validateSettings.js.map +1 -1
- package/dist/console/{inkLocaleData.d.ts → localeOptions.d.ts} +7 -2
- package/dist/console/{inkLocaleData.js → localeOptions.js} +3 -8
- package/dist/console/localeOptions.js.map +1 -0
- package/dist/console/logger.d.ts +7 -0
- package/dist/console/logger.js +48 -85
- package/dist/console/logger.js.map +1 -1
- package/dist/console/logging.d.ts +11 -1
- package/dist/console/logging.js +88 -100
- package/dist/console/logging.js.map +1 -1
- package/dist/formats/files/aggregateFiles.js +1 -1
- package/dist/formats/files/supportedFiles.d.ts +3 -0
- package/dist/formats/files/supportedFiles.js +10 -1
- package/dist/formats/files/supportedFiles.js.map +1 -1
- package/dist/formats/yaml/mergeYaml.js +1 -1
- package/dist/fs/config/loadConfig.d.ts +2 -0
- package/dist/fs/config/loadConfig.js +5 -1
- package/dist/fs/config/loadConfig.js.map +1 -1
- package/dist/fs/config/setupConfig.d.ts +18 -9
- package/dist/fs/config/setupConfig.js +51 -31
- package/dist/fs/config/setupConfig.js.map +1 -1
- package/dist/fs/createLoadTranslationsFile.d.ts +22 -1
- package/dist/fs/createLoadTranslationsFile.js +43 -20
- package/dist/fs/createLoadTranslationsFile.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/generated/version.js.map +1 -1
- package/dist/hooks/postProcess.d.ts +1 -2
- package/dist/hooks/postProcess.js +1 -1
- package/dist/hooks/postProcess.js.map +1 -1
- package/dist/locadex/setupFlow.d.ts +4 -1
- package/dist/locadex/setupFlow.js +5 -3
- package/dist/locadex/setupFlow.js.map +1 -1
- package/dist/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.js +1 -1
- package/dist/react/jsx/utils/jsxParsing/parseJsx.js +1 -1
- package/dist/react/jsx/utils/parseString.js +1 -1
- package/dist/react/jsx/utils/stringParsing/derivation/index.js +1 -1
- package/dist/setup/buildTools/index.d.ts +44 -0
- package/dist/setup/buildTools/index.js +10 -0
- package/dist/setup/buildTools/index.js.map +1 -0
- package/dist/setup/buildTools/vite.d.ts +2 -0
- package/dist/setup/buildTools/vite.js +61 -0
- package/dist/setup/buildTools/vite.js.map +1 -0
- package/dist/setup/developmentCredentials.d.ts +40 -5
- package/dist/setup/developmentCredentials.js +119 -37
- package/dist/setup/developmentCredentials.js.map +1 -1
- package/dist/setup/instructions/base.md +1 -1
- package/dist/setup/onboarding.d.ts +131 -0
- package/dist/setup/onboarding.js +289 -0
- package/dist/setup/onboarding.js.map +1 -0
- package/dist/setup/setupTarget.d.ts +1 -0
- package/dist/setup/setupTarget.js +52 -0
- package/dist/setup/setupTarget.js.map +1 -0
- package/dist/setup/setupViteSPA.d.ts +32 -1
- package/dist/setup/setupViteSPA.js +110 -20
- package/dist/setup/setupViteSPA.js.map +1 -1
- package/dist/setup/userInput.d.ts +12 -3
- package/dist/setup/userInput.js +27 -11
- package/dist/setup/userInput.js.map +1 -1
- package/dist/setup/wizard.d.ts +19 -3
- package/dist/setup/wizard.js +119 -105
- package/dist/setup/wizard.js.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.js +13 -1
- package/dist/types/index.js.map +1 -0
- package/dist/utils/credentials.d.ts +9 -6
- package/dist/utils/credentials.js +36 -22
- package/dist/utils/credentials.js.map +1 -1
- package/dist/utils/monorepoVersionCheck.d.ts +1 -1
- package/dist/utils/monorepoVersionCheck.js +5 -5
- package/dist/utils/monorepoVersionCheck.js.map +1 -1
- package/dist/utils/packageManager.js +13 -14
- package/dist/utils/packageManager.js.map +1 -1
- package/package.json +5 -9
- package/dist/console/inkFields.d.ts +0 -23
- package/dist/console/inkFields.js +0 -88
- package/dist/console/inkFields.js.map +0 -1
- package/dist/console/inkLayout.d.ts +0 -7
- package/dist/console/inkLayout.js +0 -140
- package/dist/console/inkLayout.js.map +0 -1
- package/dist/console/inkLocaleData.js.map +0 -1
- package/dist/console/inkPrompts.d.ts +0 -8
- package/dist/console/inkPrompts.js +0 -499
- package/dist/console/inkPrompts.js.map +0 -1
- package/dist/console/inkSession.d.ts +0 -3
- package/dist/console/inkSession.js +0 -42
- package/dist/console/inkSession.js.map +0 -1
- package/dist/console/inkTerminal.d.ts +0 -4
- package/dist/console/inkTerminal.js +0 -15
- package/dist/console/inkTerminal.js.map +0 -1
- package/dist/console/inkTheme.d.ts +0 -1
- package/dist/console/inkTheme.js +0 -6
- package/dist/console/inkTheme.js.map +0 -1
- package/dist/console/inkTypes.d.ts +0 -69
- package/dist/console/inkTypes.js +0 -1
- package/dist/console/inkUtils.d.ts +0 -24
- package/dist/console/inkUtils.js +0 -87
- package/dist/console/inkUtils.js.map +0 -1
- package/dist/console/terminalSession.d.ts +0 -5
- package/dist/console/terminalSession.js +0 -38
- package/dist/console/terminalSession.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupConfig.js","names":[],"sources":["../../../src/fs/config/setupConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { displayCreatedConfigFile } from '../../console/logging.js';\nimport { FilesOptions, SupportedFrameworks } from '../../types/index.js';\nimport {
|
|
1
|
+
{"version":3,"file":"setupConfig.js","names":[],"sources":["../../../src/fs/config/setupConfig.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { displayCreatedConfigFile } from '../../console/logging.js';\nimport { FilesOptions, SupportedFrameworks } from '../../types/index.js';\nimport {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/internal';\nimport { GT_CONFIG_SCHEMA_URL } from '../../utils/constants.js';\n\nexport type SetupConfigUpdate = {\n projectId?: string;\n defaultLocale?: string;\n locales?: string[];\n src?: string[];\n files?: FilesOptions;\n framework?: SupportedFrameworks;\n baseUrl?: string;\n publish?: boolean;\n /** Removes stale global CDN intent when the selected runtime forbids it. */\n clearPublish?: boolean;\n /** File format entries deselected by an explicit format list. */\n removeFiles?: string[];\n /** Drops files.gt.output after an explicit switch to CDN storage. */\n clearGtOutput?: boolean;\n};\n\nfunction asObject(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\n/**\n * The config setup writes: the existing content with the update applied.\n * Unrelated fields and per-format options are kept; locales are replaced.\n */\nexport function mergeSetupConfig(\n oldContent: Record<string, unknown>,\n options: SetupConfigUpdate\n): Record<string, unknown> {\n // Filter out empty string values from the config object\n const newContent = {\n ...(options.projectId && { projectId: options.projectId }),\n ...(options.defaultLocale && { defaultLocale: options.defaultLocale }),\n ...(options.src && { src: options.src }),\n ...(options.framework && { framework: options.framework }),\n ...(options.baseUrl && { baseUrl: options.baseUrl }),\n ...(options.publish && { publish: options.publish }),\n };\n const mergedContent: Record<string, unknown> = {\n $schema: GT_CONFIG_SCHEMA_URL,\n ...oldContent,\n ...newContent,\n };\n\n if (options.clearPublish) {\n delete mergedContent.publish;\n }\n\n // Preserve unrelated file configuration and nested GT options when setup\n // only needs to add or update a translation output path.\n if (options.files || options.removeFiles?.length || options.clearGtOutput) {\n const oldFiles = asObject(oldContent.files);\n const files: Record<string, unknown> = { ...oldFiles, ...options.files };\n const gt = { ...asObject(oldFiles.gt), ...options.files?.gt };\n if (options.clearGtOutput) delete gt.output;\n if (Object.keys(gt).length > 0) files.gt = gt;\n else delete files.gt;\n for (const format of options.removeFiles ?? []) delete files[format];\n if (Object.keys(files).length > 0) mergedContent.files = files;\n else delete mergedContent.files;\n }\n\n // The selected locale list replaces the configured one.\n if (options.locales) {\n mergedContent.locales = options.locales;\n }\n return mergedContent;\n}\n\n/**\n * Creates the config file, or applies the update to the existing one.\n * @param {string} configFilepath - The path to the config file.\n * @param {SetupConfigUpdate} options - The values setup resolved.\n * @throws When the existing file is not valid JSON or cannot be written.\n */\nexport async function createOrUpdateConfig(\n configFilepath: string,\n options: SetupConfigUpdate\n): Promise<string> {\n try {\n let oldContent: Record<string, unknown> = {};\n if (fs.existsSync(configFilepath)) {\n const parsed = JSON.parse(\n await fs.promises.readFile(configFilepath, 'utf-8')\n );\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n Array.isArray(parsed)\n )\n throw new Error('the file does not contain a JSON object');\n oldContent = parsed as Record<string, unknown>;\n }\n\n const mergedJsonContent = JSON.stringify(\n mergeSetupConfig(oldContent, options),\n null,\n 2\n );\n await fs.promises.writeFile(configFilepath, mergedJsonContent, 'utf-8');\n\n // show update in console\n displayCreatedConfigFile(configFilepath);\n } catch (error) {\n throw new Error(\n createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: `Could not update ${configFilepath}`,\n details: formatDiagnosticErrorDetails(error),\n fix: 'Fix or remove the file, then rerun the command',\n })\n );\n }\n return configFilepath;\n}\n"],"mappings":";;;;;AA0BA,SAAS,SAAS,OAAyC;AACzD,QAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GAC7D,QACD,EAAE;;;;;;AAOR,SAAgB,iBACd,YACA,SACyB;CAEzB,MAAM,aAAa;EACjB,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,eAAe;EACrE,GAAI,QAAQ,OAAO,EAAE,KAAK,QAAQ,KAAK;EACvC,GAAI,QAAQ,aAAa,EAAE,WAAW,QAAQ,WAAW;EACzD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACnD,GAAI,QAAQ,WAAW,EAAE,SAAS,QAAQ,SAAS;EACpD;CACD,MAAM,gBAAyC;EAC7C,SAAS;EACT,GAAG;EACH,GAAG;EACJ;AAED,KAAI,QAAQ,aACV,QAAO,cAAc;AAKvB,KAAI,QAAQ,SAAS,QAAQ,aAAa,UAAU,QAAQ,eAAe;EACzE,MAAM,WAAW,SAAS,WAAW,MAAM;EAC3C,MAAM,QAAiC;GAAE,GAAG;GAAU,GAAG,QAAQ;GAAO;EACxE,MAAM,KAAK;GAAE,GAAG,SAAS,SAAS,GAAG;GAAE,GAAG,QAAQ,OAAO;GAAI;AAC7D,MAAI,QAAQ,cAAe,QAAO,GAAG;AACrC,MAAI,OAAO,KAAK,GAAG,CAAC,SAAS,EAAG,OAAM,KAAK;MACtC,QAAO,MAAM;AAClB,OAAK,MAAM,UAAU,QAAQ,eAAe,EAAE,CAAE,QAAO,MAAM;AAC7D,MAAI,OAAO,KAAK,MAAM,CAAC,SAAS,EAAG,eAAc,QAAQ;MACpD,QAAO,cAAc;;AAI5B,KAAI,QAAQ,QACV,eAAc,UAAU,QAAQ;AAElC,QAAO;;;;;;;;AAST,eAAsB,qBACpB,gBACA,SACiB;AACjB,KAAI;EACF,IAAI,aAAsC,EAAE;AAC5C,MAAI,GAAG,WAAW,eAAe,EAAE;GACjC,MAAM,SAAS,KAAK,MAClB,MAAM,GAAG,SAAS,SAAS,gBAAgB,QAAQ,CACpD;AACD,OACE,OAAO,WAAW,YAClB,WAAW,QACX,MAAM,QAAQ,OAAO,CAErB,OAAM,IAAI,MAAM,0CAA0C;AAC5D,gBAAa;;EAGf,MAAM,oBAAoB,KAAK,UAC7B,iBAAiB,YAAY,QAAQ,EACrC,MACA,EACD;AACD,QAAM,GAAG,SAAS,UAAU,gBAAgB,mBAAmB,QAAQ;AAGvE,2BAAyB,eAAe;UACjC,OAAO;AACd,QAAM,IAAI,MACR,wBAAwB;GACtB,QAAQ;GACR,UAAU;GACV,cAAc,oBAAoB;GAClC,SAAS,6BAA6B,MAAM;GAC5C,KAAK;GACN,CAAC,CACH;;AAEH,QAAO"}
|
|
@@ -1 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Every loadTranslations file the app has, in gt-next's lookup order
|
|
3
|
+
* (resolveConfigFilepath): root before src, .ts before .js. gt-next uses the
|
|
4
|
+
* first one, and falls back to the next when it is deleted.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findLoadTranslationsFiles(appDirectory: string): string[];
|
|
7
|
+
export type LoadTranslationsFileResult = 'created' | 'updated' | 'unchanged' | 'custom';
|
|
8
|
+
/**
|
|
9
|
+
* Creates or updates the generated loadTranslations.js for translationsDir
|
|
10
|
+
* (relative to appDirectory) and empty stubs for non-default locales. A
|
|
11
|
+
* loader that was not matching the previous config's generated template, or
|
|
12
|
+
* another loadTranslations file the app uses instead, is left untouched and
|
|
13
|
+
* reported as 'custom'.
|
|
14
|
+
* Directory and stub failures propagate.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createLoadTranslationsFile({ appDirectory, translationsDir, defaultLocale, locales, previousTranslationsDir, }: {
|
|
17
|
+
appDirectory: string;
|
|
18
|
+
translationsDir?: string;
|
|
19
|
+
defaultLocale: string;
|
|
20
|
+
locales: string[];
|
|
21
|
+
previousTranslationsDir?: string;
|
|
22
|
+
}): Promise<LoadTranslationsFileResult>;
|
|
@@ -9,13 +9,8 @@ function toRelativeImportPath(relativePath) {
|
|
|
9
9
|
if (!normalizedPath) return "./";
|
|
10
10
|
return normalizedPath === ".." || normalizedPath.startsWith("../") || normalizedPath.startsWith("./") ? `${normalizedPath}/` : `./${normalizedPath}/`;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const loadTranslationsDir = usingSrcDirectory ? path.join(appDirectory, "src") : appDirectory;
|
|
15
|
-
const publicPath = toRelativeImportPath(path.relative(loadTranslationsDir, path.resolve(appDirectory, translationsDir)));
|
|
16
|
-
const filePath = usingSrcDirectory ? path.join(appDirectory, "src", "loadTranslations.js") : path.join(appDirectory, "loadTranslations.js");
|
|
17
|
-
if (!fs.existsSync(filePath)) {
|
|
18
|
-
const loadTranslationsContent = `
|
|
12
|
+
function getLoaderContent(translationsDir, publicPath) {
|
|
13
|
+
return `
|
|
19
14
|
export default async function loadTranslations(locale) {
|
|
20
15
|
try {
|
|
21
16
|
// Load translations from ${translationsDir} directory
|
|
@@ -28,20 +23,48 @@ export default async function loadTranslations(locale) {
|
|
|
28
23
|
}
|
|
29
24
|
}
|
|
30
25
|
`;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Every loadTranslations file the app has, in gt-next's lookup order
|
|
29
|
+
* (resolveConfigFilepath): root before src, .ts before .js. gt-next uses the
|
|
30
|
+
* first one, and falls back to the next when it is deleted.
|
|
31
|
+
*/
|
|
32
|
+
function findLoadTranslationsFiles(appDirectory) {
|
|
33
|
+
return ["", "src"].flatMap((directory) => [".ts", ".js"].map((extension) => path.join(appDirectory, directory, `loadTranslations${extension}`))).filter((candidate) => fs.existsSync(candidate));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates or updates the generated loadTranslations.js for translationsDir
|
|
37
|
+
* (relative to appDirectory) and empty stubs for non-default locales. A
|
|
38
|
+
* loader that was not matching the previous config's generated template, or
|
|
39
|
+
* another loadTranslations file the app uses instead, is left untouched and
|
|
40
|
+
* reported as 'custom'.
|
|
41
|
+
* Directory and stub failures propagate.
|
|
42
|
+
*/
|
|
43
|
+
async function createLoadTranslationsFile({ appDirectory, translationsDir = DEFAULT_TRANSLATIONS_DIR, defaultLocale, locales, previousTranslationsDir }) {
|
|
44
|
+
const loadTranslationsDir = fs.existsSync(path.join(appDirectory, "src")) ? path.join(appDirectory, "src") : appDirectory;
|
|
45
|
+
const translationsPath = path.resolve(appDirectory, translationsDir);
|
|
46
|
+
const publicPath = toRelativeImportPath(path.relative(loadTranslationsDir, translationsPath));
|
|
47
|
+
const filePath = path.join(loadTranslationsDir, "loadTranslations.js");
|
|
48
|
+
const content = getLoaderContent(translationsDir, publicPath);
|
|
49
|
+
const previousContents = previousTranslationsDir === void 0 ? [] : [previousTranslationsDir, ...!path.isAbsolute(previousTranslationsDir) ? [`./${previousTranslationsDir}`] : []].flatMap((directory) => [directory, `${directory}/`]).map((directory) => getLoaderContent(directory, toRelativeImportPath(path.relative(loadTranslationsDir, path.resolve(appDirectory, previousTranslationsDir)))));
|
|
50
|
+
const [loaderPath] = findLoadTranslationsFiles(appDirectory);
|
|
51
|
+
const existing = loaderPath === filePath ? await fs.promises.readFile(filePath, "utf8") : void 0;
|
|
52
|
+
await fs.promises.mkdir(translationsPath, { recursive: true });
|
|
53
|
+
for (const locale of new Set(locales)) {
|
|
54
|
+
if (locale === defaultLocale) continue;
|
|
55
|
+
const stubPath = path.join(translationsPath, `${locale}.json`);
|
|
56
|
+
if (!fs.existsSync(stubPath)) await fs.promises.writeFile(stubPath, "{}");
|
|
57
|
+
}
|
|
58
|
+
if (loaderPath !== void 0 && loaderPath !== filePath || existing !== void 0 && existing !== content && !previousContents.includes(existing)) {
|
|
59
|
+
logger.info(`Found a custom ${chalk.cyan(path.basename(loaderPath ?? filePath))} at ${chalk.cyan(loaderPath ?? filePath)}; leaving it unchanged.`);
|
|
60
|
+
return "custom";
|
|
61
|
+
}
|
|
62
|
+
if (existing === content) return "unchanged";
|
|
63
|
+
await fs.promises.writeFile(filePath, content);
|
|
64
|
+
logger.info(`${existing === void 0 ? "Created" : "Updated"} ${chalk.cyan("loadTranslations.js")} at ${chalk.cyan(filePath)}.`);
|
|
65
|
+
return existing === void 0 ? "created" : "updated";
|
|
43
66
|
}
|
|
44
67
|
//#endregion
|
|
45
|
-
export { createLoadTranslationsFile };
|
|
68
|
+
export { createLoadTranslationsFile, findLoadTranslationsFiles };
|
|
46
69
|
|
|
47
70
|
//# sourceMappingURL=createLoadTranslationsFile.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLoadTranslationsFile.js","names":[],"sources":["../../src/fs/createLoadTranslationsFile.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\nimport { DEFAULT_TRANSLATIONS_DIR } from '../utils/constants.js';\n\nfunction toRelativeImportPath(relativePath: string) {\n const normalizedPath = relativePath.split(path.sep).join(path.posix.sep);\n\n if (!normalizedPath) {\n return './';\n }\n\n // Dynamic imports must use explicit relative specifiers; values like\n // \"src/_gt\" are otherwise treated as package names by Vite and Node.\n const hasExplicitRelativePrefix =\n normalizedPath === '..' ||\n normalizedPath.startsWith('../') ||\n normalizedPath.startsWith('./');\n\n return hasExplicitRelativePrefix\n ? `${normalizedPath}/`\n : `./${normalizedPath}/`;\n}\n\nexport async function
|
|
1
|
+
{"version":3,"file":"createLoadTranslationsFile.js","names":[],"sources":["../../src/fs/createLoadTranslationsFile.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\nimport { DEFAULT_TRANSLATIONS_DIR } from '../utils/constants.js';\n\nfunction toRelativeImportPath(relativePath: string) {\n const normalizedPath = relativePath.split(path.sep).join(path.posix.sep);\n\n if (!normalizedPath) {\n return './';\n }\n\n // Dynamic imports must use explicit relative specifiers; values like\n // \"src/_gt\" are otherwise treated as package names by Vite and Node.\n const hasExplicitRelativePrefix =\n normalizedPath === '..' ||\n normalizedPath.startsWith('../') ||\n normalizedPath.startsWith('./');\n\n return hasExplicitRelativePrefix\n ? `${normalizedPath}/`\n : `./${normalizedPath}/`;\n}\n\nfunction getLoaderContent(translationsDir: string, publicPath: string) {\n return `\nexport default async function loadTranslations(locale) {\n try {\n // Load translations from ${translationsDir} directory\n // This matches the GT config files.gt.output path\n const t = await import(\\`${publicPath}\\${locale}.json\\`);\n return t.default;\n } catch (error) {\n console.warn(\\`Failed to load translations for locale \\${locale}:\\`, error);\n return {};\n }\n}\n`;\n}\n\n/**\n * Every loadTranslations file the app has, in gt-next's lookup order\n * (resolveConfigFilepath): root before src, .ts before .js. gt-next uses the\n * first one, and falls back to the next when it is deleted.\n */\nexport function findLoadTranslationsFiles(appDirectory: string): string[] {\n return ['', 'src']\n .flatMap((directory) =>\n ['.ts', '.js'].map((extension) =>\n path.join(appDirectory, directory, `loadTranslations${extension}`)\n )\n )\n .filter((candidate) => fs.existsSync(candidate));\n}\n\nexport type LoadTranslationsFileResult =\n | 'created'\n | 'updated'\n | 'unchanged'\n | 'custom';\n\n/**\n * Creates or updates the generated loadTranslations.js for translationsDir\n * (relative to appDirectory) and empty stubs for non-default locales. A\n * loader that was not matching the previous config's generated template, or\n * another loadTranslations file the app uses instead, is left untouched and\n * reported as 'custom'.\n * Directory and stub failures propagate.\n */\nexport async function createLoadTranslationsFile({\n appDirectory,\n translationsDir = DEFAULT_TRANSLATIONS_DIR,\n defaultLocale,\n locales,\n previousTranslationsDir,\n}: {\n appDirectory: string;\n translationsDir?: string;\n defaultLocale: string;\n locales: string[];\n previousTranslationsDir?: string;\n}): Promise<LoadTranslationsFileResult> {\n const usingSrcDirectory = fs.existsSync(path.join(appDirectory, 'src'));\n\n const loadTranslationsDir = usingSrcDirectory\n ? path.join(appDirectory, 'src')\n : appDirectory;\n const translationsPath = path.resolve(appDirectory, translationsDir);\n const publicPath = toRelativeImportPath(\n path.relative(loadTranslationsDir, translationsPath)\n );\n const filePath = path.join(loadTranslationsDir, 'loadTranslations.js');\n const content = getLoaderContent(translationsDir, publicPath);\n // Config paths lose leading ./ and trailing / through path.join, but\n // legacy generated comments retain them. Keep the import and body exact.\n const previousContents =\n previousTranslationsDir === undefined\n ? []\n : [\n previousTranslationsDir,\n ...(!path.isAbsolute(previousTranslationsDir)\n ? [`./${previousTranslationsDir}`]\n : []),\n ]\n .flatMap((directory) => [directory, `${directory}/`])\n .map((directory) =>\n getLoaderContent(\n directory,\n toRelativeImportPath(\n path.relative(\n loadTranslationsDir,\n path.resolve(appDirectory, previousTranslationsDir)\n )\n )\n )\n );\n\n const [loaderPath] = findLoadTranslationsFiles(appDirectory);\n const existing =\n loaderPath === filePath\n ? await fs.promises.readFile(filePath, 'utf8')\n : undefined;\n // Stubs first, so a directory failure leaves no loader pointing at it; a\n // custom loader also gets them, like the Vite loader.\n await fs.promises.mkdir(translationsPath, { recursive: true });\n for (const locale of new Set(locales)) {\n // Default-locale content lives in source, so it never needs a stub.\n if (locale === defaultLocale) continue;\n const stubPath = path.join(translationsPath, `${locale}.json`);\n if (!fs.existsSync(stubPath)) await fs.promises.writeFile(stubPath, '{}');\n }\n // Another loader wins over the generated one, so writing it would not help.\n if (\n (loaderPath !== undefined && loaderPath !== filePath) ||\n (existing !== undefined &&\n existing !== content &&\n !previousContents.includes(existing))\n ) {\n logger.info(\n `Found a custom ${chalk.cyan(\n path.basename(loaderPath ?? filePath)\n )} at ${chalk.cyan(loaderPath ?? filePath)}; leaving it unchanged.`\n );\n return 'custom';\n }\n\n if (existing === content) return 'unchanged';\n await fs.promises.writeFile(filePath, content);\n logger.info(\n `${existing === undefined ? 'Created' : 'Updated'} ${chalk.cyan(\n 'loadTranslations.js'\n )} at ${chalk.cyan(filePath)}.`\n );\n return existing === undefined ? 'created' : 'updated';\n}\n"],"mappings":";;;;;;AAMA,SAAS,qBAAqB,cAAsB;CAClD,MAAM,iBAAiB,aAAa,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,MAAM,IAAI;AAExE,KAAI,CAAC,eACH,QAAO;AAUT,QAJE,mBAAmB,QACnB,eAAe,WAAW,MAAM,IAChC,eAAe,WAAW,KAAK,GAG7B,GAAG,eAAe,KAClB,KAAK,eAAe;;AAG1B,SAAS,iBAAiB,iBAAyB,YAAoB;AACrE,QAAO;;;gCAGuB,gBAAgB;;+BAEjB,WAAW;;;;;;;;;;;;;;AAe1C,SAAgB,0BAA0B,cAAgC;AACxE,QAAO,CAAC,IAAI,MAAM,CACf,SAAS,cACR,CAAC,OAAO,MAAM,CAAC,KAAK,cAClB,KAAK,KAAK,cAAc,WAAW,mBAAmB,YAAY,CACnE,CACF,CACA,QAAQ,cAAc,GAAG,WAAW,UAAU,CAAC;;;;;;;;;;AAiBpD,eAAsB,2BAA2B,EAC/C,cACA,kBAAkB,0BAClB,eACA,SACA,2BAOsC;CAGtC,MAAM,sBAFoB,GAAG,WAAW,KAAK,KAAK,cAAc,MAAM,CAEzB,GACzC,KAAK,KAAK,cAAc,MAAM,GAC9B;CACJ,MAAM,mBAAmB,KAAK,QAAQ,cAAc,gBAAgB;CACpE,MAAM,aAAa,qBACjB,KAAK,SAAS,qBAAqB,iBAAiB,CACrD;CACD,MAAM,WAAW,KAAK,KAAK,qBAAqB,sBAAsB;CACtE,MAAM,UAAU,iBAAiB,iBAAiB,WAAW;CAG7D,MAAM,mBACJ,4BAA4B,KAAA,IACxB,EAAE,GACF,CACE,yBACA,GAAI,CAAC,KAAK,WAAW,wBAAwB,GACzC,CAAC,KAAK,0BAA0B,GAChC,EAAE,CACP,CACE,SAAS,cAAc,CAAC,WAAW,GAAG,UAAU,GAAG,CAAC,CACpD,KAAK,cACJ,iBACE,WACA,qBACE,KAAK,SACH,qBACA,KAAK,QAAQ,cAAc,wBAAwB,CACpD,CACF,CACF,CACF;CAET,MAAM,CAAC,cAAc,0BAA0B,aAAa;CAC5D,MAAM,WACJ,eAAe,WACX,MAAM,GAAG,SAAS,SAAS,UAAU,OAAO,GAC5C,KAAA;AAGN,OAAM,GAAG,SAAS,MAAM,kBAAkB,EAAE,WAAW,MAAM,CAAC;AAC9D,MAAK,MAAM,UAAU,IAAI,IAAI,QAAQ,EAAE;AAErC,MAAI,WAAW,cAAe;EAC9B,MAAM,WAAW,KAAK,KAAK,kBAAkB,GAAG,OAAO,OAAO;AAC9D,MAAI,CAAC,GAAG,WAAW,SAAS,CAAE,OAAM,GAAG,SAAS,UAAU,UAAU,KAAK;;AAG3E,KACG,eAAe,KAAA,KAAa,eAAe,YAC3C,aAAa,KAAA,KACZ,aAAa,WACb,CAAC,iBAAiB,SAAS,SAAS,EACtC;AACA,SAAO,KACL,kBAAkB,MAAM,KACtB,KAAK,SAAS,cAAc,SAAS,CACtC,CAAC,MAAM,MAAM,KAAK,cAAc,SAAS,CAAC,yBAC5C;AACD,SAAO;;AAGT,KAAI,aAAa,QAAS,QAAO;AACjC,OAAM,GAAG,SAAS,UAAU,UAAU,QAAQ;AAC9C,QAAO,KACL,GAAG,aAAa,KAAA,IAAY,YAAY,UAAU,GAAG,MAAM,KACzD,sBACD,CAAC,MAAM,MAAM,KAAK,SAAS,CAAC,GAC9B;AACD,QAAO,aAAa,KAAA,IAAY,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.23.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","names":[],"sources":["../../src/generated/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const PACKAGE_VERSION = '2.
|
|
1
|
+
{"version":3,"file":"version.js","names":[],"sources":["../../src/generated/version.ts"],"sourcesContent":["// This file is auto-generated. Do not edit manually.\nexport const PACKAGE_VERSION = '2.23.0';\n"],"mappings":";AACA,MAAa,kBAAkB"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
type Formatter = 'prettier' | 'biome' | 'eslint';
|
|
1
|
+
export type Formatter = 'prettier' | 'biome' | 'eslint';
|
|
2
2
|
export declare function detectFormatter(): Promise<Formatter | null>;
|
|
3
3
|
export declare function formatFiles(filesUpdated: string[], formatter?: Formatter): Promise<void>;
|
|
4
|
-
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postProcess.js","names":[],"sources":["../../src/hooks/postProcess.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { spawn } from 'node:child_process';\nimport chalk from 'chalk';\nimport { logger } from '../console/logger.js';\n\
|
|
1
|
+
{"version":3,"file":"postProcess.js","names":[],"sources":["../../src/hooks/postProcess.ts"],"sourcesContent":["import fs from 'node:fs';\nimport { spawn } from 'node:child_process';\nimport chalk from 'chalk';\nimport { logger } from '../console/logger.js';\n\nexport type Formatter = 'prettier' | 'biome' | 'eslint';\n\nexport async function detectFormatter(): Promise<Formatter | null> {\n // Try Prettier\n try {\n await import('prettier');\n return 'prettier';\n } catch {\n // Prettier is optional.\n }\n\n // Try ESLint\n try {\n await import('eslint');\n return 'eslint';\n } catch {\n // ESLint is optional.\n }\n\n // Try Biome\n try {\n return await new Promise<Formatter | null>((resolve) => {\n const child = spawn('npx', ['@biomejs/biome', '--version'], {\n stdio: 'ignore',\n });\n\n child.on('error', () => {\n resolve(null);\n });\n\n child.on('close', (code: number) => {\n if (code === 0) {\n resolve('biome');\n } else {\n resolve(null);\n }\n });\n });\n } catch {\n // Biome is optional.\n }\n\n return null;\n}\n\nexport async function formatFiles(\n filesUpdated: string[],\n formatter?: Formatter\n): Promise<void> {\n if (filesUpdated.length === 0) return;\n\n try {\n const detectedFormatter = formatter || (await detectFormatter());\n\n if (!detectedFormatter) {\n logger.warn(chalk.yellow('No supported formatter detected'));\n return;\n }\n\n if (detectedFormatter === 'prettier') {\n logger.message(chalk.dim('Cleaning up with prettier...'));\n const prettier = await import('prettier');\n for (const file of filesUpdated) {\n const config = await prettier.resolveConfig(file);\n const content = await fs.promises.readFile(file, 'utf-8');\n const formatted = await prettier.format(content, {\n ...config,\n filepath: file,\n });\n await fs.promises.writeFile(file, formatted);\n }\n return;\n }\n\n if (detectedFormatter === 'biome') {\n logger.message(chalk.dim('Cleaning up with biome...'));\n try {\n await new Promise<void>((resolve) => {\n const args = [\n '@biomejs/biome',\n 'format',\n '--write',\n ...filesUpdated.map((file) => file),\n ];\n\n // Formatter output is diagnostics; keep stdout free for commands' data.\n const child = spawn('npx', args, {\n stdio: ['ignore', process.stderr, 'inherit'],\n });\n\n child.on('error', (error: Error) => {\n logger.warn(\n chalk.yellow('Biome formatting failed: ' + error.message)\n );\n resolve();\n });\n\n child.on('close', (code: number) => {\n if (code !== 0) {\n logger.warn(\n chalk.yellow(`Biome formatting failed with exit code ${code}`)\n );\n }\n resolve();\n });\n });\n } catch (error) {\n logger.warn(chalk.yellow('Biome formatting failed: ' + String(error)));\n }\n return;\n }\n\n if (detectedFormatter === 'eslint') {\n logger.message(chalk.dim('Cleaning up with eslint...'));\n const { ESLint } = await import('eslint');\n const eslint = new ESLint({\n fix: true,\n overrideConfigFile: undefined, // Will use project's .eslintrc\n });\n for (const file of filesUpdated) {\n const results = await eslint.lintFiles([file]);\n await ESLint.outputFixes(results);\n }\n return;\n }\n } catch (e) {\n logger.warn(chalk.yellow('Unable to run code formatter: ' + String(e)));\n }\n}\n"],"mappings":";;;;;AAOA,eAAsB,kBAA6C;AAEjE,KAAI;AACF,QAAM,OAAO;AACb,SAAO;SACD;AAKR,KAAI;AACF,QAAM,OAAO;AACb,SAAO;SACD;AAKR,KAAI;AACF,SAAO,MAAM,IAAI,SAA2B,YAAY;GACtD,MAAM,QAAQ,MAAM,OAAO,CAAC,kBAAkB,YAAY,EAAE,EAC1D,OAAO,UACR,CAAC;AAEF,SAAM,GAAG,eAAe;AACtB,YAAQ,KAAK;KACb;AAEF,SAAM,GAAG,UAAU,SAAiB;AAClC,QAAI,SAAS,EACX,SAAQ,QAAQ;QAEhB,SAAQ,KAAK;KAEf;IACF;SACI;AAIR,QAAO;;AAGT,eAAsB,YACpB,cACA,WACe;AACf,KAAI,aAAa,WAAW,EAAG;AAE/B,KAAI;EACF,MAAM,oBAAoB,aAAc,MAAM,iBAAiB;AAE/D,MAAI,CAAC,mBAAmB;AACtB,UAAO,KAAK,MAAM,OAAO,kCAAkC,CAAC;AAC5D;;AAGF,MAAI,sBAAsB,YAAY;AACpC,UAAO,QAAQ,MAAM,IAAI,+BAA+B,CAAC;GACzD,MAAM,WAAW,MAAM,OAAO;AAC9B,QAAK,MAAM,QAAQ,cAAc;IAC/B,MAAM,SAAS,MAAM,SAAS,cAAc,KAAK;IACjD,MAAM,UAAU,MAAM,GAAG,SAAS,SAAS,MAAM,QAAQ;IACzD,MAAM,YAAY,MAAM,SAAS,OAAO,SAAS;KAC/C,GAAG;KACH,UAAU;KACX,CAAC;AACF,UAAM,GAAG,SAAS,UAAU,MAAM,UAAU;;AAE9C;;AAGF,MAAI,sBAAsB,SAAS;AACjC,UAAO,QAAQ,MAAM,IAAI,4BAA4B,CAAC;AACtD,OAAI;AACF,UAAM,IAAI,SAAe,YAAY;KASnC,MAAM,QAAQ,MAAM,OAAO;MAPzB;MACA;MACA;MACA,GAAG,aAAa,KAAK,SAAS,KAAK;MAIN,EAAE,EAC/B,OAAO;MAAC;MAAU,QAAQ;MAAQ;MAAU,EAC7C,CAAC;AAEF,WAAM,GAAG,UAAU,UAAiB;AAClC,aAAO,KACL,MAAM,OAAO,8BAA8B,MAAM,QAAQ,CAC1D;AACD,eAAS;OACT;AAEF,WAAM,GAAG,UAAU,SAAiB;AAClC,UAAI,SAAS,EACX,QAAO,KACL,MAAM,OAAO,0CAA0C,OAAO,CAC/D;AAEH,eAAS;OACT;MACF;YACK,OAAO;AACd,WAAO,KAAK,MAAM,OAAO,8BAA8B,OAAO,MAAM,CAAC,CAAC;;AAExE;;AAGF,MAAI,sBAAsB,UAAU;AAClC,UAAO,QAAQ,MAAM,IAAI,6BAA6B,CAAC;GACvD,MAAM,EAAE,WAAW,MAAM,OAAO;GAChC,MAAM,SAAS,IAAI,OAAO;IACxB,KAAK;IACL,oBAAoB,KAAA;IACrB,CAAC;AACF,QAAK,MAAM,QAAQ,cAAc;IAC/B,MAAM,UAAU,MAAM,OAAO,UAAU,CAAC,KAAK,CAAC;AAC9C,UAAM,OAAO,YAAY,QAAQ;;AAEnC;;UAEK,GAAG;AACV,SAAO,KAAK,MAAM,OAAO,mCAAmC,OAAO,EAAE,CAAC,CAAC"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import { Settings } from '../types/index.js';
|
|
2
|
-
|
|
2
|
+
/** Opens the GitHub connection page unless the caller only hands off the URL. */
|
|
3
|
+
export declare function setupLocadex(settings: Settings, { openBrowser }?: {
|
|
4
|
+
openBrowser?: boolean;
|
|
5
|
+
}): Promise<string>;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { logger } from "../console/logger.js";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
//#region src/locadex/setupFlow.ts
|
|
4
|
-
|
|
4
|
+
/** Opens the GitHub connection page unless the caller only hands off the URL. */
|
|
5
|
+
async function setupLocadex(settings, { openBrowser = true } = {}) {
|
|
5
6
|
const urlToOpen = `${settings.dashboardUrl}/api/integrations/github/start?returnTo=%2Fproject%2Flocadex`;
|
|
6
|
-
await import("open").then((open) => open.default(urlToOpen, { wait: false }));
|
|
7
|
-
logger.message(`${chalk.dim(`If the browser window didn't open automatically, open the following link:`)}\n\n${chalk.cyan(urlToOpen)}`);
|
|
7
|
+
if (openBrowser) await import("open").then((open) => open.default(urlToOpen, { wait: false }));
|
|
8
|
+
logger.message(`${chalk.dim(openBrowser ? `If the browser window didn't open automatically, open the following link:` : "Open the following link to connect GitHub and finish setting up Locadex:")}\n\n${chalk.cyan(urlToOpen)}`);
|
|
9
|
+
return urlToOpen;
|
|
8
10
|
}
|
|
9
11
|
//#endregion
|
|
10
12
|
export { setupLocadex };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupFlow.js","names":[],"sources":["../../src/locadex/setupFlow.ts"],"sourcesContent":["import { Settings } from '../types/index.js';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\n\nexport async function setupLocadex(settings: Settings): Promise<
|
|
1
|
+
{"version":3,"file":"setupFlow.js","names":[],"sources":["../../src/locadex/setupFlow.ts"],"sourcesContent":["import { Settings } from '../types/index.js';\nimport { logger } from '../console/logger.js';\nimport chalk from 'chalk';\n\n/** Opens the GitHub connection page unless the caller only hands off the URL. */\nexport async function setupLocadex(\n settings: Settings,\n { openBrowser = true }: { openBrowser?: boolean } = {}\n): Promise<string> {\n const urlToOpen = `${settings.dashboardUrl}/api/integrations/github/start?returnTo=%2Fproject%2Flocadex`;\n if (openBrowser) {\n await import('open').then((open) =>\n open.default(urlToOpen, {\n wait: false,\n })\n );\n }\n\n logger.message(\n `${chalk.dim(\n openBrowser\n ? `If the browser window didn't open automatically, open the following link:`\n : 'Open the following link to connect GitHub and finish setting up Locadex:'\n )}\\n\\n${chalk.cyan(urlToOpen)}`\n );\n return urlToOpen;\n}\n"],"mappings":";;;;AAKA,eAAsB,aACpB,UACA,EAAE,cAAc,SAAoC,EAAE,EACrC;CACjB,MAAM,YAAY,GAAG,SAAS,aAAa;AAC3C,KAAI,YACF,OAAM,OAAO,QAAQ,MAAM,SACzB,KAAK,QAAQ,WAAW,EACtB,MAAM,OACP,CAAC,CACH;AAGH,QAAO,QACL,GAAG,MAAM,IACP,cACI,8EACA,2EACL,CAAC,MAAM,MAAM,KAAK,UAAU,GAC9B;AACD,QAAO"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DATA_ATTR_PREFIX } from "../constants.js";
|
|
2
2
|
import { defaultVariableNames, getVariableName, minifyVariableType } from "../../../utils/getVariableName.js";
|
|
3
|
-
import { HTML_CONTENT_PROPS } from "@generaltranslation/format/types";
|
|
4
3
|
import { isAcceptedPluralForm } from "generaltranslation/internal";
|
|
4
|
+
import { HTML_CONTENT_PROPS } from "@generaltranslation/format/types";
|
|
5
5
|
//#region src/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.ts
|
|
6
6
|
/**
|
|
7
7
|
* Construct the data-_gt prop
|
|
@@ -15,6 +15,7 @@ import { autoInsertJsxComponents, ensureTAndVarImported } from "./autoInsertion.
|
|
|
15
15
|
import { extractSourceCode } from "../extractSourceCode.js";
|
|
16
16
|
import { nodeToStrings, parseStringExpression } from "../parseString.js";
|
|
17
17
|
import { handleDerivation } from "../stringParsing/derivation/handleDerivation.js";
|
|
18
|
+
import { isAcceptedPluralForm } from "generaltranslation/internal";
|
|
18
19
|
import { randomUUID } from "node:crypto";
|
|
19
20
|
import path from "node:path";
|
|
20
21
|
import fs from "node:fs";
|
|
@@ -22,7 +23,6 @@ import * as t from "@babel/types";
|
|
|
22
23
|
import { parse } from "@babel/parser";
|
|
23
24
|
import generateModule from "@babel/generator";
|
|
24
25
|
import { HTML_CONTENT_PROPS } from "@generaltranslation/format/types";
|
|
25
|
-
import { isAcceptedPluralForm } from "generaltranslation/internal";
|
|
26
26
|
import traverseModule from "@babel/traverse";
|
|
27
27
|
//#region src/react/jsx/utils/jsxParsing/parseJsx.ts
|
|
28
28
|
const generate = generateModule.default || generateModule;
|
|
@@ -4,11 +4,11 @@ import "./constants.js";
|
|
|
4
4
|
import { warnDeriveCircularSpreadSync, warnDeriveDestructuringSync, warnDeriveFunctionNoResultsSync, warnDeriveNonConstVariableSync, warnDeriveOptionalChainingSync, warnDeriveUnresolvableValueSync, warnFunctionNotFoundSync, warnInvalidDeclareVarNameSync } from "../../../console/index.js";
|
|
5
5
|
import { resolveImportPath } from "./resolveImportPath.js";
|
|
6
6
|
import { buildImportMap } from "./buildImportMap.js";
|
|
7
|
+
import { declareVar } from "generaltranslation/internal";
|
|
7
8
|
import fs from "node:fs";
|
|
8
9
|
import * as t from "@babel/types";
|
|
9
10
|
import { parse } from "@babel/parser";
|
|
10
11
|
import generateModule from "@babel/generator";
|
|
11
|
-
import { declareVar } from "generaltranslation/internal";
|
|
12
12
|
import traverseModule from "@babel/traverse";
|
|
13
13
|
//#region src/react/jsx/utils/parseString.ts
|
|
14
14
|
const traverse = traverseModule.default || traverseModule;
|
|
@@ -2,9 +2,9 @@ import { isValidIcu } from "../../../evaluateJsx.js";
|
|
|
2
2
|
import { warnInvalidIcuSync, warnNonStringSync } from "../../../../../console/index.js";
|
|
3
3
|
import { nodeToStrings } from "../../parseString.js";
|
|
4
4
|
import { handleDerivation } from "./handleDerivation.js";
|
|
5
|
+
import { indexVars } from "generaltranslation/internal";
|
|
5
6
|
import { randomUUID } from "node:crypto";
|
|
6
7
|
import generateModule from "@babel/generator";
|
|
7
|
-
import { indexVars } from "generaltranslation/internal";
|
|
8
8
|
//#region src/react/jsx/utils/stringParsing/derivation/index.ts
|
|
9
9
|
const generate = generateModule.default || generateModule;
|
|
10
10
|
/**
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SupportedReactFrameworks } from '../../types/index.js';
|
|
2
|
+
/** A change setup left to a person, reported as a warning. */
|
|
3
|
+
export type ManualAction = {
|
|
4
|
+
whatHappened: string;
|
|
5
|
+
fix: string;
|
|
6
|
+
};
|
|
7
|
+
/** What a build-tool hook changed, and what a person still has to do. */
|
|
8
|
+
export type SetupResult = {
|
|
9
|
+
steps: string[];
|
|
10
|
+
manualActions: ManualAction[];
|
|
11
|
+
};
|
|
12
|
+
export type BuildToolContext = {
|
|
13
|
+
appDirectory: string;
|
|
14
|
+
configFilepath: string;
|
|
15
|
+
defaultLocale: string;
|
|
16
|
+
locales: string[];
|
|
17
|
+
/** Set when translations are stored locally. */
|
|
18
|
+
translationsDir?: string;
|
|
19
|
+
/** The translations directory in the existing config. */
|
|
20
|
+
previousTranslationsDir?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Setup steps for a build tool whose app entry GT configures itself. */
|
|
23
|
+
export type BuildToolSetup = {
|
|
24
|
+
framework: SupportedReactFrameworks;
|
|
25
|
+
defaultTranslationsDir: string;
|
|
26
|
+
/** The runtime entry named in the defaults text. */
|
|
27
|
+
initializer: string;
|
|
28
|
+
/** Loads local translations itself instead of loadTranslations.js. */
|
|
29
|
+
ownsLoader: boolean;
|
|
30
|
+
skipsGTInstall(isUsingGT: boolean): boolean;
|
|
31
|
+
/** The development credentials question asked with local storage. */
|
|
32
|
+
devCredentialsOption: '--live-translations' | '--dev-credentials';
|
|
33
|
+
/** Rejects an app layout it cannot configure, before any change. */
|
|
34
|
+
preflight(appDirectory: string): Promise<void>;
|
|
35
|
+
/** Keeps an existing loader in sync when the React setup is skipped. */
|
|
36
|
+
syncLoader(ctx: BuildToolContext & {
|
|
37
|
+
translationsDir: string;
|
|
38
|
+
keepAppSource?: boolean;
|
|
39
|
+
}): Promise<SetupResult>;
|
|
40
|
+
/** Configures the app entry after gt.config.json is written. */
|
|
41
|
+
apply(ctx: BuildToolContext): Promise<SetupResult>;
|
|
42
|
+
};
|
|
43
|
+
export declare const BUILD_TOOL_SETUPS: BuildToolSetup[];
|
|
44
|
+
export declare function getBuildToolSetup(framework?: string): BuildToolSetup | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { viteSetup } from "./vite.js";
|
|
2
|
+
//#region src/setup/buildTools/index.ts
|
|
3
|
+
const BUILD_TOOL_SETUPS = [viteSetup];
|
|
4
|
+
function getBuildToolSetup(framework) {
|
|
5
|
+
return BUILD_TOOL_SETUPS.find((setup) => setup.framework === framework);
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { BUILD_TOOL_SETUPS, getBuildToolSetup };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/setup/buildTools/index.ts"],"sourcesContent":["import type { SupportedReactFrameworks } from '../../types/index.js';\nimport { viteSetup } from './vite.js';\n\n/** A change setup left to a person, reported as a warning. */\nexport type ManualAction = { whatHappened: string; fix: string };\n\n/** What a build-tool hook changed, and what a person still has to do. */\nexport type SetupResult = { steps: string[]; manualActions: ManualAction[] };\n\nexport type BuildToolContext = {\n appDirectory: string;\n configFilepath: string;\n defaultLocale: string;\n locales: string[];\n /** Set when translations are stored locally. */\n translationsDir?: string;\n /** The translations directory in the existing config. */\n previousTranslationsDir?: string;\n};\n\n/** Setup steps for a build tool whose app entry GT configures itself. */\nexport type BuildToolSetup = {\n framework: SupportedReactFrameworks;\n defaultTranslationsDir: string;\n /** The runtime entry named in the defaults text. */\n initializer: string;\n /** Loads local translations itself instead of loadTranslations.js. */\n ownsLoader: boolean;\n skipsGTInstall(isUsingGT: boolean): boolean;\n /** The development credentials question asked with local storage. */\n devCredentialsOption: '--live-translations' | '--dev-credentials';\n /** Rejects an app layout it cannot configure, before any change. */\n preflight(appDirectory: string): Promise<void>;\n /** Keeps an existing loader in sync when the React setup is skipped. */\n syncLoader(\n ctx: BuildToolContext & { translationsDir: string; keepAppSource?: boolean }\n ): Promise<SetupResult>;\n /** Configures the app entry after gt.config.json is written. */\n apply(ctx: BuildToolContext): Promise<SetupResult>;\n};\n\nexport const BUILD_TOOL_SETUPS: BuildToolSetup[] = [viteSetup];\n\nexport function getBuildToolSetup(\n framework?: string\n): BuildToolSetup | undefined {\n return BUILD_TOOL_SETUPS.find((setup) => setup.framework === framework);\n}\n"],"mappings":";;AAyCA,MAAa,oBAAsC,CAAC,UAAU;AAE9D,SAAgB,kBACd,WAC4B;AAC5B,QAAO,kBAAkB,MAAM,UAAU,MAAM,cAAc,UAAU"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { DEFAULT_VITE_TRANSLATIONS_DIR } from "../../utils/constants.js";
|
|
2
|
+
import { inspectViteSPA, setupViteSPA, writeViteLoader } from "../setupViteSPA.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
//#region src/setup/buildTools/vite.ts
|
|
6
|
+
const VITE_LOADER_FILE = "src/loadTranslations.ts";
|
|
7
|
+
/** A loader left unchanged may not read the newly chosen directory. */
|
|
8
|
+
function loaderUpdateActions(translationsDir, previousTranslationsDir, custom) {
|
|
9
|
+
if (translationsDir === previousTranslationsDir) return [];
|
|
10
|
+
const fix = `Update ${custom ? "your custom " : ""}${VITE_LOADER_FILE} to load translations from ${translationsDir}`;
|
|
11
|
+
return [{
|
|
12
|
+
whatHappened: custom ? `Your custom ${VITE_LOADER_FILE} was left unchanged, but translations now go to ${translationsDir}` : `${VITE_LOADER_FILE} was left unchanged because the React setup was skipped, but translations now go to ${translationsDir}`,
|
|
13
|
+
fix
|
|
14
|
+
}];
|
|
15
|
+
}
|
|
16
|
+
const viteSetup = {
|
|
17
|
+
framework: "vite",
|
|
18
|
+
defaultTranslationsDir: DEFAULT_VITE_TRANSLATIONS_DIR,
|
|
19
|
+
initializer: "initializeGTSPA",
|
|
20
|
+
ownsLoader: true,
|
|
21
|
+
skipsGTInstall: (isUsingGT) => isUsingGT,
|
|
22
|
+
devCredentialsOption: "--live-translations",
|
|
23
|
+
async preflight(appDirectory) {
|
|
24
|
+
await inspectViteSPA(appDirectory);
|
|
25
|
+
},
|
|
26
|
+
async syncLoader({ appDirectory, defaultLocale, locales, translationsDir, previousTranslationsDir, keepAppSource }) {
|
|
27
|
+
if (keepAppSource) return {
|
|
28
|
+
steps: [],
|
|
29
|
+
manualActions: fs.existsSync(path.join(appDirectory, VITE_LOADER_FILE)) ? loaderUpdateActions(translationsDir, previousTranslationsDir, false) : []
|
|
30
|
+
};
|
|
31
|
+
const loader = await writeViteLoader({
|
|
32
|
+
appDirectory,
|
|
33
|
+
defaultLocale,
|
|
34
|
+
locales,
|
|
35
|
+
translationsDir,
|
|
36
|
+
previousTranslationsDir,
|
|
37
|
+
create: false
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
steps: loader === "written" ? [`updated ${VITE_LOADER_FILE}`] : [],
|
|
41
|
+
manualActions: loader === "custom" ? loaderUpdateActions(translationsDir, previousTranslationsDir, true) : []
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
async apply(ctx) {
|
|
45
|
+
const { manualAction } = await setupViteSPA(ctx);
|
|
46
|
+
return manualAction ? {
|
|
47
|
+
steps: [],
|
|
48
|
+
manualActions: [{
|
|
49
|
+
whatHappened: "The existing Vite setup needs a manual review",
|
|
50
|
+
fix: manualAction
|
|
51
|
+
}]
|
|
52
|
+
} : {
|
|
53
|
+
steps: ["configured initializeGTSPA"],
|
|
54
|
+
manualActions: []
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
export { viteSetup };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=vite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","names":[],"sources":["../../../src/setup/buildTools/vite.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { DEFAULT_VITE_TRANSLATIONS_DIR } from '../../utils/constants.js';\nimport {\n inspectViteSPA,\n setupViteSPA,\n writeViteLoader,\n} from '../setupViteSPA.js';\nimport type { BuildToolSetup, ManualAction } from './index.js';\n\nconst VITE_LOADER_FILE = 'src/loadTranslations.ts';\n\n/** A loader left unchanged may not read the newly chosen directory. */\nfunction loaderUpdateActions(\n translationsDir: string,\n previousTranslationsDir: string | undefined,\n custom: boolean\n): ManualAction[] {\n if (translationsDir === previousTranslationsDir) return [];\n const fix = `Update ${custom ? 'your custom ' : ''}${VITE_LOADER_FILE} to load translations from ${translationsDir}`;\n return [\n {\n whatHappened: custom\n ? `Your custom ${VITE_LOADER_FILE} was left unchanged, but translations now go to ${translationsDir}`\n : `${VITE_LOADER_FILE} was left unchanged because the React setup was skipped, but translations now go to ${translationsDir}`,\n fix,\n },\n ];\n}\n\nexport const viteSetup: BuildToolSetup = {\n framework: 'vite',\n defaultTranslationsDir: DEFAULT_VITE_TRANSLATIONS_DIR,\n initializer: 'initializeGTSPA',\n ownsLoader: true,\n skipsGTInstall: (isUsingGT) => isUsingGT,\n devCredentialsOption: '--live-translations',\n async preflight(appDirectory) {\n await inspectViteSPA(appDirectory);\n },\n // Configure keeps an existing loader in sync; init leaves application\n // source to the person.\n async syncLoader({\n appDirectory,\n defaultLocale,\n locales,\n translationsDir,\n previousTranslationsDir,\n keepAppSource,\n }) {\n if (keepAppSource) {\n return {\n steps: [],\n manualActions: fs.existsSync(path.join(appDirectory, VITE_LOADER_FILE))\n ? loaderUpdateActions(translationsDir, previousTranslationsDir, false)\n : [],\n };\n }\n const loader = await writeViteLoader({\n appDirectory,\n defaultLocale,\n locales,\n translationsDir,\n previousTranslationsDir,\n create: false,\n });\n return {\n steps: loader === 'written' ? [`updated ${VITE_LOADER_FILE}`] : [],\n manualActions:\n loader === 'custom'\n ? loaderUpdateActions(translationsDir, previousTranslationsDir, true)\n : [],\n };\n },\n async apply(ctx) {\n const { manualAction } = await setupViteSPA(ctx);\n return manualAction\n ? {\n steps: [],\n manualActions: [\n {\n whatHappened: 'The existing Vite setup needs a manual review',\n fix: manualAction,\n },\n ],\n }\n : { steps: ['configured initializeGTSPA'], manualActions: [] };\n },\n};\n"],"mappings":";;;;;AAUA,MAAM,mBAAmB;;AAGzB,SAAS,oBACP,iBACA,yBACA,QACgB;AAChB,KAAI,oBAAoB,wBAAyB,QAAO,EAAE;CAC1D,MAAM,MAAM,UAAU,SAAS,iBAAiB,KAAK,iBAAiB,6BAA6B;AACnG,QAAO,CACL;EACE,cAAc,SACV,eAAe,iBAAiB,kDAAkD,oBAClF,GAAG,iBAAiB,sFAAsF;EAC9G;EACD,CACF;;AAGH,MAAa,YAA4B;CACvC,WAAW;CACX,wBAAwB;CACxB,aAAa;CACb,YAAY;CACZ,iBAAiB,cAAc;CAC/B,sBAAsB;CACtB,MAAM,UAAU,cAAc;AAC5B,QAAM,eAAe,aAAa;;CAIpC,MAAM,WAAW,EACf,cACA,eACA,SACA,iBACA,yBACA,iBACC;AACD,MAAI,cACF,QAAO;GACL,OAAO,EAAE;GACT,eAAe,GAAG,WAAW,KAAK,KAAK,cAAc,iBAAiB,CAAC,GACnE,oBAAoB,iBAAiB,yBAAyB,MAAM,GACpE,EAAE;GACP;EAEH,MAAM,SAAS,MAAM,gBAAgB;GACnC;GACA;GACA;GACA;GACA;GACA,QAAQ;GACT,CAAC;AACF,SAAO;GACL,OAAO,WAAW,YAAY,CAAC,WAAW,mBAAmB,GAAG,EAAE;GAClE,eACE,WAAW,WACP,oBAAoB,iBAAiB,yBAAyB,KAAK,GACnE,EAAE;GACT;;CAEH,MAAM,MAAM,KAAK;EACf,MAAM,EAAE,iBAAiB,MAAM,aAAa,IAAI;AAChD,SAAO,eACH;GACE,OAAO,EAAE;GACT,eAAe,CACb;IACE,cAAc;IACd,KAAK;IACN,CACF;GACF,GACD;GAAE,OAAO,CAAC,6BAA6B;GAAE,eAAe,EAAE;GAAE;;CAEnE"}
|
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
import type { Settings, SupportedFrameworks } from '../types/index.js';
|
|
2
|
+
import { type OnboardingSession } from './onboarding.js';
|
|
3
|
+
/** .env.local never reaches production; the runtime key there is set on the host. */
|
|
4
|
+
export declare function productionRuntimeKeyGuidance(dashboardUrl: string): string;
|
|
2
5
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the key is never printed.
|
|
6
|
+
* Interactive setup keeps the browser login with its device fallback;
|
|
7
|
+
* noninteractive setup always shows a device code (and emits it as a JSON
|
|
8
|
+
* event) and waits for a person to approve it, without opening a browser.
|
|
7
9
|
*/
|
|
8
|
-
export declare function
|
|
10
|
+
export declare function signInForSetup(session: OnboardingSession, baseUrl: string | undefined): Promise<void>;
|
|
11
|
+
/** An existing project, or the inputs for creating one. */
|
|
12
|
+
export type DevelopmentProject = {
|
|
13
|
+
id: string;
|
|
14
|
+
} | {
|
|
15
|
+
create: {
|
|
16
|
+
orgId: string;
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export type DevelopmentProjectOptions = {
|
|
21
|
+
createProject?: boolean;
|
|
22
|
+
orgId?: string;
|
|
23
|
+
projectName?: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Records project inputs a noninteractive run is missing, before signing in,
|
|
27
|
+
* so it never waits for approval only to fail on a missing flag.
|
|
28
|
+
*/
|
|
29
|
+
export declare function checkDevelopmentProjectInputs(session: OnboardingSession, settings: Settings, options: DevelopmentProjectOptions,
|
|
30
|
+
/** Where settings.projectId came from, so a person can remove it. */
|
|
31
|
+
projectIdSource: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Chooses the project for development credentials without creating anything:
|
|
34
|
+
* a supplied or configured ID, explicit creation inputs, or (interactively)
|
|
35
|
+
* a selection among the account's projects.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveDevelopmentProject(session: OnboardingSession, settings: Settings, options: DevelopmentProjectOptions, cwd?: string): Promise<DevelopmentProject | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates the chosen project if needed, mints a development key limited to
|
|
40
|
+
* runtime translation, and saves both to .env.local. Callers inspect
|
|
41
|
+
* .env.local first; the key is never printed.
|
|
42
|
+
*/
|
|
43
|
+
export declare function provisionDevelopmentCredentials(session: OnboardingSession, project: DevelopmentProject, settings: Settings, framework: SupportedFrameworks | undefined, cwd?: string): Promise<void>;
|