feat(custom-widgets): complete Custom JSX v2 (#6390)
This commit is contained in:
1 parent
3a1245cbc5
commit
acdfcbb18e
416 files changed
+37853
-18066
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import { Parser } from "acorn";
|
||||
import jsx from "acorn-jsx";
|
||||
|
||||
import type { AstNode } from "./interpreter-foundation";
|
||||
import { asNode, asNodeArray, SafeJsxError } from "./interpreter-foundation";
|
||||
import { CUSTOM_JSX_LIMITS } from "./policy";
|
||||
|
||||
const JsxParser = Parser.extend(jsx());
|
||||
|
||||
export function parseCustomJsxTemplate(template: string): AstNode {
|
||||
if (template.length > CUSTOM_JSX_LIMITS.templateLength) {
|
||||
throw new SafeJsxError(`Template exceeds the ${CUSTOM_JSX_LIMITS.templateLength} character limit`);
|
||||
}
|
||||
let program: AstNode;
|
||||
try {
|
||||
program = JsxParser.parse(`<>${template}</>`, {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
allowAwaitOutsideFunction: false,
|
||||
allowReturnOutsideFunction: false,
|
||||
}) as unknown as AstNode;
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unable to parse JSX template";
|
||||
throw new SafeJsxError(
|
||||
/Argument name clash/iu.test(message)
|
||||
? "DUPLICATE_LOCAL_BINDING: Callback parameter names must be unique"
|
||||
: message,
|
||||
);
|
||||
}
|
||||
const body = asNodeArray(program.body, "program body");
|
||||
if (body.length !== 1 || body[0]?.type !== "ExpressionStatement") {
|
||||
throw new SafeJsxError("Template must contain JSX only");
|
||||
}
|
||||
return asNode(body[0].expression, "template expression");
|
||||
}
|
||||
|
||||
export function normalizeCustomJsxText(value: string): string {
|
||||
const lines = value.replace(/\r/g, "").split("\n");
|
||||
let result = "";
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
let line = lines[index] ?? "";
|
||||
line = line.replace(/\t/g, " ");
|
||||
if (index !== 0) line = line.replace(/^\s+/, "");
|
||||
if (index !== lines.length - 1) line = line.replace(/\s+$/, "");
|
||||
if (!line) continue;
|
||||
if (result) result += " ";
|
||||
result += line;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user