• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import fs from 'fs';
17import path from 'path';
18import { createSourceFile, ScriptTarget } from 'typescript';
19import { collectAllFileName, getAllClassDeclaration, dtsFileList, getOhosInterfacesDir } from './common/commonUtils';
20import { getSourceFileAssembly } from './declaration-node/sourceFileElementsAssemply';
21import { generateEntry } from './generate/generateEntry';
22import { generateIndex } from './generate/generateIndex';
23import { generateSourceFileElements } from './generate/generateMockJsFile';
24import { generateSystemIndex } from './generate/generateSystemIndex';
25
26/**
27 * get all api .d.ts file path
28 * @param dir
29 * @returns
30 */
31function getAllDtsFile(dir: string): Array<string> {
32  const arr = fs.readdirSync(dir);
33  if (!dir.toString().includes('node_modules') && !dir.toString().includes(path.join('@internal', 'component'))) {
34    arr.forEach(value => {
35      const fullPath = path.join(dir, value);
36      const stats = fs.statSync(fullPath);
37      if (stats.isDirectory()) {
38        getAllDtsFile(fullPath);
39      } else {
40        dtsFileList.push(fullPath);
41      }
42    });
43  }
44  return dtsFileList;
45}
46
47/**
48 * delete the old mock file befor generate new mock file
49 * @param outDir
50 */
51function deleteOldMockJsFile(outDir: string): void {
52  const arr = fs.readdirSync(outDir);
53  arr.forEach(value => {
54    const currPath = path.join(outDir, value);
55    const stas = fs.statSync(currPath);
56    if (stas.isDirectory()) {
57      deleteOldMockJsFile(currPath);
58    } else {
59      fs.unlink(currPath, function (err) {
60        if (err) {
61          console.log(err);
62        }
63      });
64    }
65  });
66}
67
68/**
69 * mkdir
70 * @param dirname
71 * @returns
72 */
73function mkdirsSync(dirname): boolean {
74  if (fs.existsSync(dirname)) {
75    return true;
76  } else {
77    if (mkdirsSync(path.dirname(dirname))) {
78      fs.mkdirSync(dirname);
79      return true;
80    }
81  }
82  return false;
83}
84
85/**
86 * hgandle all ets file mock logic
87 * @param outMockJsFileDir automated mock file output path
88 * @returns
89 */
90function etsFileToMock(outMockJsFileDir: string): void {
91  let index = 0;
92  while (index < dtsFileList.length) {
93    const value = dtsFileList[index];
94    index++;
95
96    if (!value.endsWith('.d.ts') && !value.endsWith('.d.ets')) {
97      continue;
98    }
99
100    const code = fs.readFileSync(value);
101    const sourceFile = createSourceFile(value, code.toString(), ScriptTarget.Latest);
102    let fileName: string;
103    if (value.endsWith('.d.ts')) {
104      fileName = path.basename(value, '.d.ts');
105    } else if (value.endsWith('.d.ets')) {
106      fileName = path.basename(value, '.d.ets');
107    } else {
108      continue;
109    }
110    let outputFileName = '';
111    if (fileName.includes('@')) {
112      outputFileName = fileName.split('@')[1].replace(/\./g, '_');
113    } else {
114      outputFileName = fileName;
115    }
116
117    let tmpOutputMockJsFileDir = outMockJsFileDir;
118    if (!outputFileName.startsWith('system_')) {
119      tmpOutputMockJsFileDir = path.join(outMockJsFileDir, 'napi');
120    }
121
122    if (value.startsWith(getOhosInterfacesDir()) && !apiInputPath.startsWith(getOhosInterfacesDir())) {
123      tmpOutputMockJsFileDir = path.join(tmpOutputMockJsFileDir, '@ohos');
124    }
125
126    let dirName = '';
127    dirName = path.join(tmpOutputMockJsFileDir, path.dirname(value).split(`${path.sep}api`)[1]);
128    if (!fs.existsSync(dirName)) {
129      mkdirsSync(dirName);
130    }
131    const sourceFileEntity = getSourceFileAssembly(sourceFile, fileName);
132    const filePath = path.join(dirName, outputFileName + '.js');
133    fs.writeFileSync(filePath, '');
134    fs.appendFileSync(path.join(filePath), generateSourceFileElements('', sourceFileEntity, sourceFile, outputFileName));
135  }
136}
137
138/**
139 * Project Entry Function
140 * @param apiInputPath interface_sdk-js\api absolute file path
141 * @returns
142 */
143function main(apiInputPath): void {
144  const dtsDir = apiInputPath;
145  const outMockJsFileDir = path.join(__dirname, '../../runtime/main/extend/systemplugin');
146  getAllDtsFile(dtsDir);
147
148  dtsFileList.forEach(value => {
149    collectAllFileName(value);
150    if (value.endsWith('.d.ts') || value.endsWith('.d.ets')) {
151      const code = fs.readFileSync(value);
152      const sourceFile = createSourceFile(value, code.toString(), ScriptTarget.Latest);
153      getAllClassDeclaration(sourceFile);
154    }
155  });
156
157  etsFileToMock(outMockJsFileDir);
158
159  if (!fs.existsSync(path.join(outMockJsFileDir, 'napi'))) {
160    mkdirsSync(path.join(outMockJsFileDir, 'napi'));
161  }
162  fs.writeFileSync(path.join(outMockJsFileDir, 'napi', 'index.js'), generateIndex());
163  fs.writeFileSync(path.join(outMockJsFileDir, 'index.js'), generateSystemIndex());
164  fs.writeFileSync(path.join(outMockJsFileDir, 'entry.js'), generateEntry());
165}
166
167const paramIndex = 2;
168const apiInputPath = process.argv[paramIndex];
169main(apiInputPath);
170