|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/ts.ts
- var _promises = require('fs/promises');
- var _fs = require('fs');
- var _path = require('path'); var _path2 = _interopRequireDefault(_path);
-
-
-
-
-
-
- var _common = require('@vue-macros/common');
- var _types = require('@babel/types');
- var tsFileCache = {};
- async function getTSFile(filePath) {
- if (tsFileCache[filePath])
- return tsFileCache[filePath];
- const content = await _promises.readFile.call(void 0, filePath, "utf-8");
- const { code, lang } = _common.getFileCodeAndLang.call(void 0, content, filePath);
- const program = _common.babelParse.call(void 0, code, lang);
- return tsFileCache[filePath] = {
- filePath,
- content,
- ast: program.body
- };
- }
- function isTSDeclaration(node) {
- return _types.isDeclaration.call(void 0, node) && node.type.startsWith("TS");
- }
- function mergeTSProperties(a, b) {
- return {
- callSignatures: [...a.callSignatures, ...b.callSignatures],
- constructSignatures: [...a.constructSignatures, ...b.constructSignatures],
- methods: { ...a.methods, ...b.methods },
- properties: { ...a.properties, ...b.properties }
- };
- }
- async function resolveTSProperties({
- type,
- scope
- }) {
- switch (type.type) {
- case "TSInterfaceBody":
- return resolveTypeElements(scope, type.body);
- case "TSTypeLiteral":
- return resolveTypeElements(scope, type.members);
- case "TSInterfaceDeclaration": {
- let properties = resolveTypeElements(scope, type.body.body);
- if (type.extends) {
- const resolvedExtends = (await Promise.all(
- type.extends.map(
- (node) => node.expression.type === "Identifier" ? resolveTSReferencedType({
- scope,
- type: node.expression
- }) : void 0
- )
- )).filter(filterValidExtends);
- if (resolvedExtends.length > 0) {
- const ext = (await Promise.all(
- resolvedExtends.map((resolved) => resolveTSProperties(resolved))
- )).reduceRight((acc, curr) => mergeTSProperties(acc, curr));
- properties = mergeTSProperties(ext, properties);
- }
- }
- return properties;
- }
- case "TSIntersectionType": {
- let properties = {
- callSignatures: [],
- constructSignatures: [],
- methods: {},
- properties: {}
- };
- for (const subType of type.types) {
- const resolved = await resolveTSReferencedType({
- scope,
- type: subType
- });
- if (!filterValidExtends(resolved))
- continue;
- properties = mergeTSProperties(
- properties,
- await resolveTSProperties(resolved)
- );
- }
- return properties;
- }
- case "TSMappedType": {
- const properties = {
- callSignatures: [],
- constructSignatures: [],
- methods: {},
- properties: {}
- };
- if (!type.typeParameter.constraint)
- return properties;
- const constraint = await resolveTSReferencedType({
- type: type.typeParameter.constraint,
- scope
- });
- if (!(constraint == null ? void 0 : constraint.type))
- return properties;
- const types = constraint.type.type === "TSUnionType" ? constraint.type.types : [constraint.type];
- for (const subType of types) {
- if (subType.type !== "TSLiteralType")
- continue;
- const literal = subType.literal;
- if (!_common.isStaticExpression.call(void 0, literal))
- continue;
- const key = _common.resolveLiteral.call(void 0,
- literal
- );
- if (!key)
- continue;
- properties.properties[String(key)] = {
- value: type.typeAnnotation ? { scope, type: type.typeAnnotation } : null,
- optional: type.optional === "+" || type.optional === true,
- signature: { type, scope }
- };
- }
- return properties;
- }
- case "TSFunctionType": {
- const properties = {
- callSignatures: [{ type, scope }],
- constructSignatures: [],
- methods: {},
- properties: {}
- };
- return properties;
- }
- default:
- throw new Error(`unknown node: ${type == null ? void 0 : type.type}`);
- }
- function filterValidExtends(node) {
- return !isTSExports(node) && [
- "TSInterfaceDeclaration",
- "TSTypeLiteral",
- "TSIntersectionType"
- ].includes(node == null ? void 0 : node.type.type);
- }
- }
- function resolveTypeElements(scope, elements) {
- var _a;
- const properties = {
- callSignatures: [],
- constructSignatures: [],
- methods: {},
- properties: {}
- };
- const tryGetKey = (element) => {
- try {
- return _common.resolveObjectKey.call(void 0, element.key, element.computed, false);
- } catch (e) {
- }
- };
- for (const element of elements) {
- switch (element.type) {
- case "TSCallSignatureDeclaration":
- properties.callSignatures.push({ scope, type: element });
- break;
- case "TSConstructSignatureDeclaration":
- properties.constructSignatures.push({ scope, type: element });
- break;
- case "TSMethodSignature": {
- const key = tryGetKey(element);
- if (!key)
- continue;
- if (properties.properties[key])
- continue;
- if (!properties.methods[key])
- properties.methods[key] = [];
- if (element.typeAnnotation) {
- properties.methods[key].push({ scope, type: element });
- }
- break;
- }
- case "TSPropertySignature": {
- const key = tryGetKey(element);
- if (!key)
- continue;
- if (!properties.properties[key] && !properties.methods[key]) {
- const type = (_a = element.typeAnnotation) == null ? void 0 : _a.typeAnnotation;
- properties.properties[key] = {
- value: type ? { type, scope } : null,
- optional: !!element.optional,
- signature: { type: element, scope }
- };
- }
- break;
- }
- case "TSIndexSignature":
- break;
- }
- }
- return properties;
- }
- async function resolveTSReferencedType(ref, stacks = []) {
- var _a;
- const { scope, type } = ref;
- if (stacks.some((stack) => stack.scope === scope && stack.type === type)) {
- return ref;
- }
- stacks.push(ref);
- if (type.type === "TSTypeAliasDeclaration" || type.type === "TSParenthesizedType") {
- return resolveTSReferencedType({ scope, type: type.typeAnnotation }, stacks);
- }
- let refNames;
- if (type.type === "Identifier") {
- refNames = [type.name];
- } else if (type.type === "TSTypeReference") {
- if (type.typeName.type === "Identifier") {
- refNames = [type.typeName.name];
- } else {
- refNames = resolveTSEntityName(type.typeName).map((id) => id.name);
- }
- } else if (type.type === "TSModuleDeclaration" && type.body.type === "TSModuleBlock") {
- return resolveTSExports({ type: type.body, scope });
- } else {
- return { scope, type };
- }
- const [refName, ...restNames] = refNames;
- const { body, file } = resolveTSScope(scope);
- for (let node of body) {
- if (node.type === "ImportDeclaration") {
- const specifier = node.specifiers.find(
- (specifier2) => specifier2.type === "ImportSpecifier" && specifier2.imported.type === "Identifier" && specifier2.imported.name === refName || specifier2.type === "ImportNamespaceSpecifier" && specifier2.local.name === refName
- );
- if (!specifier)
- continue;
- const resolved = await resolveTSFileId(node.source.value, file.filePath);
- if (!resolved)
- continue;
- const exports = await resolveTSExports(await getTSFile(resolved));
- let type2 = exports;
- for (const name of specifier.type === "ImportSpecifier" ? refNames : restNames) {
- type2 = type2 == null ? void 0 : type2[name];
- }
- return type2;
- }
- if (node.type === "ExportNamedDeclaration" && node.declaration)
- node = node.declaration;
- if (isTSDeclaration(node)) {
- if (((_a = node.id) == null ? void 0 : _a.type) !== "Identifier")
- continue;
- if (node.id.name !== refName)
- continue;
- const resolved = await resolveTSReferencedType(
- { scope, type: node },
- stacks
- );
- if (!resolved)
- return;
- if (restNames.length === 0) {
- return resolved;
- } else {
- let exports = resolved;
- for (const name of restNames) {
- exports = exports[name];
- }
- return exports;
- }
- }
- }
- if (type.type === "TSTypeReference")
- return { scope, type };
- }
- function resolveTSScope(scope) {
- const isFile = "ast" in scope;
- const file = isFile ? scope : resolveTSScope(scope.scope).file;
- const body = isFile ? scope.ast : scope.type.body;
- return {
- isFile,
- file,
- body
- };
- }
- function resolveTSEntityName(node) {
- if (node.type === "Identifier")
- return [node];
- else {
- return [...resolveTSEntityName(node.left), node.right];
- }
- }
- var exportsSymbol = Symbol("exports");
- var tsFileExportsCache = /* @__PURE__ */ new Map();
- function isTSExports(val) {
- return !!val && typeof val === "object" && exportsSymbol in val;
- }
- async function resolveTSExports(scope) {
- var _a;
- if (tsFileExportsCache.has(scope))
- return tsFileExportsCache.get(scope);
- const exports = {
- [exportsSymbol]: true
- };
- tsFileExportsCache.set(scope, exports);
- const { body, file } = resolveTSScope(scope);
- for (const stmt of body) {
- if (stmt.type === "ExportDefaultDeclaration") {
- } else if (stmt.type === "ExportAllDeclaration") {
- const resolved = await resolveTSFileId(stmt.source.value, file.filePath);
- if (!resolved)
- continue;
- const sourceExports = await resolveTSExports(await getTSFile(resolved));
- Object.assign(exports, sourceExports);
- } else if (stmt.type === "ExportNamedDeclaration") {
- let sourceExports;
- if (stmt.source) {
- const resolved = await resolveTSFileId(stmt.source.value, file.filePath);
- if (!resolved)
- continue;
- sourceExports = await resolveTSExports(await getTSFile(resolved));
- }
- for (const specifier of stmt.specifiers) {
- if (specifier.type === "ExportDefaultSpecifier") {
- continue;
- }
- if (specifier.type === "ExportNamespaceSpecifier") {
- exports[specifier.exported.name] = sourceExports;
- } else {
- const exportedName = specifier.exported.type === "Identifier" ? specifier.exported.name : specifier.exported.value;
- if (stmt.source) {
- exports[exportedName] = sourceExports[specifier.local.name];
- } else {
- exports[exportedName] = await resolveTSReferencedType({
- scope,
- type: specifier.local
- });
- }
- }
- }
- if (isTSDeclaration(stmt.declaration)) {
- const decl = stmt.declaration;
- if (((_a = decl.id) == null ? void 0 : _a.type) === "Identifier") {
- const exportedName = decl.id.name;
- exports[exportedName] = await resolveTSReferencedType({
- scope,
- type: decl
- });
- }
- }
- }
- }
- return exports;
- }
- var resolveTSFileIdImpl = resolveTSFileIdNode;
- function resolveTSFileId(id, importer) {
- return resolveTSFileIdImpl(id, importer);
- }
- function resolveTSFileIdNode(id, importer) {
- function tryResolve(id2, importer2) {
- const filePath = _path2.default.resolve(importer2, "..", id2);
- if (!_fs.existsSync.call(void 0, filePath))
- return;
- return filePath;
- }
- return tryResolve(id, importer) || tryResolve(`${id}.ts`, importer) || tryResolve(`${id}.d.ts`, importer) || tryResolve(`${id}/index`, importer) || tryResolve(`${id}/index.ts`, importer) || tryResolve(`${id}/index.d.ts`, importer);
- }
- function setResolveTSFileIdImpl(impl) {
- resolveTSFileIdImpl = impl;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- exports.tsFileCache = tsFileCache; exports.getTSFile = getTSFile; exports.isTSDeclaration = isTSDeclaration; exports.mergeTSProperties = mergeTSProperties; exports.resolveTSProperties = resolveTSProperties; exports.resolveTypeElements = resolveTypeElements; exports.resolveTSReferencedType = resolveTSReferencedType; exports.resolveTSScope = resolveTSScope; exports.resolveTSEntityName = resolveTSEntityName; exports.exportsSymbol = exportsSymbol; exports.tsFileExportsCache = tsFileExportsCache; exports.isTSExports = isTSExports; exports.resolveTSExports = resolveTSExports; exports.resolveTSFileId = resolveTSFileId; exports.resolveTSFileIdNode = resolveTSFileIdNode; exports.setResolveTSFileIdImpl = setResolveTSFileIdImpl;
|