@lang-tag/cli 0.11.0 → 0.11.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/README.md CHANGED
@@ -14,7 +14,7 @@ The core is optimized for performance, with a bundle size of just **~1KB** ([che
14
14
 
15
15
  ### Effortless translation structure
16
16
 
17
- Instead of manually managing centralized translation files, `lang-tag` lets you colocate keys within components and automatically organizes them into namespaces based on your project structure. For example, all components in `components/orders` or pages in `pages/order` share the `orders` namespace. You define a simple folder-to-namespace mapping once, and `lang-tag` handles merging and file organization—while you retain full control over how namespaces are merged.
17
+ Instead of manually managing centralized translation files, `lang-tag` lets you colocate keys within components and automatically organizes them into namespaces based on your project structure. For example, all components in `components/orders` or pages in `pages/order` share the `orders` namespace. You define a simple directory-to-namespace mapping once, and `lang-tag` handles merging and file organization—while you retain full control over how namespaces are merged.
18
18
 
19
19
  > Set your rules, then let `lang-tag` do the rest.
20
20
 
@@ -23,7 +23,7 @@ Instead of manually managing centralized translation files, `lang-tag` lets you
23
23
  Full functionality is available through an advanced CLI that keeps your application bundle size untouched:
24
24
 
25
25
  - **Automatic translation collection** – `lang-tag collect` scans your project for translation tags and aggregates them into organized JSON files (e.g., `public/locales/en/common.json`), based on your configuration
26
- - **Dynamic configuration updates** – `lang-tag regenerate-tags` automatically refreshes translation settings in your code, using rules defined in your configuration (e.g., mapping namespaces based on folder structure)
26
+ - **Dynamic configuration updates** – `lang-tag regenerate-tags` automatically refreshes translation settings in your code, using rules defined in your configuration (e.g., mapping namespaces based on directory structure)
27
27
  - **Third-party translation import** – `lang-tag import` detects and integrates translations from external libraries, adapting them to your project’s translation system
28
28
  - **Watch mode** – `lang-tag watch` monitors your source files for changes and automatically re-collects/re-generates translations when needed
29
29
 
@@ -6,26 +6,26 @@ export interface PathBasedConfigGeneratorOptions {
6
6
  */
7
7
  includeFileName?: boolean;
8
8
  /**
9
- * Whether to completely remove folders wrapped in brackets () or [].
10
- * If false, only the brackets are removed from folder names.
9
+ * Whether to completely remove directories wrapped in brackets () or [].
10
+ * If false, only the brackets are removed from directory names.
11
11
  * @default true
12
12
  *
13
13
  * @example
14
14
  * - true: 'app/(admin)/users' -> 'app/users'
15
15
  * - false: 'app/(admin)/users' -> 'app/admin/users'
16
16
  */
17
- removeBracketedFolders?: boolean;
17
+ removeBracketedDirectories?: boolean;
18
18
  /**
19
- * List of folder names to completely ignore globally.
19
+ * List of directory names to completely ignore globally.
20
20
  * These will be removed from all paths regardless of their position.
21
21
  * @default []
22
22
  *
23
23
  * @example ['src', 'app', 'components']
24
24
  */
25
- ignoreFolders?: string[];
25
+ ignoreDirectories?: string[];
26
26
  /**
27
- * When true, automatically extracts root folder names from the config.includes patterns
28
- * and adds them to the ignoreFolders list.
27
+ * When true, automatically extracts root directory names from the config.includes patterns
28
+ * and adds them to the ignoreDirectories list.
29
29
  *
30
30
  * @default false
31
31
  *
@@ -36,9 +36,9 @@ export interface PathBasedConfigGeneratorOptions {
36
36
  * // With includes: ['(src|app)/**\/*.{js,ts,jsx,tsx}', 'components/**\/*.{jsx,tsx}']
37
37
  * // Automatically ignores: ['src', 'app', 'components']
38
38
  */
39
- ignoreIncludesRootFolders?: boolean;
39
+ ignoreIncludesRootDirectories?: boolean;
40
40
  /**
41
- * Hierarchical structure for ignoring specific folder patterns.
41
+ * Hierarchical structure for ignoring specific directory patterns.
42
42
  * Keys represent path segments to match, values indicate what to ignore at that level.
43
43
  *
44
44
  * @example
@@ -98,9 +98,9 @@ export interface PathBasedConfigGeneratorOptions {
98
98
  * export default {
99
99
  * onConfigGeneration: pathBasedConfigGenerator({
100
100
  * includeFileName: false,
101
- * removeBracketedFolders: true,
102
- * ignoreFolders: ['lib', 'utils'],
103
- * ignoreIncludesRootFolders: true, // Auto-ignores root folders from includes
101
+ * removeBracketedDirectories: true,
102
+ * ignoreDirectories: ['lib', 'utils'],
103
+ * ignoreIncludesRootDirectories: true, // Auto-ignores root directories from includes
104
104
  * lowercaseNamespace: true,
105
105
  * fallbackNamespace: 'common'
106
106
  * })
@@ -22,9 +22,9 @@ const caseLib__namespace = /* @__PURE__ */ _interopNamespaceDefault(caseLib);
22
22
  function pathBasedConfigGenerator(options = {}) {
23
23
  const {
24
24
  includeFileName = false,
25
- removeBracketedFolders = true,
26
- ignoreFolders = [],
27
- ignoreIncludesRootFolders = false,
25
+ removeBracketedDirectories = true,
26
+ ignoreDirectories = [],
27
+ ignoreIncludesRootDirectories = false,
28
28
  ignoreStructured = {},
29
29
  lowercaseNamespace = false,
30
30
  namespaceCase,
@@ -35,10 +35,10 @@ function pathBasedConfigGenerator(options = {}) {
35
35
  return async (event) => {
36
36
  const { relativePath, langTagConfig } = event;
37
37
  const actualFallbackNamespace = fallbackNamespace ?? langTagConfig.collect?.defaultNamespace;
38
- let finalIgnoreFolders = [...ignoreFolders];
39
- if (ignoreIncludesRootFolders && langTagConfig.includes) {
40
- const extractedFolders = extractRootFoldersFromIncludes(langTagConfig.includes);
41
- finalIgnoreFolders = [.../* @__PURE__ */ new Set([...finalIgnoreFolders, ...extractedFolders])];
38
+ let finalIgnoreDirectories = [...ignoreDirectories];
39
+ if (ignoreIncludesRootDirectories && langTagConfig.includes) {
40
+ const extractedDirectories = extractRootDirectoriesFromIncludes(langTagConfig.includes);
41
+ finalIgnoreDirectories = [.../* @__PURE__ */ new Set([...finalIgnoreDirectories, ...extractedDirectories])];
42
42
  }
43
43
  let pathSegments = relativePath.split(path.sep).filter(Boolean);
44
44
  if (pathSegments.length === 0) {
@@ -54,12 +54,12 @@ function pathBasedConfigGenerator(options = {}) {
54
54
  pathSegments = pathSegments.map((segment) => {
55
55
  const bracketMatch = segment.match(/^[\(\[](.+)[\)\]]$/);
56
56
  if (bracketMatch) {
57
- return removeBracketedFolders ? null : bracketMatch[1];
57
+ return removeBracketedDirectories ? null : bracketMatch[1];
58
58
  }
59
59
  return segment;
60
60
  }).filter((seg) => seg !== null);
61
61
  pathSegments = applyStructuredIgnore(pathSegments, ignoreStructured);
62
- pathSegments = pathSegments.filter((seg) => !finalIgnoreFolders.includes(seg));
62
+ pathSegments = pathSegments.filter((seg) => !finalIgnoreDirectories.includes(seg));
63
63
  let namespace;
64
64
  let path$1;
65
65
  if (pathSegments.length >= 1) {
@@ -139,8 +139,8 @@ function applyCaseTransform(str, caseType) {
139
139
  }
140
140
  return str;
141
141
  }
142
- function extractRootFoldersFromIncludes(includes) {
143
- const folders = /* @__PURE__ */ new Set();
142
+ function extractRootDirectoriesFromIncludes(includes) {
143
+ const directories = /* @__PURE__ */ new Set();
144
144
  for (const pattern of includes) {
145
145
  let cleanPattern = pattern.replace(/^\.\//, "");
146
146
  const match = cleanPattern.match(/^([^/]+)/);
@@ -148,12 +148,12 @@ function extractRootFoldersFromIncludes(includes) {
148
148
  const firstSegment = match[1];
149
149
  const groupMatch = firstSegment.match(/^[\(\[]([^\)\]]+)[\)\]]$/);
150
150
  if (groupMatch) {
151
- const groupFolders = groupMatch[1].split("|").map((f) => f.trim());
152
- groupFolders.forEach((folder) => folders.add(folder));
151
+ const groupDirectories = groupMatch[1].split("|").map((f) => f.trim());
152
+ groupDirectories.forEach((directory) => directories.add(directory));
153
153
  } else {
154
- folders.add(firstSegment);
154
+ directories.add(firstSegment);
155
155
  }
156
156
  }
157
- return Array.from(folders);
157
+ return Array.from(directories);
158
158
  }
159
159
  exports.pathBasedConfigGenerator = pathBasedConfigGenerator;
@@ -3,9 +3,9 @@ import * as caseLib from "case";
3
3
  function pathBasedConfigGenerator(options = {}) {
4
4
  const {
5
5
  includeFileName = false,
6
- removeBracketedFolders = true,
7
- ignoreFolders = [],
8
- ignoreIncludesRootFolders = false,
6
+ removeBracketedDirectories = true,
7
+ ignoreDirectories = [],
8
+ ignoreIncludesRootDirectories = false,
9
9
  ignoreStructured = {},
10
10
  lowercaseNamespace = false,
11
11
  namespaceCase,
@@ -16,10 +16,10 @@ function pathBasedConfigGenerator(options = {}) {
16
16
  return async (event) => {
17
17
  const { relativePath, langTagConfig } = event;
18
18
  const actualFallbackNamespace = fallbackNamespace ?? langTagConfig.collect?.defaultNamespace;
19
- let finalIgnoreFolders = [...ignoreFolders];
20
- if (ignoreIncludesRootFolders && langTagConfig.includes) {
21
- const extractedFolders = extractRootFoldersFromIncludes(langTagConfig.includes);
22
- finalIgnoreFolders = [.../* @__PURE__ */ new Set([...finalIgnoreFolders, ...extractedFolders])];
19
+ let finalIgnoreDirectories = [...ignoreDirectories];
20
+ if (ignoreIncludesRootDirectories && langTagConfig.includes) {
21
+ const extractedDirectories = extractRootDirectoriesFromIncludes(langTagConfig.includes);
22
+ finalIgnoreDirectories = [.../* @__PURE__ */ new Set([...finalIgnoreDirectories, ...extractedDirectories])];
23
23
  }
24
24
  let pathSegments = relativePath.split(sep).filter(Boolean);
25
25
  if (pathSegments.length === 0) {
@@ -35,12 +35,12 @@ function pathBasedConfigGenerator(options = {}) {
35
35
  pathSegments = pathSegments.map((segment) => {
36
36
  const bracketMatch = segment.match(/^[\(\[](.+)[\)\]]$/);
37
37
  if (bracketMatch) {
38
- return removeBracketedFolders ? null : bracketMatch[1];
38
+ return removeBracketedDirectories ? null : bracketMatch[1];
39
39
  }
40
40
  return segment;
41
41
  }).filter((seg) => seg !== null);
42
42
  pathSegments = applyStructuredIgnore(pathSegments, ignoreStructured);
43
- pathSegments = pathSegments.filter((seg) => !finalIgnoreFolders.includes(seg));
43
+ pathSegments = pathSegments.filter((seg) => !finalIgnoreDirectories.includes(seg));
44
44
  let namespace;
45
45
  let path;
46
46
  if (pathSegments.length >= 1) {
@@ -120,8 +120,8 @@ function applyCaseTransform(str, caseType) {
120
120
  }
121
121
  return str;
122
122
  }
123
- function extractRootFoldersFromIncludes(includes) {
124
- const folders = /* @__PURE__ */ new Set();
123
+ function extractRootDirectoriesFromIncludes(includes) {
124
+ const directories = /* @__PURE__ */ new Set();
125
125
  for (const pattern of includes) {
126
126
  let cleanPattern = pattern.replace(/^\.\//, "");
127
127
  const match = cleanPattern.match(/^([^/]+)/);
@@ -129,13 +129,13 @@ function extractRootFoldersFromIncludes(includes) {
129
129
  const firstSegment = match[1];
130
130
  const groupMatch = firstSegment.match(/^[\(\[]([^\)\]]+)[\)\]]$/);
131
131
  if (groupMatch) {
132
- const groupFolders = groupMatch[1].split("|").map((f) => f.trim());
133
- groupFolders.forEach((folder) => folders.add(folder));
132
+ const groupDirectories = groupMatch[1].split("|").map((f) => f.trim());
133
+ groupDirectories.forEach((directory) => directories.add(directory));
134
134
  } else {
135
- folders.add(firstSegment);
135
+ directories.add(firstSegment);
136
136
  }
137
137
  }
138
- return Array.from(folders);
138
+ return Array.from(directories);
139
139
  }
140
140
  export {
141
141
  pathBasedConfigGenerator
package/index.cjs CHANGED
@@ -1422,12 +1422,12 @@ async function generateDefaultConfig() {
1422
1422
  return `${importStatement}
1423
1423
 
1424
1424
  const generationAlgorithm = pathBasedConfigGenerator({
1425
- ignoreIncludesRootFolders: true,
1426
- removeBracketedFolders: true,
1425
+ ignoreIncludesRootDirectories: true,
1426
+ removeBracketedDirectories: true,
1427
1427
  namespaceCase: 'kebab',
1428
1428
  pathCase: 'camel',
1429
1429
  clearOnDefaultNamespace: true,
1430
- ignoreFolders: ['core', 'utils', 'helpers']
1430
+ ignoreDirectories: ['core', 'utils', 'helpers']
1431
1431
  });
1432
1432
 
1433
1433
  /** @type {import('@lang-tag/cli/config').LangTagCLIConfig} */
package/index.js CHANGED
@@ -1402,12 +1402,12 @@ async function generateDefaultConfig() {
1402
1402
  return `${importStatement}
1403
1403
 
1404
1404
  const generationAlgorithm = pathBasedConfigGenerator({
1405
- ignoreIncludesRootFolders: true,
1406
- removeBracketedFolders: true,
1405
+ ignoreIncludesRootDirectories: true,
1406
+ removeBracketedDirectories: true,
1407
1407
  namespaceCase: 'kebab',
1408
1408
  pathCase: 'camel',
1409
1409
  clearOnDefaultNamespace: true,
1410
- ignoreFolders: ['core', 'utils', 'helpers']
1410
+ ignoreDirectories: ['core', 'utils', 'helpers']
1411
1411
  });
1412
1412
 
1413
1413
  /** @type {import('@lang-tag/cli/config').LangTagCLIConfig} */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lang-tag/cli",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"