@windrun-huaiin/dev-scripts 6.8.2 → 6.9.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.
Files changed (65) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +137 -1410
  4. package/dist/cli.mjs +145 -432
  5. package/dist/commands/check-translations.d.ts +3 -0
  6. package/dist/commands/check-translations.d.ts.map +1 -0
  7. package/dist/commands/check-translations.js +132 -0
  8. package/dist/commands/check-translations.mjs +130 -0
  9. package/dist/commands/clean-translations.d.ts +3 -0
  10. package/dist/commands/clean-translations.d.ts.map +1 -0
  11. package/dist/commands/clean-translations.js +148 -0
  12. package/dist/commands/clean-translations.mjs +146 -0
  13. package/dist/commands/create-diaomao-app.d.ts +2 -0
  14. package/dist/commands/create-diaomao-app.d.ts.map +1 -0
  15. package/dist/commands/create-diaomao-app.js +151 -0
  16. package/dist/commands/create-diaomao-app.mjs +149 -0
  17. package/dist/commands/deep-clean.d.ts +3 -0
  18. package/dist/commands/deep-clean.d.ts.map +1 -0
  19. package/dist/commands/deep-clean.js +119 -0
  20. package/dist/commands/deep-clean.mjs +117 -0
  21. package/dist/commands/easy-changeset.d.ts +2 -0
  22. package/dist/commands/easy-changeset.d.ts.map +1 -0
  23. package/dist/commands/easy-changeset.js +39 -0
  24. package/dist/commands/easy-changeset.mjs +37 -0
  25. package/dist/commands/generate-blog-index.d.ts +3 -0
  26. package/dist/commands/generate-blog-index.d.ts.map +1 -0
  27. package/dist/commands/generate-blog-index.js +302 -0
  28. package/dist/commands/generate-blog-index.mjs +300 -0
  29. package/dist/commands/generate-nextjs-architecture.d.ts +3 -0
  30. package/dist/commands/generate-nextjs-architecture.d.ts.map +1 -0
  31. package/dist/commands/generate-nextjs-architecture.js +84 -0
  32. package/dist/commands/generate-nextjs-architecture.mjs +82 -0
  33. package/dist/config/index.d.ts +10 -0
  34. package/dist/config/index.d.ts.map +1 -0
  35. package/dist/config/index.js +173 -0
  36. package/dist/config/index.mjs +170 -0
  37. package/dist/config/schema.d.ts +34 -0
  38. package/dist/config/schema.d.ts.map +1 -0
  39. package/dist/config/schema.js +80 -0
  40. package/dist/config/schema.mjs +78 -0
  41. package/dist/index.d.ts +6 -49
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +9 -996
  44. package/dist/index.mjs +4 -3
  45. package/dist/utils/file-scanner.d.ts +22 -0
  46. package/dist/utils/file-scanner.d.ts.map +1 -0
  47. package/dist/utils/file-scanner.js +70 -0
  48. package/dist/utils/file-scanner.mjs +65 -0
  49. package/dist/utils/logger.d.ts +24 -0
  50. package/dist/utils/logger.d.ts.map +1 -0
  51. package/dist/utils/logger.js +63 -0
  52. package/dist/utils/logger.mjs +61 -0
  53. package/dist/utils/translation-parser.d.ts +29 -0
  54. package/dist/utils/translation-parser.d.ts.map +1 -0
  55. package/dist/utils/translation-parser.js +225 -0
  56. package/dist/utils/translation-parser.mjs +218 -0
  57. package/package.json +5 -5
  58. package/dist/chunk-GVR6HFHM.mjs +0 -989
  59. package/dist/chunk-GVR6HFHM.mjs.map +0 -1
  60. package/dist/cli.d.mts +0 -1
  61. package/dist/cli.js.map +0 -1
  62. package/dist/cli.mjs.map +0 -1
  63. package/dist/index.d.mts +0 -49
  64. package/dist/index.js.map +0 -1
  65. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,218 @@
