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 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.0";
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.0';
2
+ export const PACKAGE_VERSION = '2.8.1';
@@ -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.0",
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",