@lang-tag/cli 0.11.2 → 0.12.0
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/algorithms/config-generation/config-keeper.d.ts +47 -0
- package/algorithms/config-generation/index.d.ts +1 -0
- package/algorithms/index.cjs +39 -2
- package/algorithms/index.d.ts +1 -1
- package/algorithms/index.js +39 -2
- package/config.d.ts +13 -2
- package/index.cjs +26 -12
- package/index.js +26 -12
- package/package.json +1 -1
- package/template/base-app.mustache +6 -1
- package/template/base-library.mustache +6 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { LangTagCLIConfigGenerationEvent } from '../../config.ts';
|
|
2
|
+
export type ConfigKeeperMode = 'namespace' | 'path' | 'both';
|
|
3
|
+
export interface ConfigKeeperOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The name of the property in the tag configuration that indicates what should be kept.
|
|
6
|
+
* @default 'keep'
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* lang({ click: "Click" }, { namespace: 'common', path: 'button', keep: 'namespace' })
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
propertyName?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a config keeper algorithm that preserves original configuration values
|
|
16
|
+
* when they are marked to be kept using a special property (default: 'keep').
|
|
17
|
+
*
|
|
18
|
+
* This algorithm should be applied AFTER other generation algorithms to prevent
|
|
19
|
+
* them from overwriting values that should be preserved.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const pathAlgorithm = pathBasedConfigGenerator({ ... });
|
|
24
|
+
* const keeper = configKeeper();
|
|
25
|
+
*
|
|
26
|
+
* onConfigGeneration: async (event) => {
|
|
27
|
+
* // First, apply path-based generation
|
|
28
|
+
* await pathAlgorithm(event);
|
|
29
|
+
*
|
|
30
|
+
* // Then, restore any values marked to be kept
|
|
31
|
+
* await keeper(event);
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Usage in tag:
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // This will keep the namespace even if path-based algorithm tries to change it
|
|
38
|
+
* lang({ click: "Click" }, { namespace: 'common', path: 'button', keep: 'namespace' })
|
|
39
|
+
*
|
|
40
|
+
* // This will keep the path even if path-based algorithm tries to change it
|
|
41
|
+
* lang({ click: "Click" }, { namespace: 'common', path: 'old.path', keep: 'path' })
|
|
42
|
+
*
|
|
43
|
+
* // This will keep both namespace and path
|
|
44
|
+
* lang({ click: "Click" }, { namespace: 'common', path: 'button', keep: 'both' })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function configKeeper(options?: ConfigKeeperOptions): (event: LangTagCLIConfigGenerationEvent) => Promise<void>;
|
package/algorithms/index.cjs
CHANGED
|
@@ -19,6 +19,7 @@ function _interopNamespaceDefault(e) {
|
|
|
19
19
|
return Object.freeze(n);
|
|
20
20
|
}
|
|
21
21
|
const caseLib__namespace = /* @__PURE__ */ _interopNamespaceDefault(caseLib);
|
|
22
|
+
const TRIGGER_NAME$1 = "path-based-config-generator";
|
|
22
23
|
function pathBasedConfigGenerator(options = {}) {
|
|
23
24
|
const {
|
|
24
25
|
includeFileName = false,
|
|
@@ -88,7 +89,7 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
88
89
|
if (path$1) {
|
|
89
90
|
newConfig.path = path$1;
|
|
90
91
|
} else {
|
|
91
|
-
event.save(
|
|
92
|
+
event.save(null, TRIGGER_NAME$1);
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
95
|
} else {
|
|
@@ -100,7 +101,7 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
if (Object.keys(newConfig).length > 0) {
|
|
103
|
-
event.save(newConfig);
|
|
104
|
+
event.save(newConfig, TRIGGER_NAME$1);
|
|
104
105
|
}
|
|
105
106
|
};
|
|
106
107
|
}
|
|
@@ -156,4 +157,40 @@ function extractRootDirectoriesFromIncludes(includes) {
|
|
|
156
157
|
}
|
|
157
158
|
return Array.from(directories);
|
|
158
159
|
}
|
|
160
|
+
const TRIGGER_NAME = "config-keeper";
|
|
161
|
+
function configKeeper(options = {}) {
|
|
162
|
+
const propertyName = options.propertyName ?? "keep";
|
|
163
|
+
return async (event) => {
|
|
164
|
+
if (!event.isSaved) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (!event.config) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const keepMode = event.config[propertyName];
|
|
171
|
+
if (!keepMode) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (keepMode !== "namespace" && keepMode !== "path" && keepMode !== "both") {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
let restoredConfig;
|
|
178
|
+
if (event.savedConfig === null) {
|
|
179
|
+
restoredConfig = { ...event.config };
|
|
180
|
+
delete restoredConfig.namespace;
|
|
181
|
+
delete restoredConfig.path;
|
|
182
|
+
} else {
|
|
183
|
+
restoredConfig = { ...event.savedConfig };
|
|
184
|
+
}
|
|
185
|
+
if ((keepMode === "namespace" || keepMode === "both") && event.config.namespace !== void 0) {
|
|
186
|
+
restoredConfig.namespace = event.config.namespace;
|
|
187
|
+
}
|
|
188
|
+
if ((keepMode === "path" || keepMode === "both") && event.config.path !== void 0) {
|
|
189
|
+
restoredConfig.path = event.config.path;
|
|
190
|
+
}
|
|
191
|
+
restoredConfig[propertyName] = keepMode;
|
|
192
|
+
event.save(restoredConfig, TRIGGER_NAME);
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
exports.configKeeper = configKeeper;
|
|
159
196
|
exports.pathBasedConfigGenerator = pathBasedConfigGenerator;
|
package/algorithms/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* These algorithms can be used in your lang-tag-cli config file
|
|
5
5
|
* to customize how tags are processed during collection and regeneration.
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export * from './config-generation/index.ts';
|
package/algorithms/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sep } from "pathe";
|
|
2
2
|
import * as caseLib from "case";
|
|
3
|
+
const TRIGGER_NAME$1 = "path-based-config-generator";
|
|
3
4
|
function pathBasedConfigGenerator(options = {}) {
|
|
4
5
|
const {
|
|
5
6
|
includeFileName = false,
|
|
@@ -69,7 +70,7 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
69
70
|
if (path) {
|
|
70
71
|
newConfig.path = path;
|
|
71
72
|
} else {
|
|
72
|
-
event.save(
|
|
73
|
+
event.save(null, TRIGGER_NAME$1);
|
|
73
74
|
return;
|
|
74
75
|
}
|
|
75
76
|
} else {
|
|
@@ -81,7 +82,7 @@ function pathBasedConfigGenerator(options = {}) {
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
if (Object.keys(newConfig).length > 0) {
|
|
84
|
-
event.save(newConfig);
|
|
85
|
+
event.save(newConfig, TRIGGER_NAME$1);
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
88
|
}
|
|
@@ -137,6 +138,42 @@ function extractRootDirectoriesFromIncludes(includes) {
|
|
|
137
138
|
}
|
|
138
139
|
return Array.from(directories);
|
|
139
140
|
}
|
|
141
|
+
const TRIGGER_NAME = "config-keeper";
|
|
142
|
+
function configKeeper(options = {}) {
|
|
143
|
+
const propertyName = options.propertyName ?? "keep";
|
|
144
|
+
return async (event) => {
|
|
145
|
+
if (!event.isSaved) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (!event.config) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const keepMode = event.config[propertyName];
|
|
152
|
+
if (!keepMode) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (keepMode !== "namespace" && keepMode !== "path" && keepMode !== "both") {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
let restoredConfig;
|
|
159
|
+
if (event.savedConfig === null) {
|
|
160
|
+
restoredConfig = { ...event.config };
|
|
161
|
+
delete restoredConfig.namespace;
|
|
162
|
+
delete restoredConfig.path;
|
|
163
|
+
} else {
|
|
164
|
+
restoredConfig = { ...event.savedConfig };
|
|
165
|
+
}
|
|
166
|
+
if ((keepMode === "namespace" || keepMode === "both") && event.config.namespace !== void 0) {
|
|
167
|
+
restoredConfig.namespace = event.config.namespace;
|
|
168
|
+
}
|
|
169
|
+
if ((keepMode === "path" || keepMode === "both") && event.config.path !== void 0) {
|
|
170
|
+
restoredConfig.path = event.config.path;
|
|
171
|
+
}
|
|
172
|
+
restoredConfig[propertyName] = keepMode;
|
|
173
|
+
event.save(restoredConfig, TRIGGER_NAME);
|
|
174
|
+
};
|
|
175
|
+
}
|
|
140
176
|
export {
|
|
177
|
+
configKeeper,
|
|
141
178
|
pathBasedConfigGenerator
|
|
142
179
|
};
|
package/config.d.ts
CHANGED
|
@@ -195,11 +195,22 @@ export interface LangTagCLIConfigGenerationEvent {
|
|
|
195
195
|
*/
|
|
196
196
|
readonly config: Readonly<LangTagTranslationsConfig> | undefined;
|
|
197
197
|
readonly langTagConfig: LangTagCLIConfig;
|
|
198
|
+
/**
|
|
199
|
+
* Indicates whether the `save()` method has been called during this event.
|
|
200
|
+
*/
|
|
201
|
+
readonly isSaved: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* The updated configuration that was passed to the `save()` method.
|
|
204
|
+
* - `undefined` if `save()` has not been called yet
|
|
205
|
+
* - `null` if `save(null)` was called to remove the configuration
|
|
206
|
+
* - `LangTagTranslationsConfig` object if a new configuration was saved
|
|
207
|
+
*/
|
|
208
|
+
readonly savedConfig: LangTagTranslationsConfig | null | undefined;
|
|
198
209
|
/**
|
|
199
210
|
* Tells CLI to replace tag configuration
|
|
200
|
-
*
|
|
211
|
+
* null = means configuration will be removed
|
|
201
212
|
**/
|
|
202
|
-
save(config: LangTagTranslationsConfig |
|
|
213
|
+
save(config: LangTagTranslationsConfig | null, triggerName?: string): void;
|
|
203
214
|
}
|
|
204
215
|
export interface LangTagCLICollectConfigFixEvent {
|
|
205
216
|
config: LangTagTranslationsConfig;
|
package/index.cjs
CHANGED
|
@@ -447,35 +447,50 @@ async function checkAndRegenerateFileLangTags(config, logger, file, path$12) {
|
|
|
447
447
|
return false;
|
|
448
448
|
}
|
|
449
449
|
const replacements = [];
|
|
450
|
+
let lastUpdatedLine = 0;
|
|
450
451
|
for (let tag of tags) {
|
|
451
452
|
let newConfig = void 0;
|
|
452
453
|
let shouldUpdate = false;
|
|
453
454
|
const frozenConfig = tag.parameterConfig ? deepFreezeObject(tag.parameterConfig) : tag.parameterConfig;
|
|
454
|
-
|
|
455
|
+
const event = {
|
|
455
456
|
langTagConfig: config,
|
|
456
457
|
config: frozenConfig,
|
|
457
458
|
absolutePath: file,
|
|
458
459
|
relativePath: path$12,
|
|
459
460
|
isImportedLibrary: path$12.startsWith(libraryImportsDir),
|
|
460
|
-
|
|
461
|
-
|
|
461
|
+
isSaved: false,
|
|
462
|
+
savedConfig: void 0,
|
|
463
|
+
save: (updatedConfig, triggerName) => {
|
|
464
|
+
if (!updatedConfig && updatedConfig !== null) throw new Error("Wrong config data");
|
|
465
|
+
newConfig = updatedConfig;
|
|
462
466
|
shouldUpdate = true;
|
|
467
|
+
event.isSaved = true;
|
|
468
|
+
event.savedConfig = updatedConfig;
|
|
469
|
+
logger.debug('Called save for "{path}" with config "{config}" triggered by: ("{trigger}")', { path: path$12, config: JSON.stringify(updatedConfig), trigger: triggerName || "-" });
|
|
463
470
|
}
|
|
464
|
-
}
|
|
471
|
+
};
|
|
472
|
+
await config.onConfigGeneration(event);
|
|
465
473
|
if (!shouldUpdate) {
|
|
466
474
|
continue;
|
|
467
475
|
}
|
|
468
|
-
|
|
476
|
+
lastUpdatedLine = tag.line;
|
|
477
|
+
if (!isConfigSame(tag.parameterConfig, newConfig)) {
|
|
469
478
|
replacements.push({ tag, config: newConfig });
|
|
470
479
|
}
|
|
471
480
|
}
|
|
472
481
|
if (replacements.length) {
|
|
473
482
|
const newContent = processor.replaceTags(fileContent, replacements);
|
|
474
483
|
await promises.writeFile(file, newContent, "utf-8");
|
|
484
|
+
logger.info('Lang tag configurations written for file "{path}" (file://{file}:{line})', { path: path$12, file, line: lastUpdatedLine });
|
|
475
485
|
return true;
|
|
476
486
|
}
|
|
477
487
|
return false;
|
|
478
488
|
}
|
|
489
|
+
function isConfigSame(c1, c2) {
|
|
490
|
+
if (!c1 && !c2) return true;
|
|
491
|
+
if (c1 && typeof c1 === "object" && c2 && typeof c2 === "object" && JSON5.stringify(c1) === JSON5.stringify(c2)) return true;
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
479
494
|
const CONFIG_FILE_NAME = ".lang-tag.config.js";
|
|
480
495
|
const EXPORTS_FILE_NAME = ".lang-tag.exports.json";
|
|
481
496
|
const LANG_TAG_DEFAULT_CONFIG = {
|
|
@@ -994,7 +1009,6 @@ async function $LT_CMD_RegenerateTags() {
|
|
|
994
1009
|
const path2 = file.substring(charactersToSkip);
|
|
995
1010
|
const localDirty = await checkAndRegenerateFileLangTags(config, logger, file, path2);
|
|
996
1011
|
if (localDirty) {
|
|
997
|
-
logger.info('Lang tag configurations written for file "{path}"', { path: path2 });
|
|
998
1012
|
dirty = true;
|
|
999
1013
|
}
|
|
1000
1014
|
}
|
|
@@ -1395,10 +1409,7 @@ async function handleFile(config, logger, cwdRelativeFilePath, event) {
|
|
|
1395
1409
|
}
|
|
1396
1410
|
const cwd = process.cwd();
|
|
1397
1411
|
const absoluteFilePath = path.join(cwd, cwdRelativeFilePath);
|
|
1398
|
-
|
|
1399
|
-
if (dirty) {
|
|
1400
|
-
logger.info(`Lang tag configurations written for file "{filePath}"`, { filePath: cwdRelativeFilePath });
|
|
1401
|
-
}
|
|
1412
|
+
await checkAndRegenerateFileLangTags(config, logger, absoluteFilePath, cwdRelativeFilePath);
|
|
1402
1413
|
const files = await $LT_CollectCandidateFilesWithTags({ filesToScan: [cwdRelativeFilePath], config, logger });
|
|
1403
1414
|
const namespaces = await $LT_GroupTagsToNamespaces({ logger, files, config });
|
|
1404
1415
|
const changedNamespaces = await $LT_WriteToNamespaces({ config, namespaces, logger });
|
|
@@ -1428,7 +1439,7 @@ async function detectModuleSystem() {
|
|
|
1428
1439
|
}
|
|
1429
1440
|
async function generateDefaultConfig() {
|
|
1430
1441
|
const moduleSystem = await detectModuleSystem();
|
|
1431
|
-
const importStatement = moduleSystem === "esm" ? `import { pathBasedConfigGenerator } from '@lang-tag/cli/algorithms';` : `const { pathBasedConfigGenerator } = require('@lang-tag/cli/algorithms');`;
|
|
1442
|
+
const importStatement = moduleSystem === "esm" ? `import { pathBasedConfigGenerator, configKeeper } from '@lang-tag/cli/algorithms';` : `const { pathBasedConfigGenerator, configKeeper } = require('@lang-tag/cli/algorithms');`;
|
|
1432
1443
|
const exportStatement = moduleSystem === "esm" ? "export default config;" : "module.exports = config;";
|
|
1433
1444
|
return `${importStatement}
|
|
1434
1445
|
|
|
@@ -1440,6 +1451,7 @@ const generationAlgorithm = pathBasedConfigGenerator({
|
|
|
1440
1451
|
clearOnDefaultNamespace: true,
|
|
1441
1452
|
ignoreDirectories: ['core', 'utils', 'helpers']
|
|
1442
1453
|
});
|
|
1454
|
+
const keeper = configKeeper();
|
|
1443
1455
|
|
|
1444
1456
|
/** @type {import('@lang-tag/cli/config').LangTagCLIConfig} */
|
|
1445
1457
|
const config = {
|
|
@@ -1452,9 +1464,11 @@ const config = {
|
|
|
1452
1464
|
// We do not modify imported configurations
|
|
1453
1465
|
if (event.isImportedLibrary) return;
|
|
1454
1466
|
|
|
1455
|
-
if (event.config?.
|
|
1467
|
+
if (event.config?.keep === 'both') return;
|
|
1456
1468
|
|
|
1457
1469
|
await generationAlgorithm(event);
|
|
1470
|
+
|
|
1471
|
+
await keeper(event);
|
|
1458
1472
|
},
|
|
1459
1473
|
collect: {
|
|
1460
1474
|
defaultNamespace: 'common',
|
package/index.js
CHANGED
|
@@ -427,35 +427,50 @@ async function checkAndRegenerateFileLangTags(config, logger, file, path2) {
|
|
|
427
427
|
return false;
|
|
428
428
|
}
|
|
429
429
|
const replacements = [];
|
|
430
|
+
let lastUpdatedLine = 0;
|
|
430
431
|
for (let tag of tags) {
|
|
431
432
|
let newConfig = void 0;
|
|
432
433
|
let shouldUpdate = false;
|
|
433
434
|
const frozenConfig = tag.parameterConfig ? deepFreezeObject(tag.parameterConfig) : tag.parameterConfig;
|
|
434
|
-
|
|
435
|
+
const event = {
|
|
435
436
|
langTagConfig: config,
|
|
436
437
|
config: frozenConfig,
|
|
437
438
|
absolutePath: file,
|
|
438
439
|
relativePath: path2,
|
|
439
440
|
isImportedLibrary: path2.startsWith(libraryImportsDir),
|
|
440
|
-
|
|
441
|
-
|
|
441
|
+
isSaved: false,
|
|
442
|
+
savedConfig: void 0,
|
|
443
|
+
save: (updatedConfig, triggerName) => {
|
|
444
|
+
if (!updatedConfig && updatedConfig !== null) throw new Error("Wrong config data");
|
|
445
|
+
newConfig = updatedConfig;
|
|
442
446
|
shouldUpdate = true;
|
|
447
|
+
event.isSaved = true;
|
|
448
|
+
event.savedConfig = updatedConfig;
|
|
449
|
+
logger.debug('Called save for "{path}" with config "{config}" triggered by: ("{trigger}")', { path: path2, config: JSON.stringify(updatedConfig), trigger: triggerName || "-" });
|
|
443
450
|
}
|
|
444
|
-
}
|
|
451
|
+
};
|
|
452
|
+
await config.onConfigGeneration(event);
|
|
445
453
|
if (!shouldUpdate) {
|
|
446
454
|
continue;
|
|
447
455
|
}
|
|
448
|
-
|
|
456
|
+
lastUpdatedLine = tag.line;
|
|
457
|
+
if (!isConfigSame(tag.parameterConfig, newConfig)) {
|
|
449
458
|
replacements.push({ tag, config: newConfig });
|
|
450
459
|
}
|
|
451
460
|
}
|
|
452
461
|
if (replacements.length) {
|
|
453
462
|
const newContent = processor.replaceTags(fileContent, replacements);
|
|
454
463
|
await writeFile(file, newContent, "utf-8");
|
|
464
|
+
logger.info('Lang tag configurations written for file "{path}" (file://{file}:{line})', { path: path2, file, line: lastUpdatedLine });
|
|
455
465
|
return true;
|
|
456
466
|
}
|
|
457
467
|
return false;
|
|
458
468
|
}
|
|
469
|
+
function isConfigSame(c1, c2) {
|
|
470
|
+
if (!c1 && !c2) return true;
|
|
471
|
+
if (c1 && typeof c1 === "object" && c2 && typeof c2 === "object" && JSON5.stringify(c1) === JSON5.stringify(c2)) return true;
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
459
474
|
const CONFIG_FILE_NAME = ".lang-tag.config.js";
|
|
460
475
|
const EXPORTS_FILE_NAME = ".lang-tag.exports.json";
|
|
461
476
|
const LANG_TAG_DEFAULT_CONFIG = {
|
|
@@ -974,7 +989,6 @@ async function $LT_CMD_RegenerateTags() {
|
|
|
974
989
|
const path2 = file.substring(charactersToSkip);
|
|
975
990
|
const localDirty = await checkAndRegenerateFileLangTags(config, logger, file, path2);
|
|
976
991
|
if (localDirty) {
|
|
977
|
-
logger.info('Lang tag configurations written for file "{path}"', { path: path2 });
|
|
978
992
|
dirty = true;
|
|
979
993
|
}
|
|
980
994
|
}
|
|
@@ -1375,10 +1389,7 @@ async function handleFile(config, logger, cwdRelativeFilePath, event) {
|
|
|
1375
1389
|
}
|
|
1376
1390
|
const cwd = process.cwd();
|
|
1377
1391
|
const absoluteFilePath = path__default.join(cwd, cwdRelativeFilePath);
|
|
1378
|
-
|
|
1379
|
-
if (dirty) {
|
|
1380
|
-
logger.info(`Lang tag configurations written for file "{filePath}"`, { filePath: cwdRelativeFilePath });
|
|
1381
|
-
}
|
|
1392
|
+
await checkAndRegenerateFileLangTags(config, logger, absoluteFilePath, cwdRelativeFilePath);
|
|
1382
1393
|
const files = await $LT_CollectCandidateFilesWithTags({ filesToScan: [cwdRelativeFilePath], config, logger });
|
|
1383
1394
|
const namespaces = await $LT_GroupTagsToNamespaces({ logger, files, config });
|
|
1384
1395
|
const changedNamespaces = await $LT_WriteToNamespaces({ config, namespaces, logger });
|
|
@@ -1408,7 +1419,7 @@ async function detectModuleSystem() {
|
|
|
1408
1419
|
}
|
|
1409
1420
|
async function generateDefaultConfig() {
|
|
1410
1421
|
const moduleSystem = await detectModuleSystem();
|
|
1411
|
-
const importStatement = moduleSystem === "esm" ? `import { pathBasedConfigGenerator } from '@lang-tag/cli/algorithms';` : `const { pathBasedConfigGenerator } = require('@lang-tag/cli/algorithms');`;
|
|
1422
|
+
const importStatement = moduleSystem === "esm" ? `import { pathBasedConfigGenerator, configKeeper } from '@lang-tag/cli/algorithms';` : `const { pathBasedConfigGenerator, configKeeper } = require('@lang-tag/cli/algorithms');`;
|
|
1412
1423
|
const exportStatement = moduleSystem === "esm" ? "export default config;" : "module.exports = config;";
|
|
1413
1424
|
return `${importStatement}
|
|
1414
1425
|
|
|
@@ -1420,6 +1431,7 @@ const generationAlgorithm = pathBasedConfigGenerator({
|
|
|
1420
1431
|
clearOnDefaultNamespace: true,
|
|
1421
1432
|
ignoreDirectories: ['core', 'utils', 'helpers']
|
|
1422
1433
|
});
|
|
1434
|
+
const keeper = configKeeper();
|
|
1423
1435
|
|
|
1424
1436
|
/** @type {import('@lang-tag/cli/config').LangTagCLIConfig} */
|
|
1425
1437
|
const config = {
|
|
@@ -1432,9 +1444,11 @@ const config = {
|
|
|
1432
1444
|
// We do not modify imported configurations
|
|
1433
1445
|
if (event.isImportedLibrary) return;
|
|
1434
1446
|
|
|
1435
|
-
if (event.config?.
|
|
1447
|
+
if (event.config?.keep === 'both') return;
|
|
1436
1448
|
|
|
1437
1449
|
await generationAlgorithm(event);
|
|
1450
|
+
|
|
1451
|
+
await keeper(event);
|
|
1438
1452
|
},
|
|
1439
1453
|
collect: {
|
|
1440
1454
|
defaultNamespace: 'common',
|
package/package.json
CHANGED
|
@@ -13,9 +13,14 @@ import { createCallableTranslations } from 'lang-tag';
|
|
|
13
13
|
import { ReactNode, useMemo } from 'react';
|
|
14
14
|
{{/isReact}}
|
|
15
15
|
|
|
16
|
+
{{#isTypeScript}}
|
|
17
|
+
interface TagConfig extends LangTagTranslationsConfig {
|
|
18
|
+
keep?: 'namespace' | 'path' | 'both'
|
|
19
|
+
}
|
|
20
|
+
{{/isTypeScript}}
|
|
16
21
|
export function {{tagName}}{{#isTypeScript}}<T extends LangTagTranslations>{{/isTypeScript}}(
|
|
17
22
|
baseTranslations{{#isTypeScript}}: T{{/isTypeScript}},
|
|
18
|
-
config{{#isTypeScript}}?:
|
|
23
|
+
config{{#isTypeScript}}?: TagConfig{{/isTypeScript}},
|
|
19
24
|
) {
|
|
20
25
|
// Example integration with react-i18next:
|
|
21
26
|
// const namespace = config?.namespace || '';
|
|
@@ -21,9 +21,14 @@ import {
|
|
|
21
21
|
} from 'react';
|
|
22
22
|
{{/isReact}}
|
|
23
23
|
|
|
24
|
+
{{#isTypeScript}}
|
|
25
|
+
interface TagConfig extends LangTagTranslationsConfig {
|
|
26
|
+
keep?: 'namespace' | 'path' | 'both'
|
|
27
|
+
}
|
|
28
|
+
{{/isTypeScript}}
|
|
24
29
|
export function {{tagName}}<T extends LangTagTranslations>(
|
|
25
30
|
baseTranslations: T,
|
|
26
|
-
config?:
|
|
31
|
+
config?: TagConfig,
|
|
27
32
|
) {
|
|
28
33
|
const createTranslationHelper = (normalized{{#isTypeScript}}: CallableTranslations<T> | null{{/isTypeScript}}) =>
|
|
29
34
|
createCallableTranslations(baseTranslations, config, {
|