@hadss/hmrouter-plugin 1.0.0-rc.9 → 1.1.0-beta.0

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
@@ -1,3 +1,7 @@
1
+ # HMRouterPlugin
2
+
3
+ HMRouter路由框架编译插件,需要配合[HMRouter](https://ohpm.openharmony.cn/#/cn/detail/@hadss%2Fhmrouter)使用
4
+
1
5
  ## 编译插件配置
2
6
 
3
7
  1.修改项目的`hvigor/hvigor-config.json`文件,加入路由编译插件
@@ -5,9 +9,9 @@
5
9
  ```json5
6
10
  {
7
11
  "dependencies": {
8
- "@hadss/hmrouter-plugin": "^1.0.0-rc.9" // 使用npm仓版本号
12
+ "@hadss/hmrouter-plugin": "^1.0.0-rc.10" // 使用npm仓版本号
9
13
  },
10
- // ...其他配置
14
+ // ...其余配置
11
15
  }
12
16
  ```
13
17
 
@@ -63,9 +67,11 @@ export default {
63
67
  `hmrouter_config.json`文件用于配置该插件在编译期的行为
64
68
 
65
69
  > 配置文件读取规则为 模块 > 工程 > 默认
70
+ >
66
71
  > 优先使用本模块内的配置,如果没有配置,则找模块目录的上级目录(最多找三层目录,找到则停止),若找不到则使用默认配置
67
72
 
68
73
  > 1.0.0-rc.6 版本开始,支持混淆配置`autoObfuscation`
74
+ >
69
75
  > 1.0.0-rc.9 版本开始,支持自定义模版配置`customPageTemplate`
70
76
 
71
77
  | 配置项 | 类型 | 是否必填 | 说明 |
@@ -229,12 +235,11 @@ export struct <%= componentName %>Generated {
229
235
  | static interactiveFinish | navigationId: string, ndId: string, event: GestureEvent | void | 手势转场动画更新 |
230
236
  | static interactiveProgress | navigationId: string, ndId: string, event: GestureEvent | void | 手势转场动画结束 |
231
237
 
232
- ## 依赖版本
238
+ ## 依赖系统版本
233
239
 
234
240
  最低版本
235
241
 
236
242
  ```text
237
- HarmonyOS NEXT Developer Beta5版本及以上
238
243
  DevEco Studio 5.0.3.700及以上
239
244
  hvigor 5.5.1及以上
240
245
  ```
@@ -242,7 +247,6 @@ hvigor 5.5.1及以上
242
247
  **推荐使用**
243
248
 
244
249
  ```text
245
- HarmonyOS NEXT Beta1版本及以上
246
250
  DevEco Studio 5.0.3.800及以上
247
251
  hvigor 5.7.3及以上
248
252
  ```
@@ -253,6 +257,6 @@ hvigor 5.7.3及以上
253
257
  > [HMRouterPlugin] Your DevEco Studio version less than 5.0.3.800, may cause remote hsp dependencies get failed
254
258
  > ```
255
259
 
256
- ## HMRouter 使用
260
+ ## HMRouter路由框架使用
257
261
 
258
262
  详见[@hadss/hmrouter](https://ohpm.openharmony.cn/#/cn/detail/@hadss%2Fhmrouter)
@@ -3,6 +3,29 @@ import { HMRouterPluginConfig } from './HMRouterPluginConfig';
3
3
  export declare class AnalyzerController {
4
4
  private analyzeResult;
5
5
  analyzeFile(sourceFilePath: string, config: HMRouterPluginConfig): void;
6
- parsePageUrl(): void;
6
+ parseConstants(): void;
7
+ private parsePropertyValue;
7
8
  getAnalyzeResultSet(): Set<AnalyzerResultLike>;
9
+ clearAnalyzeResultSet(): void;
10
+ }
11
+ export declare class AnalyzerService {
12
+ private readonly sourceFilePath;
13
+ private sourceFile;
14
+ private config;
15
+ private analyzerResultSet;
16
+ private importMap;
17
+ constructor(sourceFilePath: string, config: HMRouterPluginConfig);
18
+ start(): void;
19
+ getResult(): Set<AnalyzerResultLike>;
20
+ private analyzeImport;
21
+ private analyzeRouter;
22
+ private parseFileByLineOrder;
23
+ private analyzeComponent;
24
+ private addToResultSet;
25
+ private parseDecorator;
26
+ private parseDecoratorArguments;
27
+ private parseIdentifierPropertyValue;
28
+ private parsePrimitiveValue;
29
+ private getVariableFilePath;
30
+ private getOtherModuleVariableFilePath;
8
31
  }
@@ -3,12 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AnalyzerController = void 0;
6
+ exports.AnalyzerService = exports.AnalyzerController = void 0;
7
7
  const ts_morph_1 = require("ts-morph");
8
8
  const Logger_1 = require("./common/Logger");
9
- const CommonConstants_1 = __importDefault(require("./constants/CommonConstants"));
10
9
  const TsAstUtil_1 = require("./utils/TsAstUtil");
10
+ const CommonConstants_1 = __importDefault(require("./constants/CommonConstants"));
11
11
  const FileUtil_1 = __importDefault(require("./utils/FileUtil"));
12
+ const ConfigConstants_1 = __importDefault(require("./constants/ConfigConstants"));
13
+ const PluginStore_1 = __importDefault(require("./store/PluginStore"));
12
14
  class AnalyzerController {
13
15
  constructor() {
14
16
  this.analyzeResult = new Set();
@@ -20,31 +22,55 @@ class AnalyzerController {
20
22
  item.pageSourceFile = sourceFilePath;
21
23
  this.analyzeResult.add(item);
22
24
  });
23
- this.parsePageUrl();
25
+ this.parseConstants();
24
26
  }
25
- parsePageUrl() {
27
+ parseConstants() {
26
28
  this.analyzeResult.forEach((item) => {
27
- if (item.annotation !== 'HMRouter') {
28
- return;
29
+ Object.getOwnPropertyNames(item).forEach((key) => {
30
+ let propertyValue = Reflect.get(item, key);
31
+ propertyValue = this.parsePropertyValue(propertyValue);
32
+ if (propertyValue === '') {
33
+ Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING);
34
+ throw new Error('constants value cannot be an empty string, filePath:' + item.pageSourceFile);
35
+ }
36
+ Reflect.set(item, key, propertyValue);
37
+ });
38
+ });
39
+ }
40
+ parsePropertyValue(propertyValue) {
41
+ if (propertyValue.type === 'constant') {
42
+ try {
43
+ return TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.TsAstUtil.getSourceFile(propertyValue.variableFilePath), propertyValue.variableName);
29
44
  }
30
- let pageUrl = item.pageUrl;
31
- if (pageUrl.type === 'constant') {
32
- pageUrl =
33
- TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.project.addSourceFileAtPath(pageUrl.variableFilePath), pageUrl.variableName);
45
+ catch (error) {
46
+ Logger_1.Logger.error(`Failed to parse constant ${propertyValue.variableName}: ${error.message}`);
47
+ throw new Error(`Failed to parse constant ${propertyValue.variableName}: ${error.message}`);
34
48
  }
35
- else if (pageUrl.type === 'object') {
36
- pageUrl = TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.project.addSourceFileAtPath(pageUrl.variableFilePath), pageUrl.variableName, pageUrl.propertyName);
49
+ }
50
+ else if (propertyValue.type === 'object') {
51
+ try {
52
+ return TsAstUtil_1.TsAstUtil.parseConstantValue(TsAstUtil_1.TsAstUtil.getSourceFile(propertyValue.variableFilePath), propertyValue.variableName, propertyValue.propertyName);
37
53
  }
38
- if (pageUrl === '') {
39
- Logger_1.Logger.error(Logger_1.PluginError.ERR_NOT_EMPTY_STRING);
40
- throw new Error('constant value cannot be an empty string');
54
+ catch (error) {
55
+ Logger_1.Logger.error(`Failed to parse object property ${propertyValue.variableName}.${propertyValue.propertyName}: ${error.message}`);
56
+ throw new Error(`Failed to parse object property ${propertyValue.variableName}.${propertyValue.propertyName}: ${error.message}`);
41
57
  }
42
- item.pageUrl = pageUrl;
43
- });
58
+ }
59
+ else if (propertyValue.type === 'array') {
60
+ return propertyValue.value.map((item) => {
61
+ return this.parsePropertyValue(item);
62
+ });
63
+ }
64
+ else {
65
+ return propertyValue;
66
+ }
44
67
  }
45
68
  getAnalyzeResultSet() {
46
69
  return this.analyzeResult;
47
70
  }
71
+ clearAnalyzeResultSet() {
72
+ this.analyzeResult.clear();
73
+ }
48
74
  }
49
75
  exports.AnalyzerController = AnalyzerController;
50
76
  class AnalyzerService {
@@ -75,9 +101,9 @@ class AnalyzerService {
75
101
  return this.analyzerResultSet;
76
102
  }
77
103
  analyzeImport() {
78
- this.sourceFile.getImportDeclarations().forEach(importDeclaration => {
104
+ this.sourceFile.getImportDeclarations().forEach((importDeclaration) => {
79
105
  const moduleSpecifier = importDeclaration.getModuleSpecifierValue();
80
- const namedImports = importDeclaration.getNamedImports().map(namedImport => namedImport.getName());
106
+ const namedImports = importDeclaration.getNamedImports().map((namedImport) => namedImport.getName());
81
107
  const defaultImport = importDeclaration.getDefaultImport()?.getText();
82
108
  const namespaceImport = importDeclaration.getNamespaceImport()?.getText();
83
109
  const importNames = [];
@@ -91,20 +117,23 @@ class AnalyzerService {
91
117
  importNames.push(namespaceImport);
92
118
  }
93
119
  if (importNames.length > 0) {
94
- let variableFilePath = FileUtil_1.default.pathResolve(this.config.modulePath, moduleSpecifier);
95
- importNames.forEach((item) => {
96
- if (FileUtil_1.default.exist(variableFilePath)) {
97
- TsAstUtil_1.importVariableCache.set(variableFilePath + CommonConstants_1.default.VARIABLE_SEPARATOR + item, '');
98
- }
99
- });
100
- this.importMap.set(moduleSpecifier, importNames);
120
+ if (this.importMap.has(moduleSpecifier)) {
121
+ const existingImports = this.importMap.get(moduleSpecifier);
122
+ this.importMap.set(moduleSpecifier, [...new Set([...existingImports, ...importNames])]);
123
+ }
124
+ else {
125
+ this.importMap.set(moduleSpecifier, importNames);
126
+ }
101
127
  }
102
128
  });
103
129
  }
104
130
  analyzeRouter() {
105
- let viewNameArr = this.sourceFile.getChildrenOfKind(ts_morph_1.SyntaxKind.ExpressionStatement).map((node) => {
131
+ let viewNameArr = this.sourceFile
132
+ .getChildrenOfKind(ts_morph_1.SyntaxKind.ExpressionStatement)
133
+ .map((node) => {
106
134
  return node.getText();
107
- }).filter((text) => {
135
+ })
136
+ .filter((text) => {
108
137
  return text != 'struct';
109
138
  });
110
139
  this.sourceFile.getChildrenOfKind(ts_morph_1.SyntaxKind.MissingDeclaration).forEach((node, index) => {
@@ -112,23 +141,42 @@ class AnalyzerService {
112
141
  this.addToResultSet(decorator, viewNameArr[index]);
113
142
  });
114
143
  });
144
+ this.sourceFile.getExportAssignments().forEach((exportAssignment, index) => {
145
+ exportAssignment.getDescendantsOfKind(ts_morph_1.SyntaxKind.Decorator).forEach((decorator) => {
146
+ let result = this.addToResultSet(decorator, viewNameArr[index]);
147
+ result.isDefaultExport = true;
148
+ });
149
+ });
115
150
  }
116
151
  parseFileByLineOrder() {
117
152
  const statements = this.sourceFile.getStatements();
118
153
  const sortedStatements = statements.sort((a, b) => a.getStart() - b.getStart());
119
154
  let HMRouterExists = false;
120
- sortedStatements.forEach(statement => {
155
+ let useNavDst = false;
156
+ sortedStatements.forEach((statement) => {
121
157
  if (statement.getKind() === ts_morph_1.SyntaxKind.MissingDeclaration && statement.getText().includes('HMRouter')) {
122
158
  HMRouterExists = true;
159
+ useNavDst = false;
160
+ const text = statement.getText();
161
+ if (/(useNavDst\s*:\s*true)/.test(text)) {
162
+ useNavDst = true;
163
+ Logger_1.Logger.info('Found HMRouter with useNavDst=true, skipping NavDestination check');
164
+ }
123
165
  }
124
166
  if (statement.getKind() === ts_morph_1.SyntaxKind.Block && HMRouterExists) {
125
167
  HMRouterExists = false;
126
- statement.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier).forEach((node) => {
127
- if (node.getText() === 'NavDestination') {
128
- Logger_1.Logger.error(Logger_1.PluginError.ERR_WRONG_DECORATION);
129
- throw new Error('NavDestination is not allowed in HMRouter, filePath:' + this.sourceFilePath);
130
- }
131
- });
168
+ if (useNavDst) {
169
+ return;
170
+ }
171
+ let reg = new RegExp(/NavDestination\s*\(\s*\)/);
172
+ let text = statement.getText();
173
+ const cleanedCodeBlock = text
174
+ .replace(/(["'`]).*?\1/g, '')
175
+ .replace(/\/\/.*|\/\*[\s\S]*?\*\//g, '');
176
+ if (reg.test(cleanedCodeBlock)) {
177
+ Logger_1.Logger.error(Logger_1.PluginError.ERR_WRONG_DECORATION);
178
+ throw new Error('NavDestination is not allowed in HMRouter, filePath:' + this.sourceFilePath);
179
+ }
132
180
  }