1
+ /**
2
+ * extract translation keys and namespaces from file content
3
+ */
4
+ function extractTranslationsInfo(content, filePath) {
5
+ const result = {
6
+ namespaces: new Map(),
7
+ keys: []
8
+ };
9
+ // match getTranslations({ locale, namespace: 'namespace' }) or getTranslations('namespace')
10
+ const getTranslationsPattern = /getTranslations\(\s*(?:{[^}]*namespace:\s*['"]([^'"]+)['"][^}]*}|['"]([^'"]+)['"])\s*\)/g;
11
+ let match;
12
+ while ((match = getTranslationsPattern.exec(content)) !== null) {
13
+ const namespace = match[1] || match[2];
14
+ if (namespace) {
15
+ // try to find assignment statement, like const t = await getTranslations(...)
16
+ // find the nearest const declaration
17
+ const linesBefore = content.substring(0, match.index).split('\n');
18
+ for (let i = linesBefore.length - 1; i >= Math.max(0, linesBefore.length - 5); i--) {
19
+ const line = linesBefore[i];
20
+ const constMatch = /const\s+(\w+)\s*=/.exec(line);
21
+ if (constMatch && !line.includes('useTranslations') && !line.includes('getTranslations')) {
22
+ result.namespaces.set(constMatch[1], namespace);
23
+ break;
24
+ }
25
+ }
26
+ }
27
+ }
28
+ // match useTranslations('namespace')
29
+ const useTranslationsPattern = /useTranslations\(\s*['"]([^'"]+)['"]\s*\)/g;
30
+ while ((match = useTranslationsPattern.exec(content)) !== null) {
31
+ const namespace = match[1];
32
+ // try to find assignment statement, like const t = useTranslations(...)
33
+ // find the line containing useTranslations
34
+ const currentLine = content.substring(0, match.index).split('\n').pop() || '';
35
+ const constMatch = /const\s+(\w+)\s*=/.exec(currentLine);
36
+ if (constMatch) {
37
+ result.namespaces.set(constMatch[1], namespace);
38
+ }
39
+ }
40
+ // match t('key') or t("key"), and check if t is associated with known namespaces
41
+ // modify the matching pattern of t function call
42
+ const tPatterns = [
43
+ // normal string key: t('key') or t("key")
44
+ /(\w+)\(\s*['"]([^'"]+)['"]\s*\)/g,
45
+ // template string key: t(`tags.${id}`) or t(`section.${key}`)
46
+ /(\w+)\(\s*`([^`]+)`\s*\)/g,
47
+ // variable key: t(item.key) or t(item.id)
48
+ /(\w+)\(\s*(\w+)\.(\w+)\s*\)/g
49
+ ];
50
+ for (const pattern of tPatterns) {
51
+ let match;
52
+ while ((match = pattern.exec(content)) !== null) {
53
+ const funcName = match[1];
54
+ // if the function name is associated with known namespaces
55
+ if (result.namespaces.has(funcName)) {
56
+ const namespace = result.namespaces.get(funcName);
57
+ if (!namespace)
58
+ continue;
59
+ if (pattern.source.includes('`')) {
60
+ // handle template string
61
+ const templateStr = match[2];
62
+ // extract static part (the part before the variable)
63
+ const staticPart = templateStr.split(/\${(?:id|key)}/)[0].trim();
64
+ if (staticPart && !staticPart.includes('/')) {
65
+ // for tags.${id}这样的形式,记录整个 tags 命名空间
66
+ const segments = staticPart.split('.');
67
+ if (segments.length > 0) {
68
+ // record the base path
69
+ result.keys.push(`${namespace}.${segments[0]}`);
70
+ // if it is multi-level, also record the full path
71
+ if (segments.length > 1) {
72
+ result.keys.push(`${namespace}.${segments.join('.')}`);
73
+ }
74
+ // special handling for tags namespace
75
+ if (segments[0] === 'tags') {
76
+ // add all known tag keys
77
+ ['productUpdates', 'tutorials', 'makeMoney', 'roadOverSea', 'insights'].forEach(tag => {
78
+ result.keys.push(`${namespace}.tags.${tag}`);
79
+ });
80
+ }
81
+ }
82
+ }
83
+ }
84
+ else if (pattern.source.includes('\\w+\\.\\w+')) {
85
+ // handle variable key t(item.key)
86
+ const varName = match[2];
87
+ match[3];
88
+ // find the possible value of the variable in the file content
89
+ const varPattern = new RegExp(`${varName}\\s*=\\s*{[^}]*key:\\s*['"]([^'"]+)['"]`);
90
+ const varMatch = content.match(varPattern);
91
+ if (varMatch) {
92
+ // if the variable definition is found, add the actual key
93
+ result.keys.push(`${namespace}.${varMatch[1]}`);
94
+ }
95
+ else {
96
+ // if the specific definition is not found, try to infer from the context
97
+ // check if it is used in an array or object of MenuItem type
98
+ if (content.includes('MenuItem[]') || content.includes('MenuItem}')) {
99
+ // add all possible menu keys
100
+ ['journey'].forEach(menuKey => {
101
+ result.keys.push(`${namespace}.${menuKey}`);
102
+ });
103
+ }
104
+ }
105
+ }
106
+ else {
107
+ // handle normal string key
108
+ const key = match[2];
109
+ if (!key.includes('/') && key !== '') {
110
+ result.keys.push(`${namespace}.${key}`);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ // match <FormattedMessage id="key" />
117
+ const formattedMessagePattern = /<FormattedMessage[^>]*id=['"]([^'"]+)['"]/g;
118
+ while ((match = formattedMessagePattern.exec(content)) !== null) {
119
+ const key = match[1];
120
+ if (!key.includes('/') && key !== '') {
121
+ // for FormattedMessage, we need to guess the namespace
122
+ // usually we can find useTranslations call in the same file
123
+ if (result.namespaces.size > 0) {
124
+ const namespace = Array.from(result.namespaces.values())[0];
125
+ result.keys.push(`${namespace}.${key}`);
126
+ }
127
+ else {
128
+ // if the namespace is not found, try to infer from the file path
129
+ const pathMatch = filePath.match(/\[locale\]\/(?:\([^)]+\)\/)?([^/]+)/);
130
+ if (pathMatch && pathMatch[1]) {
131
+ const possibleNamespace = pathMatch[1];
132
+ result.keys.push(`${possibleNamespace}.${key}`);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ /**
140
+ * get all keys from an object (including nested keys)
141
+ */
142
+ function getAllKeys(obj, prefix = '') {
143
+ let keys = [];
144
+ for (const key in obj) {
145
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
146
+ const newKey = prefix ? `${prefix}.${key}` : key;
147
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
148
+ keys = [...keys, ...getAllKeys(obj[key], newKey)];
149
+ }
150
+ else {
151
+ keys.push(newKey);
152
+ }
153
+ }
154
+ }
155
+ return keys;
156
+ }
157
+ /**
158
+ * check if the key exists in the translation file
159
+ */
160
+ function checkKeyExists(key, translations) {
161
+ const parts = key.split('.');
162
+ let current = translations;
163
+ for (const part of parts) {
164
+ if (current[part] === undefined) {
165
+ return false;
166
+ }
167
+ current = current[part];
168
+ }
169
+ return true;
170
+ }
171
+ /**
172
+ * check if the namespace exists in the translation file
173
+ */
174
+ function checkNamespaceExists(namespace, translations) {
175
+ return translations[namespace] !== undefined;
176
+ }
177
+ /**
178
+ * remove the specified key from the translation object
179
+ */
180
+ function removeKeyFromTranslations(key, translations) {
181
+ const parts = key.split('.');
182
+ const lastPart = parts.pop();
183
+ if (!lastPart)
184
+ return false;
185
+ let current = translations;
186
+ // navigate to the parent object of the last level
187
+ for (const part of parts) {
188
+ if (current[part] === undefined || typeof current[part] !== 'object') {
189
+ return false;
190
+ }
191
+ current = current[part];
192
+ }
193
+ // delete the key
194
+ if (current[lastPart] !== undefined) {
195
+ delete current[lastPart];
196
+ return true;
197
+ }
198
+ return false;
199
+ }
200
+ /**
201
+ * clean empty objects (recursively)
202
+ */
203
+ function cleanEmptyObjects(obj) {
204
+ for (const key in obj) {
205
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
206
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
207
+ obj[key] = cleanEmptyObjects(obj[key]);
208
+ // if the object is empty, delete it
209
+ if (Object.keys(obj[key]).length === 0) {
210
+ delete obj[key];
211
+ }
212
+ }
213
+ }
214
+ }
215
+ return obj;
216
+ }
217
+
218
+ export { checkKeyExists, checkNamespaceExists, cleanEmptyObjects, extractTranslationsInfo, getAllKeys, removeKeyFromTranslations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/dev-scripts",
3
- "version": "6.8.2",
3
+ "version": "6.9.1",
4
4
  "description": "Development scripts for multilingual projects",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,7 +15,6 @@
15
15
  "devDependencies": {
16
16
  "@types/node": "^20.0.0",
17
17
  "@types/fs-extra": "^11.0.4",
18
- "tsup": "^8.0.0",
19
18
  "typescript": "^5.0.0"
20
19
  },
21
20
  "peerDependencies": {
@@ -41,8 +40,9 @@
41
40
  "access": "public"
42
41
  },
43
42
  "scripts": {
44
- "build": "tsup",
45
- "build:prod": "tsup",
46
- "dev": "tsup --watch"
43
+ "build": "rollup -c rollup.config.mjs",
44
+ "build:prod": "rollup -c rollup.config.mjs",
45
+ "dev": "rollup -c rollup.config.mjs --watch",
46
+ "clean": "rm -rf dist"
47
47
  }
48
48
  }