88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import type { PageAst } from "@wrnexus/syntax";
|
|
|
|
export interface ComponentContractMetadata {
|
|
name: string;
|
|
kind: PageAst["kind"];
|
|
props: Array<{
|
|
name: string;
|
|
type: string;
|
|
required: boolean;
|
|
default?: string;
|
|
options?: string[];
|
|
}>;
|
|
outputs: Array<{ name: string; payloadName?: string; payloadType?: string }>;
|
|
functions: Array<{
|
|
name: string;
|
|
runtime: string;
|
|
async: boolean;
|
|
parameters: Array<{ name: string; type: string; optional: boolean }>;
|
|
returnType: string;
|
|
}>;
|
|
states: Array<{ name: string; runtime: string; type: string; initializer: string }>;
|
|
computed: Array<{ name: string; type: string; expression: string }>;
|
|
imports: Array<{
|
|
source: string;
|
|
typeOnly: boolean;
|
|
defaultImport?: string;
|
|
namedImports: string[];
|
|
}>;
|
|
}
|
|
|
|
function unionOptions(type: string | undefined): string[] | undefined {
|
|
if (!type || !type.includes("|")) return undefined;
|
|
const values = type
|
|
.split("|")
|
|
.map((part) => part.trim())
|
|
.filter((part) => /^(?:"[^"]*"|'[^']*')$/.test(part))
|
|
.map((part) => part.slice(1, -1));
|
|
return values.length ? values : undefined;
|
|
}
|
|
|
|
export function createComponentContract(ast: PageAst): ComponentContractMetadata {
|
|
return {
|
|
name: ast.name,
|
|
kind: ast.kind,
|
|
props: ast.props.map((prop) => ({
|
|
name: prop.name,
|
|
type: prop.valueType ?? "unknown",
|
|
required: prop.required,
|
|
...(prop.default !== "undefined" ? { default: prop.default } : {}),
|
|
...(unionOptions(prop.valueType) ? { options: unionOptions(prop.valueType) } : {}),
|
|
})),
|
|
outputs: ast.outputs.map((output) => ({
|
|
name: output.name,
|
|
...(output.payload
|
|
? { payloadName: output.payload.name, payloadType: output.payload.valueType }
|
|
: {}),
|
|
})),
|
|
functions: ast.runtimeFunctions.map((fn) => ({
|
|
name: fn.name,
|
|
runtime: fn.runtime,
|
|
async: fn.async,
|
|
parameters: fn.parameters.map((param) => ({
|
|
name: param.name,
|
|
type: param.valueType ?? "unknown",
|
|
optional: param.optional,
|
|
})),
|
|
returnType: fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown"),
|
|
})),
|
|
states: ast.states.map((state) => ({
|
|
name: state.name,
|
|
runtime: state.runtime,
|
|
type: state.valueType ?? "unknown",
|
|
initializer: state.expr,
|
|
})),
|
|
computed: ast.computed.map((entry) => ({
|
|
name: entry.name,
|
|
type: entry.valueType ?? "unknown",
|
|
expression: entry.expr,
|
|
})),
|
|
imports: ast.structuredImports.map((entry) => ({
|
|
source: entry.source,
|
|
typeOnly: entry.typeOnly,
|
|
...(entry.defaultImport ? { defaultImport: entry.defaultImport } : {}),
|
|
namedImports: entry.namedImports.map((named) => named.local),
|
|
})),
|
|
};
|
|
}
|