release: WRNexusJS 0.8.0
Quality / quality (ubuntu-latest) (push) Failing after 12m19s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-04 12:19:09 +05:30
parent 4cebacadfe
commit 72e4d3eceb
108 changed files with 2276 additions and 532 deletions
+139 -7
View File
@@ -1,6 +1,6 @@
"use strict";
// Generated by scripts/build-editor-compiler.mjs. Do not edit directly.
// WRN editor compiler source hash: b9e9a9ed0492c387198e368436696480ef2eca5a850ed94852c78c73c70d2959
// WRN editor compiler source hash: 1d2e0d1e1c38a4513b0fce3631bae003f7c28069920c5386ecc68cbe728bf57b
// WRN editor compiler generator hash: c71e7fe4258c97b73b384ff14b321f0cf0b30cc2ed0322f5f84b04e757159b18
// Generated with TypeScript: 5.9.3
const __nodeRequire = require;
@@ -4845,6 +4845,18 @@ function formatOpeningTag(value, unit, depth, printWidth = 100, multilineAttribu
opensElement,
};
}
if (parsed.attributes.length === 0 && !parsed.selfClosing) {
const lines = [`${baseIndent}<${parsed.tagName}>`];
if (parsed.trailingClosing) {
if (parsed.inlineContent)
lines.push(`${childIndent}${parsed.inlineContent}`);
lines.push(`${baseIndent}</${parsed.tagName}>`);
}
else if (parsed.remainder) {
lines.push(`${childIndent}${parsed.remainder}`);
}
return { lines, opensElement };
}
const lines = [
`${baseIndent}<${parsed.tagName}`,
...parsed.attributes.flatMap((attribute) => formatAttribute(attribute, childIndent, unit)),
@@ -4886,6 +4898,73 @@ function isMultilineOpeningTagStart(value) {
function isClosingTag(value) {
return /^<\/[A-Za-z][\w$:.-]*\s*>/.test(value);
}
/**
* Preserve compact, already-balanced HTML fragments as one line.
*
* A line such as `<span>Page</span><b>→</b><span>API</span>` is valid and
* intentionally compact. Expanding only its first opening tag makes later
* formatter passes treat the remaining siblings as children, causing runaway
* indentation and false closing-tag diagnostics. Balanced fragments are kept
* intact while normal multiline opening tags continue through the formatter.
*/
function isBalancedInlineHtmlFragment(value) {
if (!value.startsWith("<") || value.startsWith("</") || value.startsWith("<!--")) {
return false;
}
const stack = [];
let tagCount = 0;
let rootCount = 0;
let hasNestedElement = false;
let hasOutsideText = false;
let index = 0;
while (index < value.length) {
const tagStart = value.indexOf("<", index);
if (tagStart === -1) {
if (stack.length === 0 && value.slice(index).trim())
hasOutsideText = true;
break;
}
if (stack.length === 0 && value.slice(index, tagStart).trim())
hasOutsideText = true;
if (value.startsWith("<!--", tagStart)) {
const commentEnd = value.indexOf("-->", tagStart + 4);
if (commentEnd === -1)
return false;
index = commentEnd + 3;
continue;
}
const relativeEnd = findOpeningTagEnd(value.slice(tagStart));
if (relativeEnd === -1)
return false;
const tag = value.slice(tagStart, tagStart + relativeEnd + 1);
const match = /^<\/?([A-Za-z][\w$:.-]*)[\s\S]*?>$/.exec(tag);
if (!match) {
index = tagStart + 1;
continue;
}
tagCount += 1;
const tagName = match[1];
const normalizedName = /^[a-z]/.test(tagName) ? tagName.toLowerCase() : tagName;
const closing = tag.startsWith("</");
const selfClosing = /\/\s*>$/.test(tag);
const voidElement = VOID_ELEMENTS.has(tagName.toLowerCase());
if (closing) {
if (stack.at(-1) !== normalizedName)
return false;
stack.pop();
}
else {
if (stack.length === 0)
rootCount += 1;
else
hasNestedElement = true;
if (!selfClosing && !voidElement)
stack.push(normalizedName);
}
index = tagStart + relativeEnd + 1;
}
return (tagCount >= 2 && stack.length === 0 && (rootCount > 1 || hasNestedElement || hasOutsideText));
}
function isControlBlockOpen(value) {
return /^\{#(?:if|each)\b[\s\S]*\}$/.test(value);
}
@@ -4991,6 +5070,41 @@ function collectOpeningTag(inputLines, startIndex) {
endIndex: index,
};
}
function isPreservedRawBlockStart(value) {
return (/<pre(?:\s|>)/i.test(value) &&
!/<\/pre\s*>/i.test(value.slice(0, value.search(/<pre(?:\s|>)/i))));
}
function hasPreservedRawBlockEnd(value) {
return /<\/pre\s*>/i.test(value);
}
function transformOutsidePreservedRawBlocks(lines, transformLine) {
const output = [];
let preserving = false;
for (const line of lines) {
if (preserving) {
output.push(line);
if (hasPreservedRawBlockEnd(line))
preserving = false;
continue;
}
if (isPreservedRawBlockStart(line)) {
output.push(line);
preserving = !hasPreservedRawBlockEnd(line);
continue;
}
output.push(...transformLine(line));
}
return output;
}
function collectPreservedRawBlock(lines, startIndex) {
const collected = [lines[startIndex]];
let index = startIndex;
while (!hasPreservedRawBlockEnd(collected.at(-1) || "") && index + 1 < lines.length) {
index += 1;
collected.push(lines[index]);
}
return { lines: collected, endIndex: index };
}
/**
* Put WRN template control markers on their own lines before indentation.
*
@@ -5000,7 +5114,7 @@ function collectOpeningTag(inputLines, startIndex) {
*/
function expandInlineControlBlocks(lines) {
const marker = /(\{#(?:if|each)\b[^}]*\}|\{:(?:else(?:\s+if\b[^}]*)?|empty)\}|\{\/(?:if|each)\})/g;
return lines.flatMap((line) => {
return transformOutsidePreservedRawBlocks(lines, (line) => {
if (!marker.test(line))
return [line];
marker.lastIndex = 0;
@@ -5013,7 +5127,7 @@ function expandInlineControlBlocks(lines) {
});
}
function expandStructuredStateDeclarations(lines, unit) {
return lines.flatMap((line) => {
return transformOutsidePreservedRawBlocks(lines, (line) => {
const match = /^(\s*state\s+[A-Za-z_$][\w$]*\s*=\s*)([\\[{][\s\S]*)$/.exec(line);
if (!match)
return [line];
@@ -5068,6 +5182,14 @@ function formatWrnPass(source, options = {}) {
index += 1;
continue;
}
if (isPreservedRawBlockStart(value)) {
const collected = collectPreservedRawBlock(inputLines, index);
const depth = codeDepth + htmlDepth + controlDepth;
output.push(`${unit.repeat(depth)}${collected.lines[0].trimStart()}`);
output.push(...collected.lines.slice(1));
index = collected.endIndex + 1;
continue;
}
if (isMultilineOpeningTagStart(value)) {
const collected = collectOpeningTag(inputLines, index);
value = collected.value;
@@ -5090,7 +5212,11 @@ function formatWrnPass(source, options = {}) {
lineHtmlDepth = Math.max(0, htmlDepth - 1);
}
const depth = lineCodeDepth + lineHtmlDepth + lineControlDepth;
if (value.startsWith("<") &&
const inlineFragmentFits = unit.repeat(depth).length + value.length <= printWidth;
if (isBalancedInlineHtmlFragment(value) && inlineFragmentFits) {
output.push(`${unit.repeat(depth)}${value}`);
}
else if (value.startsWith("<") &&
!value.startsWith("</") &&
!value.startsWith("<!--") &&
!value.startsWith("<!") &&
@@ -6639,11 +6765,17 @@ function runtimeTypeOf(annotation) {
if (!annotation)
return "unknown";
const type = annotation.trim().replace(/^readonly\s+/, "");
if (/^(?:string|String)(?:\s*\|\s*(?:null|undefined))*$/.test(type))
const unionParts = type.split("|").map((part) => part.trim());
const concreteParts = unionParts.filter((part) => !/^(?:null|undefined)$/.test(part));
if (/^(?:string|String)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
(concreteParts.length > 0 && concreteParts.every((part) => /^(?:"[^"]*"|'[^']*')$/.test(part))))
return "string";
if (/^(?:number|Number)(?:\s*\|\s*(?:null|undefined))*$/.test(type))
if (/^(?:number|Number)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
(concreteParts.length > 0 &&
concreteParts.every((part) => /^-?(?:\d+\.?\d*|\.\d+)$/.test(part))))
return "number";
if (/^(?:boolean|Boolean)(?:\s*\|\s*(?:null|undefined))*$/.test(type))
if (/^(?:boolean|Boolean)(?:\s*\|\s*(?:null|undefined))*$/.test(type) ||
(concreteParts.length > 0 && concreteParts.every((part) => /^(?:true|false)$/.test(part))))
return "boolean";
if (/^bigint(?:\s*\|\s*(?:null|undefined))*$/.test(type))
return "bigint";