fix(editor): type nested attribute expressions
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/typecheck",
|
||||
"version": "0.8.15",
|
||||
"version": "0.8.16",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { dirname, join, normalize, resolve } from "node:path";
|
||||
import ts from "typescript";
|
||||
import {
|
||||
containsReadonlyPropMutation,
|
||||
extractInterpolations,
|
||||
inferredRuntimeType,
|
||||
parse,
|
||||
runtimeTypeOf,
|
||||
@@ -332,6 +333,9 @@ export function virtualTypeScriptModule(
|
||||
if (ast.dataApis.length) append(`declare const api: { ${apiType} };`);
|
||||
append(`declare const props: Readonly<${ast.name}Props>;`);
|
||||
append("declare const refs: Record<string, Element | null>;");
|
||||
append(
|
||||
"declare const toast: ((message: string, options?: Record<string, unknown>) => unknown) & { success(message: string, options?: Record<string, unknown>): unknown; error(message: string, options?: Record<string, unknown>): unknown; danger(message: string, options?: Record<string, unknown>): unknown; warning(message: string, options?: Record<string, unknown>): unknown; info(message: string, options?: Record<string, unknown>): unknown; dismiss(id: string | number): void; clear(): void };",
|
||||
);
|
||||
append(
|
||||
"declare function useFetch(path: string, method?: string | { method?: string; query?: unknown; params?: unknown; body?: unknown; data?: unknown }, input?: unknown): Promise<any>;",
|
||||
);
|
||||
@@ -382,7 +386,7 @@ export function virtualTypeScriptModule(
|
||||
for (const attr of node.attrs) {
|
||||
const expressions = attr.event
|
||||
? [attr.value]
|
||||
: [...attr.value.matchAll(/\{([^{}]+)\}/g)].map((match) => match[1]!.trim());
|
||||
: extractInterpolations(attr.value).map((segment) => segment.expression);
|
||||
for (const expression of expressions) {
|
||||
if (!expression.trim()) continue;
|
||||
const declarations = [
|
||||
|
||||
@@ -112,3 +112,32 @@ test("accepts handler payload, loop locals, and the public useFetch helper", ()
|
||||
);
|
||||
expect(diagnostics.filter((diagnostic) => diagnostic.code === "WRN-TYPE-2304")).toEqual([]);
|
||||
});
|
||||
|
||||
test("accepts multiline array props containing nested object literals", () => {
|
||||
const root = app();
|
||||
const diagnostics = checkWrnSource(
|
||||
`page Contact {
|
||||
view {
|
||||
<div data-component="StatsBar" items="{[
|
||||
{ label: 'Product catalog', value: '81', suffix: ' apps' },
|
||||
{ label: 'Starting point', value: 'One workflow' }
|
||||
]}"></div>
|
||||
}
|
||||
}`,
|
||||
{ appRoot: root, filePath: join(root, "app", "pages", "contact.wrn") },
|
||||
);
|
||||
expect(diagnostics.filter((diagnostic) => diagnostic.code.startsWith("WRN-TYPE-"))).toEqual([]);
|
||||
});
|
||||
|
||||
test("provides the toast API to view event expressions", () => {
|
||||
const root = app();
|
||||
const diagnostics = checkWrnSource(
|
||||
`page Contact {
|
||||
view {
|
||||
<form @wrn:success="toast.success('Sent', { title: 'Request sent' })"></form>
|
||||
}
|
||||
}`,
|
||||
{ appRoot: root, filePath: join(root, "app", "pages", "contact.wrn") },
|
||||
);
|
||||
expect(diagnostics.filter((diagnostic) => diagnostic.code.startsWith("WRN-TYPE-"))).toEqual([]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user