@zohodesk/client_build_tool 0.0.11-exp.15.2 → 0.0.11-exp.15.4

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/README.md CHANGED
@@ -98,105 +98,3 @@ fixes :-
98
98
 
99
99
  - preload plc undefined url fixed
100
100
 
101
- # Changelog and Release Notes
102
-
103
- - remove babel-plugin-module-resolver dependencies
104
-
105
- **Adjustments:-**
106
- - Public Folder configuration is separated for development and production
107
-
108
- **Bug Fix:-**
109
- - Fixed the issue where the build log was not visible when `stats (bundle integrity)` was enabled. The problem was resolved by adding an error check in the `bundleIntegrity plugin`.
110
- - Removed the babel-plugin-module-resolver dependency to resolve the alias resolution issue in the application.
111
- - Fixed the issue where a space in the variable name causes it to return an undefined value.
112
- - Fixed the URL path generation issue that occurred while using context in the development setup.
113
-
114
-
115
-
116
- # v0.0.11
117
-
118
- # v0.0.10 (12-05-2025)
119
- **Feature:-**
120
- - `alias` support for `build:es` and `build:lib`
121
- - Add babel-plugin-module-resolver dependencies
122
- - Modify getBabelPlugin to include module resolver with aliases
123
-
124
- **Bug Fix:-**
125
- - Enhance runBabelForTSFile to handle both .tsx and .ts file extensions
126
- - Update mockApiHandler to ensure mock function is called correctly
127
-
128
- **Change:-**
129
- - Refactor defaultConfigValues.js to include cli options for enableRTLSplit
130
-
131
- ## v0.0.9
132
-
133
- **Feature:-**
134
- - externals was added to Prevent bundling of certain imported packages and retrieve these external dependencies at runtime.
135
- - to use externals, we use the following pattern in `app > externals` :
136
-
137
- For example
138
- ```
139
- externals: {
140
- <key> : <value>
141
- }
142
- ```
143
-
144
- ## v0.0.6 (4-09-2023)
145
-
146
- **Feature:-**
147
- - Generating bundle integrity report json file for the build assets only in production mode. To use this feature we need to add `stats > enable` or cli flags `enable_stats`.
148
- - Added Resource Cleanup plugin to cleanup resource retained by build tool. this plugin is controlled by efc flag resourcecleanup flag.
149
- - added support for using regex expression to get group of chunks chunkId via Resource Hint plugin prefetch/preload hook.
150
- only will be activate when `resourceHints` => `allowPrefetchingMultipleChunks` as `true`
151
- - added support for glob pattern for custom chunks split logic.
152
- - added options to split chunks base config in the key `app` => `customChunksBaseConfig` as object
153
-
154
- **Change:-**
155
- - i18n name not generated issue fix.
156
- - public path not correctly set issue fix.
157
- - changing plugin hook stages in i18nRuntimePlugin and sourceMapPlugin
158
- ## v0.0.5 (6-08-2023)
159
-
160
- **Changes:--**
161
- - Typo fix in i18nRuntimeDealerPlugin.js
162
- - fixing some bugs in resolvers.js file
163
-
164
- ## v0.0.3 (1-08-2023)
165
-
166
- **Changes:--**
167
- - `devtool` default value changed from `hidden-cheap-source-map` to `source-map`
168
- - unwanted files deleted from build
169
-
170
- **Issue Fix:--**
171
- - The issue with the source map not being created in the build has been fixed."
172
-
173
-
174
- ## v0.0.2 (28-04-2023)
175
-
176
- **Features:-**
177
-
178
- - `devModeContentHashAllowedTypes` support added for some project there will be a need for hash even though they run dev mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devModeContentHashAllowedTypes)
179
- - `devLikeHash` support for disable content hash for file names in production mode. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#devLikeHash)
180
- - `disableReactDevWarning` disable react dev warning such as prop-type warnings will be removed in dev mode build or server. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#disableReactDevWarning) can be enabled via `--disable_react_dev_warning` too.
181
- - `statsLogConfig` support to customize default webpack log after build finished. for details [details](https://zgit.csez.zohocorpin.com/zohodesk/react-cli/-/blob/3.0.0/packages/client_build_tool/ConfigurationDocumentation.md#statsLogConfig) can be enabled via `--disable_react_dev_warning` too.
182
- - `enableChunkHash` renamed as `enableFileNameHashing`
183
-
184
- - `pre_processor` command to run the preprocessor.js file.preProcessor runs in build, start, buildEs, buildLib commands bu default. and we have watch mode support as well with the option (`-w`)
185
- - `createSeparateSmap` flag `source_map_enable` renamed as `enable_smap`
186
- - `removeAttribute` option changes as `babelCustomizations.removeAttribute`
187
- - `removePropTypes` support for remove the prop types package in the output build.
188
- - `devConsoleExclude` support for remove the _console statements_ such as _console.log_, _console.warn_ in the output build.
189
- - `manifestJson` default value set as false.
190
- - `customAttributes` support for add attributes to html, link , script tag in the output build.
191
-
192
-
193
- ## v0.0.1 (18-04-2023)
194
-
195
- First Release
196
- **Features:-**
197
-
198
- - 'start' command to run react app
199
- - 'build' command to create build for react app
200
- - 'build:lib' command to create lib for react library
201
- - 'build:es' command to create es for react library
202
- - 'templates' command to create es for react library
@@ -15,6 +15,8 @@ var _propertiesUtils = require("../I18nSplitPlugin/utils/propertiesUtils");
15
15
 
16
16
  var _I18nGroupRuntimeModule = require("./I18nGroupRuntimeModule");
17
17
 
18
+ var _i18nDataLoader = require("./utils/i18nDataLoader");
19
+
18
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
21
 
20
22
  const {
@@ -27,7 +29,6 @@ class I18nNumericIndexPlugin {
27
29
  this.options = options;
28
30
  this.numericMap = {};
29
31
  this.customGroups = {};
30
- this.nextNumericId = 1;
31
32
  }
32
33
 
33
34
  apply(compiler) {
@@ -99,6 +100,20 @@ class I18nNumericIndexPlugin {
99
100
 
100
101
  if (!jsResourcePath || !propertiesFolderPath) {
101
102
  return;
103
+ } // Load existing numeric map if available
104
+
105
+
106
+ if (numericMapPath) {
107
+ const mapData = (0, _i18nDataLoader.loadNumericMap)(numericMapPath, compilation);
108
+
109
+ if (mapData && mapData.sortedKeys) {
110
+ // Initialize numericMap from existing data
111
+ mapData.sortedKeys.forEach((key, id) => {
112
+ if (key) {
113
+ this.numericMap[key] = id;
114
+ }
115
+ });
116
+ }
102
117
  } // Read JSResources.properties
103
118
 
104
119
 
@@ -113,7 +128,15 @@ class I18nNumericIndexPlugin {
113
128
  folderPath: propertiesFolderPath,
114
129
  disableDefault: false,
115
130
  jsResourceI18nKeys: jsResourceKeys
116
- });
131
+ }); // For en_US, use only JSResources (don't merge with ApplicationResources_en_US)
132
+
133
+ if (allI18nObject['en_US']) {
134
+ allI18nObject['en_US'] = jsResourceKeys;
135
+ } else {
136
+ // If en_US doesn't exist in the folder, create it from JSResources
137
+ allI18nObject['en_US'] = jsResourceKeys;
138
+ }
139
+
117
140
  const locales = Object.keys(allI18nObject); // Process each locale
118
141
 
119
142
  locales.forEach(locale => {
@@ -127,21 +150,21 @@ class I18nNumericIndexPlugin {
127
150
  }); // Process each key
128
151
 
129
152
  Object.keys(localeData).forEach(key => {
130
- const value = localeData[key]; // Check if key belongs to a custom group
153
+ const value = localeData[key]; // Simple logic: if has numeric ID use it, otherwise it's dynamic
131
154
 
132
- const belongsToGroup = this.getKeyGroup(key);
155
+ if (this.numericMap[key]) {
156
+ const numericKey = String(this.numericMap[key]); // Check if belongs to a custom group
133
157
 
134
- if (belongsToGroup) {
135
- // Add to custom group
136
- const numericKey = this.getNumericKey(key);
137
- groupData[belongsToGroup][numericKey] = value;
138
- } else if (this.isDynamicKey(value)) {
139
- // Add to dynamic chunk (keep string keys for dynamic)
140
- dynamicData[key] = value;
158
+ const belongsToGroup = this.getKeyGroup(key);
159
+
160
+ if (belongsToGroup) {
161
+ groupData[belongsToGroup][numericKey] = value;
162
+ } else {
163
+ numericData[numericKey] = value;
164
+ }
141
165
  } else {
142
- // Add to numeric chunk
143
- const numericKey = this.getNumericKey(key);
144
- numericData[numericKey] = value;
166
+ // No numeric ID = dynamic key (regardless of placeholders)
167
+ dynamicData[key] = value;
145
168
  }
146
169
  }); // Emit numeric chunk
147
170
 
@@ -156,11 +179,7 @@ class I18nNumericIndexPlugin {
156
179
  this.emitChunk(compilation, groupConfig.filenameTemplate || `i18n-chunk/[locale]/${groupName}.i18n.js`, locale, data, jsonpFunc, groupName);
157
180
  }
158
181
  });
159
- }); // Save numeric map
160
-
161
- if (numericMapPath) {
162
- this.saveNumericMap(numericMapPath);
163
- }
182
+ }); // Don't save numeric map - it should only be generated by the external script
164
183
  }
