UNPKG

dets

Version:

A TypeScript declaration file bundler.

1,516 lines (1,496 loc) 276 kB
#!/usr/bin/env node var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/helpers/comments.ts function isUnique(value, index, self) { return self.indexOf(value) === index; } function getAllJsDocs(checker, decls) { const allDocs = decls.map((decl) => getJsDocs(checker, decl)); return { comment: allDocs.map((m) => m.comment).reduce((p, c) => [...p, ...c], []).filter(isUnique), tags: allDocs.map((m) => m.tags).reduce((p, c) => [...p, ...c], []).filter(isUnique) }; } function getJsDocs(checker, node) { if ((0, import_typescript.isMethodDeclaration)(node) || (0, import_typescript.isMethodSignature)(node) || (0, import_typescript.isCallSignatureDeclaration)(node)) { const sign = checker.getSignatureFromDeclaration(node); if (sign) { return { comment: sign.getDocumentationComment(checker), tags: sign.getJsDocTags() }; } } return { comment: node.symbol?.getDocumentationComment(checker), tags: node.symbol?.getJsDocTags() }; } function stringifyJsDocTagText(txt) { if (typeof txt === "string") { if (txt.startsWith("http ://") || txt.startsWith("https ://")) { return txt.replace(" ", ""); } return txt; } else if (Array.isArray(txt)) { return txt.map((s) => s.text).join(""); } return ""; } function stringifyJsDocs(doc) { const tags = (doc.tags || []).filter((m) => !removedTags.includes(m.name)).map((m) => `@${m.name}${newLineTags.includes(m.name) ? "\n" : m.text ? " " : ""}${stringifyJsDocTagText(m.text)}`); const result = doc.comment?.map((m) => m.text) ?? []; if (tags && result.length) { return [result.join(""), ...tags].join("\n"); } else if (tags) { return tags.join("\n"); } else { return result.join(""); } } function shouldDrop(canDrop, tags) { let found = false; if (tags) { for (const tag of tags) { switch (tag.name) { case "ignore": found = canDrop; break; case "dets_ignore": return true; case "dets_preserve": return false; } } } return found; } function getCommentOrDrop(checker, node, canDrop = false) { const doc = getJsDocs(checker, node); if (shouldDrop(canDrop, doc.tags)) { return void 0; } return stringifyJsDocs(doc); } function getComment(checker, node) { const doc = getJsDocs(checker, node); return stringifyJsDocs(doc); } var import_typescript, newLineTags, removedTags; var init_comments = __esm({ "src/helpers/comments.ts"() { import_typescript = require("typescript"); newLineTags = ["example"]; removedTags = ["dets_removeprop", "dets_removeclause", "dets_preserve", "dets_ignore"]; } }); // src/helpers/constants.ts var tslibRoot, tslibPrefix, globalFiles, globalIndicator, modulesRoot, typesRoot; var init_constants = __esm({ "src/helpers/constants.ts"() { tslibRoot = "/node_modules/typescript/lib"; tslibPrefix = "lib."; globalFiles = ["globals.d.ts", "global.d.ts"]; globalIndicator = "__global"; modulesRoot = "/node_modules/"; typesRoot = "/node_modules/@types/"; } }); // src/helpers/identifiers.ts function getLibRefName(libName) { if (libName[0] === "@") { libName = libName.substring(1); } const parts = libName.split(/[\/\-\.]/g); return parts.map((p) => p[0].toUpperCase() + p.substring(1)).join(""); } function getTypeRefName(name) { if ((0, import_typescript2.isIdentifier)(name)) { return name.text; } else { const ns = getTypeRefName(name.left); return `${ns}.${name.right.text}`; } } function getPredicateName(name) { if ((0, import_typescript2.isIdentifier)(name)) { return name.text; } else { return "this"; } } function getExportName(name) { if (!name) { return void 0; } else if ((0, import_typescript2.isIdentifier)(name)) { return name.text; } else if ((0, import_typescript2.isStringLiteral)(name)) { return name.text; } else { return name.text; } } function getParameterElement(element) { const spread = "dotDotDotToken" in element && element.dotDotDotToken ? "..." : ""; const name = (0, import_typescript2.isBindingElement)(element) ? getParameterName(element.name) : getParameterName(element); return `${spread}${name}`; } function getParameterName(name) { if ((0, import_typescript2.isIdentifier)(name)) { return name.text; } else if ((0, import_typescript2.isObjectBindingPattern)(name)) { const content = name.elements.map(getParameterElement).join(", "); return `{ ${content} }`; } else if ((0, import_typescript2.isArrayBindingPattern)(name)) { const content = name.elements.map(getParameterElement).join(", "); return `[${content}]`; } else { return ""; } } function makeModule(fileName, root2) { const relFile = (0, import_path5.relative)(root2, fileName); const ext = (0, import_path5.extname)(fileName); const file = !relFile.startsWith(".") ? `./${relFile}` : relFile; return file.substring(0, file.length - ext.length); } function getLibName(fileName, root2) { if (fileName) { if (fileName.indexOf(typesRoot) !== -1) { const start = fileName.lastIndexOf(typesRoot) + typesRoot.length; const name = fileName.substring(start).split("/").shift(); if (name.indexOf("__") !== -1) { const [scope, lib] = name.split("__"); return `@${scope}/${lib}`; } return name; } else if (fileName.indexOf(modulesRoot) !== -1) { const start = fileName.lastIndexOf(modulesRoot) + modulesRoot.length; const [scope, lib] = fileName.substring(start).split("/"); if (scope.indexOf("@") === 0) { return `${scope}/${lib}`; } return scope; } else { return makeModule(fileName, root2); } } return void 0; } var import_typescript2, import_path5; var init_identifiers = __esm({ "src/helpers/identifiers.ts"() { import_typescript2 = require("typescript"); import_path5 = require("path"); init_constants(); } }); // src/helpers/node.ts function getModule(node) { while (node) { if ((0, import_typescript3.isModuleDeclaration)(node) && (0, import_typescript3.isSourceFile)(node.parent) && (0, import_typescript3.isStringLiteral)(node.name)) { return node.name.text; } node = node.parent; } return void 0; } function getDeclarationFromSymbol(checker, symbol) { if (!symbol) { return void 0; } else if (symbol.flags === import_typescript3.SymbolFlags.Alias) { const aliasSymbol = checker.getAliasedSymbol(symbol); return getDeclarationFromSymbol(checker, aliasSymbol); } else { const decl = symbol.valueDeclaration || symbol.declarations?.[0]; if (decl && (0, import_typescript3.isImportSpecifier)(decl)) { return getDeclarationFromNode(checker, decl.name); } return decl; } } function getDeclarationFromNode(checker, node) { const symbol = getSymbol(checker, node); return getDeclarationFromSymbol(checker, symbol); } function getSymbol(checker, node) { const symbol = node.aliasSymbol ?? node.symbol; if (symbol) { return symbol; } else if ((0, import_typescript3.isTypeReferenceNode)(node)) { const ref = node.typeName; return ref.aliasSymbol ?? ref.symbol ?? checker.getSymbolAtLocation(ref); } else { return checker.getSymbolAtLocation(node); } } function isDefaultExport(node) { return node.symbol?.name === "default"; } function shouldInclude(node) { return (0, import_typescript3.isModuleDeclaration)(node) || (0, import_typescript3.isExportDeclaration)(node) || isNodeExported(node); } function isNodeExported(node, alsoTopLevel = false) { return (0, import_typescript3.isExportAssignment)(node) || ((0, import_typescript3.getCombinedModifierFlags)(node) & import_typescript3.ModifierFlags.Export) !== 0 || alsoTopLevel && !!node.parent && node.parent.kind === import_typescript3.SyntaxKind.SourceFile; } function isPrivate(type) { return type.kind === import_typescript3.SyntaxKind.PrivateKeyword; } function isPublic(type) { return type.kind === import_typescript3.SyntaxKind.PublicKeyword; } function isStatic(type) { return type.kind === import_typescript3.SyntaxKind.StaticKeyword; } function isProtected(type) { return type.kind === import_typescript3.SyntaxKind.ProtectedKeyword; } function isReadonly(type) { return type.kind === import_typescript3.SyntaxKind.ReadonlyKeyword; } var import_typescript3; var init_node = __esm({ "src/helpers/node.ts"() { import_typescript3 = require("typescript"); } }); // src/helpers/paths.ts function findAppRoot(root2, app) { return (0, import_path6.resolve)(root2, app); } function isBaseLib(path) { if (path in pathCache) { return pathCache[path]; } else if (path) { const parts = path.split("/"); const part = parts.pop(); const newPath = parts.join("/"); const result = newPath.endsWith(tslibRoot) && part.startsWith(tslibPrefix) || globalFiles.includes(part); pathCache[path] = result; return result; } else { return false; } } var import_path6, pathCache; var init_paths = __esm({ "src/helpers/paths.ts"() { import_path6 = require("path"); init_constants(); pathCache = {}; } }); // src/helpers/strings.ts function makeIdentifier(identifier) { return checkIdentifier.test(identifier) ? identifier : JSON.stringify(identifier); } function formatContent(content) { return content.split("\n").map((line) => line ? ` ${line} ` : "\n").join(""); } function toContent(lines, terminator) { const content = lines.map((line) => `${line}${terminator}`).join("\n"); return formatContent(content); } function toBlock(lines, terminator) { if (lines.length > 0) { return `{ ${toContent(lines, terminator)}}`; } return "{}"; } var checkIdentifier; var init_strings = __esm({ "src/helpers/strings.ts"() { checkIdentifier = /^[a-zA-Z\_\$][a-zA-Z0-9\_\$]*$/; } }); // src/helpers/symbol.ts function fullyQualifiedName(symbol, delimiter) { const parts = []; do { parts.push(symbol.name); symbol = symbol.parent; } while (symbol && symbol.flags === import_typescript4.SymbolFlags.NamespaceModule && symbol.name !== globalIndicator); return parts.reverse().join(delimiter); } function isGlobal(symbol) { const parent = symbol?.parent; if (parent) { if (parent.name === globalIndicator) { return true; } return isGlobal(parent); } return false; } function getSymbolName(symbol) { if (symbol.flags === import_typescript4.SymbolFlags.EnumMember) { return `${symbol.parent.name}.${symbol.name}`; } else if (symbol.parent?.flags === import_typescript4.SymbolFlags.NamespaceModule) { return fullyQualifiedName(symbol, "."); } return symbol.name; } function getModifiers(symbol) { const decorators = []; if (symbol) { const modifiers = symbol.declarations?.[0]?.modifiers ?? []; modifiers.some(isPrivate) && decorators.push("private"); modifiers.some(isPublic) && decorators.push("public"); modifiers.some(isProtected) && decorators.push("protected"); modifiers.some(isStatic) && decorators.push("static"); modifiers.some(isReadonly) && decorators.push("readonly"); } return decorators.join(" "); } var import_typescript4; var init_symbol = __esm({ "src/helpers/symbol.ts"() { import_typescript4 = require("typescript"); init_constants(); init_node(); } }); // src/helpers/index.ts var init_helpers = __esm({ "src/helpers/index.ts"() { init_comments(); init_identifiers(); init_node(); init_paths(); init_strings(); init_symbol(); } }); // src/output/stringify.ts function stringifyComment(type) { if (type.comment) { const lines = type.comment.split("\n").map((line) => ` * ${line} `).join(""); return `/** ${lines} */ `; } return ""; } function stringifyPropName(name) { return typeof name === "string" ? makeIdentifier(name) : `[${stringifyNode(name)}]`; } function stringifyTupleProp(type) { const target = type.valueType; const comment = stringifyComment(type); const isOpt = type.optional ? "?" : ""; const name = stringifyPropName(type.name); if (typeof target === "undefined") { return `${comment}${name}${isOpt}: any`; } else if (target.kind === "function") { return `${comment}${name}${isOpt}: ${stringifySignature(target, 0 /* default */)}`; } else { return `${comment}${name}${isOpt}: ${stringifyNode(target)}`; } } function stringifyProp(type) { const target = type.valueType; const comment = stringifyComment(type); const isOpt = type.optional ? "?" : ""; const modifier = type.modifiers ? `${type.modifiers} ` : ""; const name = stringifyPropName(type.name); if (typeof target === "undefined") { return `${comment}${modifier}${name}${isOpt}: any`; } else if (target.kind === "function") { return `${comment}${modifier}${name}${isOpt}${stringifySignature(target, 1 /* property */)}`; } else { return `${comment}${modifier}${name}${isOpt}: ${stringifyNode(target)}`; } } function stringifyParameter(param, allowModifiers = true) { const isOpt = param.optional ? "?" : ""; const spread = param.spread ? "..." : ""; const modifiers = allowModifiers && param.modifiers ? `${param.modifiers} ` : ""; return `${modifiers}${spread}${param.param}${isOpt}: ${stringifyNode(param.value)}`; } function stringifyParameters(params, allowModifiers = true) { return params.map((p) => stringifyParameter(p, allowModifiers)).join(", "); } function stringifySignature(type, mode, anonymous = false) { const ctor = type.kind === "new" ? "new " : ""; const prop = (mode & 1 /* property */) !== 0; const paren = (mode & 2 /* parenthesis */) !== 0; const comment = anonymous ? stringifyComment(type) : ""; const parameters = stringifyParameters(type.parameters); const ta = stringifyTypeArgs(type); const rt = stringifyNode(type.returnType); const del = prop ? ": " : " => "; const result = `${ctor}${ta}(${parameters})${del}${rt}`; const fn = paren ? `(${result})` : result; return `${comment}${fn}`; } function stringifyConstructor(type) { const modifiedParameters = type.parameters.filter((m) => m.modifiers); const parameters = stringifyParameters(type.parameters, false); const modifiers = type.modifiers ? `${type.modifiers} ` : ""; const body = modifiedParameters.map((p) => { const isOpt = p.optional ? "?" : ""; const type2 = stringifyNode(p.value); return `${p.modifiers} ${p.param}${isOpt}: ${type2};`; }).join("\n"); const head = `${modifiers}constructor(${parameters})`; return [body, head].filter(Boolean).join("\n"); } function stringifyIndex(type) { const isOpt = type.optional ? "?" : ""; const index = stringifyParameters(type.parameters); return `[${index}]${isOpt}: ${stringifyNode(type.valueType)}`; } function stringifyMapped(type) { const isOpt = type.optional ? "?" : ""; const index = `${type.name} in ${stringifyNode(type.constraint)}`; return `[${index}]${isOpt}: ${stringifyNode(type.value)}`; } function stringifyAccess(type) { const right2 = stringifyNode(type.name); const left2 = stringifyNode(type.object); return `${left2}.${right2}`; } function stringifyIndexedAccess(type) { const right2 = stringifyNode(type.index); const left2 = stringifyNode(type.object); return `${left2}[${right2}]`; } function stringifyInterface(type) { const lines = type.props.map((p) => stringifyNode(p, 1 /* property */)); if (type.mapped) { lines.push(stringifyMapped(type.mapped)); } return toBlock(lines, ";"); } function stringifyClass(type) { const lines = type.props.map((p) => stringifyNode(p)); return toBlock(lines, ";"); } function stringifyEnum(values) { const lines = values.map((p) => stringifyNode(p)); return toBlock(lines, ","); } function stringifyExtends(type) { const { extends: es } = type; return es.length ? ` extends ${es.map((t) => stringifyNode(t)).join(", ")}` : ""; } function stringifyImplements(type) { const { implements: is } = type; return is.length ? ` implements ${is.map((t) => stringifyNode(t)).join(", ")}` : ""; } function stringifyTypes(types) { return types.map((t) => stringifyNode(t)).join(", "); } function stringifyTypeArgs(type) { if (type.types?.length > 0) { return `<${stringifyTypes(type.types)}>`; } return ""; } function stringifyTypeParameter(type) { const name = stringifyNode(type.parameter); const constraint = stringifyNode(type.constraint); const defaults = stringifyNode(type.default); const constraintClause = constraint ? ` extends ${constraint}` : ""; const defaultsClause = defaults ? ` = ${defaults}` : ""; return `${name}${constraintClause}${defaultsClause}`; } function stringifyTernary(condition) { const t = stringifyNode(condition.check); const e = stringifyNode(condition.extends); const p = stringifyNode(condition.primary); const a = stringifyNode(condition.alternate); return `${t} extends ${e} ? ${p} : ${a}`; } function stringifyMember(member) { const key = stringifyPropName(member.name); const name = `${stringifyComment(member)}${key}`; if (member.value) { return `${name} = ${stringifyNode(member.value)}`; } return name; } function stringifySetAccessor(accessor) { const comment = stringifyComment(accessor); const modifier = accessor.modifiers ? `${accessor.modifiers} ` : ""; const args = stringifyParameters(accessor.parameters); return `${comment}${modifier}set ${accessor.name}(${args})`; } function stringifyGetAccessor(accessor) { const comment = stringifyComment(accessor); const modifier = accessor.modifiers ? `${accessor.modifiers} ` : ""; const result = stringifyNode(accessor.type); return `${comment}${modifier}get ${accessor.name}(): ${result}`; } function stringifyPredicate(predicate) { const type = stringifyNode(predicate.value); return `${predicate.name} is ${type}`; } function stringifyImport(type) { const head = `import(${stringifyNode(type.value)})`; if (type.qualifier) { return `${head}.${type.qualifier}`; } return head; } function stringifyReadonly(type) { const value = type.value; if (value.kind === "ref" && value.refName === "Array" && value.types.length === 1) { const [arg] = value.types; return `readonly ${stringifyNode(arg)}[]`; } return `readonly ${stringifyNode(value)}`; } function stringifyNode(type, mode = 0 /* default */) { switch (type?.kind) { case "interface": return stringifyInterface(type); case "prop": return stringifyProp(type); case "tuple-prop": return stringifyTupleProp(type); case "ref": return `${type.refName}${stringifyTypeArgs(type)}`; case "typeParameter": return stringifyTypeParameter(type); case "union": return type.types.map((u) => stringifyNode(u, 2 /* parenthesis */)).join(" | "); case "intersection": return type.types.map((u) => stringifyNode(u)).join(" & "); case "member": return stringifyMember(type); case "conditional": return stringifyTernary(type); case "readonly": return stringifyReadonly(type); case "unique": return `unique ${stringifyNode(type.value)}`; case "keyof": return `keyof ${stringifyNode(type.value)}`; case "import": return stringifyImport(type); case "infer": return `infer ${stringifyNode(type.parameter)}`; case "any": case "null": case "void": case "undefined": case "boolean": case "unknown": case "bigint": case "number": case "never": case "string": return type.kind; case "nonPrimitive": return type.name || "object"; case "esSymbol": return "symbol"; case "unidentified": return "any"; case "literal": return `${type.value}`; case "access": return stringifyAccess(type); case "indexedAccess": return stringifyIndexedAccess(type); case "index": return stringifyIndex(type); case "class": return `class ${stringifyClass(type)}`; case "constructor": return stringifyConstructor(type); case "mapped": return stringifyMapped(type); case "substitution": return stringifyNode(type.variable); case "rest": return `...${stringifyNode(type.value)}`; case "new": case "function": return stringifySignature(type, mode, true); case "tuple": return `[${stringifyTypes(type.types)}]`; case "set": return stringifySetAccessor(type); case "get": return stringifyGetAccessor(type); case "predicate": return stringifyPredicate(type); case "template": return `\`${type.parts.map((p) => typeof p === "string" ? p : `\${${stringifyNode(p)}}`).join("")}\``; case "parenthesis": return `(${stringifyNode(type.value)})`; } return ""; } var init_stringify = __esm({ "src/output/stringify.ts"() { init_helpers(); } }); // src/output/exports.ts function stringifyExport(type) { switch (type?.kind) { case "interface": return `${stringifyComment(type)}export interface ${type.name}${stringifyTypeArgs(type)}${stringifyExtends( type )} ${stringifyInterface(type)}`; case "class": return `${stringifyComment(type)}export class ${type.name}${stringifyTypeArgs(type)}${stringifyExtends( type )}${stringifyImplements(type)} ${stringifyClass(type)}`; case "alias": return `${stringifyComment(type)}export type ${type.name}${stringifyTypeArgs(type)} = ${stringifyNode( type.child )};`; case "enumLiteral": return `${stringifyComment(type)}export ${type.const ? "const enum" : "enum"} ${type.name} ${stringifyEnum( type.values )}`; case "const": return `${stringifyComment(type)}export const ${type.name}: ${stringifyNode(type.value)};`; case "function": return `${stringifyComment(type)}export function ${type.name}${stringifySignature( type, 1 /* property */ )};`; case "default": const sc = type.value.kind === "class" ? "" : ";"; return `${stringifyComment(type)}export default ${stringifyNode(type.value)}${sc}`; } return ""; } function stringifyExports(refs) { return refs.map((r) => stringifyExport(r)).filter((m) => !!m).join("\n\n"); } var init_exports = __esm({ "src/output/exports.ts"() { init_stringify(); } }); // src/output/module.ts function stringifyModule(name, refs) { const content = stringifyExports(refs); const formattedContent = formatContent(content); return `declare module "${name}" { ${formattedContent}}`; } var init_module = __esm({ "src/output/module.ts"() { init_exports(); init_helpers(); } }); // src/output/declaration.ts function stringifyDeclaration(context) { const { noModuleDeclaration } = context.flags; const modules = Object.keys(context.modules).filter((moduleName) => Object.keys(context.modules[moduleName]).length > 0).map((moduleName) => { const refs = context.modules[moduleName]; if (noModuleDeclaration && moduleName === context.name) { return stringifyExports(refs); } return stringifyModule(moduleName, refs); }).join("\n\n"); const preamble = context.usedImports.map((lib) => `import * as ${getLibRefName(lib)} from '${lib}';`).join("\n"); if (preamble) { return `${preamble} ${modules}`; } return modules; } var init_declaration = __esm({ "src/output/declaration.ts"() { init_module(); init_exports(); init_helpers(); } }); // src/output/index.ts var init_output = __esm({ "src/output/index.ts"() { init_declaration(); init_exports(); init_module(); } }); // src/logger.ts var defaultLogger, wrapLogger; var init_logger = __esm({ "src/logger.ts"() { defaultLogger = { error(message) { throw new Error(message); }, warn(message) { console.warn(message); }, info(message) { console.info(message); }, verbose(message) { console.log(message); } }; wrapLogger = (logger, level) => { return { error(message) { level >= 1 && logger.error(message); }, warn(message) { level >= 2 && logger.warn(message); }, info(message) { level >= 3 && logger.info(message); }, verbose(message) { level >= 4 && logger.verbose(message); } }; }; } }); // src/input/api.ts function includeApi(context, node, interfaceName) { if ((0, import_typescript5.isInterfaceDeclaration)(node) && node.name.text === interfaceName) { context.exports.push(node); } else { context.log.verbose(`Skipping API using interface "${interfaceName}" from node: ${node}`); } } var import_typescript5; var init_api = __esm({ "src/input/api.ts"() { import_typescript5 = require("typescript"); } }); // src/input/exports.ts function includeExports(context, key, symbol) { const defs = {}; if (symbol) { context.checker.getExportsOfModule(symbol).forEach((exp) => { const decl = exp.valueDeclaration || exp.declarations?.[0]; if (!decl) { } else if (ts.isExportSpecifier(decl)) { const name = decl.name?.text; if (name) { defs[name] = getDeclarationFromNode(context.checker, decl); } } else if (ts.isExportAssignment(decl)) { defs["default"] = getDeclarationFromNode(context.checker, decl); } else if (ts.isVariableDeclaration(decl)) { defs[getParameterName(decl.name)] = decl; } else if (ts.isFunctionDeclaration(decl) || ts.isInterfaceDeclaration(decl) || ts.isClassDeclaration(decl) || ts.isTypeAliasDeclaration(decl) || ts.isEnumDeclaration(decl)) { const name = isDefaultExport(decl) ? "default" : decl.name?.text; if (name) { defs[name] = decl; } } else if (ts.isMethodDeclaration(decl) || ts.isPropertyDeclaration(decl)) { } else if (ts.isModuleDeclaration(decl)) { defs[decl.name.text] = decl; } else if (ts.isImportEqualsDeclaration(decl)) { } else if (ts.isNamespaceExport(decl)) { defs[decl.name.text] = decl; } else { context.log.warn(`Skipping import of unknown node (kind: ${decl.kind}).`); } }); } context.availableImports[key] = defs; } var ts; var init_exports2 = __esm({ "src/input/exports.ts"() { ts = __toESM(require("typescript")); init_helpers(); } }); // src/input/utils.ts function createBinding(context, lib, name) { if (!context.usedImports.includes(lib)) { context.usedImports.push(lib); } return `${getLibRefName(lib)}.${name}`; } function getDefault(value) { return { kind: "default", name: "default", value }; } function getRef(refName, types = []) { return { kind: "ref", refName, types }; } function getSymbolName2(imports, node) { if (imports) { for (const name of Object.keys(imports)) { if (imports[name] === node) { return name; } } } return void 0; } function isImportedFile(node, root2, imports) { const fn = node.getSourceFile()?.fileName; if (fn) { const libName = getLibName(fn, root2); return Object.keys(imports).some((name) => name === libName); } return false; } function getPackage(node, symbol, root2, imports) { const fn = node.getSourceFile()?.fileName; const base = isBaseLib(fn) || false; const global = isGlobal(symbol); if (!base) { const libName = getLibName(fn, root2); const [lib] = Object.keys(imports).filter((name) => { if (global) { return name === libName; } const exports2 = Object.values(imports[name]); if (exports2.includes(node)) { return true; } else if (symbol?.parent?.flags === ts2.SymbolFlags.NamespaceModule) { const parentNode = symbol.parent?.declarations[0]; return exports2.includes(parentNode); } return false; }); const symbolName = getSymbolName2(imports[lib], node); return { external: !!lib, moduleName: lib && getModule(node) || lib, symbolName, global, base, lib, fn }; } return { external: true, moduleName: void 0, symbolName: void 0, global, base, lib: void 0, fn }; } var ts2; var init_utils = __esm({ "src/input/utils.ts"() { ts2 = __toESM(require("typescript")); init_helpers(); } }); // src/input/includes.ts function isText(actual, expected) { if (typeof actual === "string") { return actual === expected; } else if (Array.isArray(actual)) { return actual.some((m) => m.text === expected); } return false; } function includeClauses(context, clauses, newClause, tags = []) { const types = []; for (const clause of newClause.types) { const decl = getDeclarationFromNode(context.checker, clause.expression); const name = decl?.symbol?.name; if (decl && !tags.some((m) => m.name === "dets_removeclause" && isText(m.text, name))) { types.push(clause); } } clauses.push({ ...newClause, types: ts3.factory.createNodeArray(types) }); } function includeProp(props, newProp, getPropName, tags = []) { const name = getPropName(newProp.name); if (tags.some((m) => m.name === "dets_removeprop" && isText(m.text, name))) { return; } for (const oldProp of props) { if (oldProp.kind === newProp.kind && getPropName(oldProp.name) === name) { if (!ts3.isMethodSignature(newProp) && !ts3.isCallSignatureDeclaration(newProp)) { return; } } } props.push(newProp); } var ts3; var init_includes = __esm({ "src/input/includes.ts"() { ts3 = __toESM(require("typescript")); init_helpers(); } }); // src/input/node.ts var ts4, DeclVisitor; var init_node2 = __esm({ "src/input/node.ts"() { ts4 = __toESM(require("typescript")); init_utils(); init_includes(); init_helpers(); DeclVisitor = class { constructor(context) { this.context = context; this.queue = []; this.modules = []; this.processed = []; const [defaultModule] = Object.keys(context.modules ?? {}); this.refs = context.modules[defaultModule] ?? []; this.names = context.moduleNames[defaultModule] ?? /* @__PURE__ */ new Map(); for (const node of context.exports) { this.enqueue(node); } } logVerbose(message) { this.context.log.verbose(message); } logWarn(message) { this.context.log.warn(message); } printWarning(type, node) { this.logWarn( `Could not resolve ${type} at position ${node.pos} of "${node.getSourceFile()?.fileName}". Kind: ${node.kind}.` ); } swapName(oldName, newName) { const refs = this.refs; const last = refs.pop(); if (!last) { } else if (last.kind === "default") { if (last.value.kind === "ref") { const name = last.value.refName; for (let i = refs.length; i--; ) { const ref = refs[i]; if (ref.name === name) { refs.splice(i, 1, { ...ref, name: newName }); break; } } } } else if ("name" in last && last.name === oldName) { refs.push({ ...last, name: newName }); } else { refs.push(last); } } findName(node) { return this.names.get(node); } createName(name) { const altStart = `${name}___`; const available = /* @__PURE__ */ new Set(); for (const m of this.names.values()) { if (m === name || m.startsWith(altStart)) { available.add(m); } } const count = available.size; if (count) { return `${altStart}${count}`; } return name; } getName(node, suggested) { const existing = this.findName(node); if (!existing) { this.logVerbose(`Missing "name". Retrieving with suggestion "${suggested}".`); const name = this.createName(suggested); const decls = node.symbol?.declarations ?? [node]; decls.forEach((decl) => this.names.set(decl, name)); return name; } return existing; } normalizeName(node) { const c = this.context; const symbol = node.symbol ?? node.aliasSymbol ?? c.checker.getSymbolAtLocation(node); const { moduleName, lib, symbolName, global } = getPackage(node, symbol, c.root, c.availableImports); if (!lib) { const name = global ? fullyQualifiedName(symbol, "_") : getSymbolName(symbol); return this.getName(node, name); } else if (global) { return fullyQualifiedName(symbol, "."); } else { return createBinding(c, moduleName, symbolName ?? getSymbolName(symbol)); } } convertToTypeNodeFromType(type) { const c = this.context.checker; return c.typeToTypeNode(type, void 0, ts4.NodeBuilderFlags.NoTruncation); } convertToTypeNodeFromNode(node) { const type = this.context.checker.getTypeAtLocation(node); return this.convertToTypeNodeFromType(type); } valueFromLiteral(node) { switch (node.literal.kind) { case ts4.SyntaxKind.StringLiteral: return JSON.stringify(node.literal.text); case ts4.SyntaxKind.TrueKeyword: return "true"; case ts4.SyntaxKind.FalseKeyword: return "false"; case ts4.SyntaxKind.NumericLiteral: case ts4.SyntaxKind.BigIntLiteral: return node.literal.text; case ts4.SyntaxKind.NullKeyword: return "null"; default: this.logVerbose(`No match for literal node kind "${node.literal.kind}". Trying to get from type node...`); const type = this.context.checker.getTypeFromTypeNode(node); return type?.intrinsicName ?? type?.value; } } getInferredType(node) { const typeNode = this.convertToTypeNodeFromNode(node); return this.getTypeNode(typeNode); } getUnion(node) { return { kind: "union", types: node.types.map((m) => this.getNode(m)) }; } getLiteral(node) { return { kind: "literal", value: this.valueFromLiteral(node) }; } getNode(node) { if (ts4.isTypeNode(node)) { return this.getTypeNode(node); } else if (ts4.isTypeAliasDeclaration(node) || ts4.isFunctionDeclaration(node) || ts4.isInterfaceDeclaration(node) || ts4.isClassDeclaration(node)) { this.enqueue(node); return getRef(this.normalizeName(node), this.getTypeParameters(node.typeParameters)); } else if (isDefaultExport(node) || ts4.isVariableDeclaration(node) || ts4.isVariableStatement(node)) { this.enqueue(node); return getRef(this.normalizeName(node)); } else if (ts4.isPropertyAssignment(node)) { return { kind: "prop", modifiers: getModifiers(node.symbol), name: node.symbol.name, //@ts-ignore optional: node.questionToken !== void 0, valueType: this.getExpression(node.initializer) }; } this.logVerbose(`Node is presumably a reference. Found kind "${node.kind}".`); return getRef(node.symbol.name); } getPropDeclaration(node) { const type = node.type ?? this.convertToTypeNodeFromNode(node); return this.getTypeNode(type); } getPropValue(node) { if (ts4.isPropertySignature(node)) { return this.getTypeNode(node.type); } else if (ts4.isMethodSignature(node)) { return this.getMethodSignature(node); } else if (ts4.isPropertyDeclaration(node)) { return this.getPropDeclaration(node); } else if (ts4.isMethodDeclaration(node)) { return this.getMethodSignature(node); } this.printWarning("property", node); } getNormalProp(node) { const { checker, flags } = this.context; const canDrop = !flags.noIgnore; const comment = getCommentOrDrop(checker, node.emitNode?.commentRange ?? node, canDrop); if (typeof comment === "string") { return { kind: "prop", name: this.getPropName(node.name), modifiers: getModifiers(node.symbol), optional: node.questionToken !== void 0, comment, valueType: this.getPropValue(node) }; } this.logVerbose(`The prop "${this.getPropName(node.name)}" was skipped due to @ignore.`); return void 0; } getIndexProp(node) { return { kind: "index", parameters: this.getFunctionParameters(node.parameters), optional: node.questionToken !== void 0, valueType: this.getTypeNode(node.type) }; } getConstructor(node) { return { kind: "constructor", parameters: this.getFunctionParameters(node.parameters), modifiers: getModifiers(node.symbol), comment: getComment(this.context.checker, node) }; } getClassMember(node) { const { checker, flags } = this.context; const canDrop = !flags.noIgnore; const comment = getCommentOrDrop(checker, node, canDrop); if (node.name) { if (typeof comment === "string") { return { kind: "prop", name: node.name.getText(), modifiers: getModifiers(node.symbol), optional: false, comment, valueType: this.getPropValue(node) }; } this.logVerbose(`The member "${node.name.getText()}" was skipped due to @ignore.`); } return void 0; } getProps(nodes) { const props = []; nodes?.forEach((node) => { if (ts4.isIndexSignatureDeclaration(node)) { props.push(this.getIndexProp(node)); } else if (ts4.isCallSignatureDeclaration(node)) { props.push(this.getMethodSignature(node)); } else if (ts4.isConstructSignatureDeclaration(node)) { props.push(this.getConstructorCall(node)); } else if (ts4.isGetAccessor(node)) { const prop = this.getGetAccessor(node); prop && props.push(prop); } else if (ts4.isSetAccessor(node)) { const prop = this.getSetAccessor(node); prop && props.push(prop); } else if (ts4.isPropertySignature(node)) { const prop = this.getNormalProp(node); prop && props.push(prop); } else { this.logVerbose(`Getting props - assuming node of kind "${node?.kind}" is a normal prop.`); const prop = this.getNormalProp(node); prop && props.push(prop); } }); return props; } getClassMembers(nodes) { const members = []; nodes?.forEach((node) => { if (ts4.isConstructorDeclaration(node)) { members.push(this.getConstructor(node)); } else if (ts4.isCallSignatureDeclaration(node)) { members.push(this.getMethodSignature(node)); } else if (ts4.isConstructSignatureDeclaration(node)) { members.push(this.getConstructorCall(node)); } else if (ts4.isGetAccessor(node)) { const member = this.getGetAccessor(node); member && members.push(member); } else if (ts4.isSetAccessor(node)) { const member = this.getSetAccessor(node); member && members.push(member); } else if (ts4.isIndexSignatureDeclaration(node)) { members.push(this.getIndexProp(node)); } else { this.logVerbose(`Getting class members - assuming node of kind "${node?.kind}" is a class member.`); const member = this.getClassMember(node); member && members.push(member); } }); return members; } getEnumMember(node) { const value = node.initializer; return { kind: "member", name: this.getPropName(node.name), value: value && this.getExpression(value), comment: getComment(this.context.checker, node) }; } getEnumMembers(nodes) { return nodes?.map((node) => this.getEnumMember(node)) ?? []; } getReturnType(node) { const checker = this.context.checker; const type = node.type ?? this.convertToTypeNodeFromType(checker.getReturnTypeOfSignature(checker.getSignatureFromDeclaration(node))); return this.getTypeNode(type); } getFunctionDeclaration(node) { const name = this.getName(node, node.name.text); return { ...this.getMethodSignature(node), name }; } getMethodSignature(node) { return { kind: "function", name: void 0, parameters: this.getFunctionParameters(node.parameters), returnType: this.getReturnType(node), types: this.getTypeParameters(node.typeParameters), comment: getComment(this.context.checker, node) }; } getConstructorCall(node) { return { kind: "new", parameters: this.getFunctionParameters(node.parameters), returnType: this.getTypeNode(node.type), types: this.getTypeParameters(node.typeParameters), comment: getComment(this.context.checker, node) }; } getTypeParameter(node) { return { kind: "typeParameter", parameter: getRef(node.name.text), constraint: node.constraint && this.getTypeNode(node.constraint), default: node.default && this.getTypeNode(node.default) }; } getTypeParameters(nodes) { return nodes?.map((node) => this.getTypeParameter(node)) ?? []; } getTypeArguments(nodes) { return nodes?.map((node) => this.getTypeNode(node)) ?? []; } getFunctionParameterValue(node) { if (node.type) { return this.getTypeNode(node.type); } const typeNode = this.convertToTypeNodeFromNode(node); if (typeNode) { return this.getTypeNode(typeNode); } else if (node.initializer) { return this.getExpression(node.initializer); } else { this.logVerbose( `Found unidentified node of kind "${node.kind}" in function parameter value. Falling back to "any".` ); return { kind: "any" }; } } getFunctionParameter(node) { return { kind: "parameter", param: getParameterName(node.name), spread: node.dotDotDotToken !== void 0, optional: node.questionToken !== void 0 || node.initializer !== void 0, modifiers: getModifiers(node.symbol), value: this.getFunctionParameterValue(node) }; } getFunctionParameters(nodes) { return nodes?.map((node) => this.getFunctionParameter(node)) ?? []; } getIndexAccess(node) { return { kind: "indexedAccess", index: this.getTypeNode(node.indexType), object: this.getTypeNode(node.objectType) }; } getTypeOperator(node) { switch (node.operator) { case ts4.SyntaxKind.KeyOfKeyword: return { kind: "keyof", value: this.getTypeNode(node.type) }; case ts4.SyntaxKind.UniqueKeyword: return { kind: "unique", value: this.getTypeNode(node.type) }; case ts4.SyntaxKind.ReadonlyKeyword: return { kind: "readonly", value: this.getTypeNode(node.type) }; default: this.logWarn(`Found unknown type operator node of kind "${node.kind}".`); } } getMappedType(node) { const p = node.typeParameter; return { kind: "interface", name: void 0, extends: [], props: [], types: [], comment: getComment(this.context.checker, node), mapped: { kind: "mapped", constraint: this.getTypeNode(p.constraint), name: p.name.text, optional: node.questionToken !== void 0, value: this.getTypeNode(node.type) } }; } getConditionalType(node) { return { kind: "conditional", alternate: this.getTypeNode(node.falseType), check: this.getTypeNode(node.checkType), extends: this.getTypeNode(node.extendsType), primary: this.getTypeNode(node.trueType) }; } getPredicate(node) { return { kind: "predicate", name: getPredicateName(node.parameterName), value: this.getTypeNode(node.type) }; } getSetAccessor(node) { const { checker, flags } = this.context; const canDrop = !flags.noIgnore; const comment = getCommentOrDrop(checker, node, canDrop); if (typeof comment === "string") { return { kind: "set", name: this.getPropName(node.name), parameters: this.getFunctionParameters(node.parameters), comment, modifiers: getModifiers(node.symbol) }; } this.logVerbose(`The setter "${this.getPropName(node.name)}" was skipped due to @ignore.`); return void 0; } getGetAccessor(node) { const { checker, flags } = this.context; const canDrop = !flags.noIgnore; const comment = getCommentOrDrop(checker, node, canDrop); if (typeof comment === "string") { return { kind: "get", name: this.getPropName(node.name), type: this.getReturnType(node), comment, modifiers: getModifiers(node.symbol) }; } this.logVerbose(`The getter "${this.getPropName(node.name)}" was skipped due to @ignore.`); return void 0; } getTypeReference(node) { const c = this.context.checker; const decl = getDeclarationFromNode(c, node); if (decl && !ts4.isTypeParameterDeclaration(decl)) { this.enqueue(decl); return getRef(this.normalizeName(decl), this.getTypeArguments(node.typeArguments)); } return getRef(getTypeRefName(node.typeName), this.getTypeArguments(node.typeArguments)); } getTypeLiteral(node) { return { kind: "interface", name: void 0, comment: getComment(this.context.checker, node), extends: [], props: this.getProps(node.members), types: [] }; } getExpressionWithTypeArguments(node) { const decl = getDeclarationFromNode(this.context.checker, node.expression); if (decl) { this.enqueue(decl); return getRef(this.normalizeName(decl), this.getTypeArguments(node.typeArguments)); } return { kind: "ref", refName: "any", types: [] }; } getArray(node) { return getRef("Array", [this.getTypeNode(node.elementType)]); } getInfer(node) { return { kind: "infer", parameter: this.getTypeParameter(node.typeParameter) }; } getIntersection(node) { return { kind: "intersection", types: node.types.map((n) => this.getTypeNode(n)) }; } getTuple(node) { return { kind: "tuple", types: (node["elementTypes"] ?? node.elements).map((n) => this.getTypeNode(n)) }; } getParenthesis(node) { return { kind: "parenthesis", value: this.getTypeNode(node.type) }; } getTypeQueryNode(node) { const symbol = this.context.checker.getSymbolAtLocation(node.exprName); if (sy