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,50 +1,117 @@
|
|
|
1
1
|
import { logger } from "../console/logger.js";
|
|
2
|
-
import {
|
|
2
|
+
import { promptConfirm, promptSelect, promptText } from "../console/logging.js";
|
|
3
|
+
import { createUserAuthError } from "../auth/errors.js";
|
|
3
4
|
import { api } from "../utils/api.js";
|
|
4
|
-
import {
|
|
5
|
+
import { setCredentials } from "../utils/credentials.js";
|
|
6
|
+
import { loginInteractively } from "../auth/interactiveLogin.js";
|
|
7
|
+
import { OnboardingError } from "./onboarding.js";
|
|
5
8
|
import chalk from "chalk";
|
|
6
9
|
import path from "node:path";
|
|
7
|
-
import { createDiagnosticMessage } from "generaltranslation/diagnostics";
|
|
10
|
+
import { createDiagnosticMessage, formatDiagnosticErrorDetails } from "generaltranslation/diagnostics";
|
|
8
11
|
import { ProjectApiKeyPermission } from "generaltranslation/api";
|
|
12
|
+
import { ApiError } from "generaltranslation/errors";
|
|
9
13
|
//#region src/setup/developmentCredentials.ts
|
|
10
14
|
const DEVELOPMENT_KEY_NAME = "Development key (gt init)";
|
|
11
|
-
|
|
15
|
+
/** .env.local never reaches production; the runtime key there is set on the host. */
|
|
16
|
+
function productionRuntimeKeyGuidance(dashboardUrl) {
|
|
17
|
+
return `${chalk.dim("For runtime translation in production, create an API key in the dashboard")} ${chalk.cyan(dashboardUrl)} ${chalk.dim("and set GT_API_KEY and GT_PROJECT_ID in your hosting environment.")}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Interactive setup keeps the browser login with its device fallback;
|
|
21
|
+
* noninteractive setup always shows a device code (and emits it as a JSON
|
|
22
|
+
* event) and waits for a person to approve it, without opening a browser.
|
|
23
|
+
*/
|
|
24
|
+
async function signInForSetup(session, baseUrl) {
|
|
25
|
+
try {
|
|
26
|
+
await loginInteractively(baseUrl, session.interactive, (deviceCode) => session.emit({
|
|
27
|
+
type: "authorization_required",
|
|
28
|
+
...deviceCode
|
|
29
|
+
}));
|
|
30
|
+
} catch (error) {
|
|
31
|
+
throw new OnboardingError(createUserAuthError("Sign in failed", error));
|
|
32
|
+
}
|
|
33
|
+
logger.message("You are now signed in.");
|
|
34
|
+
}
|
|
35
|
+
function noAccessibleOrgError(dashboardUrl) {
|
|
12
36
|
return createDiagnosticMessage({
|
|
13
37
|
source: "gt",
|
|
14
38
|
severity: "Error",
|
|
15
|
-
whatHappened: "
|
|
39
|
+
whatHappened: "No accessible organizations were found",
|
|
16
40
|
fix: `Create an organization in the dashboard ${dashboardUrl} or ask an admin for access, then rerun the setup wizard`
|
|
17
41
|
});
|
|
18
42
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}))
|
|
43
|
+
function projectCreationDeniedError(orgId, error) {
|
|
44
|
+
return createDiagnosticMessage({
|
|
45
|
+
source: "gt",
|
|
46
|
+
severity: "Error",
|
|
47
|
+
whatHappened: `Project creation was denied for organization ${orgId}`,
|
|
48
|
+
why: "Listing an organization does not confirm permission to create projects in it",
|
|
49
|
+
fix: "Ask an organization admin for org:projects:create, or use credentials that have that permission for this organization",
|
|
50
|
+
details: formatDiagnosticErrorDetails(error)
|
|
28
51
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
}
|
|
53
|
+
const noProjectChosenError = createDiagnosticMessage({
|
|
54
|
+
source: "gt",
|
|
55
|
+
severity: "Error",
|
|
56
|
+
whatHappened: "No project was chosen for the development credentials",
|
|
57
|
+
reassurance: "No project files were changed",
|
|
58
|
+
fix: "Rerun with --project-id <id> or --create-project, or skip them with --no-dev-credentials"
|
|
59
|
+
});
|
|
60
|
+
async function resolveNewProject(session, settings, options, cwd) {
|
|
61
|
+
const orgs = await api.listOrgs();
|
|
62
|
+
if (orgs.length === 0) throw new OnboardingError(noAccessibleOrgError(settings.dashboardUrl));
|
|
63
|
+
if (options.orgId && !orgs.some((org) => org.id === options.orgId)) session.reject(`--org-id ${options.orgId} is not an accessible organization`);
|
|
64
|
+
const orgId = await session.answer("--org-id", {
|
|
65
|
+
explicit: options.orgId,
|
|
66
|
+
configured: orgs.length === 1 ? orgs[0].id : void 0,
|
|
67
|
+
ask: () => promptSelect({
|
|
68
|
+
message: "Which organization should own the new project?",
|
|
69
|
+
options: orgs.map((org) => ({
|
|
70
|
+
value: org.id,
|
|
71
|
+
label: org.name
|
|
72
|
+
}))
|
|
73
|
+
})
|
|
33
74
|
});
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
const name = await session.answer("--project-name", {
|
|
76
|
+
explicit: options.projectName?.trim() || void 0,
|
|
77
|
+
ask: async () => (await promptText({
|
|
78
|
+
message: "What should the project be called?",
|
|
79
|
+
defaultValue: path.basename(cwd)
|
|
80
|
+
})).trim() || path.basename(cwd)
|
|
37
81
|
});
|
|
38
|
-
|
|
39
|
-
|
|
82
|
+
return orgId && name ? { create: {
|
|
83
|
+
orgId,
|
|
84
|
+
name
|
|
85
|
+
} } : void 0;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Records project inputs a noninteractive run is missing, before signing in,
|
|
89
|
+
* so it never waits for approval only to fail on a missing flag.
|
|
90
|
+
*/
|
|
91
|
+
function checkDevelopmentProjectInputs(session, settings, options, projectIdSource) {
|
|
92
|
+
if (settings.projectId && options.createProject) session.reject(`--create-project cannot be combined with project ${settings.projectId} from ${projectIdSource}; remove --create-project to keep using it, or remove the project ID from ${projectIdSource} to create a new project`);
|
|
93
|
+
if (settings.projectId || session.interactive) return;
|
|
94
|
+
if (!options.createProject) session.require("--project-id or --create-project");
|
|
95
|
+
else if (!options.projectName?.trim()) session.require("--project-name");
|
|
40
96
|
}
|
|
41
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Chooses the project for development credentials without creating anything:
|
|
99
|
+
* a supplied or configured ID, explicit creation inputs, or (interactively)
|
|
100
|
+
* a selection among the account's projects.
|
|
101
|
+
*/
|
|
102
|
+
async function resolveDevelopmentProject(session, settings, options, cwd = process.cwd()) {
|
|
103
|
+
if (settings.projectId) return { id: settings.projectId };
|
|
104
|
+
if (options.createProject) return resolveNewProject(session, settings, options, cwd);
|
|
42
105
|
const projects = await api.listProjects();
|
|
43
106
|
if (projects.length === 0) {
|
|
44
|
-
|
|
45
|
-
|
|
107
|
+
const create = await session.answer("--project-id or --create-project", { ask: () => promptConfirm({
|
|
108
|
+
message: "No projects found for your account. Create a new project?",
|
|
109
|
+
defaultValue: true
|
|
110
|
+
}) });
|
|
111
|
+
if (create === false) throw new OnboardingError(noProjectChosenError);
|
|
112
|
+
return create ? resolveNewProject(session, settings, options, cwd) : void 0;
|
|
46
113
|
}
|
|
47
|
-
const choice = await promptSelect({
|
|
114
|
+
const choice = await session.answer("--project-id or --create-project", { ask: () => promptSelect({
|
|
48
115
|
message: "Which project should this app use?",
|
|
49
116
|
options: [...projects.map((project) => ({
|
|
50
117
|
value: project,
|
|
@@ -54,29 +121,44 @@ async function selectProject(settings, cwd) {
|
|
|
54
121
|
value: null,
|
|
55
122
|
label: "Create a new project"
|
|
56
123
|
}]
|
|
57
|
-
});
|
|
58
|
-
|
|
124
|
+
}) });
|
|
125
|
+
if (choice === void 0) return void 0;
|
|
126
|
+
return choice ? { id: choice.id } : resolveNewProject(session, settings, options, cwd);
|
|
59
127
|
}
|
|
60
128
|
/**
|
|
61
|
-
*
|
|
62
|
-
* translation, and saves both to .env.local.
|
|
63
|
-
*
|
|
64
|
-
* the key is never printed.
|
|
129
|
+
* Creates the chosen project if needed, mints a development key limited to
|
|
130
|
+
* runtime translation, and saves both to .env.local. Callers inspect
|
|
131
|
+
* .env.local first; the key is never printed.
|
|
65
132
|
*/
|
|
66
|
-
async function provisionDevelopmentCredentials(settings, framework, cwd = process.cwd()) {
|
|
67
|
-
|
|
68
|
-
|
|
133
|
+
async function provisionDevelopmentCredentials(session, project, settings, framework, cwd = process.cwd()) {
|
|
134
|
+
let projectId;
|
|
135
|
+
if ("id" in project) projectId = project.id;
|
|
136
|
+
else {
|
|
137
|
+
const { orgId, name } = project.create;
|
|
138
|
+
const { project: created } = await api.createProject(orgId, {
|
|
139
|
+
name,
|
|
140
|
+
defaultLocale: settings.defaultLocale
|
|
141
|
+
}).catch((error) => {
|
|
142
|
+
if (!(error instanceof ApiError) || error.code !== 403) throw error;
|
|
143
|
+
throw new OnboardingError(projectCreationDeniedError(orgId, error));
|
|
144
|
+
});
|
|
145
|
+
logger.info(`Created ${created.name} (${created.id})`);
|
|
146
|
+
session.step(`created project ${created.id}`);
|
|
147
|
+
projectId = created.id;
|
|
148
|
+
}
|
|
69
149
|
const { apiKey } = await api.createProjectApiKey(projectId, {
|
|
70
150
|
name: DEVELOPMENT_KEY_NAME,
|
|
71
151
|
permissions: [ProjectApiKeyPermission["PROJECT:TRANSLATIONS:GENERATE"]]
|
|
72
152
|
});
|
|
153
|
+
session.step("created a development key");
|
|
73
154
|
await setCredentials({
|
|
74
155
|
projectId,
|
|
75
156
|
apiKey: apiKey.key
|
|
76
157
|
}, framework, cwd);
|
|
158
|
+
session.step("saved development credentials to .env.local");
|
|
77
159
|
logger.success(`Saved the project ID and a development key to ${chalk.cyan(".env.local")}.`);
|
|
78
160
|
}
|
|
79
161
|
//#endregion
|
|
80
|
-
export { provisionDevelopmentCredentials };
|
|
162
|
+
export { checkDevelopmentProjectInputs, productionRuntimeKeyGuidance, provisionDevelopmentCredentials, resolveDevelopmentProject, signInForSetup };
|
|
81
163
|
|
|
82
164
|
//# sourceMappingURL=developmentCredentials.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"developmentCredentials.js","names":[],"sources":["../../src/setup/developmentCredentials.ts"],"sourcesContent":["import path from 'node:path';\nimport chalk from 'chalk';\nimport { ProjectApiKeyPermission } from 'generaltranslation/api';\nimport { createDiagnosticMessage } from 'generaltranslation/diagnostics';\nimport { logger } from '../console/logger.js';\nimport {\n logErrorAndExit,\n promptSelect,\n promptText,\n} from '../console/logging.js';\nimport type { Settings, SupportedFrameworks } from '../types/index.js';\nimport { api } from '../utils/api.js';\nimport {\n inspectCredentialsEnvFile,\n setCredentials,\n} from '../utils/credentials.js';\n\nconst DEVELOPMENT_KEY_NAME = 'Development key (gt init)';\n\ntype ProjectChoice = Awaited<ReturnType<typeof api.listProjects>>[number];\n\nfunction noCreatableOrgError(dashboardUrl: string): string {\n return createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened:\n 'You are not a member of an organization that can create projects',\n fix: `Create an organization in the dashboard ${dashboardUrl} or ask an admin for access, then rerun the setup wizard`,\n });\n}\n\nasync function createProject(settings: Settings, cwd: string) {\n // Organizations are only needed to create; picking an existing project\n // must work for members without create access.\n const orgs = await api.listOrgs();\n if (orgs.length === 0) {\n return logErrorAndExit(noCreatableOrgError(settings.dashboardUrl));\n }\n const orgId =\n orgs.length === 1\n ? orgs[0].id\n : await promptSelect({\n message: 'Which organization should own the new project?',\n options: orgs.map((org) => ({ value: org.id, label: org.name })),\n });\n const name = await promptText({\n message: 'What should the project be called?',\n defaultValue: path.basename(cwd),\n validate: (value) => value.trim().length > 0 || 'Enter a project name',\n });\n const { project } = await api.createProject(orgId, {\n name: name.trim() || path.basename(cwd),\n defaultLocale: settings.defaultLocale,\n });\n logger.info(`Created ${project.name} (${project.id})`);\n return project.id;\n}\n\nasync function selectProject(settings: Settings, cwd: string) {\n const projects = await api.listProjects();\n if (projects.length === 0) {\n logger.info('No projects found for your account; creating one.');\n return createProject(settings, cwd);\n }\n const choice = await promptSelect<ProjectChoice | null>({\n message: 'Which project should this app use?',\n options: [\n ...projects.map((project) => ({\n value: project,\n label: project.name,\n hint: project.orgName,\n })),\n { value: null, label: 'Create a new project' },\n ],\n });\n return choice ? choice.id : createProject(settings, cwd);\n}\n\n/**\n * Picks or creates the project, mints a development key limited to runtime\n * translation, and saves both to .env.local. The file is checked before any\n * key exists, every service call completes before anything is written, and\n * the key is never printed.\n */\nexport async function provisionDevelopmentCredentials(\n settings: Settings,\n framework: SupportedFrameworks | undefined,\n cwd: string = process.cwd()\n): Promise<void> {\n await inspectCredentialsEnvFile(cwd);\n const projectId = settings.projectId || (await selectProject(settings, cwd));\n const { apiKey } = await api.createProjectApiKey(projectId, {\n name: DEVELOPMENT_KEY_NAME,\n permissions: [ProjectApiKeyPermission['PROJECT:TRANSLATIONS:GENERATE']],\n });\n await setCredentials({ projectId, apiKey: apiKey.key }, framework, cwd);\n logger.success(\n `Saved the project ID and a development key to ${chalk.cyan('.env.local')}.`\n );\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAM,uBAAuB;AAI7B,SAAS,oBAAoB,cAA8B;AACzD,QAAO,wBAAwB;EAC7B,QAAQ;EACR,UAAU;EACV,cACE;EACF,KAAK,2CAA2C,aAAa;EAC9D,CAAC;;AAGJ,eAAe,cAAc,UAAoB,KAAa;CAG5D,MAAM,OAAO,MAAM,IAAI,UAAU;AACjC,KAAI,KAAK,WAAW,EAClB,QAAO,gBAAgB,oBAAoB,SAAS,aAAa,CAAC;CAEpE,MAAM,QACJ,KAAK,WAAW,IACZ,KAAK,GAAG,KACR,MAAM,aAAa;EACjB,SAAS;EACT,SAAS,KAAK,KAAK,SAAS;GAAE,OAAO,IAAI;GAAI,OAAO,IAAI;GAAM,EAAE;EACjE,CAAC;CACR,MAAM,OAAO,MAAM,WAAW;EAC5B,SAAS;EACT,cAAc,KAAK,SAAS,IAAI;EAChC,WAAW,UAAU,MAAM,MAAM,CAAC,SAAS,KAAK;EACjD,CAAC;CACF,MAAM,EAAE,YAAY,MAAM,IAAI,cAAc,OAAO;EACjD,MAAM,KAAK,MAAM,IAAI,KAAK,SAAS,IAAI;EACvC,eAAe,SAAS;EACzB,CAAC;AACF,QAAO,KAAK,WAAW,QAAQ,KAAK,IAAI,QAAQ,GAAG,GAAG;AACtD,QAAO,QAAQ;;AAGjB,eAAe,cAAc,UAAoB,KAAa;CAC5D,MAAM,WAAW,MAAM,IAAI,cAAc;AACzC,KAAI,SAAS,WAAW,GAAG;AACzB,SAAO,KAAK,oDAAoD;AAChE,SAAO,cAAc,UAAU,IAAI;;CAErC,MAAM,SAAS,MAAM,aAAmC;EACtD,SAAS;EACT,SAAS,CACP,GAAG,SAAS,KAAK,aAAa;GAC5B,OAAO;GACP,OAAO,QAAQ;GACf,MAAM,QAAQ;GACf,EAAE,EACH;GAAE,OAAO;GAAM,OAAO;GAAwB,CAC/C;EACF,CAAC;AACF,QAAO,SAAS,OAAO,KAAK,cAAc,UAAU,IAAI;;;;;;;;AAS1D,eAAsB,gCACpB,UACA,WACA,MAAc,QAAQ,KAAK,EACZ;AACf,OAAM,0BAA0B,IAAI;CACpC,MAAM,YAAY,SAAS,aAAc,MAAM,cAAc,UAAU,IAAI;CAC3E,MAAM,EAAE,WAAW,MAAM,IAAI,oBAAoB,WAAW;EAC1D,MAAM;EACN,aAAa,CAAC,wBAAwB,iCAAiC;EACxE,CAAC;AACF,OAAM,eAAe;EAAE;EAAW,QAAQ,OAAO;EAAK,EAAE,WAAW,IAAI;AACvE,QAAO,QACL,iDAAiD,MAAM,KAAK,aAAa,CAAC,GAC3E"}
|
|
1
|
+
{"version":3,"file":"developmentCredentials.js","names":[],"sources":["../../src/setup/developmentCredentials.ts"],"sourcesContent":["import path from 'node:path';\nimport chalk from 'chalk';\nimport { ProjectApiKeyPermission } from 'generaltranslation/api';\nimport {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/diagnostics';\nimport { ApiError } from 'generaltranslation/errors';\nimport { logger } from '../console/logger.js';\nimport { promptConfirm, promptSelect, promptText } from '../console/logging.js';\nimport type { Settings, SupportedFrameworks } from '../types/index.js';\nimport { api } from '../utils/api.js';\nimport { setCredentials } from '../utils/credentials.js';\nimport { createUserAuthError } from '../auth/errors.js';\nimport { loginInteractively } from '../auth/interactiveLogin.js';\nimport { OnboardingError, type OnboardingSession } from './onboarding.js';\n\nconst DEVELOPMENT_KEY_NAME = 'Development key (gt init)';\n\n/** .env.local never reaches production; the runtime key there is set on the host. */\nexport function productionRuntimeKeyGuidance(dashboardUrl: string): string {\n return `${chalk.dim('For runtime translation in production, create an API key in the dashboard')} ${chalk.cyan(dashboardUrl)} ${chalk.dim('and set GT_API_KEY and GT_PROJECT_ID in your hosting environment.')}`;\n}\n\n/**\n * Interactive setup keeps the browser login with its device fallback;\n * noninteractive setup always shows a device code (and emits it as a JSON\n * event) and waits for a person to approve it, without opening a browser.\n */\nexport async function signInForSetup(\n session: OnboardingSession,\n baseUrl: string | undefined\n): Promise<void> {\n try {\n await loginInteractively(baseUrl, session.interactive, (deviceCode) =>\n session.emit({ type: 'authorization_required', ...deviceCode })\n );\n } catch (error) {\n throw new OnboardingError(createUserAuthError('Sign in failed', error));\n }\n logger.message('You are now signed in.');\n}\n\ntype ProjectChoice = Awaited<ReturnType<typeof api.listProjects>>[number];\n\n/** An existing project, or the inputs for creating one. */\nexport type DevelopmentProject =\n | { id: string }\n | { create: { orgId: string; name: string } };\n\nexport type DevelopmentProjectOptions = {\n createProject?: boolean;\n orgId?: string;\n projectName?: string;\n};\n\nfunction noAccessibleOrgError(dashboardUrl: string): string {\n return createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'No accessible organizations were found',\n fix: `Create an organization in the dashboard ${dashboardUrl} or ask an admin for access, then rerun the setup wizard`,\n });\n}\n\nfunction projectCreationDeniedError(orgId: string, error: unknown): string {\n return createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: `Project creation was denied for organization ${orgId}`,\n why: 'Listing an organization does not confirm permission to create projects in it',\n fix: 'Ask an organization admin for org:projects:create, or use credentials that have that permission for this organization',\n details: formatDiagnosticErrorDetails(error),\n });\n}\n\nconst noProjectChosenError = createDiagnosticMessage({\n source: 'gt',\n severity: 'Error',\n whatHappened: 'No project was chosen for the development credentials',\n reassurance: 'No project files were changed',\n fix: 'Rerun with --project-id <id> or --create-project, or skip them with --no-dev-credentials',\n});\n\nasync function resolveNewProject(\n session: OnboardingSession,\n settings: Settings,\n options: DevelopmentProjectOptions,\n cwd: string\n): Promise<DevelopmentProject | undefined> {\n // Discovery lists accessible organizations, not creation permissions.\n // The API enforces creation permission when provisioning the project.\n const orgs = await api.listOrgs();\n if (orgs.length === 0) {\n throw new OnboardingError(noAccessibleOrgError(settings.dashboardUrl));\n }\n if (options.orgId && !orgs.some((org) => org.id === options.orgId)) {\n session.reject(\n `--org-id ${options.orgId} is not an accessible organization`\n );\n }\n const orgId = await session.answer('--org-id', {\n explicit: options.orgId,\n // One organization is not a choice between options.\n configured: orgs.length === 1 ? orgs[0].id : undefined,\n ask: () =>\n promptSelect({\n message: 'Which organization should own the new project?',\n options: orgs.map((org) => ({ value: org.id, label: org.name })),\n }),\n });\n const name = await session.answer('--project-name', {\n explicit: options.projectName?.trim() || undefined,\n ask: async () =>\n (\n await promptText({\n message: 'What should the project be called?',\n defaultValue: path.basename(cwd),\n })\n ).trim() || path.basename(cwd),\n });\n return orgId && name ? { create: { orgId, name } } : undefined;\n}\n\n/**\n * Records project inputs a noninteractive run is missing, before signing in,\n * so it never waits for approval only to fail on a missing flag.\n */\nexport function checkDevelopmentProjectInputs(\n session: OnboardingSession,\n settings: Settings,\n options: DevelopmentProjectOptions,\n /** Where settings.projectId came from, so a person can remove it. */\n projectIdSource: string\n): void {\n if (settings.projectId && options.createProject) {\n session.reject(\n `--create-project cannot be combined with project ${settings.projectId} from ${projectIdSource}; remove --create-project to keep using it, or remove the project ID from ${projectIdSource} to create a new project`\n );\n }\n if (settings.projectId || session.interactive) return;\n if (!options.createProject) {\n session.require('--project-id or --create-project');\n } else if (!options.projectName?.trim()) {\n session.require('--project-name');\n }\n}\n\n/**\n * Chooses the project for development credentials without creating anything:\n * a supplied or configured ID, explicit creation inputs, or (interactively)\n * a selection among the account's projects.\n */\nexport async function resolveDevelopmentProject(\n session: OnboardingSession,\n settings: Settings,\n options: DevelopmentProjectOptions,\n cwd: string = process.cwd()\n): Promise<DevelopmentProject | undefined> {\n if (settings.projectId) return { id: settings.projectId };\n if (options.createProject) {\n return resolveNewProject(session, settings, options, cwd);\n }\n const projects = await api.listProjects();\n if (projects.length === 0) {\n // Creating a project is its own choice, separate from creating a key.\n const create = await session.answer('--project-id or --create-project', {\n ask: () =>\n promptConfirm({\n message: 'No projects found for your account. Create a new project?',\n defaultValue: true,\n }),\n });\n if (create === false) throw new OnboardingError(noProjectChosenError);\n return create\n ? resolveNewProject(session, settings, options, cwd)\n : undefined;\n }\n const choice = await session.answer<ProjectChoice | null>(\n '--project-id or --create-project',\n {\n ask: () =>\n promptSelect<ProjectChoice | null>({\n message: 'Which project should this app use?',\n options: [\n ...projects.map((project) => ({\n value: project,\n label: project.name,\n hint: project.orgName,\n })),\n { value: null, label: 'Create a new project' },\n ],\n }),\n }\n );\n if (choice === undefined) return undefined;\n return choice\n ? { id: choice.id }\n : resolveNewProject(session, settings, options, cwd);\n}\n\n/**\n * Creates the chosen project if needed, mints a development key limited to\n * runtime translation, and saves both to .env.local. Callers inspect\n * .env.local first; the key is never printed.\n */\nexport async function provisionDevelopmentCredentials(\n session: OnboardingSession,\n project: DevelopmentProject,\n settings: Settings,\n framework: SupportedFrameworks | undefined,\n cwd: string = process.cwd()\n): Promise<void> {\n let projectId: string;\n if ('id' in project) {\n projectId = project.id;\n } else {\n const { orgId, name } = project.create;\n const { project: created } = await api\n .createProject(orgId, { name, defaultLocale: settings.defaultLocale })\n .catch((error: unknown) => {\n if (!(error instanceof ApiError) || error.code !== 403) throw error;\n throw new OnboardingError(projectCreationDeniedError(orgId, error));\n });\n logger.info(`Created ${created.name} (${created.id})`);\n session.step(`created project ${created.id}`);\n projectId = created.id;\n }\n const { apiKey } = await api.createProjectApiKey(projectId, {\n name: DEVELOPMENT_KEY_NAME,\n permissions: [ProjectApiKeyPermission['PROJECT:TRANSLATIONS:GENERATE']],\n });\n session.step('created a development key');\n await setCredentials({ projectId, apiKey: apiKey.key }, framework, cwd);\n session.step('saved development credentials to .env.local');\n logger.success(\n `Saved the project ID and a development key to ${chalk.cyan('.env.local')}.`\n );\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ This project is using [General Translation](https://generaltranslation.com/docs/
|
|
|
4
4
|
|
|
5
5
|
## Configuration
|
|
6
6
|
|
|
7
|
-
The General Translation configuration file is called `gt.config.json`. It is
|
|
7
|
+
The General Translation configuration file is called `gt.config.json`. It is located in the root of a project; pass `--config` to use a different path.
|
|
8
8
|
|
|
9
9
|
```json
|
|
10
10
|
{
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { type FrameworkObject, type SupportedReactFrameworks } from '../types/index.js';
|
|
3
|
+
import { type SetupFileFormat } from '../formats/files/supportedFiles.js';
|
|
4
|
+
import { type PackageManager } from '../utils/packageManager.js';
|
|
5
|
+
/** Answers accepted by `gt configure` (and the gt-vue `gt init`). */
|
|
6
|
+
export type ConfigureOptions = {
|
|
7
|
+
config: string;
|
|
8
|
+
src?: string[];
|
|
9
|
+
interactive?: boolean;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
defaults?: boolean;
|
|
12
|
+
defaultLocale?: string;
|
|
13
|
+
locales?: string[];
|
|
14
|
+
storage?: 'local' | 'cdn';
|
|
15
|
+
translationsDir?: string;
|
|
16
|
+
fileFormats?: Array<SetupFileFormat | 'none'>;
|
|
17
|
+
filePatterns?: string[];
|
|
18
|
+
liveTranslations?: boolean;
|
|
19
|
+
devCredentials?: boolean;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
createProject?: boolean;
|
|
22
|
+
orgId?: string;
|
|
23
|
+
projectName?: string;
|
|
24
|
+
packageManager?: string;
|
|
25
|
+
};
|
|
26
|
+
/** Answers accepted by the React-aware `gt init`. */
|
|
27
|
+
export type InitOptions = ConfigureOptions & {
|
|
28
|
+
locadex?: boolean;
|
|
29
|
+
reactSetup?: boolean;
|
|
30
|
+
framework?: SupportedReactFrameworks;
|
|
31
|
+
format?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** Flags for every configuration question; values prefill interactive runs. */
|
|
34
|
+
export declare function attachConfigureFlags(command: Command, sourceHelp: string): Command;
|
|
35
|
+
/**
|
|
36
|
+
* Pre-action hooks, such as the monorepo version check, can exit before
|
|
37
|
+
* runOnboarding installs its own result reporting; `--json` callers still
|
|
38
|
+
* get a result. runOnboarding takes over once it starts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function reportJsonExitsBeforeOnboarding(command: string): void;
|
|
41
|
+
/** Configuration flags plus the React application setup and Locadex choices. */
|
|
42
|
+
export declare function attachInitFlags(command: Command, sourceHelp: string): Command;
|
|
43
|
+
export type OnboardingEvent = {
|
|
44
|
+
type: 'authorization_required';
|
|
45
|
+
verificationUri: string;
|
|
46
|
+
verificationUriComplete?: string;
|
|
47
|
+
userCode: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: 'handoff';
|
|
50
|
+
url: string;
|
|
51
|
+
reason: 'locadex';
|
|
52
|
+
} | {
|
|
53
|
+
type: 'result';
|
|
54
|
+
command: string;
|
|
55
|
+
outcome: 'success' | 'needs_human_action' | 'failed';
|
|
56
|
+
completedSteps: string[];
|
|
57
|
+
url?: string;
|
|
58
|
+
/** Manual steps setup could not do, for needs_human_action. */
|
|
59
|
+
actions?: string[];
|
|
60
|
+
missingOptions?: string[];
|
|
61
|
+
error?: string;
|
|
62
|
+
};
|
|
63
|
+
/** Needs-input and validation failures, raised before setup changes files. */
|
|
64
|
+
export declare class OnboardingError extends Error {
|
|
65
|
+
readonly missingOptions: string[];
|
|
66
|
+
constructor(message: string, missingOptions?: string[]);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* One setup run: how unanswered questions are resolved, which options are
|
|
70
|
+
* still missing, and which steps already changed the project.
|
|
71
|
+
*/
|
|
72
|
+
export declare class OnboardingSession {
|
|
73
|
+
readonly command: string;
|
|
74
|
+
readonly interactive: boolean;
|
|
75
|
+
readonly json: boolean;
|
|
76
|
+
defaults: boolean;
|
|
77
|
+
readonly completedSteps: string[];
|
|
78
|
+
/** Manual steps left for a person; they make the outcome needs_human_action. */
|
|
79
|
+
readonly humanActions: string[];
|
|
80
|
+
private readonly missing;
|
|
81
|
+
private readonly invalid;
|
|
82
|
+
private reported;
|
|
83
|
+
constructor(command: string, options: Pick<ConfigureOptions, 'json' | 'interactive'>);
|
|
84
|
+
/**
|
|
85
|
+
* Explicit flag, then existing config, then the recommended value when
|
|
86
|
+
* defaults were accepted, then a prompt. Noninteractive runs use the
|
|
87
|
+
* fallback of an optional question, or record the option as missing.
|
|
88
|
+
*/
|
|
89
|
+
answer<T>(option: string, { explicit, configured, recommended, fallback, ask, }: {
|
|
90
|
+
explicit?: T;
|
|
91
|
+
configured?: T;
|
|
92
|
+
recommended?: T;
|
|
93
|
+
fallback?: T;
|
|
94
|
+
ask: () => Promise<T>;
|
|
95
|
+
}): Promise<T | undefined>;
|
|
96
|
+
require(option: string): void;
|
|
97
|
+
reject(problem: string): void;
|
|
98
|
+
/** Stops before any change when an answer is missing or invalid. */
|
|
99
|
+
assertResolved(): void;
|
|
100
|
+
step(name: string): void;
|
|
101
|
+
emit(event: OnboardingEvent): void;
|
|
102
|
+
/** A result for exits that bypass runOnboarding (e.g. settings validation). */
|
|
103
|
+
reportUnexpectedExit(code: number): void;
|
|
104
|
+
}
|
|
105
|
+
export type OnboardingOutcome = {
|
|
106
|
+
outcome: 'success';
|
|
107
|
+
} | {
|
|
108
|
+
outcome: 'needs_human_action';
|
|
109
|
+
url: string;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Runs one setup command: selects prompt and output modes, then reports the
|
|
113
|
+
* outcome. Failures exit nonzero with the steps that already ran.
|
|
114
|
+
*/
|
|
115
|
+
export declare function runOnboarding(command: string, options: Pick<ConfigureOptions, 'json' | 'interactive'>, run: (session: OnboardingSession) => Promise<OnboardingOutcome>): Promise<void>;
|
|
116
|
+
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
117
|
+
/** Reads the setup config, failing before any change when it is unusable. */
|
|
118
|
+
export declare function readSetupConfig(configFilepath: string): Record<string, unknown>;
|
|
119
|
+
export declare const INIT_SOURCE_HELP = "Space-separated list of glob patterns containing the app's source code, by default 'src/**/*.{js,jsx,ts,tsx}' 'app/**/*.{js,jsx,ts,tsx}' 'pages/**/*.{js,jsx,ts,tsx}' 'components/**/*.{js,jsx,ts,tsx}'";
|
|
120
|
+
export declare function setupConfigPath(options: Pick<ConfigureOptions, 'config'>): string;
|
|
121
|
+
export declare function getConfiguredFramework(config: Record<string, unknown>): SupportedReactFrameworks | 'mintlify' | undefined;
|
|
122
|
+
/** JSON mode keeps the banner off stdout. */
|
|
123
|
+
export declare function displaySetupHeader(session: OnboardingSession, message: string): void;
|
|
124
|
+
export declare function describeDefaults(framework: FrameworkObject | undefined): string;
|
|
125
|
+
/** Setup patterns name where each locale's files live, so they need [locale]. */
|
|
126
|
+
export declare function validateSetupPattern(pattern: string): true | string;
|
|
127
|
+
/** Parses `--file-patterns <format>=<glob>` values, grouped by format. */
|
|
128
|
+
export declare function parseFilePatterns(session: OnboardingSession, values?: string[]): Map<SetupFileFormat, string[]>;
|
|
129
|
+
/** Detects the package manager, or asks only when prompts are allowed. */
|
|
130
|
+
export declare function resolvePackageManager(session: OnboardingSession, specified?: string): Promise<PackageManager | undefined>;
|
|
131
|
+
export declare function installWithProgress(session: OnboardingSession, packageName: string, packageManager: PackageManager, asDevDependency: boolean): Promise<void>;
|