@vue-macros/api
Version:
General API for Vue Macros.
329 lines (328 loc) • 13.5 kB
TypeScript
import { MagicStringAST, SFC, SFC as SFC$1, TransformError, parseSFC } from "@vue-macros/common";
import * as neverthrow0 from "neverthrow";
import { ResultAsync as ResultAsync$1 } from "neverthrow";
import { BigIntLiteral, BooleanLiteral, CallExpression, Declaration, Expression, ExpressionStatement, Identifier, LVal, Node, NumericLiteral, ObjectMethod, ObjectProperty, Statement, StringLiteral, TSCallSignatureDeclaration, TSConstructSignatureDeclaration, TSFunctionType, TSIndexedAccessType, TSInterfaceBody, TSInterfaceDeclaration, TSIntersectionType, TSLiteralType, TSMappedType, TSMethodSignature, TSModuleBlock, TSParenthesizedType, TSPropertySignature, TSType, TSTypeAliasDeclaration, TSTypeElement, TSTypeLiteral, TSTypeOperator, TSTypeReference, TSUnionType, TemplateLiteral, TypeScript, VariableDeclaration, VoidPattern } from "@babel/types";
import { Plugin } from "vite";
export * from "@vue-macros/common";
//#region src/error.d.ts
type ErrorVueSFC = "<script> is not supported, only <script setup>.";
type ErrorResolveTS = "Cannot resolve TS definition." | "Cannot resolve TS definition. Union type contains different types of results." | `Cannot resolve TS definition: ${string}` | `Cannot resolve TS type: ${string}`;
type ErrorWithDefaults = "withDefaults: first argument must be a defineProps call.";
type ErrorUnknownNode = `Unknown node: ${string}` | `Unknown ${"import" | "export"} type: ${string}`;
type Error = TransformError<ErrorVueSFC | ErrorResolveTS | ErrorWithDefaults | ErrorUnknownNode>;
type ResultAsync<T> = neverthrow0.ResultAsync<T, Error>;
//#endregion
//#region src/ts/is.d.ts
type TSDeclaration = TypeScript & Declaration;
declare function isTSDeclaration(node: any): node is TSDeclaration;
//#endregion
//#region src/ts/scope.d.ts
interface TSScopeBase {
exports?: TSNamespace;
declarations?: TSNamespace;
}
interface TSFile extends TSScopeBase {
kind: "file";
filePath: string;
content: string;
/** could be undefined if it's a JSON file */
ast: Statement[] | undefined;
}
interface TSModule extends TSScopeBase {
kind: "module";
ast: TSModuleBlock;
scope: TSScope;
}
type TSScope = TSFile | TSModule;
declare const tsFileCache: Record<string, TSFile>;
declare function getTSFile(filePath: string): Promise<TSFile>;
interface ResolvedTSScope {
isFile: boolean;
file: TSFile;
body: Statement[] | undefined;
exports?: TSNamespace;
declarations?: TSNamespace;
}
declare function resolveTSScope(scope: TSScope): ResolvedTSScope;
//#endregion
//#region src/ts/resolve-reference.d.ts
interface TSResolvedType<T = Exclude<TSType, TSParenthesizedType> | Exclude<TSDeclaration, TSTypeAliasDeclaration>> {
scope: TSScope;
type: T;
}
type TSReferencedType = TSType | Identifier | TSDeclaration;
declare function isSupportedForTSReferencedType(node: Node): node is TSReferencedType;
/**
* Resolve a reference to a type.
*
* Supports `type` and `interface` only.
*
* @limitation don't support non-TS declaration (e.g. class, function...)
*/
declare function resolveTSReferencedType(ref: TSResolvedType<TSReferencedType>, stacks?: TSResolvedType<any>[]): ResultAsync$1<TSResolvedType | TSNamespace | undefined, TransformError<ErrorUnknownNode>>;
//#endregion
//#region src/ts/namespace.d.ts
declare const namespaceSymbol: unique symbol;
type TSNamespace = { [K in string]: TSResolvedType | TSNamespace | undefined } & {
[namespaceSymbol]: true;
};
declare function isTSNamespace(val: unknown): val is TSNamespace;
/**
* Get exports of the TS file.
*
* @limitation don't support non-TS declaration (e.g. class, function...)
*/
declare function resolveTSNamespace(scope: TSScope): ResultAsync$1<void, TransformError<ErrorUnknownNode>>;
//#endregion
//#region src/ts/property.d.ts
interface TSProperties {
callSignatures: Array<TSResolvedType<TSCallSignatureDeclaration | TSFunctionType>>;
constructSignatures: Array<TSResolvedType<TSConstructSignatureDeclaration>>;
methods: Record<string | number, Array<TSResolvedType<TSMethodSignature>>>;
properties: Record<string | number, {
value: TSResolvedType<TSType> | null;
optional: boolean;
signature: TSResolvedType<TSPropertySignature | TSMappedType>;
}>;
}
declare function mergeTSProperties(a: TSProperties, b: TSProperties): TSProperties;
declare function checkForTSProperties(node?: Node): node is TSInterfaceDeclaration | TSInterfaceBody | TSTypeLiteral | TSIntersectionType | TSMappedType | TSFunctionType;
/**
* get properties of `interface` or `type` declaration
*
* @limitation don't support index signature
*/
declare function resolveTSProperties({
type,
scope
}: TSResolvedType<TSInterfaceDeclaration | TSInterfaceBody | TSTypeLiteral | TSIntersectionType | TSMappedType | TSFunctionType>): ResultAsync$1<TSProperties, TransformError<ErrorUnknownNode>>;
declare function getTSPropertiesKeys(properties: TSProperties): string[];
//#endregion
//#region src/ts/resolve-file.d.ts
declare function resolveDts(id: string, importer: string): Promise<string | undefined>;
declare const resolveDtsHMR: NonNullable<Plugin["handleHotUpdate"]>;
//#endregion
//#region src/ts/resolve.d.ts
declare function resolveTSTemplateLiteral({
type,
scope
}: TSResolvedType<TemplateLiteral>): ResultAsync$1<StringLiteral[], TransformError<ErrorUnknownNode>>;
declare function resolveTSLiteralType({
type,
scope
}: TSResolvedType<TSLiteralType>): ResultAsync$1<StringLiteral[] | NumericLiteral | StringLiteral | BooleanLiteral | BigIntLiteral | undefined, TransformError<ErrorUnknownNode>>;
/**
* @limitation don't support index signature
*/
declare function resolveTypeElements(scope: TSScope, elements: Array<TSTypeElement>): TSProperties;
declare function resolveTSIndexedAccessType({
scope,
type
}: TSResolvedType<TSIndexedAccessType>, stacks?: TSResolvedType<any>[]): ResultAsync$1<{
type: TSUnionType;
scope: TSScope;
} | void, TransformError<ErrorUnknownNode>>;
declare function resolveTSTypeOperator({
scope,
type
}: TSResolvedType<TSTypeOperator>, stacks?: TSResolvedType<any>[]): ResultAsync$1<StringLiteral[] | void, TransformError<ErrorUnknownNode>>;
declare function resolveMaybeTSUnion<T extends Node>(node: T | T[]): T[];
declare function resolveMaybeTSUnion<T extends Node>(node: T): (T | TSType)[];
//#endregion
//#region src/vue/types.d.ts
declare enum DefinitionKind {
/**
* Definition is a referenced variable.
*
* @example defineSomething(foo)
*/
Reference = "Reference",
/**
* Definition is a `ObjectExpression`.
*
* @example defineSomething({ ... })
*/
Object = "Object",
/**
* Definition is TypeScript interface.
*
* @example defineSomething<{ ... }>()
*/
TS = "TS",
}
interface ASTDefinition<T extends Node> {
code: string;
scope: TSFile | TSModule | undefined;
ast: T;
}
//#endregion
//#region src/vue/emits.d.ts
declare function handleTSEmitsDefinition({
s,
file,
offset,
defineEmitsAst,
typeDeclRaw,
declId,
statement
}: {
s: MagicStringAST;
file: TSFile;
sfc: SFC$1;
offset: number;
defineEmitsAst: CallExpression;
typeDeclRaw: TSType;
statement: DefineEmitsStatement;
declId?: VoidPattern | LVal;
}): ResultAsync$1<TSEmits, TransformError<ErrorResolveTS | ErrorUnknownNode>>;
type Emits = TSEmits | undefined;
type DefineEmitsStatement = VariableDeclaration | ExpressionStatement;
interface EmitsBase {
declId?: VoidPattern | LVal;
statementAst: DefineEmitsStatement;
defineEmitsAst: CallExpression;
}
interface TSEmits extends EmitsBase {
kind: DefinitionKind.TS;
definitions: Record<string, ASTDefinition<TSCallSignatureDeclaration | TSFunctionType | TSPropertySignature | TSMappedType>[]>;
definitionsAst: ASTDefinition<TSTypeLiteral | TSIntersectionType | TSInterfaceDeclaration | TSFunctionType>;
/**
* Adds a new emit to the definitions. `definitions` will updated after this call.
*
* Added definition cannot be set and removed again.
*
* @example add('change', '(evt: "change", value: string): void')
*/
addEmit: (name: string | StringLiteral, signature: string) => void;
/**
* Modify a definition of a emit. `definitions` will updated after this call.
*
* @limitation Cannot set the emit added by `addEmit`.
*
* @example setEmit('foo', 0, '(evt: "change", value: string): void')
*
* @returns false if the definition does not exist.
*/
setEmit: (name: string | StringLiteral, index: number, signature: string) => boolean;
/**
* Removes specified emit from TS interface. `definitions` will updated after this call.
*
* @limitation Cannot remove emit added by `addEmit`. (it will be removed in definitions though)
*
* @returns `true` if emit was removed, `false` if emit was not found.
*/
removeEmit: (name: string | StringLiteral, index: number) => boolean;
}
//#endregion
//#region src/vue/props.d.ts
declare function handleTSPropsDefinition({
s,
file,
offset,
definePropsAst,
typeDeclRaw,
withDefaultsAst,
defaultsDeclRaw,
statement,
declId
}: {
s: MagicStringAST;
file: TSFile;
sfc: SFC$1;
offset: number;
definePropsAst: CallExpression;
typeDeclRaw: TSType;
withDefaultsAst?: CallExpression;
defaultsDeclRaw?: DefaultsASTRaw;
statement: DefinePropsStatement;
declId?: VoidPattern | LVal;
}): ResultAsync$1<TSProps, TransformError<ErrorResolveTS | ErrorUnknownNode>>;
type Props = TSProps | undefined;
type DefinePropsStatement = VariableDeclaration | ExpressionStatement;
type DefaultsASTRaw = CallExpression["arguments"][number];
interface PropsBase {
declId?: VoidPattern | LVal;
statementAst: DefinePropsStatement;
definePropsAst: CallExpression;
withDefaultsAst?: CallExpression;
}
interface TSPropsMethod {
type: "method";
methods: ASTDefinition<TSMethodSignature>[];
optional: boolean;
}
interface TSPropsProperty {
type: "property";
value: ASTDefinition<TSResolvedType["type"]> | undefined;
optional: boolean;
signature: ASTDefinition<TSPropertySignature | TSMappedType>;
/** Whether added by `addProp` API */
addByAPI: boolean;
}
interface RuntimePropDefinition {
type: string[];
required: boolean;
default?: (key?: string) => string;
}
interface TSProps extends PropsBase {
kind: DefinitionKind.TS;
definitions: Record<string | number, TSPropsMethod | TSPropsProperty>;
definitionsAst: ASTDefinition<TSInterfaceDeclaration | TSTypeLiteral | TSIntersectionType | TSUnionType | TSMappedType | TSTypeReference>;
/**
* Default value of props.
*
* `undefined` if not defined or it's not a static expression that cannot be analyzed statically.
*/
defaults?: Record<string, ObjectMethod | ObjectProperty>;
/**
* `undefined` if not defined.
*/
defaultsAst?: Expression;
/**
* Adds a new prop to the definitions. `definitions` will updated after this call.
*
* Added definition cannot be set and removed again.
*
* @example addProp('foo', 'string | boolean')
*
* @returns false if the definition already exists.
*/
addProp: (name: string | StringLiteral, type: string, optional?: boolean) => boolean;
/**
* Modify a definition of a prop. `definitions` will updated after this call.
*
* @limitation Cannot set the prop added by `addProp`.
*
* @example setProp('foo', 'string | boolean')
*
* @returns false if the definition does not exist.
*/
setProp: (name: string | StringLiteral, type: string, optional?: boolean) => boolean;
/**
* Removes specified prop from TS interface. `definitions` will updated after this call.
*
* @limitation Cannot remove prop added by `addProp`. (it will be removed in definitions though)
*
* @returns `true` if prop was removed, `false` if prop was not found.
*/
removeProp: (name: string | StringLiteral) => boolean;
/**
* get runtime definitions.
*/
getRuntimeDefinitions: () => ResultAsync$1<Record<string, RuntimePropDefinition>, TransformError<ErrorUnknownNode>>;
}
//#endregion
//#region src/vue/analyze.d.ts
interface AnalyzeResult {
props: Props;
emits: Emits;
}
declare function analyzeSFC(s: MagicStringAST, sfc: SFC$1): ResultAsync$1<AnalyzeResult, Error>;
//#endregion
//#region src/vue/utils.d.ts
declare const UNKNOWN_TYPE = "Unknown";
declare function inferRuntimeType(node: TSResolvedType | TSNamespace): ResultAsync$1<string[], TransformError<ErrorUnknownNode>>;
declare function attachNodeLoc(node: Node, newNode: Node): void;
declare function genRuntimePropDefinition(types: string[] | undefined, isProduction: boolean, properties: string[]): string;
//#endregion
export { ASTDefinition, AnalyzeResult, DefaultsASTRaw, DefineEmitsStatement, DefinePropsStatement, DefinitionKind, Emits, EmitsBase, Error, ErrorResolveTS, ErrorUnknownNode, ErrorVueSFC, ErrorWithDefaults, Props, PropsBase, ResultAsync, RuntimePropDefinition, type SFC, TSDeclaration, TSEmits, TSFile, TSModule, TSNamespace, TSProperties, TSProps, TSPropsMethod, TSPropsProperty, TSResolvedType, TSScope, TSScopeBase, UNKNOWN_TYPE, analyzeSFC, attachNodeLoc, checkForTSProperties, genRuntimePropDefinition, getTSFile, getTSPropertiesKeys, handleTSEmitsDefinition, handleTSPropsDefinition, inferRuntimeType, isSupportedForTSReferencedType, isTSDeclaration, isTSNamespace, mergeTSProperties, namespaceSymbol, parseSFC, resolveDts, resolveDtsHMR, resolveMaybeTSUnion, resolveTSIndexedAccessType, resolveTSLiteralType, resolveTSNamespace, resolveTSProperties, resolveTSReferencedType, resolveTSScope, resolveTSTemplateLiteral, resolveTSTypeOperator, resolveTypeElements, tsFileCache };