@zohodesk/client_build_tool 0.0.9-exp.8 → 0.0.10-exp.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/client_build_tool",
3
- "version": "0.0.9-exp.8",
3
+ "version": "0.0.10-exp.1",
4
4
  "description": "A CLI tool to build web applications and client libraries",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -31,7 +31,7 @@
31
31
  "@babel/core": "7.18.5",
32
32
  "@babel/preset-env": "7.18.2",
33
33
  "@babel/preset-react": "7.17.12",
34
- "@zohodesk/client_packages_group": "1.0.2",
34
+ "@zohodesk/client_packages_group": "1.0.3-exp.2",
35
35
  "babel-loader": "9.1.2",
36
36
  "babel-plugin-transform-react-remove-prop-types": "0.4.24",
37
37
  "babel-plugin-transform-remove-console": "6.9.4",
@@ -1,20 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.generateShortHash = generateShortHash;
7
-
8
- var _crypto = require("crypto");
9
-
10
- function generateShortHash(str, length = 8) {
11
- if (typeof str !== 'string' || str.length === 0) {
12
- return '';
13
- }
14
-
15
- try {
16
- return (0, _crypto.createHash)('md5').update(str).digest('hex').slice(0, length);
17
- } catch (error) {
18
- return '';
19
- }
20
- }
@@ -1,47 +0,0 @@
1
- "use strict";
2
-
3
- const HtmlWebpackPlugin = require('html-webpack-plugin');
4
-
5
- var {
6
- urlConcat
7
- } = require("../../../../server/urlConcat");
8
-
9
- const pluginName = 'I18nNumericIndexHtmlInjectorPlugin';
10
-
11
- class I18nNumericIndexHtmlInjectorPlugin {
12
- constructor(options) {
13
- this.options = options;
14
- }
15
-
16
- apply(compiler) {
17
- compiler.hooks.thisCompilation.tap(pluginName, compilation => {
18
- HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(pluginName, (hookData, cb) => {
19
- const {
20
- assets
21
- } = hookData;
22
- const {
23
- i18nAssetsPublicPathPrefix = ''
24
- } = this.options;
25
- const DEFAULT_LOCALE = '{{--user-locale}}';
26
- const NUMERIC_FILENAME = `i18n-chunks/${DEFAULT_LOCALE}/numeric.i18n.js`;
27
- const DYNAMIC_FILENAME = `i18n-chunks/${DEFAULT_LOCALE}/dynamic.i18n.js`;
28
- const newI18nAssetUrlsToAdd = [];
29
- const numericAssetUrl = urlConcat('', NUMERIC_FILENAME);
30
- newI18nAssetUrlsToAdd.push(numericAssetUrl);
31
- const dynamicAssetUrl = urlConcat('', DYNAMIC_FILENAME);
32
- newI18nAssetUrlsToAdd.push(dynamicAssetUrl);
33
-
34
- if (newI18nAssetUrlsToAdd.length > 0) {
35
- assets.js = [...newI18nAssetUrlsToAdd, ...assets.js];
36
- }
37
-
38
- cb(null, hookData);
39
- });
40
- });
41
- }
42
-
43
- }
44
-
45
- module.exports = {
46
- I18nNumericIndexHtmlInjectorPlugin
47
- };
@@ -1,190 +0,0 @@
1
- "use strict";
2
-
3
- const fs = require('fs');
4
-
5
- const path = require('path');
6
-
7
- const {
8
- sources,
9
- Compilation
10
- } = require('webpack');
11
-
12
- const {
13
- createHash
14
- } = require("../I18nSplitPlugin/createHash");
15
-
16
- const {
17
- RawSource
18
- } = sources;
19
- const pluginName = 'I18nNumericIndexPlugin';
20
-
21
- class I18nNumericIndexPlugin {
22
- constructor(options) {
23
- this.options = options;
24
- this.numericMap = null;
25
- this.numericMapPath = options.numericMapPath;
26
- }
27
-
28
- loadNumericMapOnce(compilation) {
29
- if (this.numericMap) {
30
- return this.numericMap;
31
- }
32
-
33
- try {
34
- if (this.numericMapPath && fs.existsSync(this.numericMapPath)) {
35
- const fileContent = fs.readFileSync(this.numericMapPath, 'utf-8');
36
- const parsedData = JSON.parse(fileContent);
37
-
38
- if (parsedData && parsedData.sortedOriginalKeys && parsedData.totalKeys !== undefined) {
39
- this.numericMap = {
40
- sortedOriginalKeys: parsedData.sortedOriginalKeys,
41
- totalKeys: parsedData.totalKeys
42
- };
43
- compilation.logger.info(`${pluginName}: Loaded numeric map from ${this.numericMapPath}.`);
44
- return this.numericMap;
45
- } else {
46
- compilation.logger.error(`${pluginName}: Invalid format in numeric map file at ${this.numericMapPath}.`);
47
- this.numericMap = {
48
- sortedOriginalKeys: [],
49
- totalKeys: 0
50
- };
51
- }
52
- } else {
53
- compilation.logger.warn(`${pluginName}: Numeric map path not provided or file not found at ${this.numericMapPath}.`);
54
- this.numericMap = {
55
- sortedOriginalKeys: [],
56
- totalKeys: 0
57
- };
58
- }
59
- } catch (err) {
60
- compilation.logger.error(`${pluginName}: Error loading numeric map from ${this.numericMapPath}: ${err.message}`);
61
- this.numericMap = {
62
- sortedOriginalKeys: [],
63
- totalKeys: 0
64
- };
65
- }
66
-
67
- return this.numericMap;
68
- }
69
-
70
- emitFile(compilation, baseFilenameTemplate, locale, fileContentData, jsonpFunc, typeSuffix = '') {
71
- const fileContent = `${jsonpFunc}(${JSON.stringify(fileContentData)});`;
72
- const source = new RawSource(fileContent);
73
- const actualContentHash = createHash({
74
- //
75
- outputOptions: compilation.outputOptions,
76
- content: fileContent
77
- });
78
- let processedFilenameTemplate = baseFilenameTemplate.replace(/\[locale\]/g, locale).replace(/\[name\]/g, locale).replace(/\[id\]/g, locale);
79
- const finalFileName = compilation.getAssetPath(processedFilenameTemplate, {
80
- locale: locale,
81
- contentHash: actualContentHash,
82
- hash: compilation.hash,
83
- chunk: {
84
- id: `i18n-${typeSuffix || 'data'}-${locale}`,
85
- name: `${typeSuffix || 'data'}-${locale}`,
86
- hash: actualContentHash,
87
- contentHash: {
88
- [this.options.moduleType || 'i18n/mini-extract']: actualContentHash
89
- }
90
- },
91
- contentHashType: this.options.moduleType || 'i18n/mini-extract'
92
- });
93
- compilation.emitAsset(finalFileName, source);
94
- compilation.logger.info(`${pluginName}: Emitted ${typeSuffix} i18n file for locale ${locale} to ${finalFileName}`);
95
- }
96
-
97
- apply(compiler) {
98
- compiler.hooks.thisCompilation.tap(pluginName, compilation => {
99
- compilation.hooks.processAssets.tapAsync({
100
- name: pluginName,
101
- stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
102
- }, (assets, callback) => {
103
- const {
104
- sortedOriginalKeys,
105
- totalKeys
106
- } = this.loadNumericMapOnce(compilation);
107
-
108
- if (totalKeys === 0 && (!sortedOriginalKeys || sortedOriginalKeys.length === 0)) {
109
- compilation.logger.info(`${pluginName}: No numeric keys to process. Skipping numeric file emission.`);
110
- }
111
-
112
- const globallyUsedLiteralKeys = new Set();
113
- const globallyUsedCommentKeys = new Set();
114
-
115
- for (const module of compilation.modules) {
116
- if (module.buildInfo) {
117
- if (Array.isArray(module.buildInfo.loaderIdentifiedLiteralI18nKeys)) {
118
- module.buildInfo.loaderIdentifiedLiteralI18nKeys.forEach(key => globallyUsedLiteralKeys.add(key));
119
- }
120
-
121
- if (Array.isArray(module.buildInfo.loaderIdentifiedCommentI18nKeys)) {
122
- module.buildInfo.loaderIdentifiedCommentI18nKeys.forEach(key => globallyUsedCommentKeys.add(key));
123
- }
124
- }
125
- }
126
-
127
- compilation.logger.info(`${pluginName}: Globally identified Literal Keys: ${globallyUsedLiteralKeys.size}, Comment Keys: ${globallyUsedCommentKeys.size}`);
128
- const {
129
- locales,
130
- allI18nObject,
131
- numericFilenameTemplate,
132
- dynamicFilenameTemplate,
133
- numericJsonpFunc,
134
- dynamicJsonpFunc
135
- } = this.options;
136
-
137
- if (!locales || !allI18nObject || !numericFilenameTemplate || !dynamicFilenameTemplate || !numericJsonpFunc || !dynamicJsonpFunc) {
138
- compilation.errors.push(new Error(`${pluginName}: Missing some required options (locales, allI18nObject, filename templates, jsonp funcs).`));
139
- return callback();
140
- }
141
-
142
- if (totalKeys > 0 && sortedOriginalKeys && sortedOriginalKeys.length > 0) {
143
- for (const locale of locales) {
144
- const localeTranslations = allI18nObject[locale] || {};
145
- const orderedNumericTranslations = new Array(totalKeys);
146
-
147
- for (let i = 0; i < totalKeys; i++) {
148
- const originalKey = sortedOriginalKeys[i];
149
-
150
- if (globallyUsedLiteralKeys.has(originalKey)) {
151
- orderedNumericTranslations[i] = localeTranslations[originalKey] !== undefined ? localeTranslations[originalKey] : 0; // Use 0 or null as placeholder for missing keys
152
- } else {
153
- orderedNumericTranslations[i] = 0; // Placeholder for keys not identified as literals or not used
154
- }
155
- }
156
-
157
- this.emitFile(compilation, numericFilenameTemplate, locale, orderedNumericTranslations, numericJsonpFunc, 'numeric');
158
- }
159
- }
160
-
161
- if (globallyUsedCommentKeys.size > 0) {
162
- for (const locale of locales) {
163
- const localeTranslations = allI18nObject[locale] || {};
164
- const dynamicKeyTranslations = {};
165
- globallyUsedCommentKeys.forEach(originalKey => {
166
- if (localeTranslations[originalKey] !== undefined) {
167
- dynamicKeyTranslations[originalKey] = localeTranslations[originalKey];
168
- } else {
169
- dynamicKeyTranslations[originalKey] = null;
170
- }
171
- });
172
-
173
- if (Object.keys(dynamicKeyTranslations).length > 0) {
174
- this.emitFile(compilation, dynamicFilenameTemplate, locale, dynamicKeyTranslations, dynamicJsonpFunc, 'dynamic');
175
- }
176
- }
177
- } else {
178
- compilation.logger.info(`${pluginName}: No globally used comment keys found. Skipping dynamic file emission.`);
179
- }
180
-
181
- callback();
182
- });
183
- });
184
- }
185
-
186
- }
187
-
188
- module.exports = {
189
- I18nNumericIndexPlugin
190
- };
@@ -1,98 +0,0 @@
1
- "use strict";
2
-
3
- const {
4
- walk
5
- } = require('estree-walker');
6
-
7
- const PREFIX_I18N_COMMENT = 'I18N';
8
- const PREFIX_I18N_COMMENT_DYNAMIC = 'dynamic-i18n-key';
9
-
10
- function getI18nKeysFromSingleComment(commentNode, validKeysSet, isDebug = false) {
11
- const functionName = '[getI18nKeysFromSingleComment]';
12
- const foundKeysInComment = [];
13
-
14
- if (!commentNode || typeof commentNode.value !== 'string') {
15
- return foundKeysInComment;
16
- }
17
-
18
- const commentString = commentNode.value.trim();
19
- let i18nKeyStr;
20
-
21
- if (commentString.startsWith(PREFIX_I18N_COMMENT)) {
22
- i18nKeyStr = commentString.slice(PREFIX_I18N_COMMENT.length).trim();
23
- } else if (commentString.startsWith(PREFIX_I18N_COMMENT_DYNAMIC)) {
24
- i18nKeyStr = commentString.slice(PREFIX_I18N_COMMENT_DYNAMIC.length).trim();
25
- }
26
-
27
- if (!i18nKeyStr) {
28
- return foundKeysInComment;
29
- }
30
-
31
- const potentialKeys = i18nKeyStr.split(',').map(key => key.trim()).filter(key => key);
32
- potentialKeys.forEach(key => {
33
- if (validKeysSet.has(key)) {
34
- foundKeysInComment.push(key);
35
- }
36
- });
37
- return foundKeysInComment;
38
- }
39
- /**
40
- * Traverses an AST and its comments to collect and categorize i18n keys.
41
- *
42
- * @param {object} astProgramNode - The Program node of the AST.
43
- * @param {object[]} commentsArray - An array of comment nodes from the AST.
44
- * @param {object} allI18nKeysMasterMap - Object map of all valid i18n keys (from JSResources).
45
- * @param {boolean} [isDebug=false] - Flag for verbose logging.
46
- * @returns {{literalKeys: Set<string>, commentKeys: Set<string>}}
47
- * literalKeys: Set of valid i18n keys found as string literals.
48
- * commentKeys: Set of valid i18n keys found in comments.
49
- */
50
-
51
-
52
- function collectAndCategorizeUsedI18nKeys(astProgramNode, commentsArray, allI18nKeysMasterMap, isDebug = false) {
53
- const functionName = '[collectAndCategorizeUsedI18nKeys]';
54
- const foundLiteralKeys = new Set();
55
- const foundCommentKeys = new Set();
56
- const validKeysSet = new Set(Object.keys(allI18nKeysMasterMap || {}));
57
-
58
- if (validKeysSet.size === 0 && isDebug) {
59
- console.warn(`${functionName} allI18nKeysMasterMap is empty. No keys can be collected.`);
60
- } // 1. Collect keys from AST string literals
61
-
62
-
63
- if (astProgramNode) {
64
- try {
65
- walk(astProgramNode, {
66
- enter(node) {
67
- if ((node.type === 'Literal' || node.type === 'StringLiteral') && typeof node.value === 'string') {
68
- if (validKeysSet.has(node.value)) {
69
- foundLiteralKeys.add(node.value);
70
- }
71
- }
72
- }
73
-
74
- });
75
- } catch (error) {
76
- console.error(`${functionName} Error during AST walk:`, error);
77
- }
78
- } // 2. Collect keys from comments
79
-
80
-
81
- if (commentsArray && Array.isArray(commentsArray)) {
82
- commentsArray.forEach(commentNode => {
83
- const keysFromComment = getI18nKeysFromSingleComment(commentNode, validKeysSet, isDebug);
84
- keysFromComment.forEach(key => {
85
- foundCommentKeys.add(key);
86
- });
87
- });
88
- }
89
-
90
- return {
91
- literalKeys: foundLiteralKeys,
92
- commentKeys: foundCommentKeys
93
- };
94
- }
95
-
96
- module.exports = {
97
- collectAndCategorizeUsedI18nKeys: collectAndCategorizeUsedI18nKeys
98
- };
@@ -1,94 +0,0 @@
1
- "use strict";
2
-
3
- const path = require('path');
4
-
5
- const fs = require('fs');
6
-
7
- let allI18nDataFromPropertiesCache = null;
8
-
9
- function loadJSResourcesOnce(options) {
10
- if (allI18nDataFromPropertiesCache) {
11
- return allI18nDataFromPropertiesCache;
12
- }
13
-
14
- let resourcePathToLoad = '';
15
-
16
- if (options.i18nIndexing && options.i18nIndexing.enable && options.i18nIndexing.jsResourcePath) {
17
- resourcePathToLoad = options.i18nIndexing.jsResourcePath;
18
- } else if (options.i18nChunkSplit && options.i18nChunkSplit.jsResource) {
19
- resourcePathToLoad = options.i18nChunkSplit.jsResource;
20
- } else {
21
- allI18nDataFromPropertiesCache = {};
22
- return allI18nDataFromPropertiesCache;
23
- }
24
-
25
- const propertiesFilePath = path.resolve(process.cwd(), resourcePathToLoad);
26
- const i18nData = {};
27
-
28
- try {
29
- const data = fs.readFileSync(propertiesFilePath, {
30
- encoding: 'utf-8'
31
- });
32
- const lines = data.split(/\r?\n/);
33
- lines.forEach(line => {
34
- const trimmedLine = line.trim();
35
-
36
- if (trimmedLine.startsWith('#') || trimmedLine.startsWith('!') || trimmedLine === '') {
37
- return;
38
- }
39
-
40
- let separatorIndex = -1;
41
-
42
- for (let i = 0; i < trimmedLine.length; i++) {
43
- if ((trimmedLine[i] === '=' || trimmedLine[i] === ':') && (i === 0 || trimmedLine[i - 1] !== '\\')) {
44
- separatorIndex = i;
45
- break;
46
- }
47
- }
48
-
49
- if (separatorIndex > 0) {
50
- let key = trimmedLine.substring(0, separatorIndex).trim();
51
- const value = trimmedLine.substring(separatorIndex + 1).trim();
52
- key = key.replace(/\\ /g, ' ');
53
-
54
- if (key) {
55
- i18nData[key] = value;
56
- }
57
- }
58
- });
59
- } catch (err) {// Silent error handling
60
- }
61
-
62
- allI18nDataFromPropertiesCache = i18nData;
63
- return allI18nDataFromPropertiesCache;
64
- }
65
-
66
- function i18nIdReplaceLoaderConfig(options) {
67
- const allI18nData = loadJSResourcesOnce(options);
68
-
69
- const i18nKeyReplaceLoaderPath = require.resolve('../loaders/i18nIdReplaceLoader.js');
70
-
71
- const loaderOptions = {
72
- allI18nData: allI18nData,
73
- sourceMaps: !!options.devtool && options.devtool.includes('source-map'),
74
- isDebug: options.mode === 'development'
75
- };
76
-
77
- if (options.i18nIndexing && options.i18nIndexing.enable) {
78
- loaderOptions.useNumericIndexing = true;
79
- loaderOptions.numericMapPath = options.i18nIndexing.numericMapPath;
80
- loaderOptions.fallbackToHash = options.i18nIndexing.fallbackToHash !== undefined ? options.i18nIndexing.fallbackToHash : true;
81
- } else {
82
- loaderOptions.useNumericIndexing = false;
83
- loaderOptions.fallbackToHash = true;
84
- }
85
-
86
- return {
87
- loader: i18nKeyReplaceLoaderPath,
88
- options: loaderOptions
89
- };
90
- }
91
-
92
- module.exports = {
93
- i18nIdReplaceLoaderConfig
94
- };
@@ -1,201 +0,0 @@
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 generator = require('@babel/generator').default;
10
-
11
- const {
12
- walk
13
- } = require('estree-walker');
14
-
15
- const {
16
- getOptions
17
- } = require('loader-utils');
18
-
19
- let collectAndCategorizeUsedI18nKeys, generateShortHash;
20
-
21
- try {
22
- collectAndCategorizeUsedI18nKeys = require('../custom_plugins/I18nSplitPlugin/utils/collectAstKeys').collectAndCategorizeUsedI18nKeys;
23
- generateShortHash = require('../common/hashUtils').generateShortHash;
24
- } catch (e) {
25
- collectAndCategorizeUsedI18nKeys = () => ({
26
- literalKeys: new Set(),
27
- commentKeys: new Set()
28
- });
29
-
30
- generateShortHash = key => key;
31
- }
32
-
33
- const LOADER_PREFIX = '[i18nIdReplaceLoader]';
34
- let numericIdMapDataCache = null;
35
- let mapLoadAttemptedForPath = {};
36
-
37
- function loadNumericIdMap(loaderContext, mapPath) {
38
- if (!mapPath) {
39
- loaderContext.emitWarning(new Error(`${LOADER_PREFIX} Numeric map path not provided in loader options.`));
40
- return null;
41
- }
42
-
43
- if (numericIdMapDataCache && mapLoadAttemptedForPath[mapPath]) {
44
- return numericIdMapDataCache;
45
- }
46
-
47
- mapLoadAttemptedForPath[mapPath] = true;
48
-
49
- try {
50
- if (fs.existsSync(mapPath)) {
51
- const fileContent = fs.readFileSync(mapPath, 'utf-8');
52
- const parsedData = JSON.parse(fileContent);
53
-
54
- if (parsedData && parsedData.originalKeyToNumericId && typeof parsedData.originalKeyToNumericId === 'object') {
55
- numericIdMapDataCache = parsedData.originalKeyToNumericId;
56
- } else {
57
- loaderContext.emitError(new Error(`${LOADER_PREFIX} Pre-generated map file (${mapPath}) is invalid or does not contain 'originalKeyToNumericId'.`));
58
- numericIdMapDataCache = null;
59
- }
60
- } else {
61
- loaderContext.emitError(new Error(`${LOADER_PREFIX} Pre-generated i18n numeric map file NOT FOUND at: ${mapPath}.`));
62
- numericIdMapDataCache = null;
63
- }
64
- } catch (err) {
65
- loaderContext.emitError(new Error(`${LOADER_PREFIX} Error loading or parsing pre-generated i18n map from ${mapPath}: ${err.message}`));
66
- numericIdMapDataCache = null;
67
- }
68
-
69
- return numericIdMapDataCache;
70
- }
71
-
72
- module.exports = function i18nIdReplaceLoader(source, map, meta) {
73
- const resourcePath = this.resourcePath;
74
- this.cacheable && this.cacheable();
75
- const options = getOptions(this) || {};
76
- const callback = this.async();
77
- const loaderContext = this;
78
-
79
- if (!options.allI18nData || typeof options.allI18nData !== 'object' || Object.keys(options.allI18nData).length === 0) {
80
- this.emitWarning(new Error(`${LOADER_PREFIX} [${resourcePath}] 'allI18nData' option is missing or empty. No replacements will be made.`));
81
- return callback(null, source, map);
82
- }
83
-
84
- let useNumericIndexing = options.useNumericIndexing !== undefined ? options.useNumericIndexing : true;
85
- let localOriginalKeyToNumericIdMap = null;
86
-
87
- if (useNumericIndexing) {
88
- localOriginalKeyToNumericIdMap = loadNumericIdMap(this, options.numericMapPath);
89
- }
90
-
91
- const fallbackToHash = options.fallbackToHash !== undefined ? options.fallbackToHash : true;
92
-
93
- try {
94
- const parserOptions = {
95
- sourceType: 'module',
96
- plugins: ['jsx', 'typescript', 'classProperties', 'optionalChaining', 'nullishCoalescingOperator'],
97
- attachComment: true,
98
- sourceFilename: resourcePath
99
- };
100
- const astFile = parser.parse(source, parserOptions);
101
- const astProgram = astFile.program;
102
- const comments = astFile.comments || [];
103
- const {
104
- literalKeys,
105
- commentKeys
106
- } = collectAndCategorizeUsedI18nKeys(astProgram, comments, options.allI18nData, options.isDebug);
107
-
108
- if (this._module) {
109
- if (!this._module.buildInfo) {
110
- this._module.buildInfo = {};
111
- }
112
-
113
- if (literalKeys.size > 0) {
114
- this._module.buildInfo.loaderIdentifiedLiteralI18nKeys = Array.from(literalKeys);
115
- }
116
-
117
- if (commentKeys.size > 0) {
118
- this._module.buildInfo.loaderIdentifiedCommentI18nKeys = Array.from(commentKeys);
119
- }
120
- }
121
-
122
- const keysToReplaceInLiterals = literalKeys;
123
-
124
- if (keysToReplaceInLiterals.size === 0) {
125
- return callback(null, source, map);
126
- }
127
-
128
- let replacementMade = false;
129
- walk(astProgram, {
130
- enter: function (node, parent, prop, index) {
131
- const walkerControl = this;
132
-
133
- if ((node.type === 'Literal' || node.type === 'StringLiteral') && typeof node.value === 'string') {
134
- const originalValue = node.value;
135
-
136
- if (keysToReplaceInLiterals.has(originalValue)) {
137
- let replaced = false;
138
-
139
- if (useNumericIndexing && localOriginalKeyToNumericIdMap) {
140
- const numericId = localOriginalKeyToNumericIdMap[originalValue];
141
-
142
- if (numericId !== undefined) {
143
- const numericLiteralNode = {
144
- type: 'NumericLiteral',
145
- value: numericId
146
- };
147
- let replacementNode = numericLiteralNode;
148
-
149
- if (parent && parent.type === 'JSXAttribute' && parent.value === node) {
150
- replacementNode = {
151
- type: 'JSXExpressionContainer',
152
- expression: numericLiteralNode
153
- };
154
- }
155
-
156
- walkerControl.replace(replacementNode);
157
- replacementMade = true;
158
- replaced = true;
159
- }
160
- }
161
-
162
- if (!replaced && fallbackToHash) {
163
- try {
164
- const hashValue = generateShortHash(originalValue);
165
- const hashedStringLiteralNode = {
166
- type: 'StringLiteral',
167
- value: hashValue
168
- };
169
- walkerControl.replace(hashedStringLiteralNode);
170
- replacementMade = true;
171
- } catch (hashError) {
172
- loaderContext.emitError(new Error(`${LOADER_PREFIX} [${resourcePath}] Error hashing key "${originalValue}": ${hashError.message}`));
173
- }
174
- }
175
- }
176
- }
177
- }
178
- });
179
-
180
- if (replacementMade) {
181
- const generateOptions = {
182
- sourceMaps: options.sourceMaps,
183
- sourceFileName: resourcePath,
184
- retainLines: false,
185
- comments: true
186
- };
187
- const output = generator(astFile, generateOptions, source);
188
- callback(null, output.code, options.sourceMaps && output.map ? output.map : map);
189
- } else {
190
- callback(null, source, map);
191
- }
192
- } catch (err) {
193
- const detailedError = new Error(`${LOADER_PREFIX} [${resourcePath}] AST Processing Error: ${err.message} (Stack: ${err.stack})`);
194
-
195
- if (err.loc) {
196
- detailedError.message += ` at line ${err.loc.line}, column ${err.loc.column}`;
197
- }
198
-
199
- callback(detailedError);
200
- }
201
- };