@ocelescope/discovery 0.1.0 → 0.5.0
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/README.md +8 -0
- package/dist/index.js +145 -136
- package/package.json +18 -24
package/README.md
CHANGED
|
@@ -28,6 +28,14 @@ export default {
|
|
|
28
28
|
} satisfies OcelescopeConfig;
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
This module's graph viewer uses [`@xyflow/react`](https://reactflow.dev). Add
|
|
32
|
+
`@xyflow/react` to your app's `dependencies` and import its stylesheet once in
|
|
33
|
+
your app entry point (`pages/_app.tsx`):
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import "@xyflow/react/dist/style.css";
|
|
37
|
+
```
|
|
38
|
+
|
|
31
39
|
## About
|
|
32
40
|
|
|
33
41
|
Part of [Ocelescope](https://github.com/promi4s/ocelescope), a framework for
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { defineModule, defineModuleRoute, useCurrentOcel } from "@ocelescope/core";
|
|
2
2
|
import { BookmarkIcon, ChartNetwork, SettingsIcon } from "lucide-react";
|
|
3
|
-
import { ActionIcon, Alert, Box, Card, Center, Divider, Drawer, LoadingOverlay, MultiSelect, NumberInput, Select, Slider, Stack,
|
|
3
|
+
import { ActionIcon, Alert, Box, Card, Center, Divider, Drawer, Input, LoadingOverlay, MultiSelect, NumberInput, Select, Slider, Stack, Text, Tooltip } from "@mantine/core";
|
|
4
4
|
import { useLocalStorage } from "@mantine/hooks";
|
|
5
5
|
import { useCreateDiscoveryTask, useDiscoveryTask, useEventCounts, useListDiscoveryFilters, useListDiscoveryMethods, useObjectCounts, useSaveDiscovery } from "@ocelescope/api-base";
|
|
6
6
|
import { Visualization } from "@ocelescope/resources";
|
|
7
|
-
import { useEffect, useMemo, useState } from "react";
|
|
7
|
+
import { memo, useEffect, useMemo, useState } from "react";
|
|
8
8
|
import { create } from "zustand";
|
|
9
9
|
import { persist } from "zustand/middleware";
|
|
10
|
+
import validator from "@rjsf/validator-ajv8";
|
|
11
|
+
import dynamic from "next/dynamic.js";
|
|
10
12
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
11
13
|
//#region src/stores/discoveryStore.ts
|
|
12
14
|
const EMPTY = {
|
|
@@ -26,8 +28,9 @@ const useDiscoveryStore = create()(persist((set) => ({
|
|
|
26
28
|
byOcel: {},
|
|
27
29
|
setSelectedMethodId: (ocelId, methodId) => set((s) => updateOcel(s, ocelId, { selectedMethodId: methodId })),
|
|
28
30
|
setFormData: (ocelId, methodId, data) => set((s) => {
|
|
31
|
+
const current = s.byOcel[ocelId] ?? EMPTY;
|
|
29
32
|
return updateOcel(s, ocelId, { formDataByMethod: {
|
|
30
|
-
...
|
|
33
|
+
...current.formDataByMethod,
|
|
31
34
|
[methodId]: data
|
|
32
35
|
} });
|
|
33
36
|
}),
|
|
@@ -60,115 +63,115 @@ const normalizeFormData = (formData) => Object.fromEntries(Object.entries(formDa
|
|
|
60
63
|
return true;
|
|
61
64
|
}));
|
|
62
65
|
//#endregion
|
|
63
|
-
//#region src/components/
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
data: eventTypeOptions,
|
|
101
|
-
searchable: true,
|
|
102
|
-
allowDeselect: false
|
|
103
|
-
});
|
|
104
|
-
if (property.type === "string" && property.enum) return /* @__PURE__ */ jsx(Select, {
|
|
105
|
-
label,
|
|
106
|
-
description,
|
|
107
|
-
value: value ?? null,
|
|
108
|
-
onChange,
|
|
109
|
-
data: property.enum.map((item, index) => ({
|
|
110
|
-
value: item,
|
|
111
|
-
label: property.enumNames?.[index] ?? item
|
|
112
|
-
})),
|
|
113
|
-
allowDeselect: false
|
|
66
|
+
//#region src/components/DiscoveryForm.tsx
|
|
67
|
+
const Form = dynamic(() => import("@rjsf/mantine").then((m) => m.Form), { ssr: false });
|
|
68
|
+
const MantineSliderWidget = ({ value, onChange, schema, label, required }) => {
|
|
69
|
+
const min = schema.minimum ?? schema.exclusiveMinimum;
|
|
70
|
+
const max = schema.maximum ?? schema.exclusiveMaximum;
|
|
71
|
+
const description = schema.description;
|
|
72
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73
|
+
/* @__PURE__ */ jsx(Input.Label, {
|
|
74
|
+
required,
|
|
75
|
+
children: label
|
|
76
|
+
}),
|
|
77
|
+
description && /* @__PURE__ */ jsx(Input.Description, { children: description }),
|
|
78
|
+
/* @__PURE__ */ jsx(NumberInput, {
|
|
79
|
+
mt: "5px",
|
|
80
|
+
min,
|
|
81
|
+
max,
|
|
82
|
+
step: 1e-4,
|
|
83
|
+
decimalScale: 4,
|
|
84
|
+
hideControls: true,
|
|
85
|
+
value: typeof value === "number" ? value : schema.default ?? min,
|
|
86
|
+
onChange: (v) => typeof v === "number" && onChange(v)
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ jsx(Slider, {
|
|
89
|
+
min,
|
|
90
|
+
max,
|
|
91
|
+
step: 1e-4,
|
|
92
|
+
label: (v) => v.toFixed(4),
|
|
93
|
+
value: typeof value === "number" ? value : schema.default ?? min,
|
|
94
|
+
onChange
|
|
95
|
+
})
|
|
96
|
+
] });
|
|
97
|
+
};
|
|
98
|
+
const WIDGETS = { "mantine-slider": MantineSliderWidget };
|
|
99
|
+
const FieldTemplate = ({ children, errors, help, hidden }) => {
|
|
100
|
+
if (hidden) return /* @__PURE__ */ jsx("div", {
|
|
101
|
+
style: { display: "none" },
|
|
102
|
+
children
|
|
114
103
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
104
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
105
|
+
children,
|
|
106
|
+
errors,
|
|
107
|
+
help
|
|
108
|
+
] });
|
|
109
|
+
};
|
|
110
|
+
const DescriptionFieldTemplate = ({ id, description }) => description ? /* @__PURE__ */ jsx(Input.Description, {
|
|
111
|
+
id,
|
|
112
|
+
mt: -8,
|
|
113
|
+
mb: 8,
|
|
114
|
+
children: description
|
|
115
|
+
}) : null;
|
|
116
|
+
const TEMPLATES = {
|
|
117
|
+
DescriptionFieldTemplate,
|
|
118
|
+
FieldTemplate
|
|
119
|
+
};
|
|
120
|
+
const UI_SCHEMA_BASE = { "ui:submitButtonOptions": { norender: true } };
|
|
121
|
+
const buildUiSchema = (schema) => {
|
|
122
|
+
const uiSchema = { ...UI_SCHEMA_BASE };
|
|
123
|
+
for (const [key, prop] of Object.entries(schema.properties ?? {})) if (prop.fieldType) uiSchema[key] = { "ui:field": prop.fieldType };
|
|
124
|
+
else if ((prop.type === "number" || prop.type === "integer") && (prop.minimum !== void 0 || prop.exclusiveMinimum !== void 0) && (prop.maximum !== void 0 || prop.exclusiveMaximum !== void 0)) uiSchema[key] = { "ui:widget": "mantine-slider" };
|
|
125
|
+
return uiSchema;
|
|
126
|
+
};
|
|
127
|
+
const makeOcelFields = (eventTypeOptions, objectTypeOptions) => {
|
|
128
|
+
const OcelTypeField = (options) => memo(({ schema, formData, onChange, required, fieldPathId: { path } }) => {
|
|
129
|
+
return /* @__PURE__ */ jsx(schema.type === "array" ? MultiSelect : Select, {
|
|
130
|
+
label: schema.title,
|
|
131
|
+
description: schema.description,
|
|
132
|
+
required,
|
|
133
|
+
value: formData ?? (schema.type === "array" ? [] : null),
|
|
134
|
+
onChange: (v) => onChange(v, path),
|
|
135
|
+
data: options,
|
|
136
|
+
clearable: true,
|
|
137
|
+
searchable: true
|
|
139
138
|
});
|
|
140
|
-
}
|
|
141
|
-
if (property.type === "integer" || property.type === "number") return /* @__PURE__ */ jsx(NumberInput, {
|
|
142
|
-
label,
|
|
143
|
-
description,
|
|
144
|
-
value,
|
|
145
|
-
onChange,
|
|
146
|
-
min: property.minimum,
|
|
147
|
-
max: property.maximum
|
|
148
|
-
});
|
|
149
|
-
if (property.type === "boolean") return /* @__PURE__ */ jsx(Switch, {
|
|
150
|
-
label,
|
|
151
|
-
description,
|
|
152
|
-
checked: Boolean(value),
|
|
153
|
-
onChange: (event) => onChange(event.currentTarget.checked)
|
|
154
139
|
});
|
|
155
|
-
return
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
140
|
+
return {
|
|
141
|
+
event_type: OcelTypeField(eventTypeOptions),
|
|
142
|
+
object_type: OcelTypeField(objectTypeOptions)
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const DiscoveryForm = ({ schema, formData, onChange, eventTypeOptions, objectTypeOptions }) => {
|
|
146
|
+
const uiSchema = useMemo(() => buildUiSchema(schema), [schema]);
|
|
147
|
+
const fields = useMemo(() => makeOcelFields(eventTypeOptions, objectTypeOptions), [eventTypeOptions, objectTypeOptions]);
|
|
148
|
+
return /* @__PURE__ */ jsx(Form, {
|
|
149
|
+
schema: {
|
|
150
|
+
...schema,
|
|
151
|
+
title: ""
|
|
152
|
+
},
|
|
153
|
+
formData,
|
|
154
|
+
validator,
|
|
155
|
+
uiSchema,
|
|
156
|
+
fields,
|
|
157
|
+
widgets: WIDGETS,
|
|
158
|
+
templates: TEMPLATES,
|
|
159
|
+
onChange: (data) => onChange(data.formData ?? {})
|
|
160
160
|
});
|
|
161
161
|
};
|
|
162
162
|
//#endregion
|
|
163
163
|
//#region src/components/DiscoveryFiltersSection.tsx
|
|
164
164
|
const DiscoveryFiltersSection = ({ availableFilters, filters, onFiltersChange, eventTypeOptions, objectTypeOptions }) => {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
const handleChange = (filterName, data) => {
|
|
166
|
+
if (filters.some((f) => f.name === filterName)) onFiltersChange(filters.map((f) => f.name === filterName ? {
|
|
167
|
+
...f,
|
|
168
|
+
payload: data
|
|
169
|
+
} : f));
|
|
170
|
+
else onFiltersChange([...filters, {
|
|
171
|
+
name: filterName,
|
|
172
|
+
payload: data
|
|
173
|
+
}]);
|
|
174
|
+
};
|
|
172
175
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
173
176
|
gap: "xs",
|
|
174
177
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
@@ -186,16 +189,12 @@ const DiscoveryFiltersSection = ({ availableFilters, filters, onFiltersChange, e
|
|
|
186
189
|
fw: 500,
|
|
187
190
|
mb: "xs",
|
|
188
191
|
children: filterSchema.name
|
|
189
|
-
}), /* @__PURE__ */ jsx(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
eventTypeOptions,
|
|
196
|
-
objectTypeOptions,
|
|
197
|
-
onChange: (value) => updateField(filterSchema.name, fieldName, value)
|
|
198
|
-
}, fieldName))
|
|
192
|
+
}), /* @__PURE__ */ jsx(DiscoveryForm, {
|
|
193
|
+
schema,
|
|
194
|
+
formData: payload,
|
|
195
|
+
onChange: (data) => handleChange(filterSchema.name, data),
|
|
196
|
+
eventTypeOptions,
|
|
197
|
+
objectTypeOptions
|
|
199
198
|
})]
|
|
200
199
|
}, filterSchema.name);
|
|
201
200
|
})]
|
|
@@ -223,7 +222,12 @@ const DiscoverySettingsContent = ({ methods, selectedMethodId, setSelectedMethod
|
|
|
223
222
|
})),
|
|
224
223
|
allowDeselect: false
|
|
225
224
|
}),
|
|
226
|
-
selectedVariants.
|
|
225
|
+
selectedVariants.find((v) => v.methodId === selectedMethodId)?.description && /* @__PURE__ */ jsx(Text, {
|
|
226
|
+
size: "sm",
|
|
227
|
+
c: "dimmed",
|
|
228
|
+
children: selectedVariants.find((v) => v.methodId === selectedMethodId)?.description
|
|
229
|
+
}),
|
|
230
|
+
selectedVariants.length > 1 && /* @__PURE__ */ jsx(Select, {
|
|
227
231
|
label: "Output Format",
|
|
228
232
|
value: selectedMethodId,
|
|
229
233
|
onChange: setSelectedMethodId,
|
|
@@ -232,22 +236,14 @@ const DiscoverySettingsContent = ({ methods, selectedMethodId, setSelectedMethod
|
|
|
232
236
|
label: v.resourceType
|
|
233
237
|
})),
|
|
234
238
|
allowDeselect: false
|
|
235
|
-
}),
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Object.entries(selectedSchema.properties ?? {}).map(([name, property]) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(DiscoveryField, {
|
|
241
|
-
name,
|
|
242
|
-
property,
|
|
243
|
-
value: activeFormData[name],
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ jsx(DiscoveryForm, {
|
|
241
|
+
schema: selectedSchema,
|
|
242
|
+
formData: activeFormData,
|
|
243
|
+
onChange: setActiveFormData,
|
|
244
244
|
eventTypeOptions: Object.keys(eventCounts),
|
|
245
|
-
objectTypeOptions: Object.keys(objectCounts)
|
|
246
|
-
|
|
247
|
-
...activeFormData,
|
|
248
|
-
[name]: value
|
|
249
|
-
})
|
|
250
|
-
}) }, name))
|
|
245
|
+
objectTypeOptions: Object.keys(objectCounts)
|
|
246
|
+
})
|
|
251
247
|
]
|
|
252
248
|
}),
|
|
253
249
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
@@ -282,7 +278,11 @@ const DiscoveryPageContent = ({ ocelId }) => {
|
|
|
282
278
|
key: PANEL_OPEN_KEY,
|
|
283
279
|
defaultValue: true
|
|
284
280
|
});
|
|
285
|
-
const { data:
|
|
281
|
+
const { data: rawMethods = [], isLoading: isMethodsLoading, error: methodsError } = useListDiscoveryMethods();
|
|
282
|
+
const methods = useMemo(() => rawMethods.map((m) => ({
|
|
283
|
+
...m,
|
|
284
|
+
variants: m.variants.filter((v) => v.enabled)
|
|
285
|
+
})).filter((m) => m.variants.length), [rawMethods]);
|
|
286
286
|
const { data: availableFilters = [] } = useListDiscoveryFilters();
|
|
287
287
|
const { data: eventCounts = {} } = useEventCounts(ocelId, void 0, { query: { enabled: true } });
|
|
288
288
|
const { data: objectCounts = {} } = useObjectCounts(ocelId, void 0, { query: { enabled: true } });
|
|
@@ -298,6 +298,16 @@ const DiscoveryPageContent = ({ ocelId }) => {
|
|
|
298
298
|
ocelId,
|
|
299
299
|
initializeFilters
|
|
300
300
|
]);
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
if (!selectedMethodId || isMethodsLoading) return;
|
|
303
|
+
if (!methods.flatMap((m) => m.variants.map((v) => v.methodId)).includes(selectedMethodId)) setSelectedMethodId(ocelId, null);
|
|
304
|
+
}, [
|
|
305
|
+
methods,
|
|
306
|
+
selectedMethodId,
|
|
307
|
+
isMethodsLoading,
|
|
308
|
+
ocelId,
|
|
309
|
+
setSelectedMethodId
|
|
310
|
+
]);
|
|
301
311
|
useEffect(() => {
|
|
302
312
|
if (selectedMethodId || methods.length === 0) return;
|
|
303
313
|
setSelectedMethodId(ocelId, methods.flatMap((m) => m.variants).find((v) => v.resourceType === "DirectlyFollowsGraph")?.methodId ?? methods[0]?.variants[0]?.methodId ?? null);
|
|
@@ -341,7 +351,6 @@ const DiscoveryPageContent = ({ ocelId }) => {
|
|
|
341
351
|
const { mutate: saveDiscovery, isPending: isSaving } = useSaveDiscovery({ mutation: { onSuccess: (_data, { taskId: savedId }) => setSavedTaskId(savedId) } });
|
|
342
352
|
const isSaved = !!taskId && savedTaskId === taskId;
|
|
343
353
|
const requestPayload = useMemo(() => normalizeFormData(activeFormData), [activeFormData]);
|
|
344
|
-
const activeFilters = useMemo(() => filters.filter((entry) => Object.values(entry.payload).every((v) => !Array.isArray(v) || v.length > 0)), [filters]);
|
|
345
354
|
useEffect(() => {
|
|
346
355
|
if (!selectedMethodId) return;
|
|
347
356
|
const timeoutId = window.setTimeout(() => {
|
|
@@ -350,7 +359,7 @@ const DiscoveryPageContent = ({ ocelId }) => {
|
|
|
350
359
|
data: {
|
|
351
360
|
methodId: selectedMethodId,
|
|
352
361
|
parameters: requestPayload,
|
|
353
|
-
filters
|
|
362
|
+
filters
|
|
354
363
|
}
|
|
355
364
|
});
|
|
356
365
|
}, 650);
|
|
@@ -362,16 +371,16 @@ const DiscoveryPageContent = ({ ocelId }) => {
|
|
|
362
371
|
selectedMethodId,
|
|
363
372
|
requestPayload,
|
|
364
373
|
ocelId,
|
|
365
|
-
filters
|
|
374
|
+
filters
|
|
366
375
|
}), [
|
|
367
376
|
ocelId,
|
|
368
377
|
requestPayload,
|
|
369
378
|
selectedMethodId,
|
|
370
|
-
|
|
379
|
+
filters
|
|
371
380
|
]),
|
|
372
381
|
requestPayload,
|
|
373
382
|
selectedMethodId,
|
|
374
|
-
|
|
383
|
+
filters
|
|
375
384
|
]);
|
|
376
385
|
const isDiscovering = isSubmittingDiscovery || task?.state === "PENDING" || task?.state === "STARTED";
|
|
377
386
|
const errorMessage = submitError || (methodsError instanceof Error ? methodsError.message : void 0) || (taskError instanceof Error ? taskError.message : void 0) || (task?.state === "FAILURE" ? "The backend discovery task failed." : void 0);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ocelescope/discovery",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "A module for discovery of OCELs",
|
|
6
6
|
"author": "Sebastian Menne <sebastian.menne@rwth-aachen.de>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -27,40 +27,34 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@
|
|
31
|
-
"@mantine/
|
|
32
|
-
"@mantine/
|
|
33
|
-
"@
|
|
34
|
-
"@rjsf/
|
|
35
|
-
"@rjsf/
|
|
36
|
-
"@rjsf/
|
|
37
|
-
"@rjsf/validator-ajv8": "^6.6.2",
|
|
30
|
+
"@mantine/carousel": "^9.4.2",
|
|
31
|
+
"@mantine/core": "^9.4.2",
|
|
32
|
+
"@mantine/hooks": "^9.4.2",
|
|
33
|
+
"@rjsf/core": "^6.7.0",
|
|
34
|
+
"@rjsf/mantine": "^6.7.0",
|
|
35
|
+
"@rjsf/utils": "^6.7.0",
|
|
36
|
+
"@rjsf/validator-ajv8": "^6.7.0",
|
|
38
37
|
"@tanstack/react-query": "^5.90.21",
|
|
39
38
|
"embla-carousel": "^8.6.0",
|
|
40
39
|
"embla-carousel-react": "^8.6.0",
|
|
41
|
-
"flat": "^6.0.1",
|
|
42
|
-
"json-schema-traverse": "^1.0.0",
|
|
43
40
|
"lucide-react": "^1.0.0",
|
|
44
|
-
"next": "^16.
|
|
45
|
-
"react": "^19.2.
|
|
46
|
-
"react-dom": "^19.2.
|
|
41
|
+
"next": "^16.2.10",
|
|
42
|
+
"react": "^19.2.7",
|
|
43
|
+
"react-dom": "^19.2.7",
|
|
47
44
|
"react-hook-form": "^7.71.2",
|
|
48
45
|
"uniqolor": "^1.1.1",
|
|
49
46
|
"zustand": "^5.0.11",
|
|
50
|
-
"@ocelescope/api-base": "0.
|
|
51
|
-
"@ocelescope/core": "0.
|
|
52
|
-
"@ocelescope/resources": "0.
|
|
47
|
+
"@ocelescope/api-base": "^0.5.0",
|
|
48
|
+
"@ocelescope/core": "^0.5.0",
|
|
49
|
+
"@ocelescope/resources": "^0.5.0"
|
|
53
50
|
},
|
|
54
51
|
"devDependencies": {
|
|
55
|
-
"@
|
|
56
|
-
"@rjsf/mantine": "^6.6.2",
|
|
52
|
+
"@rjsf/mantine": "^6.7.0",
|
|
57
53
|
"@types/file-saver": "^2.0.7",
|
|
58
|
-
"@types/node": "^
|
|
59
|
-
"@types/react": "^19.2.
|
|
54
|
+
"@types/node": "^26.1.1",
|
|
55
|
+
"@types/react": "^19.2.17",
|
|
60
56
|
"@types/react-dom": "^19.2.3",
|
|
61
|
-
"
|
|
62
|
-
"json-schema-traverse": "^1.0.0",
|
|
63
|
-
"tsdown": "^0.22.0",
|
|
57
|
+
"tsdown": "^0.22.12",
|
|
64
58
|
"typescript": "^5.9.3"
|
|
65
59
|
},
|
|
66
60
|
"scripts": {
|