fix(formatter): expand large structured prop defaults
This commit is contained in:
@@ -668,7 +668,7 @@
|
||||
},
|
||||
"packages/syntax": {
|
||||
"name": "@wrnexus/syntax",
|
||||
"version": "0.8.16",
|
||||
"version": "0.8.17",
|
||||
},
|
||||
"packages/test": {
|
||||
"name": "@wrnexus/test",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "wrnexus",
|
||||
"displayName": "WRNexus Language Support",
|
||||
"description": "Complete WRNexus v0.8.3 language support for typed imports, props, state, outputs, runtime functions, stores, diagnostics, formatting, navigation, and migration assistance.",
|
||||
"version": "0.8.9",
|
||||
"version": "0.8.10",
|
||||
"publisher": "wrnexus",
|
||||
"private": true,
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
// Generated by scripts/build-editor-compiler.mjs. Do not edit directly.
|
||||
// WRN editor compiler source hash: 884c9faffb5517c907321484014e00562654ea0ba96e432bec319e0001934446
|
||||
// WRN editor compiler source hash: edac5449f97a341e79ee7bf7e7f3676f42bbb4ec6aac4432f5ace9ff88f4f85c
|
||||
// WRN editor compiler generator hash: f8c1094b47e695151205899de28cd63d574356d26ac49219c4a43db0f2391ef5
|
||||
// Generated with TypeScript: 6.0.3
|
||||
const __nodeRequire = require;
|
||||
@@ -6227,6 +6227,26 @@ function expandStructuredStateDeclarations(lines, unit) {
|
||||
}
|
||||
});
|
||||
}
|
||||
function formatStructuredPropDeclaration(value, unit, depth, printWidth) {
|
||||
const match = /^([A-Za-z_$][\w$]*\??\s*(?::\s*[^=]+?)?\s*=\s*)([\[{][\s\S]*)$/.exec(value);
|
||||
if (!match)
|
||||
return null;
|
||||
try {
|
||||
const parsed = JSON.parse(match[2].trim());
|
||||
const compact = JSON.stringify(parsed);
|
||||
const indentation = unit.repeat(depth);
|
||||
if (indentation.length + match[1].length + compact.length <= printWidth)
|
||||
return null;
|
||||
const jsonLines = JSON.stringify(parsed, null, unit).split("\n");
|
||||
return [
|
||||
`${indentation}${match[1]}${jsonLines[0]}`,
|
||||
...jsonLines.slice(1).map((jsonLine) => `${indentation}${jsonLine}`),
|
||||
];
|
||||
}
|
||||
catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function formatWrnPass(source, options = {}) {
|
||||
const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize ?? 4);
|
||||
const printWidth = options.printWidth ?? 100;
|
||||
@@ -6282,6 +6302,12 @@ function formatWrnPass(source, options = {}) {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
const structuredProp = formatStructuredPropDeclaration(value, unit, codeDepth + htmlDepth + controlDepth, printWidth);
|
||||
if (structuredProp) {
|
||||
output.push(...structuredProp);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
const leadingClosingBraces = countLeadingClosingBraces(value);
|
||||
const closesControlBlock = isControlBlockClose(value);
|
||||
const continuesControlBlock = isControlBlockMiddle(value);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// WRN editor extension source hash: 8e634610c27521e6ccbf4e7293eb4320ecaac29944bde5236bb286ff84422203
|
||||
// WRN editor extension source hash: 2f8a27685e497dffd4c27303333c9c34fb7571b0add2e6a781240f7353f1c86b
|
||||
// WRN editor extension generator hash: 456d1d614e44e5fb1f19b784176c09cf2ade9b64ef73a17934c2698150b62728
|
||||
"use strict";
|
||||
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
// WRN editor language server source hash: 64ecd72706de345e7e8891089d2c3d1aa5c1c2beaa7cf9b816ba32a9c4ad6c54
|
||||
// WRN editor language server source hash: 6d790d593fb074f5e55837db3f757162f0e59e77cd6f8643afd1e93e6ff4a2ef
|
||||
// WRN editor language server generator hash: f593a44aaf05495b789ce7a3086bee1eebb951b884d41c0e017bbcfe5f547e72
|
||||
// @bun @bun-cjs
|
||||
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
|
||||
@@ -170722,6 +170722,26 @@ function expandStructuredStateDeclarations(lines, unit) {
|
||||
}
|
||||
});
|
||||
}
|
||||
function formatStructuredPropDeclaration(value, unit, depth, printWidth) {
|
||||
const match = /^([A-Za-z_$][\w$]*\??\s*(?::\s*[^=]+?)?\s*=\s*)([\[{][\s\S]*)$/.exec(value);
|
||||
if (!match)
|
||||
return null;
|
||||
try {
|
||||
const parsed = JSON.parse(match[2].trim());
|
||||
const compact = JSON.stringify(parsed);
|
||||
const indentation = unit.repeat(depth);
|
||||
if (indentation.length + match[1].length + compact.length <= printWidth)
|
||||
return null;
|
||||
const jsonLines = JSON.stringify(parsed, null, unit).split(`
|
||||
`);
|
||||
return [
|
||||
`${indentation}${match[1]}${jsonLines[0]}`,
|
||||
...jsonLines.slice(1).map((jsonLine) => `${indentation}${jsonLine}`)
|
||||
];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function formatWrnPass(source, options = {}) {
|
||||
const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize ?? 4);
|
||||
const printWidth = options.printWidth ?? 100;
|
||||
@@ -170778,6 +170798,12 @@ function formatWrnPass(source, options = {}) {
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
const structuredProp = formatStructuredPropDeclaration(value, unit, codeDepth + htmlDepth + controlDepth, printWidth);
|
||||
if (structuredProp) {
|
||||
output.push(...structuredProp);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
const leadingClosingBraces = countLeadingClosingBraces(value);
|
||||
const closesControlBlock = isControlBlockClose(value);
|
||||
const continuesControlBlock = isControlBlockMiddle(value);
|
||||
|
||||
@@ -20,6 +20,20 @@ test("preserves nested prop defaults while formatting", () => {
|
||||
assert.equal(formatWrn(formatted, { insertSpaces: true, tabSize: 2 }), formatted);
|
||||
});
|
||||
|
||||
test("formats large typed JSON prop defaults with the bundled formatter", () => {
|
||||
const source = `component Catalog {
|
||||
props {
|
||||
categories: unknown[] = [{"label":"Platform & Core","apps":[{"label":"Home","href":"/home"},{"label":"SSO","href":"/sso"}]},{"label":"Sales","apps":[{"label":"CRM","href":"/crm"}]}]
|
||||
}
|
||||
view { <div></div> }
|
||||
}`;
|
||||
const formatted = formatWrn(source, { insertSpaces: true, tabSize: 2, printWidth: 70 });
|
||||
|
||||
assert.match(formatted, /categories: unknown\[\] = \[\n \{/);
|
||||
assert.match(formatted, /"apps": \[\n \{/);
|
||||
assert.equal(formatWrn(formatted, { insertSpaces: true, tabSize: 2, printWidth: 70 }), formatted);
|
||||
});
|
||||
|
||||
test("formats native JSON state values with readable indentation", () => {
|
||||
const source = `component Footer {
|
||||
state footerItems = [{"label":"Accessibility","href":"/accessibility","value":"accessibility"},{"label":"Privacy","href":"/privacy","value":"privacy"}]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/syntax",
|
||||
"version": "0.8.16",
|
||||
"version": "0.8.17",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -767,6 +767,28 @@ function expandStructuredStateDeclarations(lines, unit) {
|
||||
});
|
||||
}
|
||||
|
||||
function formatStructuredPropDeclaration(value, unit, depth, printWidth) {
|
||||
const match = /^([A-Za-z_$][\w$]*\??\s*(?::\s*[^=]+?)?\s*=\s*)([\[{][\s\S]*)$/.exec(
|
||||
value,
|
||||
);
|
||||
if (!match) return null;
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(match[2].trim());
|
||||
const compact = JSON.stringify(parsed);
|
||||
const indentation = unit.repeat(depth);
|
||||
if (indentation.length + match[1].length + compact.length <= printWidth) return null;
|
||||
|
||||
const jsonLines = JSON.stringify(parsed, null, unit).split("\n");
|
||||
return [
|
||||
`${indentation}${match[1]}${jsonLines[0]}`,
|
||||
...jsonLines.slice(1).map((jsonLine) => `${indentation}${jsonLine}`),
|
||||
];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function formatWrnPass(source: string, options: FormatWrnOptions = {}): string {
|
||||
const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize ?? 4);
|
||||
|
||||
@@ -844,6 +866,18 @@ function formatWrnPass(source: string, options: FormatWrnOptions = {}): string {
|
||||
continue;
|
||||
}
|
||||
|
||||
const structuredProp = formatStructuredPropDeclaration(
|
||||
value,
|
||||
unit,
|
||||
codeDepth + htmlDepth + controlDepth,
|
||||
printWidth,
|
||||
);
|
||||
if (structuredProp) {
|
||||
output.push(...structuredProp);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const leadingClosingBraces = countLeadingClosingBraces(value);
|
||||
|
||||
const closesControlBlock = isControlBlockClose(value);
|
||||
|
||||
@@ -83,3 +83,18 @@ test("preserves balanced compact sibling markup without indentation drift", () =
|
||||
expect(formatted).toContain('<div class="strip"><span>Page</span><b>→</b><span>API</span></div>');
|
||||
expect(formatWrn(formatted, { tabSize: 2, printWidth: 80 })).toBe(formatted);
|
||||
});
|
||||
|
||||
test("formats large typed JSON prop defaults and remains idempotent", () => {
|
||||
const source = `component Catalog {
|
||||
props {
|
||||
categories: unknown[] = [{"label":"Platform & Core","value":"platform","apps":[{"label":"WRNexus Home / Business Command Center","href":"/products/home","number":"01"},{"label":"SSO & Account","href":"/products/sso","number":"02"}]},{"label":"Sales & Customer","value":"sales","apps":[{"label":"CRM","href":"/products/crm","number":"11"}]}]
|
||||
}
|
||||
view { <div></div> }
|
||||
}`;
|
||||
const formatted = formatWrn(source, options);
|
||||
|
||||
expect(formatted).toContain(`categories: unknown[] = [\n {\n "label": "Platform & Core"`);
|
||||
expect(formatted).toContain(`"apps": [\n {`);
|
||||
expect(formatWrn(formatted, options)).toBe(formatted);
|
||||
expect(() => parse(formatted)).not.toThrow();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user