gt 2.8.0 → 2.8.1
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/formats/json/extractJson.js +4 -0
- package/dist/formats/json/mergeJson.js +7 -0
- package/dist/formats/json/parseJson.js +4 -0
- package/dist/formats/json/transformJson.d.ts +13 -0
- package/dist/formats/json/transformJson.js +92 -0
- package/dist/formats/json/utils.js +5 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/types/index.d.ts +5 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# gtx-cli
|
|
2
2
|
|
|
3
|
+
## 2.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1093](https://github.com/generaltranslation/gt/pull/1093) [`69a13a5`](https://github.com/generaltranslation/gt/commit/69a13a5791254ebb4a2679321d24fecebb1fef11) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - fix: support for temporary structural transforms
|
|
8
|
+
|
|
3
9
|
## 2.8.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -2,6 +2,7 @@ import { logger } from '../../console/logger.js';
|
|
|
2
2
|
import { findMatchingItemArray, findMatchingItemObject, generateSourceObjectPointers, validateJsonSchema, } from './utils.js';
|
|
3
3
|
import { flattenJsonWithStringFilter } from './flattenJson.js';
|
|
4
4
|
import { gt } from '../../utils/gt.js';
|
|
5
|
+
import { applyStructuralTransforms } from './transformJson.js';
|
|
5
6
|
/**
|
|
6
7
|
* Extracts translated values from a full JSON file back into composite JSON format.
|
|
7
8
|
* This is the inverse of mergeJson - it takes a merged/reconstructed JSON file
|
|
@@ -36,6 +37,9 @@ export function extractJson(localContent, inputPath, options, targetLocale, defa
|
|
|
36
37
|
const canonicalDefaultLocale = useCanonicalLocaleKeys
|
|
37
38
|
? gt.resolveCanonicalLocale(defaultLocale)
|
|
38
39
|
: defaultLocale;
|
|
40
|
+
if (jsonSchema.structuralTransform && jsonSchema.composite) {
|
|
41
|
+
applyStructuralTransforms(localJson, jsonSchema.structuralTransform, jsonSchema.composite);
|
|
42
|
+
}
|
|
39
43
|
// Handle include-style schemas (simple path-based extraction)
|
|
40
44
|
if (jsonSchema.include) {
|
|
41
45
|
const extracted = flattenJsonWithStringFilter(localJson, jsonSchema.include);
|
|
@@ -6,6 +6,7 @@ import { JSONPath } from 'jsonpath-plus';
|
|
|
6
6
|
import { getLocaleProperties } from 'generaltranslation';
|
|
7
7
|
import { replaceLocalePlaceholders } from '../utils.js';
|
|
8
8
|
import { gt } from '../../utils/gt.js';
|
|
9
|
+
import { applyStructuralTransforms, unapplyStructuralTransforms, } from './transformJson.js';
|
|
9
10
|
export function mergeJson(originalContent, inputPath, options, targets, defaultLocale, localeOrder = []) {
|
|
10
11
|
const jsonSchema = validateJsonSchema(options, inputPath);
|
|
11
12
|
if (!jsonSchema) {
|
|
@@ -26,6 +27,9 @@ export function mergeJson(originalContent, inputPath, options, targets, defaultL
|
|
|
26
27
|
const canonicalLocaleOrder = useCanonicalLocaleKeys
|
|
27
28
|
? localeOrder.map((locale) => gt.resolveCanonicalLocale(locale))
|
|
28
29
|
: localeOrder;
|
|
30
|
+
if (jsonSchema.structuralTransform && jsonSchema.composite) {
|
|
31
|
+
applyStructuralTransforms(originalJson, jsonSchema.structuralTransform, jsonSchema.composite);
|
|
32
|
+
}
|
|
29
33
|
// Handle include
|
|
30
34
|
if (jsonSchema.include) {
|
|
31
35
|
const output = [];
|
|
@@ -237,6 +241,9 @@ export function mergeJson(originalContent, inputPath, options, targets, defaultL
|
|
|
237
241
|
JSONPointer.set(mergedJson, sourceObjectPointer, sourceObjectValue);
|
|
238
242
|
}
|
|
239
243
|
}
|
|
244
|
+
if (jsonSchema.structuralTransform && jsonSchema.composite) {
|
|
245
|
+
unapplyStructuralTransforms(mergedJson, jsonSchema.structuralTransform, jsonSchema.composite);
|
|
246
|
+
}
|
|
240
247
|
return [JSON.stringify(mergedJson, null, 2)];
|
|
241
248
|
}
|
|
242
249
|
function sortByLocaleOrder(items, sourceObjectOptions, localeOrder, sourceObjectPointer, defaultLocale) {
|
|
@@ -3,6 +3,7 @@ import { JSONPath } from 'jsonpath-plus';
|
|
|
3
3
|
import { exitSync } from '../../console/logging.js';
|
|
4
4
|
import { logger } from '../../console/logger.js';
|
|
5
5
|
import { findMatchingItemArray, findMatchingItemObject, generateSourceObjectPointers, validateJsonSchema, } from './utils.js';
|
|
6
|
+
import { applyStructuralTransforms } from './transformJson.js';
|
|
6
7
|
// Parse a JSON file according to a JSON schema
|
|
7
8
|
export function parseJson(content, filePath, options, defaultLocale) {
|
|
8
9
|
const jsonSchema = validateJsonSchema(options, filePath);
|
|
@@ -17,6 +18,9 @@ export function parseJson(content, filePath, options, defaultLocale) {
|
|
|
17
18
|
logger.error(`Invalid JSON file: ${filePath}`);
|
|
18
19
|
return exitSync(1);
|
|
19
20
|
}
|
|
21
|
+
if (jsonSchema.structuralTransform && jsonSchema.composite) {
|
|
22
|
+
applyStructuralTransforms(json, jsonSchema.structuralTransform, jsonSchema.composite);
|
|
23
|
+
}
|
|
20
24
|
// Handle include
|
|
21
25
|
if (jsonSchema.include) {
|
|
22
26
|
const flattenedJson = flattenJsonWithStringFilter(json, jsonSchema.include);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StructuralTransform, SourceObjectOptions } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Apply structural transforms: copy values from sourcePointer to destinationPointer
|
|
4
|
+
* for each entry resolved by the composite config's parent paths.
|
|
5
|
+
* Mutates json in-place.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyStructuralTransforms(json: any, transforms: StructuralTransform[], compositeConfig: Record<string, SourceObjectOptions>): any;
|
|
8
|
+
/**
|
|
9
|
+
* Unapply structural transforms: delete the value at destinationPointer
|
|
10
|
+
* for each entry resolved by the composite config's parent paths.
|
|
11
|
+
* Leaves sourcePointer untouched. Mutates json in-place.
|
|
12
|
+
*/
|
|
13
|
+
export declare function unapplyStructuralTransforms(json: any, transforms: StructuralTransform[], compositeConfig: Record<string, SourceObjectOptions>): any;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import JSONPointer from 'jsonpointer';
|
|
2
|
+
import { JSONPath } from 'jsonpath-plus';
|
|
3
|
+
/**
|
|
4
|
+
* Derive entry parent paths from composite sourceObjectPaths by trimming the last segment.
|
|
5
|
+
* e.g., "$.*.translations" → "$.*"
|
|
6
|
+
*/
|
|
7
|
+
function deriveEntryPaths(compositeConfig) {
|
|
8
|
+
const entryPaths = new Set();
|
|
9
|
+
for (const sourceObjectPath of Object.keys(compositeConfig)) {
|
|
10
|
+
const lastDot = sourceObjectPath.lastIndexOf('.');
|
|
11
|
+
if (lastDot > 0) {
|
|
12
|
+
entryPaths.add(sourceObjectPath.substring(0, lastDot));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return [...entryPaths];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Apply structural transforms: copy values from sourcePointer to destinationPointer
|
|
19
|
+
* for each entry resolved by the composite config's parent paths.
|
|
20
|
+
* Mutates json in-place.
|
|
21
|
+
*/
|
|
22
|
+
export function applyStructuralTransforms(json, transforms, compositeConfig) {
|
|
23
|
+
const entryPaths = deriveEntryPaths(compositeConfig);
|
|
24
|
+
for (const entryPath of entryPaths) {
|
|
25
|
+
const entries = JSONPath({
|
|
26
|
+
json,
|
|
27
|
+
path: entryPath,
|
|
28
|
+
resultType: 'all',
|
|
29
|
+
flatten: true,
|
|
30
|
+
wrap: true,
|
|
31
|
+
});
|
|
32
|
+
if (!entries)
|
|
33
|
+
continue;
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const entryObj = entry.value;
|
|
36
|
+
if (typeof entryObj !== 'object' || entryObj === null)
|
|
37
|
+
continue;
|
|
38
|
+
for (const transform of transforms) {
|
|
39
|
+
const sourceValue = JSONPointer.get(entryObj, transform.sourcePointer);
|
|
40
|
+
if (sourceValue !== undefined) {
|
|
41
|
+
JSONPointer.set(entryObj, transform.destinationPointer, sourceValue);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return json;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Unapply structural transforms: delete the value at destinationPointer
|
|
50
|
+
* for each entry resolved by the composite config's parent paths.
|
|
51
|
+
* Leaves sourcePointer untouched. Mutates json in-place.
|
|
52
|
+
*/
|
|
53
|
+
export function unapplyStructuralTransforms(json, transforms, compositeConfig) {
|
|
54
|
+
const entryPaths = deriveEntryPaths(compositeConfig);
|
|
55
|
+
for (const entryPath of entryPaths) {
|
|
56
|
+
const entries = JSONPath({
|
|
57
|
+
json,
|
|
58
|
+
path: entryPath,
|
|
59
|
+
resultType: 'all',
|
|
60
|
+
flatten: true,
|
|
61
|
+
wrap: true,
|
|
62
|
+
});
|
|
63
|
+
if (!entries)
|
|
64
|
+
continue;
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
const entryObj = entry.value;
|
|
67
|
+
if (typeof entryObj !== 'object' || entryObj === null)
|
|
68
|
+
continue;
|
|
69
|
+
for (const transform of transforms) {
|
|
70
|
+
// Navigate to parent of destinationPointer and delete the leaf key
|
|
71
|
+
const pointer = transform.destinationPointer;
|
|
72
|
+
const lastSlash = pointer.lastIndexOf('/');
|
|
73
|
+
if (lastSlash < 0)
|
|
74
|
+
continue;
|
|
75
|
+
const parentPointer = pointer.substring(0, lastSlash) || '';
|
|
76
|
+
const leafKey = pointer.substring(lastSlash + 1);
|
|
77
|
+
try {
|
|
78
|
+
const parent = parentPointer
|
|
79
|
+
? JSONPointer.get(entryObj, parentPointer)
|
|
80
|
+
: entryObj;
|
|
81
|
+
if (parent && typeof parent === 'object' && leafKey in parent) {
|
|
82
|
+
delete parent[leafKey];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
/* entry may not have the destination path */
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return json;
|
|
92
|
+
}
|
|
@@ -146,5 +146,10 @@ export function validateJsonSchema(options, filePath) {
|
|
|
146
146
|
return exitSync(1);
|
|
147
147
|
return null;
|
|
148
148
|
}
|
|
149
|
+
if (jsonSchema.structuralTransform && !jsonSchema.composite) {
|
|
150
|
+
logger.error('structuralTransform requires composite to be defined in the JSON schema');
|
|
151
|
+
return exitSync(1);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
149
154
|
return jsonSchema;
|
|
150
155
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "2.8.
|
|
1
|
+
export declare const PACKAGE_VERSION = "2.8.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const PACKAGE_VERSION = '2.8.
|
|
2
|
+
export const PACKAGE_VERSION = '2.8.1';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -218,8 +218,13 @@ export type SharedStaticAssetsConfig = {
|
|
|
218
218
|
publicPath?: string;
|
|
219
219
|
mirrorToLocales?: boolean;
|
|
220
220
|
};
|
|
221
|
+
export type StructuralTransform = {
|
|
222
|
+
sourcePointer: string;
|
|
223
|
+
destinationPointer: string;
|
|
224
|
+
};
|
|
221
225
|
export type JsonSchema = {
|
|
222
226
|
preset?: 'mintlify' | 'openapi';
|
|
227
|
+
structuralTransform?: StructuralTransform[];
|
|
223
228
|
include?: string[];
|
|
224
229
|
composite?: {
|
|
225
230
|
[sourceObjectPath: string]: SourceObjectOptions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gt",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"bin": "dist/main.js",
|
|
6
6
|
"files": [
|
|
@@ -110,9 +110,9 @@
|
|
|
110
110
|
"unified": "^11.0.5",
|
|
111
111
|
"unist-util-visit": "^5.0.0",
|
|
112
112
|
"yaml": "^2.8.0",
|
|
113
|
-
"gt-remark": "1.0.5",
|
|
114
113
|
"@generaltranslation/python-extractor": "0.1.0",
|
|
115
|
-
"generaltranslation": "8.1.14"
|
|
114
|
+
"generaltranslation": "8.1.14",
|
|
115
|
+
"gt-remark": "1.0.5"
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
118
118
|
"@babel/types": "^7.28.4",
|