gt 2.11.2 → 2.11.3
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 +6 -0
- package/dist/api/collectUserEditDiffs.d.ts +1 -1
- package/dist/api/collectUserEditDiffs.js +2 -1
- package/dist/api/saveLocalEdits.js +7 -2
- package/dist/cli/base.js +3 -1
- package/dist/cli/commands/translate.js +4 -12
- package/dist/cli/commands/upload.js +9 -1
- package/dist/formats/files/aggregateFiles.js +3 -20
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/utils/resolvePublish.d.ts +8 -1
- package/dist/utils/resolvePublish.js +27 -0
- package/dist/workflows/publish.d.ts +10 -0
- package/dist/workflows/publish.js +31 -0
- package/dist/workflows/upload.d.ts +5 -2
- package/dist/workflows/upload.js +2 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.11.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1133](https://github.com/generaltranslation/gt/pull/1133) [`4de22d7`](https://github.com/generaltranslation/gt/commit/4de22d7548b5d34c0d7e465132878d192c2f41e0) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Extending publish step to save-local and upload commands
|
|
8
|
+
|
|
3
9
|
## 2.11.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -6,4 +6,4 @@ import { FileReference } from 'generaltranslation/types';
|
|
|
6
6
|
*
|
|
7
7
|
* Must run before enqueueing new translations so rules are available to the generator.
|
|
8
8
|
*/
|
|
9
|
-
export declare function collectAndSendUserEditDiffs(files: FileReference[], settings: Settings): Promise<
|
|
9
|
+
export declare function collectAndSendUserEditDiffs(files: FileReference[], settings: Settings): Promise<boolean>;
|
|
@@ -26,7 +26,7 @@ const findLatestDownloadedVersion = (entryMap, fileId, locale) => {
|
|
|
26
26
|
*/
|
|
27
27
|
export async function collectAndSendUserEditDiffs(files, settings) {
|
|
28
28
|
if (!settings.files)
|
|
29
|
-
return;
|
|
29
|
+
return false;
|
|
30
30
|
const { resolvedPaths, placeholderPaths, transformPaths } = settings.files;
|
|
31
31
|
const fileMapping = createFileMapping(resolvedPaths, placeholderPaths, transformPaths, settings.locales, settings.defaultLocale);
|
|
32
32
|
const { entryMap } = readLockfile(settings);
|
|
@@ -153,4 +153,5 @@ export async function collectAndSendUserEditDiffs(files, settings) {
|
|
|
153
153
|
if (collectedDiffs.length > 0) {
|
|
154
154
|
await gt.submitUserEditDiffs({ diffs: collectedDiffs });
|
|
155
155
|
}
|
|
156
|
+
return collectedDiffs.length > 0;
|
|
156
157
|
}
|
|
@@ -5,6 +5,7 @@ import { BranchStep } from '../workflows/steps/BranchStep.js';
|
|
|
5
5
|
import { logErrorAndExit } from '../console/logging.js';
|
|
6
6
|
import { logger } from '../console/logger.js';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
+
import { runPublishWorkflow } from '../workflows/publish.js';
|
|
8
9
|
/**
|
|
9
10
|
* Uploads current source files to obtain file references, then collects and sends
|
|
10
11
|
* diffs for all locales based on last downloaded versions. Does not enqueue translations.
|
|
@@ -13,7 +14,7 @@ export async function saveLocalEdits(settings) {
|
|
|
13
14
|
if (!settings.files)
|
|
14
15
|
return;
|
|
15
16
|
// Collect current files from config
|
|
16
|
-
const { files } = await aggregateFiles(settings);
|
|
17
|
+
const { files, publishMap } = await aggregateFiles(settings);
|
|
17
18
|
if (!files.length)
|
|
18
19
|
return;
|
|
19
20
|
// run branch query to get branch id
|
|
@@ -33,6 +34,10 @@ export async function saveLocalEdits(settings) {
|
|
|
33
34
|
}));
|
|
34
35
|
const spinner = logger.createSpinner('dots');
|
|
35
36
|
spinner.start('Saving local edits...');
|
|
36
|
-
await collectAndSendUserEditDiffs(uploads, settings);
|
|
37
|
+
const hadDiffs = await collectAndSendUserEditDiffs(uploads, settings);
|
|
37
38
|
spinner.stop(chalk.green('Local edits saved successfully'));
|
|
39
|
+
// Publish files to CDN if diffs were detected and publish config exists
|
|
40
|
+
if (hadDiffs) {
|
|
41
|
+
await runPublishWorkflow(files, publishMap, branchResult.currentBranch.id, settings);
|
|
42
|
+
}
|
|
38
43
|
}
|
package/dist/cli/base.js
CHANGED
|
@@ -121,7 +121,9 @@ export class BaseCLI {
|
|
|
121
121
|
setupSendDiffsCommand() {
|
|
122
122
|
attachSharedFlags(this.program
|
|
123
123
|
.command('save-local')
|
|
124
|
-
.description('Save local edits for all configured files by sending diffs (no translation enqueued)'))
|
|
124
|
+
.description('Save local edits for all configured files by sending diffs (no translation enqueued)'))
|
|
125
|
+
.option('--publish', 'Publish translations to the CDN', false)
|
|
126
|
+
.action(async (initOptions) => {
|
|
125
127
|
displayHeader('Saving local edits...');
|
|
126
128
|
const settings = await generateSettings(initOptions);
|
|
127
129
|
await saveLocalEdits(settings);
|
|
@@ -9,9 +9,7 @@ import processOpenApi from '../../utils/processOpenApi.js';
|
|
|
9
9
|
import localizeStaticImports from '../../utils/localizeStaticImports.js';
|
|
10
10
|
import { getDownloadedMeta } from '../../state/recentDownloads.js';
|
|
11
11
|
import { persistPostProcessHashes } from '../../utils/persistPostprocessHashes.js';
|
|
12
|
-
import {
|
|
13
|
-
import { gt } from '../../utils/gt.js';
|
|
14
|
-
import { hasPublishConfig } from '../../utils/resolvePublish.js';
|
|
12
|
+
import { runPublishWorkflow } from '../../workflows/publish.js';
|
|
15
13
|
// Downloads translations that were completed
|
|
16
14
|
export async function handleTranslate(options, settings, fileVersionData, jobData, branchData, publishMap) {
|
|
17
15
|
if (fileVersionData) {
|
|
@@ -30,19 +28,13 @@ export async function handleTranslate(options, settings, fileVersionData, jobDat
|
|
|
30
28
|
forceDownload: options.forceDownload || options.force, // if force is true should also force download
|
|
31
29
|
});
|
|
32
30
|
// Publish/unpublish files after translations are downloaded
|
|
33
|
-
if (publishMap &&
|
|
34
|
-
const
|
|
35
|
-
.filter(([fileId]) => publishMap.has(fileId))
|
|
36
|
-
.map(([fileId, data]) => ({
|
|
31
|
+
if (publishMap && branchData?.currentBranch.id) {
|
|
32
|
+
const files = Object.entries(fileVersionData).map(([fileId, data]) => ({
|
|
37
33
|
fileId,
|
|
38
34
|
versionId: data.versionId,
|
|
39
|
-
branchId: branchData?.currentBranch.id,
|
|
40
|
-
publish: publishMap.get(fileId),
|
|
41
35
|
fileName: data.fileName,
|
|
42
36
|
}));
|
|
43
|
-
|
|
44
|
-
await publishStep.run(allFileRefs);
|
|
45
|
-
await publishStep.wait();
|
|
37
|
+
await runPublishWorkflow(files, publishMap, branchData.currentBranch.id, settings);
|
|
46
38
|
}
|
|
47
39
|
}
|
|
48
40
|
}
|
|
@@ -13,6 +13,8 @@ import { createFileMapping } from '../../formats/files/fileMapping.js';
|
|
|
13
13
|
import parseYaml from '../../formats/yaml/parseYaml.js';
|
|
14
14
|
import { hashStringSync } from '../../utils/hash.js';
|
|
15
15
|
import { hasValidCredentials } from './utils/validation.js';
|
|
16
|
+
import { buildPublishMap } from '../../utils/resolvePublish.js';
|
|
17
|
+
import { runPublishWorkflow } from '../../workflows/publish.js';
|
|
16
18
|
const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
17
19
|
/**
|
|
18
20
|
* Sends multiple files to the API for translation
|
|
@@ -180,7 +182,13 @@ export async function upload(filePaths, placeholderPaths, transformPaths, dataFo
|
|
|
180
182
|
});
|
|
181
183
|
try {
|
|
182
184
|
// Send all files in a single API call
|
|
183
|
-
|
|
185
|
+
const { branchData } = await runUploadFilesWorkflow({
|
|
186
|
+
files: uploadData,
|
|
187
|
+
options: settings,
|
|
188
|
+
});
|
|
189
|
+
// Publish files to CDN if publish config exists
|
|
190
|
+
const publishMap = buildPublishMap(filePaths, settings);
|
|
191
|
+
await runPublishWorkflow(allFiles, publishMap, branchData.currentBranch.id, settings);
|
|
184
192
|
}
|
|
185
193
|
catch (error) {
|
|
186
194
|
logErrorAndExit(`Error uploading files: ${error}`);
|
|
@@ -11,7 +11,7 @@ import { determineLibrary } from '../../fs/determineFramework/index.js';
|
|
|
11
11
|
import { hashStringSync } from '../../utils/hash.js';
|
|
12
12
|
import { preprocessContent } from './preprocessContent.js';
|
|
13
13
|
import { parseKeyedMetadata, } from '../parseKeyedMetadata.js';
|
|
14
|
-
import {
|
|
14
|
+
import { buildPublishMap } from '../../utils/resolvePublish.js';
|
|
15
15
|
/**
|
|
16
16
|
* Checks if a file path is a metadata companion file (e.g. foo.metadata.json)
|
|
17
17
|
* AND its corresponding source file (e.g. foo.json) exists in the file list.
|
|
@@ -29,32 +29,15 @@ export const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
|
|
|
29
29
|
export async function aggregateFiles(settings) {
|
|
30
30
|
// Aggregate all files to translate
|
|
31
31
|
const files = [];
|
|
32
|
-
const publishMap = new Map();
|
|
33
32
|
if (!settings.files ||
|
|
34
33
|
(Object.keys(settings.files.placeholderPaths).length === 1 &&
|
|
35
34
|
settings.files.placeholderPaths.gt)) {
|
|
36
|
-
return { files, publishMap };
|
|
35
|
+
return { files, publishMap: new Map() };
|
|
37
36
|
}
|
|
38
37
|
const { resolvedPaths: filePaths } = settings.files;
|
|
39
38
|
const skipValidation = settings.options?.skipFileValidation;
|
|
40
39
|
// Build publish map upfront from resolved paths.
|
|
41
|
-
|
|
42
|
-
// publish flag is defined. Files without any config are left out of the map
|
|
43
|
-
// so the publish endpoint is never called for them.
|
|
44
|
-
const hasGlobalPublish = settings.publish !== undefined;
|
|
45
|
-
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
46
|
-
if (filePaths[fileType]) {
|
|
47
|
-
for (const absolutePath of filePaths[fileType]) {
|
|
48
|
-
const hasExplicitConfig = settings.files.publishPaths?.has(absolutePath) ||
|
|
49
|
-
settings.files.unpublishPaths?.has(absolutePath);
|
|
50
|
-
if (hasGlobalPublish || hasExplicitConfig) {
|
|
51
|
-
const relativePath = getRelative(absolutePath);
|
|
52
|
-
const fileId = hashStringSync(relativePath);
|
|
53
|
-
publishMap.set(fileId, shouldPublishFile(absolutePath, settings));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
40
|
+
const publishMap = buildPublishMap(filePaths, settings);
|
|
58
41
|
// Process JSON files
|
|
59
42
|
if (filePaths.json) {
|
|
60
43
|
const { library, additionalModules } = determineLibrary();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.11.
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.11.3";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const PACKAGE_VERSION = '2.11.
|
|
2
|
+
export const PACKAGE_VERSION = '2.11.3';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Settings } from '../types/index.js';
|
|
1
|
+
import { Settings, ResolvedFiles } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Determines whether a file should be published based on the publish resolution logic:
|
|
4
4
|
* - If the file is explicitly opted OUT (unpublishPaths), never publish
|
|
@@ -6,6 +6,13 @@ import { Settings } from '../types/index.js';
|
|
|
6
6
|
* - Otherwise, fall back to the global publish setting
|
|
7
7
|
*/
|
|
8
8
|
export declare function shouldPublishFile(resolvedPath: string, settings: Settings): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Builds a publish map from resolved file paths.
|
|
11
|
+
* Only includes files that have an explicit publish config or when a global
|
|
12
|
+
* publish flag is defined. Files without any config are left out of the map
|
|
13
|
+
* so the publish endpoint is never called for them.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildPublishMap(filePaths: ResolvedFiles, settings: Settings): Map<string, boolean>;
|
|
9
16
|
/**
|
|
10
17
|
* Returns true if the user has any explicit publish configuration —
|
|
11
18
|
* global flag, gt-specific flag, or per-file publish/unpublish patterns.
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { SUPPORTED_FILE_EXTENSIONS } from '../formats/files/supportedFiles.js';
|
|
2
|
+
import { getRelative } from '../fs/findFilepath.js';
|
|
3
|
+
import { hashStringSync } from './hash.js';
|
|
1
4
|
/**
|
|
2
5
|
* Determines whether a file should be published based on the publish resolution logic:
|
|
3
6
|
* - If the file is explicitly opted OUT (unpublishPaths), never publish
|
|
@@ -11,6 +14,30 @@ export function shouldPublishFile(resolvedPath, settings) {
|
|
|
11
14
|
return true;
|
|
12
15
|
return settings.publish ?? false;
|
|
13
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds a publish map from resolved file paths.
|
|
19
|
+
* Only includes files that have an explicit publish config or when a global
|
|
20
|
+
* publish flag is defined. Files without any config are left out of the map
|
|
21
|
+
* so the publish endpoint is never called for them.
|
|
22
|
+
*/
|
|
23
|
+
export function buildPublishMap(filePaths, settings) {
|
|
24
|
+
const publishMap = new Map();
|
|
25
|
+
const hasGlobalPublish = settings.publish !== undefined;
|
|
26
|
+
for (const fileType of SUPPORTED_FILE_EXTENSIONS) {
|
|
27
|
+
if (filePaths[fileType]) {
|
|
28
|
+
for (const absolutePath of filePaths[fileType]) {
|
|
29
|
+
const hasExplicitConfig = settings.files.publishPaths?.has(absolutePath) ||
|
|
30
|
+
settings.files.unpublishPaths?.has(absolutePath);
|
|
31
|
+
if (hasGlobalPublish || hasExplicitConfig) {
|
|
32
|
+
const relativePath = getRelative(absolutePath);
|
|
33
|
+
const fileId = hashStringSync(relativePath);
|
|
34
|
+
publishMap.set(fileId, shouldPublishFile(absolutePath, settings));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return publishMap;
|
|
40
|
+
}
|
|
14
41
|
/**
|
|
15
42
|
* Returns true if the user has any explicit publish configuration —
|
|
16
43
|
* global flag, gt-specific flag, or per-file publish/unpublish patterns.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Settings } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Publishes files to the CDN if publish config exists and the publishMap is non-empty.
|
|
4
|
+
* Shared by translate, upload, and save-local commands.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runPublishWorkflow(files: {
|
|
7
|
+
fileId: string;
|
|
8
|
+
versionId: string;
|
|
9
|
+
fileName: string;
|
|
10
|
+
}[], publishMap: Map<string, boolean>, branchId: string, settings: Settings): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PublishStep } from './steps/PublishStep.js';
|
|
2
|
+
import { gt } from '../utils/gt.js';
|
|
3
|
+
import { hasPublishConfig } from '../utils/resolvePublish.js';
|
|
4
|
+
import { logger } from '../console/logger.js';
|
|
5
|
+
/**
|
|
6
|
+
* Publishes files to the CDN if publish config exists and the publishMap is non-empty.
|
|
7
|
+
* Shared by translate, upload, and save-local commands.
|
|
8
|
+
*/
|
|
9
|
+
export async function runPublishWorkflow(files, publishMap, branchId, settings) {
|
|
10
|
+
if (publishMap.size === 0 || !hasPublishConfig(settings))
|
|
11
|
+
return;
|
|
12
|
+
try {
|
|
13
|
+
const allFileRefs = files
|
|
14
|
+
.filter((file) => publishMap.has(file.fileId))
|
|
15
|
+
.map((file) => ({
|
|
16
|
+
fileId: file.fileId,
|
|
17
|
+
versionId: file.versionId,
|
|
18
|
+
branchId,
|
|
19
|
+
publish: publishMap.get(file.fileId),
|
|
20
|
+
fileName: file.fileName,
|
|
21
|
+
}));
|
|
22
|
+
if (allFileRefs.length === 0)
|
|
23
|
+
return;
|
|
24
|
+
const publishStep = new PublishStep(gt);
|
|
25
|
+
await publishStep.run(allFileRefs);
|
|
26
|
+
await publishStep.wait();
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
logger.warn(`Failed to publish files: ${error instanceof Error ? error.message : String(error)}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Settings } from '../types/index.js';
|
|
2
2
|
import type { FileToUpload } from 'generaltranslation/types';
|
|
3
|
+
import { BranchData } from '../types/branch.js';
|
|
3
4
|
/**
|
|
4
5
|
* Uploads multiple files to the API using a workflow pattern
|
|
5
6
|
* @param files - Array of file objects to upload
|
|
6
7
|
* @param options - The options for the API call
|
|
7
|
-
* @returns The
|
|
8
|
+
* @returns The branch data resolved during the workflow
|
|
8
9
|
*/
|
|
9
10
|
export declare function runUploadFilesWorkflow({ files, options, }: {
|
|
10
11
|
files: {
|
|
@@ -12,4 +13,6 @@ export declare function runUploadFilesWorkflow({ files, options, }: {
|
|
|
12
13
|
translations: FileToUpload[];
|
|
13
14
|
}[];
|
|
14
15
|
options: Settings;
|
|
15
|
-
}): Promise<
|
|
16
|
+
}): Promise<{
|
|
17
|
+
branchData: BranchData;
|
|
18
|
+
}>;
|
package/dist/workflows/upload.js
CHANGED
|
@@ -9,7 +9,7 @@ import { UploadTranslationsStep } from './steps/UploadTranslationsStep.js';
|
|
|
9
9
|
* Uploads multiple files to the API using a workflow pattern
|
|
10
10
|
* @param files - Array of file objects to upload
|
|
11
11
|
* @param options - The options for the API call
|
|
12
|
-
* @returns The
|
|
12
|
+
* @returns The branch data resolved during the workflow
|
|
13
13
|
*/
|
|
14
14
|
export async function runUploadFilesWorkflow({ files, options, }) {
|
|
15
15
|
try {
|
|
@@ -40,6 +40,7 @@ export async function runUploadFilesWorkflow({ files, options, }) {
|
|
|
40
40
|
await uploadTranslationsStep.wait();
|
|
41
41
|
}
|
|
42
42
|
logger.success('All files uploaded successfully');
|
|
43
|
+
return { branchData };
|
|
43
44
|
}
|
|
44
45
|
catch (error) {
|
|
45
46
|
return logErrorAndExit('Failed to upload files. ' + error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gt",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
"unified": "^11.0.5",
|
|
111
111
|
"unist-util-visit": "^5.0.0",
|
|
112
112
|
"yaml": "^2.8.0",
|
|
113
|
-
"@generaltranslation/python-extractor": "0.1.6",
|
|
114
113
|
"generaltranslation": "8.1.20",
|
|
114
|
+
"@generaltranslation/python-extractor": "0.1.6",
|
|
115
115
|
"gt-remark": "1.0.6"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|