133
181
  });
134
182
  }
@@ -167,45 +215,57 @@ class AnalyzerService {
167
215
  }
168
216
  parseDecoratorArguments(decorator) {
169
217
  let argResult = {};
170
- decorator.getArguments().map(arg => {
218
+ decorator.getArguments().map((arg) => {
171
219
  const objLiteral = arg.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
172
220
  if (objLiteral) {
173
221
  objLiteral.getProperties().forEach((prop) => {
174
222
  let propertyName = prop.getName();
175
- let propertyValue = propertyName === CommonConstants_1.default.PAGE_URL ?
176
- this.parsePageUrlValue(prop.getInitializer()) :
177
- this.parsePropertyValue(prop.getInitializer());
223
+ let propertyValue = this.parseIdentifierPropertyValue(prop.getInitializer());
178
224
  Reflect.set(argResult, propertyName, propertyValue);
179
225
  });
180
226
  }
181
227
  });
182
228
  return argResult;
183
229
  }
184
- parsePageUrlValue(value) {
230
+ parseIdentifierPropertyValue(value) {
185
231
  switch (value.getKind()) {
186
232
  case ts_morph_1.SyntaxKind.Identifier:
233
+ if (value.getText() === 'undefined') {
234
+ throw new Error(`Invalid property value, in ${this.sourceFilePath}`);
235
+ }
187
236
  return {
188
237
  type: 'constant',
189
238
  variableName: value.getText(),
190
- variableFilePath: this.getVariableFilePath(value.getText())
239
+ variableFilePath: this.getVariableFilePath(value.getText()),
191
240
  };
192
241
  case ts_morph_1.SyntaxKind.PropertyAccessExpression:
193
242
  return {
194
243
  type: 'object',
195
244
  variableName: value.getExpression().getText(),
196
245
  propertyName: value?.getName(),
197
- variableFilePath: this.getVariableFilePath(value?.getExpression().getText())
246
+ variableFilePath: this.getVariableFilePath(value?.getExpression().getText()),
247
+ };
248
+ case ts_morph_1.SyntaxKind.ArrayLiteralExpression:
249
+ return {
250
+ type: 'array',
251
+ value: value
252
+ .asKind(ts_morph_1.SyntaxKind.ArrayLiteralExpression)
253
+ ?.getElements()
254
+ .map((item) => this.parseIdentifierPropertyValue(item)),
198
255
  };
199
256
  default:
200
- return this.parsePropertyValue(value);
257
+ return this.parsePrimitiveValue(value);
201
258
  }
202
259
  }
203
- parsePropertyValue(value) {
260
+ parsePrimitiveValue(value) {
204
261
  let propertyValue;
205
262
  switch (value.getKind()) {
206
263
  case ts_morph_1.SyntaxKind.StringLiteral:
207
264
  propertyValue = value.asKind(ts_morph_1.SyntaxKind.StringLiteral)?.getLiteralValue();
208
265
  break;
266
+ case ts_morph_1.SyntaxKind.NumericLiteral:
267
+ propertyValue = value.asKind(ts_morph_1.SyntaxKind.NumericLiteral)?.getLiteralValue();
268
+ break;
209
269
  case ts_morph_1.SyntaxKind.TrueKeyword:
210
270
  propertyValue = true;
211
271
  break;
@@ -213,13 +273,16 @@ class AnalyzerService {
213
273
  propertyValue = false;
214
274
  break;
215
275
  case ts_morph_1.SyntaxKind.ArrayLiteralExpression:
216
- propertyValue = value.asKind(ts_morph_1.SyntaxKind.ArrayLiteralExpression)?.getElements()
217
- .map(item => item.asKind(ts_morph_1.SyntaxKind.StringLiteral)?.getLiteralValue());
276
+ propertyValue = value
277
+ .asKind(ts_morph_1.SyntaxKind.ArrayLiteralExpression)
278
+ ?.getElements()
279
+ .map((item) => item.asKind(ts_morph_1.SyntaxKind.StringLiteral)?.getLiteralValue());
218
280
  break;
219
281
  }
220
282
  return propertyValue;
221
283
  }
222
284
  getVariableFilePath(variableName) {
285
+ let filePath = '';
223
286
  let classesNames = this.sourceFile.getClasses().map((classes) => {
224
287
  return classes.getName();
225
288
  });
@@ -229,16 +292,52 @@ class AnalyzerService {
229
292
  if (classesNames.includes(variableName) || variableNames.includes(variableName)) {
230
293
  return this.sourceFilePath;
231
294
  }
232
- else {
233
- let filePath = '';
234
- this.importMap.forEach((value, key) => {
235
- if (value.includes(variableName)) {
236
- filePath =
237
- FileUtil_1.default.pathResolve(this.sourceFilePath.split(CommonConstants_1.default.FILE_SEPARATOR).slice(0, -1)
238
- .join(CommonConstants_1.default.FILE_SEPARATOR), key) + CommonConstants_1.default.VIEW_NAME_SUFFIX;
295
+ for (const [importPath, importNames] of this.importMap.entries()) {
296
+ if (importNames.includes(variableName)) {
297
+ try {
298
+ let currentDir = FileUtil_1.default.pathResolve(this.sourceFilePath, CommonConstants_1.default.PARENT_DELIMITER);
299
+ let tempFilePath = FileUtil_1.default.pathResolve(currentDir, importPath + CommonConstants_1.default.ETS_SUFFIX);
300
+ if (FileUtil_1.default.exist(tempFilePath)) {
301
+ filePath = tempFilePath;
302
+ }
303
+ else {
304
+ try {
305
+ filePath = this.getOtherModuleVariableFilePath(importPath, variableName);
306
+ }
307
+ catch (error) {
308
+ Logger_1.Logger.warn(`Cannot find variable ${variableName} in module ${importPath}: ${error.message}`);
309
+ }
310
+ }
239
311
  }
240
- });
241
- return filePath;
312
+ catch (error) {
313
+ Logger_1.Logger.warn(`Error parsing import path ${importPath}: ${error.message}`);
314
+ }
315
+ }
316
+ }
317
+ if (!filePath) {
318
+ Logger_1.Logger.warn(`Cannot find file path for variable ${variableName}`);
319
+ }
320
+ return filePath;
321
+ }
322
+ getOtherModuleVariableFilePath(moduleName, variableName) {
323
+ let moduleFilePath = FileUtil_1.default.pathResolve(this.config.modulePath, CommonConstants_1.default.OH_MODULE_PATH, moduleName, ConfigConstants_1.default.DEFAULT_SCAN_DIR);
324
+ if (!FileUtil_1.default.exist(moduleFilePath)) {
325
+ moduleFilePath = FileUtil_1.default.pathResolve(PluginStore_1.default.getInstance().projectFilePath, CommonConstants_1.default.OH_MODULE_PATH, moduleName, ConfigConstants_1.default.DEFAULT_SCAN_DIR);
326
+ }
327
+ let variableMap;
328
+ if (PluginStore_1.default.getInstance().variableCache.has(moduleName)) {
329
+ variableMap = PluginStore_1.default.getInstance().variableCache.get(moduleName);
330
+ }
331
+ else {
332
+ variableMap = TsAstUtil_1.TsAstUtil.parseCrossModuleVariable(moduleFilePath);
333
+ PluginStore_1.default.getInstance().variableCache.set(moduleName, variableMap);
334
+ }
335
+ for (let [key, value] of variableMap) {
336
+ if (value.includes(variableName)) {
337
+ return key;
338
+ }
242
339
  }
340
+ throw new Error(`Unknown variable ${variableName} in ${moduleName}`);
243
341
  }
244
342
  }
343
+ exports.AnalyzerService = AnalyzerService;
@@ -26,7 +26,7 @@ class HMRouterHvigorPlugin {
26
26
  });
27
27
  Logger_1.Logger.info(`Scanned ${this.scanFiles.length} files`, this.scanFiles);
28
28
  this.scanFiles.forEach((filePath) => {
29
- if (filePath.endsWith(CommonConstants_1.default.VIEW_NAME_SUFFIX)) {
29
+ if (filePath.endsWith(CommonConstants_1.default.ETS_SUFFIX)) {
30
30
  this.analyzerController.analyzeFile(filePath, this.config);
31
31
  }
32
32
  });
@@ -50,15 +50,17 @@ class HMRouterHvigorPlugin {
50
50
  if (item.customData && item.customData.annotation) {
51
51
  delete item.customData.annotation;
52
52
  delete item.customData.pageSourceFile;
53
+ delete item.customData.isDefaultExport;
53
54
  }
54
55
  return item;
55
- }),
56
+ })
56
57
  };
57
58
  const routerMapJsonStr = JSON.stringify(routerMap, null, 2);
58
59
  const routerMapFilePath = this.config.getRouterMapDir();
59
60
  FileUtil_1.default.ensureFileSync(routerMapFilePath);
60
61
  FileUtil_1.default.writeFileSync(routerMapFilePath, routerMapJsonStr);
61
62
  Logger_1.Logger.info(`hm_router_map.json has been generated in ${routerMapFilePath}`);
63
+ this.analyzerController.clearAnalyzeResultSet();
62
64
  }
63
65
  matchedPath(filePath, customPageTemplate, defaultTplFilePath) {
64
66
  for (const template of customPageTemplate) {
@@ -94,17 +96,34 @@ class HMRouterHvigorPlugin {
94
96
  let serviceName = CommonConstants_1.default.SERVICE_PREFIX + analyzeResult.serviceName;
95
97
  this.routerMap.push(new PluginModel_1.RouterInfo(serviceName, pageSourceFile, '', analyzeResult));
96
98
  break;
99
+ case CommonConstants_1.default.SERVICE_PROVIDE_ANNOTATION:
100
+ let className = CommonConstants_1.default.SERVICE_PROVIDE_PREFIX + analyzeResult.serviceName;
101
+ this.routerMap.push(new PluginModel_1.RouterInfo(className, pageSourceFile, '', analyzeResult));
102
+ break;
97
103
  }
98
104
  }
99
105
  generateBuilder(analyzeResult, pageSourceFile, tempFilePath) {
100
106
  let importPath = this.config
101
107
  .getRelativeBuilderPath(pageSourceFile)
102
108
  .replaceAll(CommonConstants_1.default.FILE_SEPARATOR, CommonConstants_1.default.DELIMITER)
103
- .replaceAll(CommonConstants_1.default.VIEW_NAME_SUFFIX, '');
109
+ .replaceAll(CommonConstants_1.default.ETS_SUFFIX, '');
104
110
  let generatorViewName = CommonConstants_1.default.VIEW_NAME_PREFIX +
105
111
  analyzeResult.name +
106
112
  StringUtil_1.StringUtil.stringToHashCode(analyzeResult.pageUrl);
107
- const templateModel = new PluginModel_1.TemplateModel(analyzeResult.pageUrl, importPath, analyzeResult.name, !!analyzeResult.dialog, generatorViewName);
113
+ const templateModel = new PluginModel_1.TemplateModel(analyzeResult.pageUrl, importPath, analyzeResult.name, !!analyzeResult.dialog, generatorViewName, analyzeResult.isDefaultExport);
114
+ if (analyzeResult.useNavDst === true) {
115
+ Logger_1.Logger.info(`Using custom template for ${analyzeResult.name} with useNavDst=true`);
116
+ const customTplPath = FileUtil_1.default.pathResolve(__dirname, CommonConstants_1.default.PARENT_DELIMITER + CommonConstants_1.default.CUSTOM_BUILDER_TEMPLATE);
117
+ if (FileUtil_1.default.exist(customTplPath)) {
118
+ tempFilePath = customTplPath;
119
+ }
120
+ else {
121
+ Logger_1.Logger.info(`Custom template not found at ${customTplPath}, falling back to default template`);
122
+ }
123
+ }
124
+ if (!FileUtil_1.default.exist(tempFilePath)) {
125
+ throw new Error('Invalid template path: ' + tempFilePath);
126
+ }
108
127
  const tpl = FileUtil_1.default.readFileSync(tempFilePath).toString();
109
128
  const templateStr = ejs_1.default.render(tpl, templateModel);
110
129
  const generatorFilePath = this.config.getGeneratedFilePath(templateModel.generatorViewName);
@@ -22,6 +22,7 @@ export declare class HMRouterPluginConfig {
22
22
  getRawFilePath(): string;
23
23
  getDefaultTplFilePath(): string;
24
24
  getObfuscationFilePath(): string;
25
+ getConsumerRulesFilePath(): string;
25
26
  }
26
27
  export interface HMRouterPluginConfigParam {
27
28
  scanDir?: string[];
@@ -21,7 +21,8 @@ class HMRouterPluginConfig {
21
21
  ConfigConstants_1.default.ANIMATOR_ANNOTATION,
22
22
  ConfigConstants_1.default.INTERCEPTOR_ANNOTATION,
23
23
  ConfigConstants_1.default.LIFECYCLE_ANNOTATION,
24
- ConfigConstants_1.default.SERVICE_ANNOTATION
24
+ ConfigConstants_1.default.SERVICE_ANNOTATION,
25
+ ConfigConstants_1.default.SERVICE_PROVIDE_ANNOTATION
25
26
  ];
26
27
  this.defaultPageTemplate =
27
28
  param.defaultPageTemplate ? param.defaultPageTemplate : ConfigConstants_1.default.DEFAULT_BUILD_TPL;
@@ -39,13 +40,13 @@ class HMRouterPluginConfig {
39
40
  return path_1.default.relative(this.builderDir, filePath);
40
41
  }
41
42
  getGeneratedFilePath(generatorViewName) {
42
- return FileUtil_1.default.pathResolve(this.modulePath, this.builderDir, generatorViewName + CommonConstants_1.default.VIEW_NAME_SUFFIX);
43
+ return FileUtil_1.default.pathResolve(this.modulePath, this.builderDir, generatorViewName + CommonConstants_1.default.ETS_SUFFIX);
43
44
  }
44
45
  getBuilderDir() {
45
46
  return FileUtil_1.default.pathResolve(this.modulePath, this.builderDir);
46
47
  }
47
48
  getBuilderFilePath(generatorViewName) {
48
- return path_1.default.join(this.builderDir, generatorViewName + CommonConstants_1.default.VIEW_NAME_SUFFIX);
49
+ return path_1.default.join(this.builderDir, generatorViewName + CommonConstants_1.default.ETS_SUFFIX);
49
50
  }
50
51
  getRouterMapDir() {
51
52
  return FileUtil_1.default.pathResolve(this.modulePath, this.routerMapDir, CommonConstants_1.default.ROUTER_MAP_NAME);
@@ -66,5 +67,8 @@ class HMRouterPluginConfig {
66
67
  getObfuscationFilePath() {
67
68
  return FileUtil_1.default.pathResolve(this.modulePath, CommonConstants_1.default.OBFUSCATION_FILE_NAME);
68
69
  }
70
+ getConsumerRulesFilePath() {
71
+ return FileUtil_1.default.pathResolve(this.modulePath, CommonConstants_1.default.CONSUMER_FILE_NAME);
72
+ }
69
73
  }
70
74
  exports.HMRouterPluginConfig = HMRouterPluginConfig;
@@ -13,6 +13,7 @@ export declare class HMRouterPluginHandle {
13
13
  private isEnableObfuscation;
14
14
  private copyRouterMapToRawFileTask;
15
15
  private writeHspModuleName;
16
+ private getRemoteHspModuleNames;
16
17
  private taskExec;
17
18
  private updateModuleJsonOpt;
18
19
  private updateBuildProfileOpt;