|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803 |
- import {
- RollupResolve
- } from "./chunk-E4LU3OPM.mjs";
- import {
- exportsSymbol,
- getTSFile,
- isTSDeclaration,
- isTSExports,
- mergeTSProperties,
- resolveTSEntityName,
- resolveTSExports,
- resolveTSFileId,
- resolveTSFileIdNode,
- resolveTSProperties,
- resolveTSReferencedType,
- resolveTSScope,
- resolveTypeElements,
- setResolveTSFileIdImpl,
- tsFileCache,
- tsFileExportsCache
- } from "./chunk-5FIR3URH.mjs";
- import {
- keyToString
- } from "./chunk-VQQLEFAO.mjs";
-
- // src/index.ts
- import { MagicString } from "@vue-macros/common";
-
- // src/vue/analyze.ts
- import {
- DEFINE_EMITS,
- DEFINE_PROPS,
- WITH_DEFAULTS,
- babelParse as babelParse3,
- isCallOf
- } from "@vue-macros/common";
-
- // src/vue/props.ts
- import {
- babelParse,
- isStaticObjectKey,
- resolveObjectExpression
- } from "@vue-macros/common";
-
- // src/vue/types.ts
- var DefinitionKind = /* @__PURE__ */ ((DefinitionKind2) => {
- DefinitionKind2["Reference"] = "Reference";
- DefinitionKind2["Object"] = "Object";
- DefinitionKind2["TS"] = "TS";
- return DefinitionKind2;
- })(DefinitionKind || {});
-
- // src/vue/utils.ts
- async function inferRuntimeType(node) {
- if (isTSExports(node))
- return ["Object"];
- switch (node.type.type) {
- case "TSStringKeyword":
- return ["String"];
- case "TSNumberKeyword":
- return ["Number"];
- case "TSBooleanKeyword":
- return ["Boolean"];
- case "TSObjectKeyword":
- return ["Object"];
- case "TSTypeLiteral": {
- const types = /* @__PURE__ */ new Set();
- for (const m of node.type.members) {
- switch (m.type) {
- case "TSCallSignatureDeclaration":
- case "TSConstructSignatureDeclaration":
- types.add("Function");
- break;
- default:
- types.add("Object");
- }
- }
- return Array.from(types);
- }
- case "TSFunctionType":
- return ["Function"];
- case "TSArrayType":
- case "TSTupleType":
- return ["Array"];
- case "TSLiteralType":
- switch (node.type.literal.type) {
- case "StringLiteral":
- return ["String"];
- case "BooleanLiteral":
- return ["Boolean"];
- case "NumericLiteral":
- case "BigIntLiteral":
- return ["Number"];
- default:
- return [`null`];
- }
- case "TSTypeReference":
- if (node.type.typeName.type === "Identifier") {
- switch (node.type.typeName.name) {
- case "Array":
- case "Function":
- case "Object":
- case "Set":
- case "Map":
- case "WeakSet":
- case "WeakMap":
- case "Date":
- case "Promise":
- return [node.type.typeName.name];
- case "Record":
- case "Partial":
- case "Readonly":
- case "Pick":
- case "Omit":
- case "Required":
- case "InstanceType":
- return ["Object"];
- case "Extract":
- if (node.type.typeParameters && node.type.typeParameters.params[1]) {
- const t = await resolveTSReferencedType({
- scope: node.scope,
- type: node.type.typeParameters.params[1]
- });
- if (t)
- return inferRuntimeType(t);
- }
- return ["null"];
- case "Exclude":
- if (node.type.typeParameters && node.type.typeParameters.params[0]) {
- const t = await resolveTSReferencedType({
- scope: node.scope,
- type: node.type.typeParameters.params[0]
- });
- if (t)
- return inferRuntimeType(t);
- }
- return ["null"];
- }
- }
- return [`null`];
- case "TSUnionType": {
- const types = (await Promise.all(
- node.type.types.map(async (subType) => {
- const resolved = await resolveTSReferencedType({
- scope: node.scope,
- type: subType
- });
- return resolved && !isTSExports(resolved) ? inferRuntimeType(resolved) : void 0;
- })
- )).flatMap((t) => t ? t : ["null"]);
- return [...new Set(types)];
- }
- case "TSIntersectionType":
- return ["Object"];
- case "TSSymbolKeyword":
- return ["Symbol"];
- case "TSInterfaceDeclaration":
- return ["Object"];
- default:
- return [`null`];
- }
- }
- function attachNodeLoc(node, newNode) {
- newNode.start = node.start;
- newNode.end = node.end;
- }
- function toRuntimeTypeString(types) {
- return types.length > 1 ? `[${types.join(", ")}]` : types[0];
- }
-
- // src/vue/props.ts
- async function handleTSPropsDefinition({
- s,
- file,
- offset,
- definePropsAst,
- typeDeclRaw,
- withDefaultsAst,
- defaultsDeclRaw,
- statement,
- declId
- }) {
- const { definitions, definitionsAst } = await resolveDefinitions({
- type: typeDeclRaw,
- scope: file
- });
- const { defaults, defaultsAst } = resolveDefaults(defaultsDeclRaw);
- const addProp = (name, value, optional) => {
- const { key, signature, valueAst, signatureAst } = buildNewProp(
- name,
- value,
- optional
- );
- if (definitions[key])
- return false;
- if (definitionsAst.scope === file) {
- if (definitionsAst.ast.type === "TSIntersectionType") {
- s.appendLeft(definitionsAst.ast.end + offset, ` & { ${signature} }`);
- } else {
- s.appendLeft(definitionsAst.ast.end + offset - 1, ` ${signature}
- `);
- }
- }
- definitions[key] = {
- type: "property",
- value: {
- code: value,
- ast: valueAst,
- scope: void 0
- },
- optional: !!optional,
- signature: {
- code: signature,
- ast: signatureAst,
- scope: void 0
- },
- addByAPI: true
- };
- return true;
- };
- const setProp = (name, value, optional) => {
- const { key, signature, signatureAst, valueAst } = buildNewProp(
- name,
- value,
- optional
- );
- const def = definitions[key];
- if (!definitions[key])
- return false;
- switch (def.type) {
- case "method": {
- attachNodeLoc(def.methods[0].ast, signatureAst);
- if (def.methods[0].scope === file)
- s.overwriteNode(def.methods[0].ast, signature, { offset });
- def.methods.slice(1).forEach((method) => {
- if (method.scope === file) {
- s.removeNode(method.ast, { offset });
- }
- });
- break;
- }
- case "property": {
- attachNodeLoc(def.signature.ast, signatureAst);
- if (def.signature.scope === file && !def.addByAPI) {
- s.overwriteNode(def.signature.ast, signature, { offset });
- }
- break;
- }
- }
- definitions[key] = {
- type: "property",
- value: {
- code: value,
- ast: valueAst,
- scope: void 0
- },
- optional: !!optional,
- signature: {
- code: signature,
- ast: signatureAst,
- scope: void 0
- },
- addByAPI: def.type === "property" && def.addByAPI
- };
- return true;
- };
- const removeProp = (name) => {
- const key = keyToString(name);
- if (!definitions[key])
- return false;
- const def = definitions[key];
- switch (def.type) {
- case "property": {
- if (def.signature.scope === file && !def.addByAPI) {
- s.removeNode(def.signature.ast, { offset });
- }
- break;
- }
- case "method":
- def.methods.forEach((method) => {
- if (method.scope === file)
- s.removeNode(method.ast, { offset });
- });
- break;
- }
- delete definitions[key];
- return true;
- };
- const getRuntimeDefinitions = async () => {
- const props = {};
- for (const [propName, def] of Object.entries(definitions)) {
- let prop;
- if (def.type === "method") {
- prop = {
- type: ["Function"],
- required: !def.optional
- };
- } else {
- const resolvedType = def.value;
- if (resolvedType) {
- prop = {
- type: await inferRuntimeType({
- scope: resolvedType.scope || file,
- type: resolvedType.ast
- }),
- required: !def.optional
- };
- } else {
- prop = { type: ["null"], required: false };
- }
- }
- const defaultValue = defaults == null ? void 0 : defaults[propName];
- if (defaultValue) {
- prop.default = (key = "default") => {
- switch (defaultValue.type) {
- case "ObjectMethod":
- return `${defaultValue.kind !== "method" ? `${defaultValue.kind} ` : ""}${defaultValue.async ? `async ` : ""}${key}(${s.sliceNode(
- defaultValue.params,
- { offset }
- )}) ${s.sliceNode(defaultValue.body, { offset })}`;
- case "ObjectProperty":
- return `${key}: ${s.sliceNode(defaultValue.value, { offset })}`;
- }
- };
- }
- props[propName] = prop;
- }
- return props;
- };
- return {
- kind: "TS" /* TS */,
- definitions,
- defaults,
- declId,
- addProp,
- setProp,
- removeProp,
- getRuntimeDefinitions,
- // AST
- definitionsAst,
- defaultsAst,
- statementAst: statement,
- definePropsAst,
- withDefaultsAst
- };
- async function resolveDefinitions(typeDeclRaw2) {
- const resolved = await resolveTSReferencedType(typeDeclRaw2);
- if (!resolved || isTSExports(resolved))
- throw new SyntaxError(`Cannot resolve TS definition.`);
- const { type: definitionsAst2, scope } = resolved;
- if (definitionsAst2.type === "TSIntersectionType") {
- const results = {};
- for (const type of definitionsAst2.types) {
- const defMap = await resolveDefinitions({ type, scope }).then(
- ({ definitions: definitions3 }) => definitions3
- );
- for (const [key, def] of Object.entries(defMap)) {
- const result = results[key];
- if (!result) {
- results[key] = def;
- continue;
- }
- if (result.type === "method" && def.type === "method") {
- result.methods.push(...def.methods);
- } else {
- results[key] = def;
- }
- }
- }
- return {
- definitions: results,
- definitionsAst: buildDefinition({ scope, type: definitionsAst2 })
- };
- } else if (definitionsAst2.type === "TSUnionType") {
- const unionDefs = [];
- const keys = /* @__PURE__ */ new Set();
- for (const type of definitionsAst2.types) {
- const defs = await resolveDefinitions({ type, scope }).then(
- ({ definitions: definitions3 }) => definitions3
- );
- Object.keys(defs).map((key) => keys.add(key));
- unionDefs.push(defs);
- }
- const results = {};
- for (const key of keys) {
- let optional = false;
- let result;
- for (const defMap of unionDefs) {
- const def = defMap[key];
- if (!def) {
- optional = true;
- continue;
- }
- optional || (optional = def.optional);
- if (!result) {
- result = def;
- continue;
- }
- if (result.type === "method" && def.type === "method") {
- result.methods.push(...def.methods);
- } else if (result.type === "property" && def.type === "property") {
- if (!def.value) {
- continue;
- } else if (!result.value) {
- result = def;
- continue;
- }
- if (def.value.ast.type === "TSImportType" || def.value.ast.type === "TSDeclareFunction" || def.value.ast.type === "TSEnumDeclaration" || def.value.ast.type === "TSInterfaceDeclaration" || def.value.ast.type === "TSModuleDeclaration" || result.value.ast.type === "TSImportType" || result.value.ast.type === "TSDeclareFunction" || result.value.ast.type === "TSEnumDeclaration" || result.value.ast.type === "TSInterfaceDeclaration" || result.value.ast.type === "TSModuleDeclaration") {
- continue;
- }
- if (result.value.ast.type === "TSUnionType") {
- result.value.ast.types.push(def.value.ast);
- } else {
- result = {
- type: "property",
- value: buildDefinition({
- scope,
- type: {
- type: "TSUnionType",
- types: [result.value.ast, def.value.ast]
- }
- }),
- signature: null,
- optional,
- addByAPI: false
- };
- }
- } else {
- throw new SyntaxError(
- `Cannot resolve TS definition. Union type contains different types of results.`
- );
- }
- }
- if (result) {
- results[key] = { ...result, optional };
- }
- }
- return {
- definitions: results,
- definitionsAst: buildDefinition({ scope, type: definitionsAst2 })
- };
- } else if (definitionsAst2.type !== "TSInterfaceDeclaration" && definitionsAst2.type !== "TSTypeLiteral" && definitionsAst2.type !== "TSMappedType")
- throw new SyntaxError(
- `Cannot resolve TS definition: ${definitionsAst2.type}.`
- );
- const properties = await resolveTSProperties({
- scope,
- type: definitionsAst2
- });
- const definitions2 = {};
- for (const [key, sign] of Object.entries(properties.methods)) {
- const methods = sign.map((sign2) => buildDefinition(sign2));
- definitions2[key] = {
- type: "method",
- methods,
- optional: sign.some((sign2) => !!sign2.type.optional)
- };
- }
- for (const [key, value] of Object.entries(properties.properties)) {
- const referenced = value.value ? await resolveTSReferencedType(value.value) : void 0;
- definitions2[key] = {
- type: "property",
- addByAPI: false,
- value: referenced && !isTSExports(referenced) ? buildDefinition(referenced) : void 0,
- optional: value.optional,
- signature: buildDefinition(value.signature)
- };
- }
- return {
- definitions: definitions2,
- definitionsAst: buildDefinition({ scope, type: definitionsAst2 })
- };
- }
- function resolveDefaults(defaultsAst2) {
- if (!defaultsAst2)
- return {};
- const isStatic = defaultsAst2.type === "ObjectExpression" && isStaticObjectKey(defaultsAst2);
- if (!isStatic)
- return { defaultsAst: defaultsAst2 };
- const defaults2 = resolveObjectExpression(defaultsAst2);
- if (!defaults2)
- return { defaultsAst: defaultsAst2 };
- return { defaults: defaults2, defaultsAst: defaultsAst2 };
- }
- function buildNewProp(name, value, optional) {
- const key = keyToString(name);
- const signature = `${name}${optional ? "?" : ""}: ${value}`;
- const valueAst = babelParse(`type T = (${value})`, "ts").body[0].typeAnnotation.typeAnnotation;
- const signatureAst = babelParse(`interface T {${signature}}`, "ts").body[0].body.body[0];
- return { key, signature, signatureAst, valueAst };
- }
- function buildDefinition({
- type,
- scope
- }) {
- return {
- code: resolveTSScope(scope).file.content.slice(type.start, type.end),
- ast: type,
- scope
- };
- }
- }
-
- // src/vue/emits.ts
- import {
- babelParse as babelParse2,
- isStaticExpression,
- resolveLiteral
- } from "@vue-macros/common";
- async function handleTSEmitsDefinition({
- s,
- file,
- offset,
- defineEmitsAst,
- typeDeclRaw,
- declId,
- statement
- }) {
- const { definitions, definitionsAst } = await resolveDefinitions({
- type: typeDeclRaw,
- scope: file
- });
- const addEmit = (name, signature) => {
- const key = keyToString(name);
- if (definitionsAst.scope === file) {
- if (definitionsAst.ast.type === "TSIntersectionType") {
- s.appendLeft(definitionsAst.ast.end + offset, ` & { ${signature} }`);
- } else {
- s.appendLeft(definitionsAst.ast.end + offset - 1, ` ${signature}
- `);
- }
- }
- if (!definitions[key])
- definitions[key] = [];
- const ast = parseSignature(signature);
- definitions[key].push({
- code: signature,
- ast,
- scope: void 0
- });
- };
- const setEmit = (name, idx, signature) => {
- const key = keyToString(name);
- const def = definitions[key][idx];
- if (!def)
- return false;
- const ast = parseSignature(signature);
- attachNodeLoc(def.ast, ast);
- if (def.scope === file)
- s.overwriteNode(def.ast, signature, { offset });
- definitions[key][idx] = {
- code: signature,
- ast,
- scope: void 0
- };
- return true;
- };
- const removeEmit = (name, idx) => {
- const key = keyToString(name);
- const def = definitions[key][idx];
- if (!def)
- return false;
- if (def.scope === file)
- s.removeNode(def.ast, { offset });
- delete definitions[key][idx];
- return true;
- };
- return {
- kind: "TS" /* TS */,
- definitions,
- definitionsAst,
- declId,
- addEmit,
- setEmit,
- removeEmit,
- statementAst: statement,
- defineEmitsAst
- };
- function parseSignature(signature) {
- return babelParse2(`interface T {${signature}}`, "ts").body[0].body.body[0];
- }
- async function resolveDefinitions(typeDeclRaw2) {
- var _a;
- const resolved = await resolveTSReferencedType(typeDeclRaw2);
- if (!resolved || isTSExports(resolved))
- throw new SyntaxError(`Cannot resolve TS definition.`);
- const { type: definitionsAst2, scope } = resolved;
- if (definitionsAst2.type !== "TSInterfaceDeclaration" && definitionsAst2.type !== "TSTypeLiteral" && definitionsAst2.type !== "TSIntersectionType" && definitionsAst2.type !== "TSFunctionType")
- throw new SyntaxError(
- `Cannot resolve TS definition: ${definitionsAst2.type}`
- );
- const properties = await resolveTSProperties({
- scope,
- type: definitionsAst2
- });
- const definitions2 = {};
- for (const signature of properties.callSignatures) {
- const evtArg = signature.type.parameters[0];
- if (!evtArg || evtArg.type !== "Identifier" || ((_a = evtArg.typeAnnotation) == null ? void 0 : _a.type) !== "TSTypeAnnotation")
- continue;
- const evtType = await resolveTSReferencedType({
- type: evtArg.typeAnnotation.typeAnnotation,
- scope: signature.scope
- });
- if (isTSExports(evtType) || !(evtType == null ? void 0 : evtType.type))
- continue;
- const types = evtType.type.type === "TSUnionType" ? evtType.type.types : [evtType.type];
- for (const type of types) {
- if (type.type !== "TSLiteralType")
- continue;
- const literal = type.literal;
- if (!isStaticExpression(literal))
- continue;
- const evt = String(
- resolveLiteral(literal)
- );
- if (!definitions2[evt])
- definitions2[evt] = [];
- definitions2[evt].push(buildDefinition(signature));
- }
- }
- return {
- definitions: definitions2,
- definitionsAst: buildDefinition({ scope, type: definitionsAst2 })
- };
- }
- function buildDefinition({
- type,
- scope
- }) {
- return {
- code: resolveTSScope(scope).file.content.slice(type.start, type.end),
- ast: type,
- scope
- };
- }
- }
-
- // src/vue/analyze.ts
- import { parseSFC } from "@vue-macros/common";
- async function analyzeSFC(s, sfc) {
- if (!sfc.scriptSetup)
- throw new Error("Only <script setup> is supported");
- const { scriptSetup } = sfc;
- const body = babelParse3(
- scriptSetup.content,
- sfc.scriptSetup.lang || "js"
- ).body;
- const offset = scriptSetup.loc.start.offset;
- const file = {
- filePath: sfc.filename,
- content: scriptSetup.content,
- ast: body
- };
- let props;
- let emits;
- for (const node of body) {
- if (node.type === "ExpressionStatement") {
- await processDefineProps({
- statement: node,
- defineProps: node.expression
- });
- await processWithDefaults({
- statement: node,
- withDefaults: node.expression
- });
- await processDefineEmits({
- statement: node,
- defineEmits: node.expression
- });
- } else if (node.type === "VariableDeclaration" && !node.declare) {
- for (const decl of node.declarations) {
- if (!decl.init)
- continue;
- await processDefineProps({
- statement: node,
- defineProps: decl.init,
- declId: decl.id
- });
- await processWithDefaults({
- statement: node,
- withDefaults: decl.init,
- declId: decl.id
- });
- await processDefineEmits({
- statement: node,
- defineEmits: decl.init,
- declId: decl.id
- });
- }
- }
- }
- return {
- props,
- emits
- };
- async function processDefineProps({
- defineProps,
- declId,
- statement,
- withDefaultsAst,
- defaultsDeclRaw
- }) {
- var _a;
- if (!isCallOf(defineProps, DEFINE_PROPS) || props)
- return false;
- const typeDeclRaw = (_a = defineProps.typeParameters) == null ? void 0 : _a.params[0];
- if (typeDeclRaw) {
- props = await handleTSPropsDefinition({
- s,
- file,
- sfc,
- offset,
- definePropsAst: defineProps,
- typeDeclRaw,
- withDefaultsAst,
- defaultsDeclRaw,
- statement,
- declId
- });
- } else {
- return false;
- }
- return true;
- }
- async function processWithDefaults({
- withDefaults,
- declId,
- statement: stmt
- }) {
- if (!isCallOf(withDefaults, WITH_DEFAULTS))
- return false;
- if (!isCallOf(withDefaults.arguments[0], DEFINE_PROPS)) {
- throw new SyntaxError(
- `${WITH_DEFAULTS}: first argument must be a ${DEFINE_PROPS} call.`
- );
- }
- const isDefineProps = await processDefineProps({
- defineProps: withDefaults.arguments[0],
- declId,
- statement: stmt,
- withDefaultsAst: withDefaults,
- defaultsDeclRaw: withDefaults.arguments[1]
- });
- if (!isDefineProps)
- return false;
- return true;
- }
- async function processDefineEmits({
- defineEmits,
- declId,
- statement
- }) {
- var _a;
- if (!isCallOf(defineEmits, DEFINE_EMITS) || emits)
- return false;
- const typeDeclRaw = (_a = defineEmits.typeParameters) == null ? void 0 : _a.params[0];
- if (typeDeclRaw) {
- emits = await handleTSEmitsDefinition({
- s,
- file,
- sfc,
- offset,
- defineEmitsAst: defineEmits,
- typeDeclRaw,
- statement,
- declId
- });
- } else {
- return false;
- }
- return true;
- }
- }
- export {
- DefinitionKind,
- MagicString,
- RollupResolve,
- analyzeSFC,
- attachNodeLoc,
- exportsSymbol,
- getTSFile,
- handleTSEmitsDefinition,
- handleTSPropsDefinition,
- inferRuntimeType,
- isTSDeclaration,
- isTSExports,
- keyToString,
- mergeTSProperties,
- parseSFC,
- resolveTSEntityName,
- resolveTSExports,
- resolveTSFileId,
- resolveTSFileIdNode,
- resolveTSProperties,
- resolveTSReferencedType,
- resolveTSScope,
- resolveTypeElements,
- setResolveTSFileIdImpl,
- toRuntimeTypeString,
- tsFileCache,
- tsFileExportsCache
- };
|