@jxsuite/studio 0.28.2 → 0.28.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/studio.js +86144 -83971
- package/dist/studio.js.map +229 -219
- package/package.json +5 -5
- package/src/browse/browse-modal.ts +9 -3
- package/src/browse/browse.ts +139 -82
- package/src/canvas/canvas-diff.ts +35 -18
- package/src/canvas/canvas-helpers.ts +55 -21
- package/src/canvas/canvas-live-render.ts +140 -89
- package/src/canvas/canvas-render.ts +127 -82
- package/src/canvas/canvas-utils.ts +68 -42
- package/src/canvas/nested-site-style.ts +15 -7
- package/src/editor/component-inline-edit.ts +90 -51
- package/src/editor/content-inline-edit.ts +75 -72
- package/src/editor/context-menu.ts +125 -71
- package/src/editor/convert-targets.ts +17 -13
- package/src/editor/convert-to-component.ts +51 -28
- package/src/editor/convert-to-repeater.ts +44 -19
- package/src/editor/inline-edit.ts +107 -52
- package/src/editor/inline-format.ts +128 -60
- package/src/editor/insertion-helper.ts +26 -14
- package/src/editor/shortcuts.ts +89 -43
- package/src/editor/slash-menu.ts +41 -26
- package/src/files/components.ts +9 -7
- package/src/files/file-ops.ts +53 -33
- package/src/files/files.ts +246 -143
- package/src/format/constraints.ts +25 -15
- package/src/format/format-host.ts +33 -10
- package/src/github/github-auth.ts +24 -14
- package/src/github/github-publish.ts +20 -14
- package/src/new-project/new-project-modal.ts +27 -18
- package/src/panels/activity-bar.ts +27 -26
- package/src/panels/ai-panel.ts +100 -44
- package/src/panels/block-action-bar.ts +84 -52
- package/src/panels/canvas-dnd.ts +47 -28
- package/src/panels/data-explorer.ts +24 -11
- package/src/panels/dnd.ts +148 -100
- package/src/panels/editors.ts +54 -37
- package/src/panels/elements-panel.ts +23 -13
- package/src/panels/events-panel.ts +48 -38
- package/src/panels/git-panel.ts +95 -60
- package/src/panels/head-panel.ts +138 -84
- package/src/panels/imports-panel.ts +66 -29
- package/src/panels/layers-panel.ts +80 -36
- package/src/panels/left-panel.ts +86 -53
- package/src/panels/overlays.ts +36 -19
- package/src/panels/panel-events.ts +48 -27
- package/src/panels/panel-scheduler.ts +41 -23
- package/src/panels/preview-render.ts +26 -26
- package/src/panels/properties-panel.ts +155 -118
- package/src/panels/pseudo-preview.ts +31 -15
- package/src/panels/quick-search.ts +28 -13
- package/src/panels/right-panel.ts +35 -24
- package/src/panels/shared.ts +46 -29
- package/src/panels/signals-panel.ts +303 -186
- package/src/panels/statusbar.ts +27 -12
- package/src/panels/style-inputs.ts +30 -24
- package/src/panels/style-panel.ts +130 -90
- package/src/panels/style-utils.ts +63 -23
- package/src/panels/stylebook-layers-panel.ts +27 -30
- package/src/panels/stylebook-panel.ts +140 -72
- package/src/panels/tab-strip.ts +21 -10
- package/src/panels/toolbar.ts +52 -40
- package/src/panels/welcome-screen.ts +1 -1
- package/src/platform.ts +2 -1
- package/src/platforms/devserver.ts +221 -105
- package/src/recent-projects.ts +15 -7
- package/src/resize-edges.ts +7 -5
- package/src/services/cem-export.ts +73 -57
- package/src/services/code-services.ts +52 -25
- package/src/services/monaco-setup.ts +5 -5
- package/src/settings/content-types-editor.ts +133 -62
- package/src/settings/css-vars-editor.ts +31 -14
- package/src/settings/defs-editor.ts +125 -63
- package/src/settings/general-settings.ts +11 -6
- package/src/settings/head-editor.ts +30 -15
- package/src/settings/schema-field-ui.ts +75 -35
- package/src/settings/settings-modal.ts +35 -17
- package/src/site-context.ts +80 -47
- package/src/state.ts +98 -65
- package/src/store.ts +42 -23
- package/src/studio.ts +165 -144
- package/src/tabs/tab.ts +51 -45
- package/src/tabs/transact.ts +230 -109
- package/src/types.ts +60 -51
- package/src/ui/button-group.ts +3 -2
- package/src/ui/color-selector.ts +33 -15
- package/src/ui/expression-editor.ts +139 -86
- package/src/ui/field-input.ts +35 -18
- package/src/ui/field-row.ts +1 -1
- package/src/ui/icons.ts +5 -6
- package/src/ui/layers.ts +33 -26
- package/src/ui/media-picker.ts +13 -7
- package/src/ui/panel-resize.ts +39 -20
- package/src/ui/spectrum.ts +4 -2
- package/src/ui/unit-selector.ts +20 -11
- package/src/ui/value-selector.ts +13 -7
- package/src/ui/widgets.ts +34 -18
- package/src/utils/canvas-media.ts +66 -33
- package/src/utils/edit-display.ts +43 -44
- package/src/utils/google-fonts.ts +10 -6
- package/src/utils/inherited-style.ts +22 -8
- package/src/utils/studio-utils.ts +88 -45
- package/src/view.ts +9 -5
- package/src/workspace/workspace.ts +49 -29
package/src/recent-projects.ts
CHANGED
|
@@ -20,8 +20,10 @@ const MAX_RECENT_FILES = 10;
|
|
|
20
20
|
export function getRecentProjects() {
|
|
21
21
|
try {
|
|
22
22
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
23
|
-
if (!raw)
|
|
24
|
-
|
|
23
|
+
if (!raw) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return (JSON.parse(raw) as RecentProject[]).toSorted((a, b) => b.timestamp - a.timestamp);
|
|
25
27
|
} catch {
|
|
26
28
|
return [];
|
|
27
29
|
}
|
|
@@ -34,7 +36,9 @@ export function getRecentProjects() {
|
|
|
34
36
|
export function addRecentProject(name: string, root: string) {
|
|
35
37
|
const projects = getRecentProjects().filter((p) => p.root !== root);
|
|
36
38
|
projects.unshift({ name, root, timestamp: Date.now() });
|
|
37
|
-
if (projects.length > MAX_RECENT)
|
|
39
|
+
if (projects.length > MAX_RECENT) {
|
|
40
|
+
projects.length = MAX_RECENT;
|
|
41
|
+
}
|
|
38
42
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(projects));
|
|
39
43
|
}
|
|
40
44
|
|
|
@@ -46,8 +50,10 @@ export function clearRecentProjects() {
|
|
|
46
50
|
export function getRecentFiles() {
|
|
47
51
|
try {
|
|
48
52
|
const raw = localStorage.getItem(FILES_STORAGE_KEY);
|
|
49
|
-
if (!raw)
|
|
50
|
-
|
|
53
|
+
if (!raw) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
return (JSON.parse(raw) as RecentFile[]).toSorted((a, b) => b.timestamp - a.timestamp);
|
|
51
57
|
} catch {
|
|
52
58
|
return [];
|
|
53
59
|
}
|
|
@@ -56,7 +62,9 @@ export function getRecentFiles() {
|
|
|
56
62
|
/** @param {{ path: string; name: string }} file */
|
|
57
63
|
export function trackRecentFile(file: { path: string; name: string }) {
|
|
58
64
|
const recent = getRecentFiles().filter((f) => f.path !== file.path);
|
|
59
|
-
recent.unshift({
|
|
60
|
-
if (recent.length > MAX_RECENT_FILES)
|
|
65
|
+
recent.unshift({ name: file.name, path: file.path, timestamp: Date.now() });
|
|
66
|
+
if (recent.length > MAX_RECENT_FILES) {
|
|
67
|
+
recent.length = MAX_RECENT_FILES;
|
|
68
|
+
}
|
|
61
69
|
localStorage.setItem(FILES_STORAGE_KEY, JSON.stringify(recent));
|
|
62
70
|
}
|
package/src/resize-edges.ts
CHANGED
|
@@ -31,7 +31,9 @@ let mounted = false;
|
|
|
31
31
|
|
|
32
32
|
export function mountResizeEdges() {
|
|
33
33
|
const wc = g.__jxPlatform?.windowControls;
|
|
34
|
-
if (!wc || !wc.getFrame || mounted)
|
|
34
|
+
if (!wc || !wc.getFrame || mounted) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
35
37
|
mounted = true;
|
|
36
38
|
|
|
37
39
|
const container = document.createElement("div");
|
|
@@ -41,10 +43,10 @@ export function mountResizeEdges() {
|
|
|
41
43
|
const el = document.createElement("div");
|
|
42
44
|
el.className = `resize-edge ${edge}`;
|
|
43
45
|
el.addEventListener("mousedown", (e) => startResize(e, edge, wc));
|
|
44
|
-
container.
|
|
46
|
+
container.append(el);
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
document.body.
|
|
49
|
+
document.body.append(container);
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
/**
|
|
@@ -88,7 +90,7 @@ async function startResize(
|
|
|
88
90
|
}
|
|
89
91
|
if (edge.includes("left")) {
|
|
90
92
|
const newW = Math.max(MIN_WIDTH, width - dx);
|
|
91
|
-
x
|
|
93
|
+
x += width - newW;
|
|
92
94
|
width = newW;
|
|
93
95
|
}
|
|
94
96
|
if (edge.includes("bottom")) {
|
|
@@ -96,7 +98,7 @@ async function startResize(
|
|
|
96
98
|
}
|
|
97
99
|
if (edge.includes("top")) {
|
|
98
100
|
const newH = Math.max(MIN_HEIGHT, height - dy);
|
|
99
|
-
y
|
|
101
|
+
y += height - newH;
|
|
100
102
|
height = newH;
|
|
101
103
|
}
|
|
102
104
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
2
|
+
import type { CemParameter, JxMutableNode, JxStateObject } from "@jxsuite/schema/types";
|
|
3
|
+
import { isFunctionDef, isJsonObject } from "@jxsuite/schema/guards";
|
|
3
4
|
|
|
4
5
|
/** Collect slot elements from the document tree. */
|
|
5
|
-
export function collectSlots(node
|
|
6
|
+
export function collectSlots(node?: JxMutableNode | null, slots: string[] = []) {
|
|
6
7
|
if (node?.tagName === "slot") {
|
|
7
|
-
|
|
8
|
+
const name = node.attributes?.name;
|
|
9
|
+
slots.push(typeof name === "string" ? name : "");
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(node?.children)) {
|
|
12
|
+
for (const c of node.children) {
|
|
13
|
+
collectSlots(typeof c === "string" ? undefined : c, slots);
|
|
14
|
+
}
|
|
8
15
|
}
|
|
9
|
-
if (Array.isArray(node?.children))
|
|
10
|
-
node.children.forEach((c: JxMutableNode | string) =>
|
|
11
|
-
collectSlots(typeof c === "string" ? undefined : c, slots),
|
|
12
|
-
);
|
|
13
16
|
return slots;
|
|
14
17
|
}
|
|
15
18
|
|
|
@@ -19,7 +22,7 @@ export function collectSlots(node: JxMutableNode | null | undefined, slots: stri
|
|
|
19
22
|
* @param {{ document: JxMutableNode }} S - Studio state
|
|
20
23
|
* @param {{
|
|
21
24
|
* defCategory: (d: unknown) => string;
|
|
22
|
-
* normParam: (p:
|
|
25
|
+
* normParam: (p: string | CemParameter) => CemParameter;
|
|
23
26
|
* collectCssParts: (node: JxMutableNode) => { name: string }[];
|
|
24
27
|
* }} helpers
|
|
25
28
|
*/
|
|
@@ -27,70 +30,80 @@ export function exportCemManifest(
|
|
|
27
30
|
S: { document: JxMutableNode },
|
|
28
31
|
helpers: {
|
|
29
32
|
defCategory: (d: unknown) => string;
|
|
30
|
-
normParam: (p:
|
|
33
|
+
normParam: (p: string | CemParameter) => CemParameter;
|
|
31
34
|
collectCssParts: (node: JxMutableNode) => { name: string }[];
|
|
32
35
|
},
|
|
33
36
|
) {
|
|
34
37
|
const { defCategory, normParam, collectCssParts } = helpers;
|
|
35
38
|
const doc = S.document;
|
|
36
|
-
const tagName = doc
|
|
37
|
-
if (!tagName || !tagName.includes("-"))
|
|
39
|
+
const { tagName } = doc;
|
|
40
|
+
if (!tagName || !tagName.includes("-")) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
38
43
|
|
|
39
44
|
const state = doc.state || {};
|
|
40
|
-
const members = [];
|
|
41
|
-
const attributes = [];
|
|
42
|
-
const events = [];
|
|
43
|
-
const seenEvents = new Set();
|
|
45
|
+
const members: Record<string, unknown>[] = [];
|
|
46
|
+
const attributes: Record<string, unknown>[] = [];
|
|
47
|
+
const events: Record<string, unknown>[] = [];
|
|
48
|
+
const seenEvents = new Set<string>();
|
|
44
49
|
|
|
45
50
|
for (const [key, d] of Object.entries(state)) {
|
|
46
|
-
if (key.startsWith("#"))
|
|
51
|
+
if (key.startsWith("#")) {
|
|
52
|
+
continue;
|
|
53
|
+
} // Private
|
|
47
54
|
|
|
48
55
|
const cat = defCategory(d);
|
|
49
56
|
|
|
50
57
|
if (cat === "function") {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (Array.isArray(d.emits)) {
|
|
64
|
-
for (const ev of d.emits) {
|
|
58
|
+
if (isFunctionDef(d)) {
|
|
59
|
+
members.push({
|
|
60
|
+
kind: "method",
|
|
61
|
+
name: key,
|
|
62
|
+
...(d.description ? { description: d.description } : {}),
|
|
63
|
+
...(d.parameters ? { parameters: d.parameters.map(normParam) } : {}),
|
|
64
|
+
...(d.deprecated
|
|
65
|
+
? { deprecated: typeof d.deprecated === "string" ? d.deprecated : true }
|
|
66
|
+
: {}),
|
|
67
|
+
});
|
|
68
|
+
// Collect emits
|
|
69
|
+
for (const ev of d.emits ?? []) {
|
|
65
70
|
if (ev.name && !seenEvents.has(ev.name)) {
|
|
66
71
|
seenEvents.add(ev.name);
|
|
67
72
|
events.push({
|
|
68
73
|
name: ev.name,
|
|
69
|
-
...(ev.type ? { type: ev.type } : {}),
|
|
74
|
+
...(ev.type !== undefined ? { type: ev.type } : {}),
|
|
70
75
|
...(ev.description ? { description: ev.description } : {}),
|
|
71
76
|
});
|
|
72
77
|
}
|
|
73
78
|
}
|
|
79
|
+
} else if (isJsonObject(d)) {
|
|
80
|
+
// Legacy $handler entry — emit a bare method member
|
|
81
|
+
const { description } = d;
|
|
82
|
+
members.push({
|
|
83
|
+
kind: "method",
|
|
84
|
+
name: key,
|
|
85
|
+
...(typeof description === "string" ? { description } : {}),
|
|
86
|
+
});
|
|
74
87
|
}
|
|
75
88
|
} else if (cat === "state") {
|
|
89
|
+
// Naked primitive values carry no metadata; object defs are signals/type defs.
|
|
90
|
+
const def: JxStateObject | null = isJsonObject(d) ? (d as JxStateObject) : null;
|
|
76
91
|
members.push({
|
|
77
92
|
kind: "field",
|
|
78
93
|
name: key,
|
|
79
|
-
...(
|
|
80
|
-
...(
|
|
81
|
-
...(
|
|
82
|
-
...(
|
|
83
|
-
...(
|
|
84
|
-
...(
|
|
85
|
-
? {
|
|
86
|
-
deprecated: typeof d.deprecated === "string" ? d.deprecated : true,
|
|
87
|
-
}
|
|
94
|
+
...(def?.type ? { type: { text: def.type } } : {}),
|
|
95
|
+
...(def && def.default !== undefined ? { default: String(def.default) } : {}),
|
|
96
|
+
...(def?.description ? { description: def.description } : {}),
|
|
97
|
+
...(def?.attribute ? { attribute: def.attribute } : {}),
|
|
98
|
+
...(def?.reflects ? { reflects: true } : {}),
|
|
99
|
+
...(def?.deprecated
|
|
100
|
+
? { deprecated: typeof def.deprecated === "string" ? def.deprecated : true }
|
|
88
101
|
: {}),
|
|
89
102
|
});
|
|
90
|
-
if (
|
|
103
|
+
if (def?.attribute) {
|
|
91
104
|
attributes.push({
|
|
92
|
-
name:
|
|
93
|
-
...(
|
|
105
|
+
name: def.attribute,
|
|
106
|
+
...(def.type ? { type: { text: def.type } } : {}),
|
|
94
107
|
fieldName: key,
|
|
95
108
|
});
|
|
96
109
|
}
|
|
@@ -99,41 +112,44 @@ export function exportCemManifest(
|
|
|
99
112
|
|
|
100
113
|
// Slots
|
|
101
114
|
const slotNames = collectSlots(doc);
|
|
102
|
-
const slots = slotNames.map((name: string) =>
|
|
103
|
-
name: name || ""
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
const slots = slotNames.map((name: string) => {
|
|
116
|
+
const slot: { name: string; description?: string } = { name: name || "" };
|
|
117
|
+
if (!name) {
|
|
118
|
+
slot.description = "Default slot";
|
|
119
|
+
}
|
|
120
|
+
return slot;
|
|
121
|
+
});
|
|
106
122
|
|
|
107
123
|
// CSS custom properties
|
|
108
124
|
const style = doc.style || {};
|
|
109
125
|
const cssProperties = Object.entries(style)
|
|
110
126
|
.filter(([k]) => k.startsWith("--"))
|
|
111
|
-
.map(([name, val]) => ({
|
|
127
|
+
.map(([name, val]) => ({ default: String(val), name }));
|
|
112
128
|
|
|
113
129
|
// CSS parts
|
|
114
130
|
const cssParts = collectCssParts(doc).map((p) => ({ name: p.name }));
|
|
115
131
|
|
|
116
132
|
const manifest = {
|
|
117
|
-
schemaVersion: "2.1.0",
|
|
118
133
|
modules: [
|
|
119
134
|
{
|
|
120
|
-
kind: "javascript-module",
|
|
121
|
-
path: "",
|
|
122
135
|
declarations: [
|
|
123
136
|
{
|
|
124
137
|
kind: "class",
|
|
138
|
+
members,
|
|
125
139
|
name: tagName,
|
|
126
140
|
tagName,
|
|
127
|
-
|
|
128
|
-
...(
|
|
129
|
-
...(
|
|
130
|
-
...(
|
|
131
|
-
...(
|
|
132
|
-
...(cssParts.length ? { cssParts } : {}),
|
|
141
|
+
...(attributes.length > 0 ? { attributes } : {}),
|
|
142
|
+
...(events.length > 0 ? { events } : {}),
|
|
143
|
+
...(slots.length > 0 ? { slots } : {}),
|
|
144
|
+
...(cssProperties.length > 0 ? { cssProperties } : {}),
|
|
145
|
+
...(cssParts.length > 0 ? { cssParts } : {}),
|
|
133
146
|
},
|
|
134
147
|
],
|
|
148
|
+
kind: "javascript-module",
|
|
149
|
+
path: "",
|
|
135
150
|
},
|
|
136
151
|
],
|
|
152
|
+
schemaVersion: "2.1.0",
|
|
137
153
|
};
|
|
138
154
|
|
|
139
155
|
const blob = new Blob([JSON.stringify(manifest, null, 2)], {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/** OXC code services (server-backed) */
|
|
2
2
|
|
|
3
3
|
import { getPlatform } from "../platform";
|
|
4
|
+
import { isJsonObject, paramNames } from "@jxsuite/schema/guards";
|
|
4
5
|
import { projectState } from "../state";
|
|
5
6
|
import { getNodeAtPath } from "../store";
|
|
6
7
|
import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
|
|
7
8
|
import type { JxPath } from "../state";
|
|
8
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
9
|
+
import type { JxFunctionDef, JxMutableNode } from "@jxsuite/schema/types";
|
|
10
|
+
import type { editor } from "monaco-editor";
|
|
9
11
|
|
|
10
12
|
export interface OxLintDiagnostic {
|
|
11
13
|
severity: string;
|
|
@@ -22,7 +24,9 @@ export interface OxLintDiagnostic {
|
|
|
22
24
|
*/
|
|
23
25
|
export async function codeService(action: string, payload: unknown) {
|
|
24
26
|
const platform = getPlatform();
|
|
25
|
-
if (!platform.codeService)
|
|
27
|
+
if (!platform.codeService) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
26
30
|
return platform.codeService(action, payload);
|
|
27
31
|
}
|
|
28
32
|
|
|
@@ -33,7 +37,9 @@ export async function codeService(action: string, payload: unknown) {
|
|
|
33
37
|
*/
|
|
34
38
|
export async function locateDocument(name: string) {
|
|
35
39
|
const platform = getPlatform();
|
|
36
|
-
if (!platform.locateFile)
|
|
40
|
+
if (!platform.locateFile) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
37
43
|
return platform.locateFile(name);
|
|
38
44
|
}
|
|
39
45
|
|
|
@@ -55,9 +61,13 @@ export async function fetchPluginSchema(
|
|
|
55
61
|
? projectState?.projectConfig?.imports?.[def.$prototype]
|
|
56
62
|
: null;
|
|
57
63
|
const src = def.$src || importedPath;
|
|
58
|
-
if (!src || !def.$prototype)
|
|
64
|
+
if (!src || !def.$prototype) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
59
67
|
const cacheKey = `${src}::${def.$prototype}`;
|
|
60
|
-
if (pluginSchemaCache.has(cacheKey))
|
|
68
|
+
if (pluginSchemaCache.has(cacheKey)) {
|
|
69
|
+
return pluginSchemaCache.get(cacheKey);
|
|
70
|
+
}
|
|
61
71
|
|
|
62
72
|
try {
|
|
63
73
|
const platform = getPlatform();
|
|
@@ -81,34 +91,34 @@ export async function fetchPluginSchema(
|
|
|
81
91
|
* @param {OxLintDiagnostic[]} diagnostics
|
|
82
92
|
*/
|
|
83
93
|
export function setLintMarkers(
|
|
84
|
-
editor:
|
|
94
|
+
editor: editor.IStandaloneCodeEditor,
|
|
85
95
|
diagnostics: OxLintDiagnostic[],
|
|
86
96
|
) {
|
|
87
97
|
const model = editor.getModel();
|
|
88
|
-
if (!model)
|
|
98
|
+
if (!model) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
89
101
|
const markers = diagnostics
|
|
90
102
|
.map((d) => {
|
|
91
103
|
const label = d.labels?.[0];
|
|
92
|
-
if (!label)
|
|
104
|
+
if (!label) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
93
107
|
const { line, column, length } = label.span;
|
|
94
108
|
return {
|
|
109
|
+
code: d.url ? { target: monaco.Uri.parse(d.url), value: d.code } : d.code,
|
|
110
|
+
endColumn: column + (length || 1),
|
|
111
|
+
endLineNumber: line,
|
|
112
|
+
message: d.message + (d.help ? `\n${d.help}` : ""),
|
|
95
113
|
severity:
|
|
96
114
|
d.severity === "error" ? monaco.MarkerSeverity.Error : monaco.MarkerSeverity.Warning,
|
|
97
|
-
message: d.message + (d.help ? `\n${d.help}` : ""),
|
|
98
|
-
startLineNumber: line,
|
|
99
|
-
startColumn: column,
|
|
100
|
-
endLineNumber: line,
|
|
101
|
-
endColumn: column + (length || 1),
|
|
102
|
-
code: d.url ? { value: d.code, target: monaco.Uri.parse(d.url) } : d.code,
|
|
103
115
|
source: "oxlint",
|
|
116
|
+
startColumn: column,
|
|
117
|
+
startLineNumber: line,
|
|
104
118
|
};
|
|
105
119
|
})
|
|
106
120
|
.filter(Boolean);
|
|
107
|
-
monaco.editor.setModelMarkers(
|
|
108
|
-
model,
|
|
109
|
-
"oxlint",
|
|
110
|
-
markers as import("monaco-editor").editor.IMarkerData[],
|
|
111
|
-
);
|
|
121
|
+
monaco.editor.setModelMarkers(model, "oxlint", markers as editor.IMarkerData[]);
|
|
112
122
|
}
|
|
113
123
|
|
|
114
124
|
/**
|
|
@@ -118,15 +128,32 @@ export function setLintMarkers(
|
|
|
118
128
|
export function getFunctionArgs(
|
|
119
129
|
editing: { type: string; defName?: string; path?: JxPath; eventKey?: string },
|
|
120
130
|
document: JxMutableNode | null | undefined,
|
|
121
|
-
) {
|
|
131
|
+
): string[] {
|
|
132
|
+
// Read parameters off any object-shaped def (covers legacy entries without $prototype).
|
|
133
|
+
const fromDef = (def: unknown): string[] | null => {
|
|
134
|
+
if (!isJsonObject(def)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const params = def.parameters;
|
|
138
|
+
if (!Array.isArray(params) || params.length === 0) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return paramNames(params as JxFunctionDef["parameters"]);
|
|
142
|
+
};
|
|
122
143
|
if (editing.type === "def") {
|
|
123
|
-
const
|
|
124
|
-
|
|
144
|
+
const args = editing.defName ? fromDef(document?.state?.[editing.defName]) : null;
|
|
145
|
+
if (args) {
|
|
146
|
+
return args;
|
|
147
|
+
}
|
|
125
148
|
} else if (editing.type === "event") {
|
|
126
|
-
if (!document || !editing.path)
|
|
149
|
+
if (!document || !editing.path) {
|
|
150
|
+
return ["state", "event"];
|
|
151
|
+
}
|
|
127
152
|
const node = getNodeAtPath(document, editing.path);
|
|
128
|
-
const
|
|
129
|
-
|
|
153
|
+
const args = node && editing.eventKey ? fromDef(node[editing.eventKey]) : null;
|
|
154
|
+
if (args) {
|
|
155
|
+
return args;
|
|
156
|
+
}
|
|
130
157
|
}
|
|
131
158
|
return ["state", "event"];
|
|
132
159
|
}
|
|
@@ -10,10 +10,10 @@ import jxSchema from "@jxsuite/schema/schema.json";
|
|
|
10
10
|
import projectSchema from "@jxsuite/schema/project-schema.json";
|
|
11
11
|
|
|
12
12
|
const WORKER_PATHS: Record<string, string> = {
|
|
13
|
+
editorWorkerService: "/monaco-editor/esm/vs/editor/editor.worker.js",
|
|
14
|
+
javascript: "/monaco-editor/esm/vs/language/typescript/ts.worker.js",
|
|
13
15
|
json: "/monaco-editor/esm/vs/language/json/json.worker.js",
|
|
14
16
|
typescript: "/monaco-editor/esm/vs/language/typescript/ts.worker.js",
|
|
15
|
-
javascript: "/monaco-editor/esm/vs/language/typescript/ts.worker.js",
|
|
16
|
-
editorWorkerService: "/monaco-editor/esm/vs/editor/editor.worker.js",
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
self.MonacoEnvironment = {
|
|
@@ -24,11 +24,9 @@ self.MonacoEnvironment = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
jsonDefaults.setDiagnosticsOptions({
|
|
27
|
-
validate: true,
|
|
28
27
|
allowComments: false,
|
|
29
28
|
schemas: [
|
|
30
29
|
{
|
|
31
|
-
uri: "https://jxsuite.com/schema/v1",
|
|
32
30
|
fileMatch: [
|
|
33
31
|
"pages/*.json",
|
|
34
32
|
"pages/**/*.json",
|
|
@@ -40,11 +38,13 @@ jsonDefaults.setDiagnosticsOptions({
|
|
|
40
38
|
"elements/**/*.json",
|
|
41
39
|
],
|
|
42
40
|
schema: jxSchema,
|
|
41
|
+
uri: "https://jxsuite.com/schema/v1",
|
|
43
42
|
},
|
|
44
43
|
{
|
|
45
|
-
uri: "https://jxsuite.com/schema/project/v1",
|
|
46
44
|
fileMatch: ["project.json"],
|
|
47
45
|
schema: projectSchema,
|
|
46
|
+
uri: "https://jxsuite.com/schema/project/v1",
|
|
48
47
|
},
|
|
49
48
|
],
|
|
49
|
+
validate: true,
|
|
50
50
|
});
|