@windrun-huaiin/dev-scripts 5.0.0 → 6.0.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
@@ -185,6 +185,51 @@ Options:
185
185
  - 生成月度统计页面
186
186
  - 自动排序和分类
187
187
 
188
+ ### deep-clean
189
+
190
+ 一键清理 node_modules、.next、dist、.turbo、pnpm-lock.yaml 等依赖和缓存目录,自动适配 monorepo 或单工程结构。
191
+
192
+ ```bash
193
+ dev-scripts deep-clean [options]
194
+
195
+ Options:
196
+ --yes 实际删除匹配到的目录(默认只预览)
197
+ -v, --verbose 显示详细日志
198
+ --config <path> 指定配置文件路径
199
+ -h, --help 显示帮助信息
200
+ ```
201
+
202
+ **无需任何配置,脚本会自动识别工程类型:**
203
+ - 如果当前目录下有 `pnpm-workspace.yaml`,会按 monorepo 规则清理:
204
+ - 根 node_modules
205
+ - packages/*/node_modules
206
+ - apps/*/node_modules
207
+ - .next、dist、.turbo 及其子包下的同名目录
208
+ - pnpm-lock.yaml
209
+ - 如果没有 `pnpm-workspace.yaml`,只清理:
210
+ - node_modules
211
+ - .next
212
+ - pnpm-lock.yaml
213
+
214
+ **输出示例:**
215
+ ```
216
+ ==============================
217
+ 当前工作目录: /your/project/path
218
+ ==============================
219
+ 【Root directory dependencies】
220
+ 🗑️ [预览] /your/project/path/node_modules
221
+ ...
222
+ 如需实际删除,请加 --yes 参数。
223
+ ```
224
+
225
+ 实际删除时:
226
+ ```
227
+ ✅ 已删除: /your/project/path/node_modules
228
+ ✅ 已删除: /your/project/path/pnpm-lock.yaml
229
+ ...
230
+ ✅ 共清理 3 个目录或文件。
231
+ ```
232
+
188
233
  ## 支持的翻译模式
189
234
 
190
235
  脚本支持多种翻译使用模式:
@@ -1,4 +1,4 @@
1
- import fs, { writeFileSync, readFileSync, mkdirSync, readdirSync } from 'fs';
1
+ import fs, { mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';
2
2
  import path, { join, dirname } from 'path';
3
3
  import fg from 'fast-glob';
4
4
 
@@ -430,6 +430,9 @@ function cleanEmptyObjects(obj) {
430
430
  // src/commands/check-translations.ts
431
431
  async function checkTranslations(config, cwd = typeof process !== "undefined" ? process.cwd() : ".") {
432
432
  const logger = new Logger(config);
433
+ logger.warn("==============================");
434
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd} \u2B55`);
435
+ logger.warn("==============================");
433
436
  try {
434
437
  logger.log("start checking translations...");
435
438
  const scanResults = await scanFiles(config, cwd);
@@ -536,6 +539,9 @@ found ${foundNamespaces.size} used namespaces in the code: ${Array.from(foundNam
536
539
  async function cleanTranslations(config, shouldRemove = false, cwd = typeof process !== "undefined" ? process.cwd() : ".") {
537
540
  const logger = new Logger(config);
538
541
  const logFileName = shouldRemove ? "remove.log" : "clean.log";
542
+ logger.warn("==============================");
543
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd} \u2B55`);
544
+ logger.warn("==============================");
539
545
  try {
540
546
  logger.log("start checking unused translation keys...");
541
547
  const scanResults = await scanFiles(config, cwd);
@@ -726,6 +732,9 @@ async function getAllBlogArticles(blogDir, cwd, logger) {
726
732
  }
727
733
  async function generateBlogIndex(config, cwd = typeof process !== "undefined" ? process.cwd() : ".") {
728
734
  const logger = new Logger(config);
735
+ logger.warn("==============================");
736
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd} \u2B55`);
737
+ logger.warn("==============================");
729
738
  try {
730
739
  if (!config.blog) {
731
740
  logger.error("Blog configuration is missing. Please configure blog settings.");
@@ -909,6 +918,6 @@ async function generateMonthlyBlogSummary(config, articles, iocFile, iocSlug, lo
909
918
  }
910
919
  }
911
920
 
912
- export { checkTranslations, cleanTranslations, generateBlogIndex, loadConfig, validateConfig };
913
- //# sourceMappingURL=chunk-564HARYU.mjs.map
914
- //# sourceMappingURL=chunk-564HARYU.mjs.map
921
+ export { Logger, checkTranslations, cleanTranslations, generateBlogIndex, loadConfig, validateConfig };
922
+ //# sourceMappingURL=chunk-6Z3ZCLNK.mjs.map
923
+ //# sourceMappingURL=chunk-6Z3ZCLNK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/schema.ts","../src/config/index.ts","../src/utils/logger.ts","../src/utils/file-scanner.ts","../src/utils/translation-parser.ts","../src/commands/check-translations.ts","../src/commands/clean-translations.ts","../src/commands/generate-blog-index.ts"],"names":["match","writeFileSync","join","readFileSync"],"mappings":"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","file":"chunk-6Z3ZCLNK.mjs","sourcesContent":["export interface DevScriptsConfig {\n // i18n config\n i18n: {\n locales: string[]\n defaultLocale: string\n messageRoot: string\n }\n \n // scan config\n scan: {\n include: string[]\n exclude?: string[]\n baseDir?: string\n }\n \n // blog config\n blog?: {\n mdxDir: string\n outputFile?: string\n metaFile?: string\n iocSlug?: string\n prefix?: string\n }\n \n // output config\n output: {\n logDir: string\n verbose?: boolean\n }\n}\n\nexport interface PackageJsonDevScripts {\n locales?: string[]\n defaultLocale?: string\n messageRoot?: string\n scanDirs?: string[]\n blogDir?: string\n logDir?: string\n}\n\nexport const DEFAULT_CONFIG: DevScriptsConfig = {\n i18n: {\n locales: ['en', 'zh'],\n defaultLocale: 'en',\n messageRoot: 'messages'\n },\n scan: {\n include: ['src/**/*.{tsx,ts,jsx,js}'],\n exclude: ['src/**/*.d.ts', 'src/**/*.test.ts', 'src/**/*.test.tsx', 'node_modules/**']\n },\n blog: {\n mdxDir: 'src/mdx/blog',\n outputFile: 'index.mdx',\n metaFile: 'meta.json',\n iocSlug: 'ioc',\n prefix: 'blog'\n },\n output: {\n logDir: 'logs',\n verbose: false\n }\n} ","import fs from 'fs'\nimport path from 'path'\nimport { DEFAULT_CONFIG, DevScriptsConfig, PackageJsonDevScripts } from '@dev-scripts/config/schema'\n\n/**\n * load config from package.json\n */\nfunction loadPackageJsonConfig(cwd: string): Partial<DevScriptsConfig> | null {\n try {\n const packageJsonPath = path.join(cwd, 'package.json')\n if (!fs.existsSync(packageJsonPath)) return null\n \n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))\n const devScripts: PackageJsonDevScripts = packageJson.devScripts\n \n // only return config if devScripts field actually exists\n if (!devScripts || Object.keys(devScripts).length === 0) {\n return null\n }\n \n // convert to standard config format\n const config: Partial<DevScriptsConfig> = {}\n \n if (devScripts.locales || devScripts.defaultLocale || devScripts.messageRoot) {\n config.i18n = {\n locales: devScripts.locales || DEFAULT_CONFIG.i18n.locales,\n defaultLocale: devScripts.defaultLocale || DEFAULT_CONFIG.i18n.defaultLocale,\n messageRoot: devScripts.messageRoot || DEFAULT_CONFIG.i18n.messageRoot\n }\n }\n \n if (devScripts.scanDirs) {\n config.scan = {\n include: devScripts.scanDirs,\n exclude: DEFAULT_CONFIG.scan.exclude\n }\n }\n \n if (devScripts.blogDir) {\n config.blog = {\n mdxDir: devScripts.blogDir,\n ...DEFAULT_CONFIG.blog\n }\n }\n \n if (devScripts.logDir) {\n config.output = {\n logDir: devScripts.logDir,\n verbose: DEFAULT_CONFIG.output.verbose\n }\n }\n \n return Object.keys(config).length > 0 ? config : null\n } catch (error) {\n console.warn(`Warning: Failed to load package.json config: ${error}`)\n return null\n }\n}\n\n/**\n * load config from dev-scripts.config.json file\n */\nfunction loadConfigFile(cwd: string): Partial<DevScriptsConfig> | null {\n try {\n const configPath = path.join(cwd, 'dev-scripts.config.json')\n if (!fs.existsSync(configPath)) {\n return null\n }\n \n return JSON.parse(fs.readFileSync(configPath, 'utf8'))\n } catch (error) {\n console.warn(`Warning: Failed to load dev-scripts.config.json: ${error}`)\n return null\n }\n}\n\n/**\n * deep merge config object\n */\nfunction mergeConfig(base: DevScriptsConfig, override: Partial<DevScriptsConfig>): DevScriptsConfig {\n const result = { ...base }\n \n for (const [key, value] of Object.entries(override)) {\n if (value !== undefined && value !== null) {\n if (typeof value === 'object' && !Array.isArray(value) && typeof result[key as keyof DevScriptsConfig] === 'object') {\n ;(result as any)[key] = { ...(result as any)[key], ...value }\n } else {\n ;(result as any)[key] = value\n }\n }\n }\n \n return result\n}\n\n/**\n * load full config\n */\nexport function loadConfig(cwd: string = typeof process !== 'undefined' ? process.cwd() : '.', override: Partial<DevScriptsConfig> = {}, verbose?: boolean): DevScriptsConfig {\n let config = { ...DEFAULT_CONFIG }\n const configSources: string[] = []\n \n // 1. load dev-scripts.config.json\n const fileConfig = loadConfigFile(cwd)\n if (fileConfig) {\n config = mergeConfig(config, fileConfig)\n configSources.push('dev-scripts.config.json')\n }\n \n // 2. load package.json config\n const packageConfig = loadPackageJsonConfig(cwd)\n if (packageConfig) {\n config = mergeConfig(config, packageConfig)\n configSources.push('package.json')\n }\n \n // 3. apply any override config\n config = mergeConfig(config, override)\n if (Object.keys(override).length > 0) {\n configSources.push('runtime override')\n }\n \n // 4. print config info in verbose mode\n const shouldPrintConfig = verbose !== undefined ? verbose : config.output.verbose\n if (shouldPrintConfig) {\n // temporarily set verbose for printing\n const configForPrint = { ...config }\n configForPrint.output = { ...config.output, verbose: true }\n printConfigInfo(configForPrint, configSources, cwd)\n }\n \n return config\n}\n\n/**\n * print config information in verbose mode\n */\nfunction printConfigInfo(config: DevScriptsConfig, sources: string[], cwd: string): void {\n console.log('\\n📋 Config Information:')\n console.log(` working directory: ${cwd}`)\n console.log(` config sources: ${sources.length > 0 ? sources.join(' + ') : 'default config'}`)\n \n console.log('\\n🌐 i18n:')\n console.log(` locales: [${config.i18n.locales.join(', ')}]`)\n console.log(` defaultLocale: ${config.i18n.defaultLocale}`)\n console.log(` messageRoot: ${config.i18n.messageRoot}`)\n \n console.log('\\n🔍 scan:')\n console.log(` include: [${config.scan.include.join(', ')}]`)\n if (config.scan.exclude && config.scan.exclude.length > 0) {\n console.log(` exclude: [${config.scan.exclude.join(', ')}]`)\n }\n if (config.scan.baseDir) {\n console.log(` baseDir: ${config.scan.baseDir}`)\n }\n \n if (config.blog) {\n console.log('\\n📝 blog:')\n console.log(` mdxDir: ${config.blog.mdxDir}`)\n console.log(` outputFile: ${config.blog.outputFile || 'index.mdx (default)'}`)\n console.log(` metaFile: ${config.blog.metaFile || 'meta.json (default)'}`)\n if (config.blog.iocSlug) {\n console.log(` iocSlug: ${config.blog.iocSlug}`)\n }\n if (config.blog.prefix) {\n console.log(` prefix: ${config.blog.prefix}`)\n }\n }\n \n console.log('\\n📤 output:')\n console.log(` logDir: ${config.output.logDir}`)\n console.log(` verbose: ${config.output.verbose}`)\n console.log('')\n}\n\n/**\n * validate config\n */\nexport function validateConfig(config: DevScriptsConfig): void {\n if (!config.i18n.locales || config.i18n.locales.length === 0) {\n throw new Error('at least one language is required')\n }\n \n if (!config.i18n.locales.includes(config.i18n.defaultLocale)) {\n throw new Error('default language must be in the supported language list')\n }\n \n if (config.scan.include.length === 0) {\n throw new Error('at least one scan path is required')\n }\n} ","import { writeFileSync, mkdirSync } from 'fs'\nimport { join, dirname } from 'path'\nimport { DevScriptsConfig } from '@dev-scripts/config/schema'\n\nexport class Logger {\n private messages: string[] = []\n private config: DevScriptsConfig\n \n constructor(config: DevScriptsConfig) {\n this.config = config\n }\n \n log(message: string): void {\n if (this.config.output.verbose) {\n console.log(message)\n }\n this.messages.push(message)\n }\n \n error(message: string): void {\n console.error(message)\n this.messages.push('[ERROR] ' + message)\n }\n \n warn(message: string): void {\n console.warn(message)\n this.messages.push('[WARN] ' + message)\n }\n \n info(message: string): void {\n console.info(message)\n this.messages.push('[INFO] ' + message)\n }\n \n success(message: string): void {\n console.log(`✅ ${message}`)\n this.messages.push(`[SUCCESS] ${message}`)\n }\n \n /**\n * save log to file\n */\n saveToFile(filename: string, cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'): void {\n try {\n const logFilePath = join(cwd, this.config.output.logDir, filename)\n const logDir = dirname(logFilePath)\n \n // create log directory if it doesn't exist\n mkdirSync(logDir, { recursive: true })\n \n writeFileSync(logFilePath, this.messages.join('\\n'), 'utf8')\n console.log(`log saved to ${logFilePath}`)\n } catch (error) {\n console.error(`failed to save log file: ${error}`)\n }\n }\n \n /**\n * clear log messages\n */\n clear(): void {\n this.messages = []\n }\n \n /**\n * get all log messages\n */\n getMessages(): string[] {\n return [...this.messages]\n }\n} ","import fg from 'fast-glob'\nimport { readFileSync } from 'fs'\nimport { DevScriptsConfig } from '@dev-scripts/config/schema'\n\nexport interface ScanResult {\n filePath: string\n content: string\n}\n\n/**\n * scan matching files\n */\nexport async function scanFiles(config: DevScriptsConfig, cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'): Promise<ScanResult[]> {\n const files: string[] = await fg(config.scan.include, {\n ignore: config.scan.exclude || [],\n cwd,\n absolute: false\n })\n\n const results: ScanResult[] = []\n \n for (const file of files) {\n try {\n const content = readFileSync(file, 'utf8')\n results.push({\n filePath: file,\n content\n })\n } catch (error) {\n console.warn(`Warning: Failed to read file ${file}: ${error}`)\n }\n }\n\n return results\n}\n\n/**\n * read JSON file from given path\n */\nexport function readJsonFile<T = any>(filePath: string): T | null {\n try {\n const content = readFileSync(filePath, 'utf8')\n return JSON.parse(content)\n } catch (error) {\n return null\n }\n}\n\n/**\n * get translation file path\n */\nexport function getTranslationFilePath(locale: string, config: DevScriptsConfig, cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'): string {\n return `${cwd}/${config.i18n.messageRoot}/${locale}.json`\n}\n\n/**\n * load all translation files\n */\nexport function loadTranslations(config: DevScriptsConfig, cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'): Record<string, Record<string, any>> {\n const translations: Record<string, Record<string, any>> = {}\n \n for (const locale of config.i18n.locales) {\n const filePath = getTranslationFilePath(locale, config, cwd)\n const translation = readJsonFile(filePath)\n \n if (translation) {\n translations[locale] = translation\n } else {\n console.warn(`Warning: Failed to load translation file for locale: ${locale}`)\n translations[locale] = {}\n }\n }\n \n return translations\n} ","// translation info interface\nexport interface TranslationInfo {\n namespaces: Map<string, string> // variable name -> namespace\n keys: string[] // full translation key path\n}\n\n/**\n * extract translation keys and namespaces from file content\n */\nexport function extractTranslationsInfo(content: string, filePath: string): TranslationInfo {\n const result: TranslationInfo = {\n namespaces: new Map<string, string>(),\n keys: []\n }\n\n // match getTranslations({ locale, namespace: 'namespace' }) or getTranslations('namespace')\n const getTranslationsPattern = /getTranslations\\(\\s*(?:{[^}]*namespace:\\s*['\"]([^'\"]+)['\"][^}]*}|['\"]([^'\"]+)['\"])\\s*\\)/g\n let match: RegExpExecArray | null\n\n while ((match = getTranslationsPattern.exec(content)) !== null) {\n const namespace = match[1] || match[2]\n if (namespace) {\n // try to find assignment statement, like const t = await getTranslations(...)\n // find the nearest const declaration\n const linesBefore = content.substring(0, match.index).split('\\n');\n for (let i = linesBefore.length - 1; i >= Math.max(0, linesBefore.length - 5); i--) {\n const line = linesBefore[i];\n const constMatch = /const\\s+(\\w+)\\s*=/.exec(line);\n if (constMatch && !line.includes('useTranslations') && !line.includes('getTranslations')) {\n result.namespaces.set(constMatch[1], namespace);\n break;\n }\n }\n }\n }\n\n // match useTranslations('namespace')\n const useTranslationsPattern = /useTranslations\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g\n while ((match = useTranslationsPattern.exec(content)) !== null) {\n const namespace = match[1]\n\n // try to find assignment statement, like const t = useTranslations(...)\n // find the line containing useTranslations\n const currentLine = content.substring(0, match.index).split('\\n').pop() || '';\n const constMatch = /const\\s+(\\w+)\\s*=/.exec(currentLine);\n if (constMatch) {\n result.namespaces.set(constMatch[1], namespace);\n }\n }\n\n // match t('key') or t(\"key\"), and check if t is associated with known namespaces\n // modify the matching pattern of t function call\n const tPatterns = [\n // normal string key: t('key') or t(\"key\")\n /(\\w+)\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n // template string key: t(`tags.${id}`) or t(`section.${key}`)\n /(\\w+)\\(\\s*`([^`]+)`\\s*\\)/g,\n // variable key: t(item.key) or t(item.id)\n /(\\w+)\\(\\s*(\\w+)\\.(\\w+)\\s*\\)/g\n ];\n\n for (const pattern of tPatterns) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const funcName = match[1];\n\n // if the function name is associated with known namespaces\n if (result.namespaces.has(funcName)) {\n const namespace = result.namespaces.get(funcName);\n if (!namespace) continue;\n\n if (pattern.source.includes('`')) {\n // handle template string\n const templateStr = match[2];\n // extract static part (the part before the variable)\n const staticPart = templateStr.split(/\\${(?:id|key)}/)[0].trim();\n if (staticPart && !staticPart.includes('/')) {\n // for tags.${id}这样的形式,记录整个 tags 命名空间\n const segments = staticPart.split('.');\n if (segments.length > 0) {\n // record the base path\n result.keys.push(`${namespace}.${segments[0]}`);\n // if it is multi-level, also record the full path\n if (segments.length > 1) {\n result.keys.push(`${namespace}.${segments.join('.')}`);\n }\n\n // special handling for tags namespace\n if (segments[0] === 'tags') {\n // add all known tag keys\n ['productUpdates', 'tutorials', 'makeMoney', 'roadOverSea', 'insights'].forEach(tag => {\n result.keys.push(`${namespace}.tags.${tag}`);\n });\n }\n }\n }\n } else if (pattern.source.includes('\\\\w+\\\\.\\\\w+')) {\n // handle variable key t(item.key)\n const varName = match[2];\n const propName = match[3];\n\n // find the possible value of the variable in the file content\n const varPattern = new RegExp(`${varName}\\\\s*=\\\\s*{[^}]*key:\\\\s*['\"]([^'\"]+)['\"]`);\n const varMatch = content.match(varPattern);\n\n if (varMatch) {\n // if the variable definition is found, add the actual key\n result.keys.push(`${namespace}.${varMatch[1]}`);\n } else {\n // if the specific definition is not found, try to infer from the context\n // check if it is used in an array or object of MenuItem type\n if (content.includes('MenuItem[]') || content.includes('MenuItem}')) {\n // add all possible menu keys\n ['journey'].forEach(menuKey => {\n result.keys.push(`${namespace}.${menuKey}`);\n });\n }\n }\n } else {\n // handle normal string key\n const key = match[2];\n if (!key.includes('/') && key !== '') {\n result.keys.push(`${namespace}.${key}`);\n }\n }\n }\n }\n }\n\n // match <FormattedMessage id=\"key\" />\n const formattedMessagePattern = /<FormattedMessage[^>]*id=['\"]([^'\"]+)['\"]/g\n while ((match = formattedMessagePattern.exec(content)) !== null) {\n const key = match[1]\n if (!key.includes('/') && key !== '') {\n // for FormattedMessage, we need to guess the namespace\n // usually we can find useTranslations call in the same file\n if (result.namespaces.size > 0) {\n const namespace = Array.from(result.namespaces.values())[0]\n result.keys.push(`${namespace}.${key}`)\n } else {\n // if the namespace is not found, try to infer from the file path\n const pathMatch = filePath.match(/\\[locale\\]\\/(?:\\([^)]+\\)\\/)?([^/]+)/)\n if (pathMatch && pathMatch[1]) {\n const possibleNamespace = pathMatch[1]\n result.keys.push(`${possibleNamespace}.${key}`)\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * get all keys from an object (including nested keys)\n */\nexport function getAllKeys(obj: Record<string, any>, prefix: string = ''): string[] {\n let keys: string[] = []\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const newKey = prefix ? `${prefix}.${key}` : key\n if (typeof obj[key] === 'object' && obj[key] !== null) {\n keys = [...keys, ...getAllKeys(obj[key], newKey)]\n } else {\n keys.push(newKey)\n }\n }\n }\n return keys\n}\n\n/**\n * check if the key exists in the translation file\n */\nexport function checkKeyExists(key: string, translations: Record<string, any>): boolean {\n const parts = key.split('.')\n let current: any = translations\n\n for (const part of parts) {\n if (current[part] === undefined) {\n return false\n }\n current = current[part]\n }\n\n return true\n}\n\n/**\n * check if the namespace exists in the translation file\n */\nexport function checkNamespaceExists(namespace: string, translations: Record<string, any>): boolean {\n return translations[namespace] !== undefined\n}\n\n/**\n * remove the specified key from the translation object\n */\nexport function removeKeyFromTranslations(key: string, translations: Record<string, any>): boolean {\n const parts = key.split('.')\n const lastPart = parts.pop()\n\n if (!lastPart) return false\n\n let current = translations\n\n // navigate to the parent object of the last level\n for (const part of parts) {\n if (current[part] === undefined || typeof current[part] !== 'object') {\n return false\n }\n current = current[part]\n }\n\n // delete the key\n if (current[lastPart] !== undefined) {\n delete current[lastPart]\n return true\n }\n\n return false\n}\n\n/**\n * clean empty objects (recursively)\n */\nexport function cleanEmptyObjects(obj: Record<string, any>): Record<string, any> {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n if (typeof obj[key] === 'object' && obj[key] !== null) {\n obj[key] = cleanEmptyObjects(obj[key])\n // if the object is empty, delete it\n if (Object.keys(obj[key]).length === 0) {\n delete obj[key]\n }\n }\n }\n }\n return obj\n} ","import { DevScriptsConfig } from '@dev-scripts/config/schema'\nimport { Logger } from '@dev-scripts/utils/logger'\nimport { scanFiles, loadTranslations } from '@dev-scripts/utils/file-scanner'\nimport { \n extractTranslationsInfo, \n getAllKeys, \n checkKeyExists, \n checkNamespaceExists \n} from '@dev-scripts/utils/translation-parser'\n\ninterface TranslationReport {\n [key: string]: string[]\n}\n\nexport async function checkTranslations(config: DevScriptsConfig, cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'): Promise<number> {\n const logger = new Logger(config)\n logger.warn('==============================')\n logger.warn(`‼️ Current working directory: ⭕ ${cwd} ⭕`)\n logger.warn('==============================')\n \n try {\n logger.log('start checking translations...')\n\n // scan all files\n const scanResults = await scanFiles(config, cwd)\n logger.log(`found ${scanResults.length} files to scan`)\n\n // load translation files\n const translations = loadTranslations(config, cwd)\n\n // collect used translation keys and namespaces\n const foundTranslationKeys: Set<string> = new Set()\n const foundNamespaces: Set<string> = new Set()\n\n // scan all files, extract translation information\n for (const { filePath, content } of scanResults) {\n try {\n const { namespaces, keys } = extractTranslationsInfo(content, filePath)\n\n if (keys.length > 0 || namespaces.size > 0) {\n logger.log(`found the following information in the file ${filePath}:`)\n\n if (namespaces.size > 0) {\n logger.log(` translation function mapping:`)\n namespaces.forEach((namespace, varName) => {\n logger.log(` - ${varName} => ${namespace}`)\n foundNamespaces.add(namespace)\n })\n }\n\n if (keys.length > 0) {\n logger.log(` translation keys:`)\n keys.forEach(key => {\n logger.log(` - ${key}`)\n foundTranslationKeys.add(key)\n })\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n logger.error(`error processing file ${filePath}: ${error.message}`)\n } else {\n logger.error(`error processing file ${filePath}: unknown error`)\n }\n }\n }\n\n logger.log(`\\nfound ${foundNamespaces.size} used namespaces in the code: ${Array.from(foundNamespaces).join(', ')}`)\n\n // check results\n const report: TranslationReport = {}\n\n // check if the namespace exists\n foundNamespaces.forEach(namespace => {\n config.i18n.locales.forEach(locale => {\n const missingNamespaceKey = `missingNamespacesIn${locale.toUpperCase()}`\n if (!checkNamespaceExists(namespace, translations[locale])) {\n report[missingNamespaceKey] = report[missingNamespaceKey] || []\n report[missingNamespaceKey].push(namespace)\n }\n })\n })\n\n // check if the translation key exists\n foundTranslationKeys.forEach(key => {\n config.i18n.locales.forEach(locale => {\n const missingKey = `missingIn${locale.toUpperCase()}`\n if (!checkKeyExists(key, translations[locale])) {\n report[missingKey] = report[missingKey] || []\n report[missingKey].push(key)\n }\n })\n })\n\n // check if the translation keys are consistent\n config.i18n.locales.forEach(locale => {\n const allKeys = getAllKeys(translations[locale])\n config.i18n.locales.forEach(otherLocale => {\n if (locale !== otherLocale) {\n const otherKeys = getAllKeys(translations[otherLocale])\n const onlyKeys = `${locale}OnlyKeys`\n report[onlyKeys] = allKeys.filter(key => !otherKeys.includes(key))\n }\n })\n })\n\n // generate report\n logger.log('\\n=== translation check report ===\\n')\n\n // first report missing namespaces, which is usually the most serious problem\n config.i18n.locales.forEach(locale => {\n const missingNamespaceKey = `missingNamespacesIn${locale.toUpperCase()}`\n if (report[missingNamespaceKey]?.length > 0) {\n logger.log(`🚨 missing namespaces in the ${locale} translation file:`)\n report[missingNamespaceKey].forEach(namespace => logger.log(` - ${namespace}`))\n } else {\n logger.success(`${locale} translation file has all used namespaces`)\n }\n })\n\n // then report missing translation keys\n config.i18n.locales.forEach(locale => {\n const missingKey = `missingIn${locale.toUpperCase()}`\n if (report[missingKey]?.length > 0) {\n logger.log(`\\n🔴 missing keys in the ${locale} translation file:`)\n report[missingKey].forEach(key => logger.log(` - ${key}`))\n } else {\n logger.success(`${locale} translation file has all used keys`)\n }\n })\n\n // finally report inconsistent keys\n config.i18n.locales.forEach(locale => {\n const onlyKeys = `${locale}OnlyKeys`\n if (report[onlyKeys]?.length > 0) {\n logger.log(`\\n⚠️ keys only exist in the ${locale} translation file:`)\n report[onlyKeys].forEach(key => logger.log(` - ${key}`))\n }\n })\n\n logger.log('\\n=== report end ===\\n')\n logger.log(\"⚠️⚠️⚠️script depends on regular matching, for multiple translation namespaces in a single file, use naming to distinguish: t1 | t2 | t3 | ... ⚠️⚠️⚠️\")\n\n // save log file\n logger.saveToFile('check.log', cwd)\n\n // if there are any problems, return non-zero status code\n return Object.values(report).some(keys => keys.length > 0) ? 1 : 0\n\n } catch (error) { \n logger.error(`error checking translations: ${error}`)\n return 1\n }\n} ","import { DevScriptsConfig } from '@dev-scripts/config/schema'\nimport { getTranslationFilePath, loadTranslations, scanFiles } from '@dev-scripts/utils/file-scanner'\nimport { Logger } from '@dev-scripts/utils/logger'\nimport {\n cleanEmptyObjects,\n extractTranslationsInfo,\n getAllKeys,\n removeKeyFromTranslations\n} from '@dev-scripts/utils/translation-parser'\nimport { writeFileSync } from 'fs'\n\ninterface CleanReport {\n [key: string]: string[]\n}\n\nexport async function cleanTranslations(\n config: DevScriptsConfig, \n shouldRemove: boolean = false,\n cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'\n): Promise<number> {\n const logger = new Logger(config)\n const logFileName = shouldRemove ? 'remove.log' : 'clean.log'\n \n logger.warn('==============================')\n logger.warn(`‼️ Current working directory: ⭕ ${cwd} ⭕`)\n logger.warn('==============================')\n \n try {\n logger.log('start checking unused translation keys...')\n\n // scan all files\n const scanResults = await scanFiles(config, cwd)\n logger.log(`找到 ${scanResults.length} 个文件需要扫描`)\n\n // load translation files\n const translations = loadTranslations(config, cwd)\n\n // collect used translation keys and namespaces\n const foundTranslationKeys: Set<string> = new Set()\n const foundNamespaces: Set<string> = new Set()\n\n // scan all files, collect used translation keys and namespaces\n for (const { filePath, content } of scanResults) {\n try {\n const { namespaces, keys } = extractTranslationsInfo(content, filePath)\n\n if (keys.length > 0 || namespaces.size > 0) {\n logger.log(`found the following information in the file ${filePath}:`)\n\n if (namespaces.size > 0) {\n logger.log(` translation function mapping:`)\n namespaces.forEach((namespace, varName) => {\n logger.log(` - ${varName} => ${namespace}`)\n foundNamespaces.add(namespace)\n })\n }\n\n if (keys.length > 0) {\n logger.log(` translation keys:`)\n keys.forEach(key => {\n logger.log(` - ${key}`)\n foundTranslationKeys.add(key)\n })\n }\n }\n } catch (error) {\n if (error instanceof Error) {\n logger.error(`error processing file ${filePath}: ${error.message}`)\n } else {\n logger.error(`error processing file ${filePath}: unknown error`)\n }\n }\n }\n\n logger.log(`\\nfound ${foundTranslationKeys.size} used translation keys in the code`)\n logger.log(`found ${foundNamespaces.size} used namespaces in the code: ${Array.from(foundNamespaces).join(', ')}`)\n\n // check unused keys in each language file\n const unusedKeys: Record<string, string[]> = {}\n const removedKeys: Record<string, string[]> = {}\n const unusedNamespaces: Record<string, string[]> = {}\n\n config.i18n.locales.forEach(locale => {\n unusedKeys[locale] = []\n removedKeys[locale] = []\n unusedNamespaces[locale] = []\n\n // get all keys in the translation file\n const allTranslationKeys = getAllKeys(translations[locale])\n\n // get all namespaces (top-level keys) in the translation file\n const allNamespaces = Object.keys(translations[locale] || {})\n\n // find unused namespaces\n allNamespaces.forEach(namespace => {\n if (!foundNamespaces.has(namespace)) {\n unusedNamespaces[locale].push(namespace)\n }\n })\n\n // find unused keys\n allTranslationKeys.forEach(key => {\n if (!foundTranslationKeys.has(key)) {\n unusedKeys[locale].push(key)\n }\n })\n\n logger.log(`\\nfound ${unusedKeys[locale].length} unused keys in the ${locale} translation file`)\n logger.log(`found ${unusedNamespaces[locale].length} unused namespaces in the ${locale} translation file`)\n })\n\n if (shouldRemove) {\n logger.log('\\nstart deleting unused translation keys...')\n\n // delete unused keys in each language file\n config.i18n.locales.forEach(locale => {\n const translationsCopy = { ...translations[locale] }\n\n unusedKeys[locale].forEach(key => {\n if (removeKeyFromTranslations(key, translationsCopy)) {\n removedKeys[locale].push(key)\n }\n })\n\n // delete unused namespaces\n unusedNamespaces[locale].forEach(namespace => {\n if (translationsCopy[namespace] !== undefined) {\n delete translationsCopy[namespace]\n logger.log(`deleted unused namespace ${namespace} from the ${locale} translation file`)\n }\n })\n\n // clean empty objects\n const cleanedTranslations = cleanEmptyObjects(translationsCopy)\n\n // save updated translation file\n const filePath = getTranslationFilePath(locale, config, cwd)\n writeFileSync(filePath, JSON.stringify(cleanedTranslations, null, 2), 'utf8')\n\n logger.log(`deleted ${removedKeys[locale].length} unused keys from the ${locale} translation file`)\n })\n } else {\n logger.log('\\nTo delete unused keys, please run the script with the --remove parameter')\n }\n\n // generate report\n logger.log('\\n=== unused translation keys report ===\\n')\n\n config.i18n.locales.forEach(locale => {\n if (unusedNamespaces[locale].length > 0) {\n logger.log(`🔍 unused namespaces in the ${locale} translation file:`)\n unusedNamespaces[locale].forEach(namespace => logger.log(` - ${namespace}`))\n } else {\n logger.success(`${locale} translation file has no unused namespaces`)\n }\n\n if (unusedKeys[locale].length > 0) {\n logger.log(`\\n🔍 unused keys in the ${locale} translation file:`)\n unusedKeys[locale].forEach(key => logger.log(` - ${key}`))\n } else {\n logger.success(`${locale} translation file has no unused keys`)\n }\n\n if (shouldRemove && removedKeys[locale].length > 0) {\n logger.log(`\\n🗑️ deleted keys from the ${locale} translation file:`)\n removedKeys[locale].forEach(key => logger.log(` - ${key}`))\n }\n })\n\n logger.log('\\n=== report end ===\\n')\n logger.log(\"⚠️⚠️⚠️script depends on regular matching, for multiple translation namespaces in a single file, use naming to distinguish: t1 | t2 | t3 | ... ⚠️⚠️⚠️\")\n\n // save log file\n logger.saveToFile(logFileName, cwd)\n\n // if there are any unused keys or namespaces, return non-zero status code\n return (Object.values(unusedKeys).some(keys => keys.length > 0) ||\n Object.values(unusedNamespaces).some(namespaces => namespaces.length > 0)) ? 1 : 0\n\n } catch (error) {\n logger.error(`error cleaning translations: ${error}`)\n return 1\n }\n} ","import { readFileSync, writeFileSync, readdirSync } from 'fs'\nimport { join } from 'path'\nimport { DevScriptsConfig } from '@dev-scripts/config/schema'\nimport { Logger } from '@dev-scripts/utils/logger'\nimport { readJsonFile } from '@dev-scripts/utils/file-scanner'\n\ninterface Frontmatter {\n title?: string\n description?: string\n icon?: string\n date?: string\n}\n\ninterface ProcessedArticle {\n slug: string\n title: string\n description?: string\n frontmatterIcon?: string\n href: string\n date?: string\n}\n\ninterface MetaJson {\n pages: string[]\n}\n\nfunction parseFrontmatter(fileContent: string): Frontmatter {\n const frontmatter: Frontmatter = {}\n const match = fileContent.match(/^---([\\s\\S]*?)---/)\n if (match && match[1]) {\n const lines = match[1].trim().split('\\n')\n for (const line of lines) {\n const [key, ...valueParts] = line.split(':')\n if (key && valueParts.length > 0) {\n const value = valueParts.join(':').trim()\n if (key.trim() === 'title') frontmatter.title = value\n if (key.trim() === 'description') frontmatter.description = value\n if (key.trim() === 'icon') frontmatter.icon = value\n if (key.trim() === 'date') frontmatter.date = value\n }\n }\n }\n return frontmatter\n}\n\nfunction getIconComponentString(iconName?: string): string | undefined {\n if (!iconName) return undefined\n return `<${iconName} />`\n}\n\nfunction getCurrentDateString(): string {\n const now = new Date()\n const year = now.getFullYear()\n const month = String(now.getMonth() + 1).padStart(2, '0')\n const day = String(now.getDate()).padStart(2, '0')\n return `${year}-${month}-${day}`\n}\n\nfunction updateFrontmatterDate(frontmatter: string): string {\n const currentDate = getCurrentDateString()\n \n // Check if date field exists\n if (frontmatter.includes('date:')) {\n // Replace existing date\n return frontmatter.replace(/date:\\s*[^\\n]*/, `date: ${currentDate}`)\n } else {\n // Add date field before the closing ---\n return frontmatter.replace(/---$/, `date: ${currentDate}\\n---`)\n }\n}\n\nasync function getAllBlogArticles(blogDir: string, cwd: string, logger: Logger): Promise<ProcessedArticle[]> {\n const articles: ProcessedArticle[] = []\n const blogPath = join(cwd, blogDir)\n \n try {\n const files = readdirSync(blogPath)\n for (const file of files) {\n if (file.endsWith('.mdx') && file !== 'index.mdx') {\n const slug = file.replace(/\\.mdx$/, '')\n const filePath = join(blogPath, file)\n try {\n const content = readFileSync(filePath, 'utf-8')\n const fm = parseFrontmatter(content)\n\n if (!fm.title) {\n logger.warn(`Article \"${file}\" is missing a title in its frontmatter. Skipping.`)\n continue\n }\n\n articles.push({\n slug,\n title: fm.title,\n description: fm.description,\n frontmatterIcon: fm.icon,\n href: `./blog/${slug}`, // Reverted to ./blog/slug format as per original requirement\n date: fm.date,\n })\n } catch (readError) {\n logger.warn(`Could not read or parse frontmatter for \"${file}\": ${readError}`)\n }\n }\n }\n } catch (dirError) {\n logger.error(`Could not read blog directory: ${dirError}`)\n return []\n }\n return articles\n}\n\nexport async function generateBlogIndex(\n config: DevScriptsConfig,\n cwd: string = typeof process !== 'undefined' ? process.cwd() : '.'\n): Promise<number> {\n const logger = new Logger(config)\n logger.warn('==============================')\n logger.warn(`‼️ Current working directory: ⭕ ${cwd} ⭕`)\n logger.warn('==============================')\n try {\n if (!config.blog) {\n logger.error('Blog configuration is missing. Please configure blog settings.')\n return 1\n }\n\n logger.log('Starting to generate blog index...')\n\n const blogPath = join(cwd, config.blog.mdxDir)\n const indexFile = join(blogPath, config.blog.outputFile || 'index.mdx')\n const metaFile = join(blogPath, config.blog.metaFile || 'meta.json')\n const iocFile = join(blogPath, `${config.blog.iocSlug || 'ioc'}.mdx`)\n const iocSlug = config.blog.iocSlug || 'ioc'\n const blogPrefix = config.blog.prefix || 'blog'\n\n let meta: MetaJson = { pages: [] }\n const metaContent = readJsonFile<MetaJson>(metaFile)\n if (metaContent) {\n meta = metaContent\n } else {\n logger.warn(`Could not read or parse ${metaFile}. No articles will be marked as featured.`)\n }\n \n // ioc related processing\n const featuredSlugs = meta.pages\n .map(p => p.endsWith('.mdx') ? p.slice(0, -4) : p)\n .filter(slug => slug !== 'index' && slug !== '...' && slug !== iocSlug && slug !== `!${iocSlug}`)\n logger.log(`Featured slugs (meta-config): ${featuredSlugs.join(', ')}`)\n\n const allArticles = await getAllBlogArticles(config.blog.mdxDir, cwd, logger)\n logger.log(`Found ${allArticles.length} all articles.`)\n\n // ioc article processing separately\n const iocArticle = allArticles.find(a => a.slug === iocSlug)\n\n const filteredArticles = allArticles.filter(a => a.slug !== iocSlug)\n\n if (filteredArticles.length === 0 && featuredSlugs.length === 0) {\n logger.warn(\"No articles found or featured. The generated index might be empty or minimal.\")\n }\n\n const featuredArticles: ProcessedArticle[] = []\n const pastArticles: ProcessedArticle[] = []\n\n filteredArticles.forEach(article => {\n if (featuredSlugs.includes(article.slug)) {\n featuredArticles.push(article)\n } else {\n pastArticles.push(article)\n }\n })\n\n // Sort articles by date in descending order (newest first)\n const sortByDateDesc = (a: ProcessedArticle, b: ProcessedArticle) => {\n if (a.date && b.date) {\n return b.date.localeCompare(a.date) // Newest first\n }\n if (a.date) return -1 // Articles with date come before those without\n if (b.date) return 1 // Articles with date come before those without\n return 0 // Keep original order if both lack dates\n }\n\n featuredArticles.sort(sortByDateDesc)\n pastArticles.sort(sortByDateDesc)\n\n logger.log(`Found ${featuredArticles.length} featured articles (sorted by date).`)\n logger.log(`Found ${pastArticles.length} past articles (sorted by date).`)\n\n // Preserve existing frontmatter or use a default\n let currentFileFrontmatter = '---\\ntitle: Blog\\ndescription: Articles and thoughts about various topics.\\nicon: Rss\\n---'\n try {\n const currentIndexContent = readFileSync(indexFile, 'utf-8')\n const frontmatterMatch = currentIndexContent.match(/^---([\\s\\S]*?)---/)\n if (frontmatterMatch && frontmatterMatch[0]) {\n currentFileFrontmatter = frontmatterMatch[0]\n logger.log('Preserving existing frontmatter from index.mdx')\n }\n } catch (error) {\n logger.warn('Could not read existing index.mdx or parse its frontmatter. Using default frontmatter.')\n }\n\n // Update date field in frontmatter\n currentFileFrontmatter = updateFrontmatterDate(currentFileFrontmatter)\n\n let mdxContent = `${currentFileFrontmatter}\\n\\n`\n\n const createCard = (article: ProcessedArticle): string => {\n const iconString = getIconComponentString(article.frontmatterIcon)\n const iconProp = iconString ? `icon={${iconString}}` : ''\n \n // Escape only double quotes in title for JSX attribute\n const escapedTitle = (article.title || '').replace(/\"/g, '&quot;')\n\n // Content of the card - should be raw, as it might be MDX\n const cardContent = article.date || article.description || '' \n \n // Ensure there's a space before href if iconProp is present and not empty\n const finalIconProp = iconProp ? `${iconProp} ` : ''\n\n const href = blogPrefix ? `./${blogPrefix}/${article.slug}` : `./${article.slug}`\n return ` <ZiaCard ${finalIconProp}href=\"${href}\" title=\"${escapedTitle}\">\\n ${cardContent}\\n </ZiaCard>\\n`\n }\n\n if (featuredArticles.length > 0) {\n mdxContent += `## Feature List\\n\\n<Cards>\\n`\n featuredArticles.forEach(article => { mdxContent += createCard(article) })\n mdxContent += `</Cards>\\n\\n`\n }\n\n if (pastArticles.length > 0) {\n mdxContent += `## Past List\\n\\n<Cards>\\n`\n pastArticles.forEach(article => { mdxContent += createCard(article) })\n mdxContent += `</Cards>\\n`\n }\n\n // add Monthly Summary block separately\n if (iocArticle) {\n mdxContent += `\\n## Monthly Summary\\n\\n<Cards>\\n`\n const iocHref = blogPrefix ? `./${blogPrefix}/${iocSlug}` : `./${iocSlug}`\n mdxContent += ` <ZiaCard href=\"${iocHref}\" title=\"Overview\">\\n ${getCurrentDateString()}\\n </ZiaCard>\\n`\n mdxContent += `</Cards>\\n`\n }\n\n if (featuredArticles.length === 0 && pastArticles.length === 0 && !iocArticle) {\n mdxContent += \"No blog posts found yet. Stay tuned!\\n\"\n }\n\n writeFileSync(indexFile, mdxContent)\n logger.success(`Successfully generated ${indexFile}`)\n\n // generate monthly statistics\n await generateMonthlyBlogSummary(config, allArticles, iocFile, iocSlug, logger)\n\n logger.log('Blog index generation completed successfully!')\n logger.saveToFile('generate-blog.log', cwd)\n\n return 0\n\n } catch (error) {\n logger.error(`Error generating blog index: ${error}`)\n return 1\n }\n}\n\n/**\n * generate blog monthly statistics details\n */\nasync function generateMonthlyBlogSummary(\n config: DevScriptsConfig,\n articles: ProcessedArticle[],\n iocFile: string,\n iocSlug: string,\n logger: Logger\n): Promise<void> {\n try {\n // filter out articles without date and slug is ioc\n const articlesWithDate = articles.filter(a => a.date && a.slug !== iocSlug)\n\n // group by month\n const monthMap: Record<string, {date: string, title: string}[]> = {}\n for (const art of articlesWithDate) {\n // only take the first 7 digits yyyy-mm\n const month = art.date!.slice(0, 7)\n if (!monthMap[month]) monthMap[month] = []\n monthMap[month].push({ date: art.date!, title: art.title })\n }\n\n // sort months in descending order\n const sortedMonths = Object.keys(monthMap).sort((a, b) => b.localeCompare(a))\n\n // sort articles by date in descending order\n for (const month of sortedMonths) {\n monthMap[month].sort((a, b) => b.date.localeCompare(a.date))\n }\n\n // read ioc.mdx original frontmatter\n let frontmatter = ''\n try {\n const content = readFileSync(iocFile, 'utf-8')\n const match = content.match(/^---([\\s\\S]*?)---/)\n if (match && match[0]) frontmatter = match[0]\n } catch {\n // File doesn't exist, use default\n }\n\n // if there is no frontmatter, use the default\n if (!frontmatter) {\n frontmatter = '---\\ntitle: Monthly Summary\\ndescription: Index and Summary\\n---'\n }\n\n // update date field in frontmatter\n frontmatter = updateFrontmatterDate(frontmatter)\n\n // generate content\n let mdx = `${frontmatter}\\n\\n\\n## Overview\\n<Files>\\n`\n if (sortedMonths.length === 0) {\n mdx += ' <File name=\"Comming Soon\" className=\"opacity-50\" disabled/>\\n'\n } else {\n for (const month of sortedMonths) {\n // Folder name format YYYY-MM(article count)\n const count = monthMap[month].length\n const folderTitle = `${month}(${count})`\n // default open the latest month\n const defaultOpen = month === sortedMonths[0] ? ' defaultOpen' : ''\n mdx += ` <Folder name=\"${folderTitle}\"${defaultOpen}>\\n`\n for (const art of monthMap[month]) {\n // File name=\"YYYY-MM-DD(Title)\" format\n const day = art.date.slice(0, 10)\n mdx += ` <File name=\"${day}(${art.title})\" />\\n`\n }\n mdx += ` </Folder>\\n`\n }\n }\n mdx += '</Files>\\n\\n'\n\n writeFileSync(iocFile, mdx)\n logger.success(`Successfully generated Monthly Blog Summary: ${iocFile}`)\n } catch (error) {\n logger.error(`Error generating monthly blog summary: ${error}`)\n }\n} "]}
package/dist/cli.js CHANGED
@@ -438,6 +438,9 @@ function cleanEmptyObjects(obj) {
438
438
  // src/commands/check-translations.ts
439
439
  async function checkTranslations(config, cwd2 = typeof process !== "undefined" ? process.cwd() : ".") {
440
440
  const logger = new Logger(config);
441
+ logger.warn("==============================");
442
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd2} \u2B55`);
443
+ logger.warn("==============================");
441
444
  try {
442
445
  logger.log("start checking translations...");
443
446
  const scanResults = await scanFiles(config, cwd2);
@@ -544,6 +547,9 @@ found ${foundNamespaces.size} used namespaces in the code: ${Array.from(foundNam
544
547
  async function cleanTranslations(config, shouldRemove = false, cwd2 = typeof process !== "undefined" ? process.cwd() : ".") {
545
548
  const logger = new Logger(config);
546
549
  const logFileName = shouldRemove ? "remove.log" : "clean.log";
550
+ logger.warn("==============================");
551
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd2} \u2B55`);
552
+ logger.warn("==============================");
547
553
  try {
548
554
  logger.log("start checking unused translation keys...");
549
555
  const scanResults = await scanFiles(config, cwd2);
@@ -734,6 +740,9 @@ async function getAllBlogArticles(blogDir, cwd2, logger) {
734
740
  }
735
741
  async function generateBlogIndex(config, cwd2 = typeof process !== "undefined" ? process.cwd() : ".") {
736
742
  const logger = new Logger(config);
743
+ logger.warn("==============================");
744
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd2} \u2B55`);
745
+ logger.warn("==============================");
737
746
  try {
738
747
  if (!config.blog) {
739
748
  logger.error("Blog configuration is missing. Please configure blog settings.");
@@ -916,10 +925,144 @@ async function generateMonthlyBlogSummary(config, articles, iocFile, iocSlug, lo
916
925
  logger.error(`Error generating monthly blog summary: ${error}`);
917
926
  }
918
927
  }
928
+ var MONOREPO_CLEAN_TARGETS = [
929
+ { pattern: "node_modules", description: "Root directory dependencies" },
930
+ { pattern: "packages/*/node_modules", description: "Package dependencies" },
931
+ { pattern: "apps/*/node_modules", description: "Application dependencies" },
932
+ { pattern: "apps/*/.next", description: "Next.js cache" },
933
+ { pattern: "packages/*/dist", description: "Package build artifacts" },
934
+ { pattern: "apps/*/dist", description: "Application build artifacts" },
935
+ { pattern: ".turbo", description: "Root directory Turbo cache" },
936
+ { pattern: "packages/*/.turbo", description: "Package Turbo cache" },
937
+ { pattern: "apps/*/.turbo", description: "Application Turbo cache" },
938
+ { pattern: "pnpm-lock.yaml", description: "pnpm lock file", isFile: true }
939
+ ];
940
+ var SINGLE_CLEAN_TARGETS = [
941
+ { pattern: "node_modules", description: "Root directory dependencies" },
942
+ { pattern: ".next", description: "Next.js cache" },
943
+ { pattern: "pnpm-lock.yaml", description: "pnpm lock file", isFile: true }
944
+ ];
945
+ function globDirsOrFiles(pattern, cwd2, isFile) {
946
+ if (!pattern.includes("*")) {
947
+ const abs = path.resolve(cwd2, pattern);
948
+ if (isFile) {
949
+ return fs.existsSync(abs) ? [abs] : [];
950
+ }
951
+ return fs.existsSync(abs) && fs.statSync(abs).isDirectory() ? [abs] : [];
952
+ }
953
+ const [base, rest] = pattern.split("/*");
954
+ const absBase = path.resolve(cwd2, base);
955
+ if (!fs.existsSync(absBase) || !fs.statSync(absBase).isDirectory()) return [];
956
+ const subdirs = fs.readdirSync(absBase);
957
+ return subdirs.map((d) => path.join(absBase, d, rest.replace(/^[\/]/, ""))).filter((p) => fs.existsSync(p) && (isFile ? true : fs.statSync(p).isDirectory()));
958
+ }
959
+ async function deepClean(config, yes = false, cwd2 = typeof process !== "undefined" ? process.cwd() : ".") {
960
+ const logger = new Logger(config);
961
+ if (process.env.NODE_ENV === "production") {
962
+ logger.error("\u274C Production environment prohibits deep clean operations");
963
+ logger.log(" If you need to clean, please set: NODE_ENV=development");
964
+ logger.saveToFile("deep-clean.log", cwd2);
965
+ return 1;
966
+ }
967
+ logger.warn("==============================");
968
+ logger.warn(`\u203C\uFE0F Current working directory: \u2B55 ${cwd2} \u2B55`);
969
+ logger.warn("==============================");
970
+ const isMonorepo = fs.existsSync(path.resolve(cwd2, "pnpm-workspace.yaml"));
971
+ const cleanTargets = isMonorepo ? MONOREPO_CLEAN_TARGETS : SINGLE_CLEAN_TARGETS;
972
+ let totalToDelete = [];
973
+ let groupDeleteMap = {};
974
+ for (const target of cleanTargets) {
975
+ const found = globDirsOrFiles(target.pattern, cwd2, target.isFile);
976
+ groupDeleteMap[target.description] = found;
977
+ if (found.length === 0) {
978
+ logger.info(`\u{1F4AF} ${target.description}: No need to clean`);
979
+ } else {
980
+ logger.log(`
981
+ [${target.description}]`);
982
+ found.forEach((p) => logger.warn(`\u{1F459} [Preview] ${p}`));
983
+ totalToDelete.push(...found);
984
+ }
985
+ }
986
+ if (totalToDelete.length === 0) {
987
+ logger.success("No directories or files to clean.");
988
+ logger.saveToFile("deep-clean.log", cwd2);
989
+ return 0;
990
+ }
991
+ if (!yes) {
992
+ logger.log("\nIf you need to actually delete, please add --yes parameter.");
993
+ logger.saveToFile("deep-clean.log", cwd2);
994
+ return 0;
995
+ }
996
+ let deleted = 0;
997
+ for (const target of cleanTargets) {
998
+ const items = groupDeleteMap[target.description] || [];
999
+ if (items.length > 0) {
1000
+ logger.log(`
1001
+ [${target.description}]`);
1002
+ for (const p of items) {
1003
+ try {
1004
+ if (target.isFile) {
1005
+ fs.unlinkSync(p);
1006
+ if (!fs.existsSync(p)) {
1007
+ logger.success(`\u{1F37B} Deleted: ${p}`);
1008
+ deleted++;
1009
+ } else {
1010
+ logger.error(`\u274C Delete failed: ${p} (file still exists)`);
1011
+ }
1012
+ } else {
1013
+ fs.rmSync(p, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
1014
+ if (!fs.existsSync(p)) {
1015
+ logger.success(`\u{1F37B} Deleted: ${p}`);
1016
+ deleted++;
1017
+ } else {
1018
+ logger.error(`\u274C Delete failed: ${p} (directory still exists)`);
1019
+ }
1020
+ }
1021
+ } catch (e) {
1022
+ logger.error(`\u274C Delete failed: ${p} (${e.message})`);
1023
+ }
1024
+ }
1025
+ }
1026
+ }
1027
+ logger.log(`
1028
+ \u{1F37A} Total cleaned: ${deleted} directories or files.`);
1029
+ logger.saveToFile("deep-clean.log", cwd2);
1030
+ return 0;
1031
+ }
1032
+ async function easyChangeset(cwd2 = typeof process !== "undefined" ? process.cwd() : ".") {
1033
+ if (process.env.NODE_ENV === "production") {
1034
+ console.log("\u274C Production environment prohibits deep clean operations");
1035
+ console.log(" If you need to clean, please set: NODE_ENV=development");
1036
+ return 1;
1037
+ }
1038
+ console.log("==============================");
1039
+ console.log(`\u203C\uFE0F Current working directory: \u2B55 ${cwd2} \u2B55`);
1040
+ console.log("==============================");
1041
+ const changesetDir = path.join(cwd2, ".changeset");
1042
+ const mdxFile = path.join(changesetDir, "d8-template.mdx");
1043
+ const mdFile = path.join(changesetDir, "d8-template.md");
1044
+ if (!fs.existsSync(changesetDir)) {
1045
+ console.log("\u274C No .changeset directory found, skipping.");
1046
+ return 1;
1047
+ }
1048
+ if (!fs.existsSync(mdxFile)) {
1049
+ console.log("\u274C No .changeset/d8-template.mdx file found, skipping.");
1050
+ return 1;
1051
+ }
1052
+ try {
1053
+ const content = fs.readFileSync(mdxFile, "utf-8");
1054
+ fs.writeFileSync(mdFile, content, "utf-8");
1055
+ console.log("\u2705 Copied d8-template.mdx content to d8-template.md");
1056
+ return 0;
1057
+ } catch (e) {
1058
+ console.log("\u274C Copy failed:", e.message);
1059
+ return 1;
1060
+ }
1061
+ }
919
1062
 
920
1063
  // src/cli.ts
921
1064
  var cwd = typeof process !== "undefined" ? process.cwd() : ".";
922
- commander.program.name("dev-scripts").description("development scripts for multi-language projects").version("1.0.0");
1065
+ commander.program.name("dev-scripts").description("development scripts for multi-language projects").version("5.0.0");
923
1066
  commander.program.command("check-translations").description("check the completeness and consistency of translation files").option("-v, --verbose", "show detailed logs", false).action(async (options) => {
924
1067
  try {
925
1068
  const config = loadConfig(cwd, {}, options.verbose);
@@ -974,6 +1117,37 @@ commander.program.command("generate-blog-index").description("generate blog inde
974
1117
  }
975
1118
  }
976
1119
  });
1120
+ commander.program.command("deep-clean").description("clean all node_modules, dist, .next, .turbo and related caches in monorepo").option("--yes", "actually delete matched directories (default only preview)", false).option("-v, --verbose", "show detailed logs", false).action(async (options) => {
1121
+ try {
1122
+ const config = loadConfig(cwd, {}, options.verbose);
1123
+ if (options.verbose) {
1124
+ config.output.verbose = true;
1125
+ }
1126
+ validateConfig(config);
1127
+ const exitCode = await deepClean(config, options.yes, cwd);
1128
+ if (typeof process !== "undefined") {
1129
+ process.exit(exitCode);
1130
+ }
1131
+ } catch (error) {
1132
+ console.error("Error:", error);
1133
+ if (typeof process !== "undefined") {
1134
+ process.exit(1);
1135
+ }
1136
+ }
1137
+ });
1138
+ commander.program.command("easy-changeset").description("copy .changeset/d8-template.mdx to .changeset/d8-template.md if both exist").action(async () => {
1139
+ try {
1140
+ const exitCode = await easyChangeset(cwd);
1141
+ if (typeof process !== "undefined") {
1142
+ process.exit(exitCode);
1143
+ }
1144
+ } catch (error) {
1145
+ console.error("Error:", error);
1146
+ if (typeof process !== "undefined") {
1147
+ process.exit(1);
1148
+ }
1149
+ }
1150
+ });
977
1151
  if (typeof process !== "undefined") {
978
1152
  commander.program.parse(process.argv);
979
1153
  }