WXL
9 天以前 2895b4ea66e09cb355aeb4e030ca0de297bf8ce3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import fs from 'fs';
import { I18NItem, I18NLanguage, I18NReport } from '../types';
 
export enum VueI18NExtractReportTypes {
  None = 0,
  Missing = 1 << 0,
  Unused = 1 << 1,
  Dynamic = 1 << 2,
  All = ~(~0 << 3)
};
 
const mightBeUsedDynamically = function (languageItem: I18NItem, dynamicKeys: I18NItem[]): boolean {
  return dynamicKeys.some(dynamicKey => languageItem.path.includes(dynamicKey.path));
}
 
export function extractI18NReport (parsedVueFiles: I18NItem[], parsedLanguageFiles: I18NLanguage, reportType: VueI18NExtractReportTypes = VueI18NExtractReportTypes.Missing + VueI18NExtractReportTypes.Unused): I18NReport {
  const missingKeys: I18NItem[] = [];
  const unusedKeys: I18NItem[] = [];
  const dynamicKeys: I18NItem[] = [];
  const dynamicReportEnabled = reportType & VueI18NExtractReportTypes.Dynamic;
 
  Object.keys(parsedLanguageFiles).forEach(language => {
    let languageItems = parsedLanguageFiles[language];
 
    parsedVueFiles.forEach(vueItem => {
      const usedByVueItem = function (languageItem: I18NItem): boolean {
        return languageItem.path === vueItem.path || languageItem.path.startsWith(vueItem.path + '.');
      }
 
      if (dynamicReportEnabled && (vueItem.path.includes('${') || vueItem.path.endsWith('.'))) {
        dynamicKeys.push(({ ...vueItem, language }))
        return
      }
 
      if (!parsedLanguageFiles[language].some(usedByVueItem)) {
        missingKeys.push(({ ...vueItem, language }));
      }
 
      languageItems = languageItems.filter(languageItem => dynamicReportEnabled ?
        !mightBeUsedDynamically(languageItem, dynamicKeys) && !usedByVueItem(languageItem) :
        !usedByVueItem(languageItem));
    });
 
    unusedKeys.push(...languageItems.map((item) => ({ ...item, language })));
  });
 
  let extracts = {};
  if (reportType & VueI18NExtractReportTypes.Missing) {
    extracts = Object.assign(extracts, { missingKeys });
  }
  if (reportType & VueI18NExtractReportTypes.Unused) {
    extracts = Object.assign(extracts, { unusedKeys });
  }
  if (dynamicReportEnabled) {
    extracts = Object.assign(extracts, { dynamicKeys });
  }
 
  return extracts;
}
 
export async function writeReportToFile (report: I18NReport, writePath: string): Promise<NodeJS.ErrnoException | void> {
  const reportString = JSON.stringify(report);
  return new Promise((resolve, reject) => {
    fs.writeFile(
      writePath,
      reportString,
      (err) => {
        if (err) {
          reject(err);
          return;
        }
        resolve();
      },
    );
  });
}