config.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.checkConfigReturnType = void 0;
  4. const tslib_1 = require("tslib");
  5. const fs_1 = tslib_1.__importDefault(require("fs"));
  6. const path_1 = tslib_1.__importDefault(require("path"));
  7. const typescript_1 = tslib_1.__importDefault(require("typescript"));
  8. const config_1 = require("../config");
  9. const utils = tslib_1.__importStar(require("../utils"));
  10. const base_1 = require("./base");
  11. const EXPORT_DEFAULT_FUNCTION = 1;
  12. const EXPORT_DEFAULT = 2;
  13. const EXPORT = 3;
  14. const globalCache = {};
  15. class ConfigGenerator extends base_1.BaseGenerator {
  16. buildParams(config) {
  17. const { baseConfig } = this;
  18. const fileList = config.fileList;
  19. const cache = globalCache[baseConfig.id] = globalCache[baseConfig.id] || {};
  20. if (!fileList.length)
  21. return;
  22. const importList = [];
  23. const declarationList = [];
  24. const moduleList = [];
  25. fileList.forEach(f => {
  26. const abUrl = path_1.default.resolve(config.dir, f);
  27. // read from cache
  28. if (!cache[abUrl] || config.file === abUrl) {
  29. const skipLibCheck = !!baseConfig.tsConfig.skipLibCheck;
  30. const { type, usePowerPartial } = checkConfigReturnType(abUrl);
  31. // skip when not usePowerPartial and skipLibCheck in ts file
  32. // because it maybe cause types error.
  33. if (path_1.default.extname(f) !== '.js' && !usePowerPartial && !skipLibCheck)
  34. return;
  35. const { moduleName: sModuleName } = utils.getModuleObjByPath(f);
  36. const moduleName = `Export${sModuleName}`;
  37. const importContext = utils.getImportStr(config.dtsDir, abUrl, moduleName, type === EXPORT);
  38. let tds = `type ${sModuleName} = `;
  39. if (type === EXPORT_DEFAULT_FUNCTION) {
  40. tds += `ReturnType<typeof ${moduleName}>;`;
  41. }
  42. else if (type === EXPORT_DEFAULT || type === EXPORT) {
  43. tds += `typeof ${moduleName};`;
  44. }
  45. else {
  46. return;
  47. }
  48. // cache the file
  49. cache[abUrl] = {
  50. import: importContext,
  51. declaration: tds,
  52. moduleName: sModuleName,
  53. };
  54. }
  55. const cacheItem = cache[abUrl];
  56. importList.push(cacheItem.import);
  57. declarationList.push(cacheItem.declaration);
  58. moduleList.push(cacheItem.moduleName);
  59. });
  60. return {
  61. importList,
  62. declarationList,
  63. moduleList,
  64. };
  65. }
  66. renderWithParams(config, params) {
  67. const dist = path_1.default.resolve(config.dtsDir, 'index.d.ts');
  68. if (!params)
  69. return { dist };
  70. if (!params.importList.length)
  71. return { dist };
  72. const { baseConfig } = this;
  73. const { importList, declarationList, moduleList } = params;
  74. const newConfigType = `New${config.interface}`;
  75. return {
  76. dist,
  77. content: `import { ${config.interface} } from '${baseConfig.framework}';\n` +
  78. `${importList.join('\n')}\n` +
  79. `${declarationList.join('\n')}\n` +
  80. `type ${newConfigType} = ${moduleList.join(' & ')};\n` +
  81. `declare module '${baseConfig.framework}' {\n` +
  82. ` interface ${config.interface} extends ${newConfigType} { }\n` +
  83. '}',
  84. };
  85. }
  86. }
  87. exports.default = ConfigGenerator;
  88. ConfigGenerator.defaultConfig = {
  89. // only need to parse config.default.ts or config.ts
  90. pattern: 'config(.default|).(ts|js)',
  91. interface: config_1.declMapping.config,
  92. };
  93. // check config return type.
  94. function checkConfigReturnType(f) {
  95. const result = utils.findExportNode(fs_1.default.readFileSync(f, 'utf-8'));
  96. const resp = {
  97. type: undefined,
  98. usePowerPartial: false,
  99. };
  100. if (result.exportDefaultNode) {
  101. const exportDefaultNode = result.exportDefaultNode;
  102. if (typescript_1.default.isFunctionLike(exportDefaultNode)) {
  103. if ((typescript_1.default.isFunctionDeclaration(exportDefaultNode) || typescript_1.default.isArrowFunction(exportDefaultNode)) && exportDefaultNode.body) {
  104. exportDefaultNode.body.forEachChild(tNode => {
  105. if (!resp.usePowerPartial && typescript_1.default.isVariableStatement(tNode)) {
  106. // check wether use PowerPartial<EggAppInfo>
  107. resp.usePowerPartial = !!tNode.declarationList.declarations.find(decl => {
  108. let typeText = decl.type ? decl.type.getText() : undefined;
  109. if (decl.initializer && typescript_1.default.isAsExpression(decl.initializer) && decl.initializer.type) {
  110. typeText = decl.initializer.type.getText();
  111. }
  112. return !!(typeText && typeText.includes('PowerPartial') && typeText.includes('EggAppConfig'));
  113. });
  114. }
  115. });
  116. }
  117. resp.type = EXPORT_DEFAULT_FUNCTION;
  118. }
  119. else {
  120. resp.type = EXPORT_DEFAULT;
  121. }
  122. }
  123. else if (result.exportNodeList.length) {
  124. resp.type = EXPORT;
  125. }
  126. return resp;
  127. }
  128. exports.checkConfigReturnType = checkConfigReturnType;