165
184
 
166
185
  parseCustomGroups(jsResourcePath, customGroups) {
@@ -207,11 +226,8 @@ class I18nNumericIndexPlugin {
207
226
  }
208
227
 
209
228
  getNumericKey(key) {
210
- if (!this.numericMap[key]) {
211
- this.numericMap[key] = this.nextNumericId++;
212
- }
213
-
214
- return String(this.numericMap[key]);
229
+ // Return numeric ID if it exists, null otherwise
230
+ return this.numericMap[key] ? String(this.numericMap[key]) : null;
215
231
  }
216
232
 
217
233
  emitChunk(compilation, filenameTemplate, locale, data, jsonpFunc, groupName = null) {
@@ -221,7 +237,8 @@ class I18nNumericIndexPlugin {
221
237
  }
222
238
 
223
239
  generateChunkContent(data, jsonpFunc, groupName) {
224
- const jsonString = JSON.stringify(data);
240
+ // Decode Unicode escapes to convert \uXXXX to actual characters
241
+ const jsonString = (0, _propertiesUtils.decodeUnicodeEscapes)(JSON.stringify(data));
225
242
 
226
243
  if (groupName) {
227
244
  // Include group name for lazy loading identification
@@ -231,18 +248,6 @@ class I18nNumericIndexPlugin {
231
248
  return `${jsonpFunc}(${jsonString});`;
232
249
  }
233
250
 
234
- saveNumericMap(mapPath) {
235
- const dir = _path.default.dirname(mapPath);
236
-
237
- if (!_fs.default.existsSync(dir)) {
238
- _fs.default.mkdirSync(dir, {
239
- recursive: true
240
- });
241
- }
242
-
243
- _fs.default.writeFileSync(mapPath, JSON.stringify(this.numericMap, null, 2));
244
- }
245
-
246
251
  }
247
252
 
248
253
  exports.default = I18nNumericIndexPlugin;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+
5
+ const path = require('path');
6
+
7
+ const {
8
+ getPropertiesAsJSON
9
+ } = require('../../I18nSplitPlugin/utils/propertiesUtils');
10
+ /**
11
+ * Load and parse a properties file
12
+ */
13
+
14
+
15
+ function loadPropertiesFile(filePath, compilation, description) {
16
+ try {
17
+ const parsed = getPropertiesAsJSON(filePath);
18
+ return parsed;
19
+ } catch (err) {
20
+ if (compilation) {
21
+ compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error loading ${description}: ${err.message}`));
22
+ }
23
+
24
+ return {};
25
+ }
26
+ }
27
+ /**
28
+ * Load numeric mapping from JSON file
29
+ */
30
+
31
+
32
+ function loadNumericMap(numericMapPath, compilation) {
33
+ try {
34
+ const fileContent = fs.readFileSync(numericMapPath, 'utf-8');
35
+ const parsedData = JSON.parse(fileContent);
36
+ let numericMap;
37
+ let totalKeys; // Handle both wrapped and flat formats
38
+
39
+ if (parsedData.originalKeyToNumericId) {
40
+ // New format with metadata
41
+ numericMap = parsedData.originalKeyToNumericId;
42
+ totalKeys = parsedData.totalKeysInMap || Object.keys(numericMap).length;
43
+ } else {
44
+ // Flat format - use directly
45
+ numericMap = parsedData;
46
+ totalKeys = Object.keys(numericMap).length;
47
+ } // Create sorted array for numeric ID lookups
48
+
49
+
50
+ const maxId = Math.max(...Object.values(numericMap));
51
+ const sortedKeys = new Array(maxId + 1);
52
+ Object.entries(numericMap).forEach(([key, id]) => {
53
+ sortedKeys[id] = key;
54
+ });
55
+ return {
56
+ sortedKeys,
57
+ totalKeys
58
+ };
59
+ } catch (err) {
60
+ if (compilation) {
61
+ compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error loading numeric map: ${err.message}`));
62
+ }
63
+
64
+ return {
65
+ sortedKeys: [],
66
+ totalKeys: 0
67
+ };
68
+ }
69
+ }
70
+ /**
71
+ * Load all locale files from properties directory
72
+ */
73
+
74
+
75
+ function loadAllLocaleFiles(propertiesPath, compilation, jsResourceBase) {
76
+ const allI18n = {};
77
+ const locales = []; // Start with English base
78
+
79
+ allI18n['en_US'] = jsResourceBase;
80
+ locales.push('en_US');
81
+
82
+ try {
83
+ const files = fs.readdirSync(propertiesPath);
84
+ files.forEach(file => {
85
+ if (!file.endsWith('.properties')) return; // Match locale-specific property files
86
+
87
+ const match = file.match(/^ApplicationResources_([a-z]{2}_[A-Z]{2})\.properties$/);
88
+
89
+ if (match) {
90
+ const locale = match[1];
91
+ const filePath = path.join(propertiesPath, file);
92
+ const localeData = loadPropertiesFile(filePath, compilation, `locale ${locale}`); // Merge with base resources
93
+
94
+ allI18n[locale] = { ...jsResourceBase,
95
+ ...localeData
96
+ };
97
+
98
+ if (!locales.includes(locale)) {
99
+ locales.push(locale);
100
+ }
101
+ }
102
+ });
103
+ } catch (err) {
104
+ if (compilation) {
105
+ compilation.errors.push(new Error(`I18nNumericIndexPlugin: Error reading properties folder: ${err.message}`));
106
+ }
107
+ }
108
+
109
+ return {
110
+ allI18n,
111
+ locales
112
+ };
113
+ }
114
+ /**
115
+ * Main loader function for i18n data
116
+ */
117
+
118
+
119
+ function loadI18nData(options, compilation) {
120
+ const jsResourcePath = path.resolve(compilation.compiler.context, options.jsResourcePath);
121
+ const propertiesPath = path.resolve(compilation.compiler.context, options.propertiesFolderPath); // Load base JS resources
122
+
123
+ const jsResourceBase = loadPropertiesFile(jsResourcePath, compilation, 'JS resources'); // Load all locale files
124
+
125
+ const {
126
+ allI18n,
127
+ locales
128
+ } = loadAllLocaleFiles(propertiesPath, compilation, jsResourceBase);
129
+ return {
130
+ jsResourceBase,
131
+ allI18n,
132
+ locales
133
+ };
134
+ }
135
+
136
+ module.exports = {
137
+ loadPropertiesFile,
138
+ loadNumericMap,
139
+ loadAllLocaleFiles,
140
+ loadI18nData
141
+ };
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.decodeUnicodeEscapes = decodeUnicodeEscapes;
6
7
  exports.getAllI18n = getAllI18n;
7
8
  exports.getPropertiesAsJSON = getPropertiesAsJSON;
8
9
  exports.jsonToString = jsonToString;
@@ -16,6 +17,21 @@ var _constants = require("../../../../../constants");
16
17
  function isComment(line) {
17
18
  return line[0] === '#';
18
19
  }
20
+ /**
21
+ * Decode Unicode escape sequences in a string
22
+ * Converts \uXXXX to the actual character
23
+ */
24
+
25
+
26
+ function decodeUnicodeEscapes(str) {
27
+ if (typeof str !== 'string') {
28
+ return str;
29
+ }
30
+
31
+ return str.replace(/\\u([0-9a-fA-F]{4})/g, (match, hex) => {
32
+ return String.fromCharCode(parseInt(hex, 16));
33
+ });
34
+ }
19
35
 
20
36
  function getPropertiesAsJSON(filePath) {
21
37
  try {
@@ -31,9 +47,11 @@ function getPropertiesAsJSON(filePath) {
31
47
 
32
48
  const ind = line.indexOf('=');
33
49
  const key = line.slice(0, ind).replace(/\\ /g, ' ');
34
- const value = line.slice(ind + 1);
50
+ let value = line.slice(ind + 1);
35
51
 
36
52
  if (key && value) {
53
+ // Decode Unicode escapes in the value
54
+ value = decodeUnicodeEscapes(value);
37
55
  i18nObj[key] = value;
38
56
  }
39
57
  }, {});
@@ -7,11 +7,34 @@ exports.jsLoaders = jsLoaders;
7
7
 
8
8
  var _babelLoaderConfig = require("./loaderConfigs/babelLoaderConfig");
9
9
 
10
+ const {
11
+ i18nIdReplaceLoaderConfig
12
+ } = require('./loaderConfigs/i18nIdReplaceLoaderConfig');
13
+
10
14
  function jsLoaders(options) {
15
+ const useLoaders = []; // Always add babel loader first
16
+
17
+ useLoaders.push((0, _babelLoaderConfig.babelLoaderConfig)(options)); // Add i18n ID replace loader if numeric indexing is enabled
18
+
19
+ const shouldUseNumericIndexing = options.i18nIndexing && options.i18nIndexing.enable || options.i18nChunkSplit && options.i18nChunkSplit.chunkSplitEnable && options.i18nChunkSplit.useNumericIndexing;
20
+
21
+ if (shouldUseNumericIndexing) {
22
+ try {
23
+ const loaderConfig = i18nIdReplaceLoaderConfig(options, options.context);
24
+
25
+ if (loaderConfig) {
26
+ useLoaders.push(loaderConfig);
27
+ }
28
+ } catch (err) {
29
+ // Silently skip if configuration fails
30
+ console.warn('[jsLoaders] Failed to configure i18n ID replace loader:', err.message);
31
+ }
32
+ }
33
+
11
34
  return [{
12
35
  test: /\.js$/,
13
36
  exclude: /node_modules/,
14
- use: [(0, _babelLoaderConfig.babelLoaderConfig)(options)] // include: path.join(appPath, folder)
37
+ use: useLoaders // include: path.join(appPath, folder)
15
38
 
16
39
  }];
17
40
  }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ const {
4
+ getPropertiesAsJSON
5
+ } = require('../custom_plugins/I18nSplitPlugin/utils/propertiesUtils');
6
+ /**
7
+ * Load i18n data from JSResources file once for all chunks
8
+ */
9
+
10
+
11
+ function loadJSResourcesOnce(options) {
12
+ let jsResourcePath; // Determine the JSResource path based on configuration
13
+
14
+ if (options.i18nIndexing && options.i18nIndexing.enable) {
15
+ jsResourcePath = options.i18nIndexing.jsResourcePath;
16
+ } else if (options.i18nChunkSplit && options.i18nChunkSplit.chunkSplitEnable && options.i18nChunkSplit.useNumericIndexing) {
17
+ jsResourcePath = options.i18nChunkSplit.jsResource;
18
+ } else {
19
+ throw new Error('i18nIdReplaceLoader requires either i18nIndexing to be enabled or i18nChunkSplit with useNumericIndexing');
20
+ }
21
+
22
+ if (!jsResourcePath) {
23
+ throw new Error('Missing required jsResourcePath in i18n options');
24
+ }
25
+
26
+ try {
27
+ const i18nData = getPropertiesAsJSON(jsResourcePath);
28
+
29
+ if (Object.keys(i18nData).length === 0) {
30
+ console.warn(`[i18nIdReplaceLoaderConfig] Warning: No i18n data found in JSResource file: ${jsResourcePath}`);
31
+ return {};
32
+ }
33
+
34
+ return i18nData;
35
+ } catch (err) {
36
+ throw new Error(`Error reading JSResource file ${jsResourcePath}: ${err.message}`);
37
+ }
38
+ }
39
+ /**
40
+ * Configure the i18n ID replace loader
41
+ */
42
+
43
+
44
+ function i18nIdReplaceLoaderConfig(options, webpackContext) {
45
+ let numericMapPath; // Determine the numeric map path based on configuration
46
+
47
+ if (options.i18nIndexing && options.i18nIndexing.enable) {
48
+ numericMapPath = options.i18nIndexing.numericMapPath;
49
+ } else if (options.i18nChunkSplit && options.i18nChunkSplit.chunkSplitEnable && options.i18nChunkSplit.useNumericIndexing) {
50
+ numericMapPath = options.i18nChunkSplit.numericMapPath;
51
+ } else {
52
+ throw new Error('i18nIdReplaceLoader requires either i18nIndexing to be enabled or i18nChunkSplit with useNumericIndexing');
53
+ }
54
+
55
+ if (!numericMapPath) {
56
+ throw new Error('numericMapPath is required in i18nIndexing or i18nChunkSplit config');
57
+ } // Load all i18n data for key detection
58
+
59
+
60
+ const allI18nData = loadJSResourcesOnce(options);
61
+
62
+ const i18nKeyReplaceLoaderPath = require.resolve('../loaders/i18nIdReplaceLoader.js');
63
+
64
+ const loaderOptions = {
65
+ allI18nData: allI18nData,
66
+ sourceMaps: false,
67
+ numericMapPath: numericMapPath,
68
+ devMode: options.i18nIndexing?.devMode || false,
69
+ includePaths: options.i18nIndexing?.loaderOptions?.includePaths || [],
70
+ excludePaths: options.i18nIndexing?.loaderOptions?.excludePaths || ['node_modules', 'tests']
71
+ };
72
+ return {
73
+ loader: i18nKeyReplaceLoaderPath,
74
+ options: loaderOptions
75
+ };
76
+ }
77
+
78
+ module.exports = {
79
+ i18nIdReplaceLoaderConfig
80
+ };
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+
5
+ const path = require('path');
6
+
7
+ const parser = require('@babel/parser');
8
+
9
+ const traverse = require('@babel/traverse').default;
10
+
11
+ const generator = require('@babel/generator').default;
12
+
13
+ const t = require('@babel/types');
14
+
15
+ const {
16
+ getOptions
17
+ } = require('loader-utils');
18
+
19
+ module.exports = function i18nIdReplaceLoader(source, map) {
20
+ const resourcePath = this.resourcePath;
21
+ this.cacheable && this.cacheable();
22
+ const options = getOptions(this) || {};
23
+ const callback = this.async(); // Skip files in excluded paths
24
+
25
+ if (options.excludePaths) {
26
+ const shouldExclude = options.excludePaths.some(excludePath => resourcePath.includes(excludePath));
27
+
28
+ if (shouldExclude) {
29
+ return callback(null, source, map);
30
+ }
31
+ } // Only process files in included paths if specified
32
+
33
+
34
+ if (options.includePaths && options.includePaths.length > 0) {
35
+ const shouldInclude = options.includePaths.some(includePath => resourcePath.includes(includePath));
36
+
37
+ if (!shouldInclude) {
38
+ return callback(null, source, map);
39
+ }
40
+ } // Validate i18n data exists
41
+
42
+
43
+ if (!options.allI18nData || Object.keys(options.allI18nData).length === 0) {
44
+ return callback(new Error(`i18nIdReplaceLoader: 'allI18nData' option is missing or empty`));
45
+ } // Load numeric ID mapping
46
+
47
+
48
+ let numericIdMap = null;
49
+
50
+ if (options.numericMapPath) {
51
+ try {
52
+ if (fs.existsSync(options.numericMapPath)) {
53
+ const fileContent = fs.readFileSync(options.numericMapPath, 'utf-8');
54
+ const parsedData = JSON.parse(fileContent); // Handle both wrapped and flat formats
55
+
56
+ if (parsedData) {
57
+ if (parsedData.originalKeyToNumericId) {
58
+ // New format with wrapper
59
+ numericIdMap = parsedData.originalKeyToNumericId;
60
+ } else if (typeof parsedData === 'object') {
61
+ // Flat format - use directly
62
+ numericIdMap = parsedData;
63
+ }
64
+ }
65
+ }
66
+ } catch (err) {// Silently continue without numeric mapping
67
+ }
68
+ } // If no numeric map available, return source as-is
69
+
70
+
71
+ if (!numericIdMap) {
72
+ return callback(null, source, map);
73
+ }
74
+
75
+ const isDevMode = options.devMode || process.env.NODE_ENV === 'development';
76
+
77
+ try {
78
+ // Parse the JavaScript/TypeScript source code
79
+ const ast = parser.parse(source, {
80
+ sourceType: 'module',
81
+ plugins: ['jsx', 'typescript', 'classProperties', 'optionalChaining', 'nullishCoalescingOperator'],
82
+ sourceFilename: resourcePath
83
+ });
84
+ let hasTransformations = false; // Traverse AST and replace i18n keys with numeric IDs
85
+
86
+ traverse(ast, {
87
+ StringLiteral(path) {
88
+ const {
89
+ node
90
+ } = path; // Check if this string is an i18n key
91
+
92
+ if (!options.allI18nData.hasOwnProperty(node.value)) {
93
+ return;
94
+ } // Replace with numeric ID if available
95
+
96
+
97
+ if (numericIdMap.hasOwnProperty(node.value)) {
98
+ const numericId = String(numericIdMap[node.value]);
99
+ path.replaceWith(t.stringLiteral(numericId));
100
+ hasTransformations = true;
101
+ }
102
+ }
103
+
104
+ }); // Generate code if transformations were made
105
+
106
+ if (hasTransformations) {
107
+ const output = generator(ast, {
108
+ sourceMaps: !!options.sourceMaps,
109
+ sourceFileName: resourcePath,
110
+ retainLines: false,
111
+ comments: true
112
+ }, source);
113
+ callback(null, output.code, output.map);
114
+ } else {
115
+ callback(null, source, map);
116
+ }
117
+ } catch (err) {
118
+ callback(err);
119
+ }
120
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/client_build_tool",
3
- "version": "0.0.11-exp.15.2",
3
+ "version": "0.0.11-exp.15.4",
4
4
  "description": "A CLI tool to build web applications and client libraries",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
package/README_backup.md DELETED
@@ -1,100 +0,0 @@
1
- # Client Build Tool
2
-
3
- This is a build tool for react based web applications.
4
-
5
- Supported and Tested Environment
6
-
7
- | Name | Version |
8
- | :--: | :------: |
9
- | node | v18.11.0 |
10
- | npm | 8.19.2 |
11
-
12
- OS : Mac , ubuntu
13
-
14
- # client_build_tool
15
-
16
- A CLI tool for build modern web application and libraries
17
-
18
- # Installation
19
-
20
- Below Steps:-
21
-
22
- > `npm i -g @zohodesk/client_build_tool`
23
-
24
- # Usage
25
-
26
- ## Step 1
27
-
28
- > `cbt template app <your-project-folder> && cd <your-project-folder>`
29
-
30
- ## Step 2
31
-
32
- Now to run app
33
-
34
- > `npm run start`
35
-
36
- ---
37
-
38
- Happy Code :>) 🤟
39
-
40
- # "Client Build Tool (CBT): Streamline and Optimize Your Client-side Build Process"
41
-
42
- ## Description:
43
-
44
- CBT is a powerful client-side build tool designed to streamline and optimize your development workflow. With CBT, you can effortlessly manage and configure your project's build process, automating tasks, and improving efficiency. It provides an intuitive interface and a comprehensive set of features to simplify the build pipeline, allowing you to focus more on coding and less on tedious configuration.
45
-
46
- ## Key Features:
47
-
48
- - **Integrated Dev Server:** Run your application locally with a built-in development server for quick feedback and real-time updates.
49
- - **Mock API Server:** Seamlessly integrate a mock API server to simulate backend interactions during development.
50
- - **Intelligent CSS Processing:** Automatically process and optimize CSS files, including customizable class name generation and advanced postcss plugins.
51
- - **Internationalization Support:** Easily manage internationalization (i18n) with efficient chunk splitting and language-specific resource loading.
52
- - **CDN Mapping:** Effortlessly map assets to a Content Delivery Network (CDN) for faster delivery and improved performance.
53
- - **Comprehensive Configuration:** Fine-tune your build process with extensive configuration options, including source maps, Babel customizations, and more.
54
- - **Service Worker Integration:** Enable service worker functionality for offline support and improved caching capabilities.
55
- - **Customizable Build Artifacts:** Define custom chunks, modify HTML templates, and generate a manifest.json file for better control over your build output.
56
- - **User-friendly Interface:** CBT provides a user-friendly interface, making it easy to configure, customize, and monitor your build process.
57
-
58
- With CBT, you can optimize your client-side development workflow, increase productivity, and deliver high-quality applications faster. Start using CBT today and experience the power of efficient and streamlined client-side builds.
59
-
60
- # Commands
61
-
62
- The following commands are available options for the `cbt` (Client Build Tool) CLI. You can execute these commands by prefixing them with `cbt`. For example, `cbt start`.
63
-
64
- - **preProcessor:** Runs the preProcessor.js in the app to set the variables before the build or run the dev mode.
65
-
66
- - **start**: Starts the development server with mode support. You can specify the mode as either `dev` or `prod`. This command is used for local development and testing.
67
-
68
- - **build**: Executes the build command with mode support. You can specify the mode as either `dev` or `prod`. This command compiles and bundles your application for deployment.
69
-
70
- - **build:lib**: Transpile the `src` folder to the `lib` folder, generating CommonJS modules. This command is specifically designed for building libraries that require CommonJS module format.
71
-
72
- - **build:es**: Transpile the `src` folder to the `es` folder, generating modules using import statements. This command is useful for building libraries that use ECMAScript module syntax.
73
-
74
- - **version**: Prints the version of the CBT CLI tool.
75
-
76
- - **template**: Creates an initial template or skeleton for your project. You can specify the option as `app`. This command sets up a basic project structure and configuration files to get you started quickly.
77
-
78
- - **mock:server**: Starts an external mock API server. This command enables you to run a separate server specifically for mocking API responses during development and testing.
79
-
80
- > Note: Make sure to replace `start` in the examples above with the actual command or script that you use to run the Client Build Tool CLI.
81
-
82
- These commands provide flexibility and control over your client-side build process, allowing you to start the development server, build your application, transpile libraries, create templates, run a mock API server, and more.
83
-
84
- For more [Details](ConfigurationDocumentation.md)
85
-
86
-
87
- version details :-
88
-
89
- # 0.0.8
90
-
91
- - Main version
92
-
93
- # 0.0.9
94
-
95
- fixes :-
96
-
97
- - service worker wrong i18n entry fixed
98
-
99
- - preload plc undefined url fixed
100
-