tsondb 0.5.10 → 0.5.12
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/src/web/components/typeInputs/ArrayTypeInput.d.ts +2 -1
- package/dist/src/web/components/typeInputs/ArrayTypeInput.js +7 -3
- package/dist/src/web/components/typeInputs/BooleanTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/BooleanTypeInput.js +4 -0
- package/dist/src/web/components/typeInputs/DateTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/DateTypeInput.js +4 -0
- package/dist/src/web/components/typeInputs/EnumTypeInput.d.ts +1 -0
- package/dist/src/web/components/typeInputs/EnumTypeInput.js +2 -2
- package/dist/src/web/components/typeInputs/FloatTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/FloatTypeInput.js +5 -1
- package/dist/src/web/components/typeInputs/IncludeIdentifierTypeInput.d.ts +1 -0
- package/dist/src/web/components/typeInputs/IncludeIdentifierTypeInput.js +2 -2
- package/dist/src/web/components/typeInputs/IntegerTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/IntegerTypeInput.js +5 -1
- package/dist/src/web/components/typeInputs/NestedEntityMapTypeInput.d.ts +2 -1
- package/dist/src/web/components/typeInputs/NestedEntityMapTypeInput.js +6 -2
- package/dist/src/web/components/typeInputs/ObjectTypeInput.d.ts +2 -1
- package/dist/src/web/components/typeInputs/ObjectTypeInput.js +8 -3
- package/dist/src/web/components/typeInputs/ReferenceIdentifierTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/ReferenceIdentifierTypeInput.js +4 -0
- package/dist/src/web/components/typeInputs/StringTypeInput.d.ts +1 -1
- package/dist/src/web/components/typeInputs/StringTypeInput.js +4 -0
- package/dist/src/web/components/typeInputs/TypeInput.d.ts +1 -0
- package/dist/src/web/components/typeInputs/TypeInput.js +14 -60
- package/dist/src/web/routes/CreateInstance.js +1 -1
- package/dist/src/web/routes/Instance.js +4 -3
- package/dist/src/web/utils/debug.d.ts +1 -0
- package/dist/src/web/utils/debug.js +5 -0
- package/package.json +1 -1
- package/public/css/styles.css +4 -4
|
@@ -4,7 +4,8 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedArrayType;
|
|
7
|
-
|
|
7
|
+
path: string | undefined;
|
|
8
|
+
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
10
11
|
onChange: (value: unknown[]) => void;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { removeAt } from "../../../shared/utils/array.js";
|
|
3
3
|
import { validateArrayConstraints } from "../../../shared/validation/array.js";
|
|
4
4
|
import { createTypeSkeleton } from "../../utils/typeSkeleton.js";
|
|
5
5
|
import { TypeInput } from "./TypeInput.js";
|
|
6
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
6
7
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
7
|
-
export const ArrayTypeInput = ({ type, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
8
|
+
export const ArrayTypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
9
|
+
if (!Array.isArray(value)) {
|
|
10
|
+
return _jsx(MismatchingTypeError, { expected: "array", actual: value });
|
|
11
|
+
}
|
|
8
12
|
const errors = validateArrayConstraints(type, value);
|
|
9
13
|
const isTuple = typeof type.minItems === "number" && type.minItems === type.maxItems;
|
|
10
14
|
return (_jsxs("div", { class: "field field--container field--array", children: [value.length > 0 && (_jsx("ol", { children: value.map((item, i) => (_jsxs("li", { class: "container-item array-item", children: [isTuple ? null : (_jsxs("div", { className: "container-item-header", children: [_jsxs("div", { className: "container-item-title", children: [i + 1, "."] }), _jsxs("button", { class: "destructive", onClick: () => {
|
|
11
15
|
onChange(removeAt(value, i));
|
|
12
|
-
}, disabled: type.minItems !== undefined && value.length <= type.minItems, children: ["Delete Item #", i + 1] })] })), _jsx(TypeInput, { type: type.items, value: item, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
16
|
+
}, disabled: type.minItems !== undefined && value.length <= type.minItems, children: ["Delete Item #", i + 1] })] })), _jsx(TypeInput, { type: type.items, path: path === undefined ? `[${i.toString()}]` : `${path}[${i.toString()}]`, value: item, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
13
17
|
onChange(value.with(i, newItem));
|
|
14
18
|
} })] }, i))) })), isTuple ? null : (_jsx("div", { class: "add-item-container", children: _jsxs("button", { onClick: () => {
|
|
15
19
|
onChange([...value, createTypeSkeleton(getDeclFromDeclName, type.items)]);
|
|
@@ -2,7 +2,7 @@ import type { FunctionComponent } from "preact";
|
|
|
2
2
|
import type { SerializedBooleanType } from "../../../node/schema/types/primitives/BooleanType.ts";
|
|
3
3
|
type Props = {
|
|
4
4
|
type: SerializedBooleanType;
|
|
5
|
-
value:
|
|
5
|
+
value: unknown;
|
|
6
6
|
onChange: (value: boolean) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const BooleanTypeInput: FunctionComponent<Props>;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
2
3
|
export const BooleanTypeInput = ({ value, onChange }) => {
|
|
4
|
+
if (typeof value !== "boolean") {
|
|
5
|
+
return _jsx(MismatchingTypeError, { expected: "boolean", actual: value });
|
|
6
|
+
}
|
|
3
7
|
return (_jsx("div", { class: "field", children: _jsx("input", { type: "checkbox", checked: value, onInput: event => {
|
|
4
8
|
onChange(event.currentTarget.checked);
|
|
5
9
|
} }) }));
|
|
@@ -2,7 +2,7 @@ import type { FunctionComponent } from "preact";
|
|
|
2
2
|
import type { SerializedDateType } from "../../../node/schema/types/primitives/DateType.ts";
|
|
3
3
|
type Props = {
|
|
4
4
|
type: SerializedDateType;
|
|
5
|
-
value:
|
|
5
|
+
value: unknown;
|
|
6
6
|
onChange: (value: string) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const DateTypeInput: FunctionComponent<Props>;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { validateDateConstraints } from "../../../shared/validation/date.js";
|
|
3
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
3
4
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
4
5
|
export const DateTypeInput = ({ type, value, onChange }) => {
|
|
6
|
+
if (typeof value !== "string") {
|
|
7
|
+
return _jsx(MismatchingTypeError, { expected: "date string", actual: value });
|
|
8
|
+
}
|
|
5
9
|
const errors = validateDateConstraints(type, value);
|
|
6
10
|
return (_jsxs("div", { class: "field", children: [_jsx("input", { type: "date", value: value, onInput: event => {
|
|
7
11
|
onChange(event.currentTarget.value);
|
|
@@ -4,6 +4,7 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedEnumType;
|
|
7
|
+
path: string | undefined;
|
|
7
8
|
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
@@ -5,7 +5,7 @@ import { createTypeSkeleton } from "../../utils/typeSkeleton.js";
|
|
|
5
5
|
import { Select } from "../Select.js";
|
|
6
6
|
import { TypeInput } from "./TypeInput.js";
|
|
7
7
|
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
8
|
-
export const EnumTypeInput = ({ type, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
8
|
+
export const EnumTypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
9
9
|
if (typeof value !== "object" ||
|
|
10
10
|
value === null ||
|
|
11
11
|
Array.isArray(value) ||
|
|
@@ -29,7 +29,7 @@ export const EnumTypeInput = ({ type, value, instanceNamesByEntity, getDeclFromD
|
|
|
29
29
|
[event.currentTarget.value]: createTypeSkeleton(getDeclFromDeclName, caseMember.type),
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
}, children: enumValues.map(enumValue => (_jsx("option", { value: enumValue, selected: enumValue === activeEnumCase, children: toTitleCase(enumValue) }, enumValue))) }), caseMember?.type == null ? null : (_jsx("div", { className: "associated-type", children: _jsx(TypeInput, { type: caseMember.type, value: value[activeEnumCase], instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newValue => {
|
|
32
|
+
}, children: enumValues.map(enumValue => (_jsx("option", { value: enumValue, selected: enumValue === activeEnumCase, children: toTitleCase(enumValue) }, enumValue))) }), caseMember?.type == null ? null : (_jsx("div", { className: "associated-type", children: _jsx(TypeInput, { type: caseMember.type, path: path === undefined ? `{${activeEnumCase}}` : `${path}.{${activeEnumCase}}`, value: value[activeEnumCase], instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newValue => {
|
|
33
33
|
onChange({
|
|
34
34
|
[discriminatorKey]: activeEnumCase,
|
|
35
35
|
[activeEnumCase]: newValue,
|
|
@@ -2,7 +2,7 @@ import type { FunctionComponent } from "preact";
|
|
|
2
2
|
import type { SerializedFloatType } from "../../../node/schema/types/primitives/FloatType.ts";
|
|
3
3
|
type Props = {
|
|
4
4
|
type: SerializedFloatType;
|
|
5
|
-
value:
|
|
5
|
+
value: unknown;
|
|
6
6
|
onChange: (value: number) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const FloatTypeInput: FunctionComponent<Props>;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { useState } from "preact/hooks";
|
|
3
3
|
import { validateNumberConstraints } from "../../../shared/validation/number.js";
|
|
4
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
4
5
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
5
6
|
export const FloatTypeInput = ({ type, value, onChange }) => {
|
|
6
|
-
const [stringValue, setStringValue] = useState(value.toString());
|
|
7
|
+
const [stringValue, setStringValue] = useState(typeof value === "number" ? value.toString() : "");
|
|
8
|
+
if (typeof value !== "number") {
|
|
9
|
+
return _jsx(MismatchingTypeError, { expected: "float", actual: value });
|
|
10
|
+
}
|
|
7
11
|
const errors = validateNumberConstraints(type, value);
|
|
8
12
|
return (_jsxs("div", { class: "field", children: [_jsx("input", { type: "number", value: stringValue, onInput: event => {
|
|
9
13
|
setStringValue(event.currentTarget.value);
|
|
@@ -4,6 +4,7 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedIncludeIdentifierType;
|
|
7
|
+
path: string | undefined;
|
|
7
8
|
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { TypeInput } from "./TypeInput.js";
|
|
3
|
-
export const IncludeIdentifierTypeInput = ({ type, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
3
|
+
export const IncludeIdentifierTypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
4
4
|
const decl = getDeclFromDeclName(type.reference);
|
|
5
5
|
if (decl === undefined) {
|
|
6
6
|
return (_jsxs("div", { role: "alert", children: ["Unresolved declaration identifier ", _jsx("code", { children: type.reference })] }));
|
|
7
7
|
}
|
|
8
|
-
return (_jsx(TypeInput, { type: decl.type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
8
|
+
return (_jsx(TypeInput, { type: decl.type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
9
9
|
};
|
|
@@ -2,7 +2,7 @@ import type { FunctionComponent } from "preact";
|
|
|
2
2
|
import type { SerializedIntegerType } from "../../../node/schema/types/primitives/IntegerType.ts";
|
|
3
3
|
type Props = {
|
|
4
4
|
type: SerializedIntegerType;
|
|
5
|
-
value:
|
|
5
|
+
value: unknown;
|
|
6
6
|
onChange: (value: number) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const IntegerTypeInput: FunctionComponent<Props>;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { useState } from "preact/hooks";
|
|
3
3
|
import { validateNumberConstraints } from "../../../shared/validation/number.js";
|
|
4
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
4
5
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
5
6
|
export const IntegerTypeInput = ({ type, value, onChange }) => {
|
|
6
|
-
const [stringValue, setStringValue] = useState(value.toString());
|
|
7
|
+
const [stringValue, setStringValue] = useState(typeof value === "number" ? value.toString() : "");
|
|
8
|
+
if (typeof value !== "number") {
|
|
9
|
+
return _jsx(MismatchingTypeError, { expected: "float", actual: value });
|
|
10
|
+
}
|
|
7
11
|
const errors = validateNumberConstraints(type, value);
|
|
8
12
|
return (_jsxs("div", { class: "field", children: [_jsx("input", { type: "number", value: stringValue, onInput: event => {
|
|
9
13
|
setStringValue(event.currentTarget.value);
|
|
@@ -4,7 +4,8 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedNestedEntityMapType;
|
|
7
|
-
|
|
7
|
+
path: string | undefined;
|
|
8
|
+
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
10
11
|
onChange: (value: Record<string, unknown>) => void;
|
|
@@ -5,8 +5,12 @@ import { toTitleCase } from "../../../shared/utils/string.js";
|
|
|
5
5
|
import { createTypeSkeleton } from "../../utils/typeSkeleton.js";
|
|
6
6
|
import { Select } from "../Select.js";
|
|
7
7
|
import { TypeInput } from "./TypeInput.js";
|
|
8
|
-
|
|
8
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
9
|
+
export const NestedEntityMapTypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
9
10
|
const [newKey, setNewKey] = useState("");
|
|
11
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
12
|
+
return _jsx(MismatchingTypeError, { expected: "object", actual: value });
|
|
13
|
+
}
|
|
10
14
|
const existingKeys = Object.keys(value);
|
|
11
15
|
const secondaryInstances = (instanceNamesByEntity[type.secondaryEntity] ?? [])
|
|
12
16
|
.slice()
|
|
@@ -20,7 +24,7 @@ export const NestedEntityMapTypeInput = ({ type, value, instanceNamesByEntity, g
|
|
|
20
24
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
21
25
|
delete newObj[key];
|
|
22
26
|
onChange(newObj);
|
|
23
|
-
}, children: ["Delete ", name] }) })] }), _jsx(TypeInput, { type: type.type, value: item, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
27
|
+
}, children: ["Delete ", name] }) })] }), _jsx(TypeInput, { type: type.type, path: path === undefined ? key : `${path}.${key}`, value: item, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
24
28
|
onChange(sortObjectKeysAlphabetically({ ...value, [key]: newItem }));
|
|
25
29
|
} })] }, key));
|
|
26
30
|
}) })), _jsxs("div", { class: "add-item-container", children: [_jsxs(Select, { value: newKey, onInput: event => {
|
|
@@ -4,7 +4,8 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedObjectType;
|
|
7
|
-
|
|
7
|
+
path: string | undefined;
|
|
8
|
+
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
10
11
|
onChange: (value: Record<string, unknown>) => void;
|
|
@@ -5,10 +5,15 @@ import { validateObjectConstraints } from "../../../shared/validation/object.js"
|
|
|
5
5
|
import { Markdown } from "../../utils/Markdown.js";
|
|
6
6
|
import { createTypeSkeleton } from "../../utils/typeSkeleton.js";
|
|
7
7
|
import { TypeInput } from "./TypeInput.js";
|
|
8
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
8
9
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
9
|
-
export const ObjectTypeInput = ({ type, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
10
|
+
export const ObjectTypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
11
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
12
|
+
return _jsx(MismatchingTypeError, { expected: "object", actual: value });
|
|
13
|
+
}
|
|
10
14
|
const errors = validateObjectConstraints(type, Object.keys(type.properties), value);
|
|
11
|
-
return (_jsxs("div", { class: "field field--container field--object", children: [_jsx("ul", { children: Object.entries(type.properties).map(([key, memberDecl]) => (_jsxs("li", { class: "container-item object-item", children: [_jsxs("div", { className: "container-item-header", children: [_jsxs("div", { className: "container-item-title", children: [_jsx("strong", { children: toTitleCase(key) }), memberDecl.comment === undefined ? null : (_jsx(Markdown, { class: "comment", string: memberDecl.comment }))] }), memberDecl.isRequired ? null : value[key] ===
|
|
15
|
+
return (_jsxs("div", { class: "field field--container field--object", children: [_jsx("ul", { children: Object.entries(type.properties).map(([key, memberDecl]) => (_jsxs("li", { class: "container-item object-item", children: [_jsxs("div", { className: "container-item-header", children: [_jsxs("div", { className: "container-item-title", children: [_jsx("strong", { children: toTitleCase(key) }), memberDecl.comment === undefined ? null : (_jsx(Markdown, { class: "comment", string: memberDecl.comment }))] }), memberDecl.isRequired ? null : value[key] ===
|
|
16
|
+
undefined ? (_jsxs("button", { onClick: () => {
|
|
12
17
|
onChange(sortObjectKeys({
|
|
13
18
|
...value,
|
|
14
19
|
[key]: createTypeSkeleton(getDeclFromDeclName, memberDecl.type),
|
|
@@ -18,7 +23,7 @@ export const ObjectTypeInput = ({ type, value, instanceNamesByEntity, getDeclFro
|
|
|
18
23
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
19
24
|
delete newObj[key];
|
|
20
25
|
onChange(newObj);
|
|
21
|
-
}, children: ["Remove ", toTitleCase(key)] }))] }), memberDecl.isRequired || value[key] !== undefined ? (_jsx(TypeInput, { type: memberDecl.type, value: value[key], instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
26
|
+
}, children: ["Remove ", toTitleCase(key)] }))] }), memberDecl.isRequired || value[key] !== undefined ? (_jsx(TypeInput, { type: memberDecl.type, path: path === undefined ? key : `${path}.${key}`, value: value[key], instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: newItem => {
|
|
22
27
|
onChange(sortObjectKeys({ ...value, [key]: newItem }, Object.keys(type.properties)));
|
|
23
28
|
} })) : null] }, key))) }), _jsx(ValidationErrors, { errors: errors })] }));
|
|
24
29
|
};
|
|
@@ -3,7 +3,7 @@ import type { SerializedReferenceIdentifierType } from "../../../node/schema/typ
|
|
|
3
3
|
import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity.ts";
|
|
4
4
|
type Props = {
|
|
5
5
|
type: SerializedReferenceIdentifierType;
|
|
6
|
-
value:
|
|
6
|
+
value: unknown;
|
|
7
7
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
8
8
|
onChange: (value: string) => void;
|
|
9
9
|
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
2
|
import { Select } from "../Select.js";
|
|
3
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
3
4
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
4
5
|
export const ReferenceIdentifierTypeInput = ({ type, value, instanceNamesByEntity, onChange, }) => {
|
|
6
|
+
if (typeof value !== "string") {
|
|
7
|
+
return _jsx(MismatchingTypeError, { expected: "string identifier", actual: value });
|
|
8
|
+
}
|
|
5
9
|
const instances = (instanceNamesByEntity[type.entity] ?? [])
|
|
6
10
|
.slice()
|
|
7
11
|
.sort((a, b) => a.name.localeCompare(b.name, undefined, { numeric: true }));
|
|
@@ -2,7 +2,7 @@ import type { FunctionComponent } from "preact";
|
|
|
2
2
|
import type { SerializedStringType } from "../../../node/schema/types/primitives/StringType.ts";
|
|
3
3
|
type Props = {
|
|
4
4
|
type: SerializedStringType;
|
|
5
|
-
value:
|
|
5
|
+
value: unknown;
|
|
6
6
|
onChange: (value: string) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const StringTypeInput: FunctionComponent<Props>;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
|
|
2
2
|
import { validateStringConstraints } from "../../../shared/validation/string.js";
|
|
3
3
|
import { Markdown } from "../../utils/Markdown.js";
|
|
4
|
+
import { MismatchingTypeError } from "./utils/MismatchingTypeError.js";
|
|
4
5
|
import { ValidationErrors } from "./utils/ValidationErrors.js";
|
|
5
6
|
export const StringTypeInput = ({ type, value, onChange }) => {
|
|
7
|
+
if (typeof value !== "string") {
|
|
8
|
+
return _jsx(MismatchingTypeError, { expected: "string", actual: value });
|
|
9
|
+
}
|
|
6
10
|
const { minLength, maxLength, pattern, isMarkdown } = type;
|
|
7
11
|
const errors = validateStringConstraints(type, value);
|
|
8
12
|
return (_jsx("div", { class: "field field--string", children: isMarkdown ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "editor", children: [_jsx("div", { class: "textarea-grow-wrap", "data-value": value, children: _jsx("textarea", { value: value, minLength: minLength, maxLength: maxLength, onInput: event => {
|
|
@@ -4,6 +4,7 @@ import type { InstanceNamesByEntity } from "../../hooks/useInstanceNamesByEntity
|
|
|
4
4
|
import type { GetDeclFromDeclName } from "../../hooks/useSecondaryDeclarations.ts";
|
|
5
5
|
type Props = {
|
|
6
6
|
type: SerializedType;
|
|
7
|
+
path: string | undefined;
|
|
7
8
|
value: unknown;
|
|
8
9
|
instanceNamesByEntity: InstanceNamesByEntity;
|
|
9
10
|
getDeclFromDeclName: GetDeclFromDeclName;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "preact/jsx-runtime";
|
|
2
2
|
import { memo } from "preact/compat";
|
|
3
|
-
import { deepEqual } from "../../../shared/utils/compare.js";
|
|
4
3
|
import { assertExhaustive } from "../../../shared/utils/typeSafety.js";
|
|
5
4
|
import { ArrayTypeInput } from "./ArrayTypeInput.js";
|
|
6
5
|
import { BooleanTypeInput } from "./BooleanTypeInput.js";
|
|
@@ -14,81 +13,36 @@ import { NestedEntityMapTypeInput } from "./NestedEntityMapTypeInput.js";
|
|
|
14
13
|
import { ObjectTypeInput } from "./ObjectTypeInput.js";
|
|
15
14
|
import { ReferenceIdentifierTypeInput } from "./ReferenceIdentifierTypeInput.js";
|
|
16
15
|
import { StringTypeInput } from "./StringTypeInput.js";
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const TypeInput = ({ type, path, value, instanceNamesByEntity, getDeclFromDeclName, onChange, }) => {
|
|
17
|
+
// console.log("rendering node at path ", path ?? "<root>")
|
|
19
18
|
switch (type.kind) {
|
|
20
19
|
case "BooleanType":
|
|
21
|
-
|
|
22
|
-
return _jsx(BooleanTypeInput, { type: type, value: value, onChange: onChange });
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
return _jsx(MismatchingTypeError, { expected: "boolean", actual: value });
|
|
26
|
-
}
|
|
20
|
+
return _jsx(BooleanTypeInput, { type: type, value: value, onChange: onChange });
|
|
27
21
|
case "DateType":
|
|
28
|
-
|
|
29
|
-
return _jsx(DateTypeInput, { type: type, value: value, onChange: onChange });
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
return _jsx(MismatchingTypeError, { expected: "date string", actual: value });
|
|
33
|
-
}
|
|
22
|
+
return _jsx(DateTypeInput, { type: type, value: value, onChange: onChange });
|
|
34
23
|
case "FloatType":
|
|
35
|
-
|
|
36
|
-
return _jsx(FloatTypeInput, { type: type, value: value, onChange: onChange });
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
return _jsx(MismatchingTypeError, { expected: "float", actual: value });
|
|
40
|
-
}
|
|
24
|
+
return _jsx(FloatTypeInput, { type: type, value: value, onChange: onChange });
|
|
41
25
|
case "IntegerType":
|
|
42
|
-
|
|
43
|
-
return _jsx(IntegerTypeInput, { type: type, value: value, onChange: onChange });
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
return _jsx(MismatchingTypeError, { expected: "integer", actual: value });
|
|
47
|
-
}
|
|
26
|
+
return _jsx(IntegerTypeInput, { type: type, value: value, onChange: onChange });
|
|
48
27
|
case "StringType":
|
|
49
|
-
|
|
50
|
-
return _jsx(StringTypeInput, { type: type, value: value, onChange: onChange });
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
return _jsx(MismatchingTypeError, { expected: "string", actual: value });
|
|
54
|
-
}
|
|
28
|
+
return _jsx(StringTypeInput, { type: type, value: value, onChange: onChange });
|
|
55
29
|
case "ArrayType":
|
|
56
|
-
|
|
57
|
-
return (_jsx(ArrayTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return _jsx(MismatchingTypeError, { expected: "array", actual: value });
|
|
61
|
-
}
|
|
30
|
+
return (_jsx(ArrayTypeInput, { type: type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
62
31
|
case "ObjectType":
|
|
63
|
-
|
|
64
|
-
return (_jsx(ObjectTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
return _jsx(MismatchingTypeError, { expected: "object", actual: value });
|
|
68
|
-
}
|
|
32
|
+
return (_jsx(ObjectTypeInput, { type: type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
69
33
|
case "TypeArgumentType":
|
|
70
34
|
return _jsx(TypeArgumentTypeInput, { type: type });
|
|
71
35
|
case "ReferenceIdentifierType":
|
|
72
|
-
|
|
73
|
-
return (_jsx(ReferenceIdentifierTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, onChange: onChange }));
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
return _jsx(MismatchingTypeError, { expected: "string identifier", actual: value });
|
|
77
|
-
}
|
|
36
|
+
return (_jsx(ReferenceIdentifierTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, onChange: onChange }));
|
|
78
37
|
case "IncludeIdentifierType":
|
|
79
|
-
return (_jsx(IncludeIdentifierTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
38
|
+
return (_jsx(IncludeIdentifierTypeInput, { type: type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
80
39
|
case "NestedEntityMapType":
|
|
81
|
-
|
|
82
|
-
return (_jsx(NestedEntityMapTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
return _jsx(MismatchingTypeError, { expected: "entity map", actual: value });
|
|
86
|
-
}
|
|
40
|
+
return (_jsx(NestedEntityMapTypeInput, { type: type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
87
41
|
case "EnumType":
|
|
88
|
-
return (_jsx(EnumTypeInput, { type: type, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
42
|
+
return (_jsx(EnumTypeInput, { type: type, path: path, value: value, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: onChange }));
|
|
89
43
|
default:
|
|
90
44
|
return assertExhaustive(type);
|
|
91
45
|
}
|
|
92
46
|
};
|
|
93
|
-
const MemoizedTypeInput = memo(TypeInput, (prevProps, nextProps) =>
|
|
47
|
+
const MemoizedTypeInput = memo(TypeInput, (prevProps, nextProps) => prevProps.value === nextProps.value && prevProps.onChange === nextProps.onChange);
|
|
94
48
|
export { MemoizedTypeInput as TypeInput };
|
|
@@ -77,7 +77,7 @@ export const CreateInstance = () => {
|
|
|
77
77
|
{ url: `/entities/${entity.name}`, label: entity.name },
|
|
78
78
|
], children: [_jsx("div", { class: "header-with-btns", children: _jsx("h1", { class: instanceName.length === 0 ? "empty-name" : undefined, children: instanceName || defaultName }) }), isLocaleEntity && (_jsxs("div", { class: "field field--id", children: [_jsx("label", { htmlFor: "id", children: "ID" }), _jsx("p", { className: "comment", children: "The instance\u2019s identifier. An IETF language tag (BCP47)." }), _jsx("input", { type: "text", id: "id", value: customId, required: true, pattern: "[a-z]{2,3}(-[A-Z]{2,3})?", placeholder: "en-US, de-DE, \u2026", onInput: event => {
|
|
79
79
|
setCustomId(event.currentTarget.value);
|
|
80
|
-
}, "aria-invalid": idErrors.length > 0 }), _jsx(ValidationErrors, { errors: idErrors })] })), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entity.type, value: instance, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: value => {
|
|
80
|
+
}, "aria-invalid": idErrors.length > 0 }), _jsx(ValidationErrors, { errors: idErrors })] })), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entity.type, path: undefined, value: instance, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: value => {
|
|
81
81
|
console.log("onChange", value);
|
|
82
82
|
setInstance(value);
|
|
83
83
|
} }), _jsxs("div", { class: "form-footer btns", children: [_jsx("button", { type: "submit", class: "primary", name: "save", children: "Save" }), _jsx("button", { type: "submit", class: "primary", name: "saveandcontinue", children: "Save and Continue" }), _jsx("button", { type: "submit", class: "primary", name: "saveandaddanother", children: "Save and Add Another" })] })] })] }));
|
|
@@ -9,6 +9,7 @@ import { TypeInput } from "../components/typeInputs/TypeInput.js";
|
|
|
9
9
|
import { useEntityFromRoute } from "../hooks/useEntityFromRoute.js";
|
|
10
10
|
import { useInstanceNamesByEntity } from "../hooks/useInstanceNamesByEntity.js";
|
|
11
11
|
import { useGetDeclFromDeclName } from "../hooks/useSecondaryDeclarations.js";
|
|
12
|
+
import { printJson } from "../utils/debug.js";
|
|
12
13
|
import { NotFound } from "./NotFound.js";
|
|
13
14
|
export const Instance = () => {
|
|
14
15
|
const { params: { name, id }, } = useRoute();
|
|
@@ -19,7 +20,7 @@ export const Instance = () => {
|
|
|
19
20
|
const [originalInstance, setOriginalInstance] = useState();
|
|
20
21
|
const { route } = useLocation();
|
|
21
22
|
useEffect(() => {
|
|
22
|
-
if (entityFromRoute && instance && id) {
|
|
23
|
+
if (entityFromRoute?.entity && instance?.content && id) {
|
|
23
24
|
const defaultName = id;
|
|
24
25
|
const instanceName = getSerializedDisplayNameFromEntityInstance(entityFromRoute.entity, instance.content, defaultName);
|
|
25
26
|
const entityName = entityFromRoute.entity.name;
|
|
@@ -28,7 +29,7 @@ export const Instance = () => {
|
|
|
28
29
|
else {
|
|
29
30
|
document.title = "Not found — TSONDB";
|
|
30
31
|
}
|
|
31
|
-
}, [entityFromRoute, id, instance]);
|
|
32
|
+
}, [entityFromRoute?.entity, id, instance?.content]);
|
|
32
33
|
useEffect(() => {
|
|
33
34
|
if (name && id) {
|
|
34
35
|
getInstanceByEntityNameAndId(name, id)
|
|
@@ -89,5 +90,5 @@ export const Instance = () => {
|
|
|
89
90
|
}
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
|
-
}, children: "Delete" })] }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entityFromRoute.entity.type, value: instance.content, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: handleOnChange }), _jsx("div", { class: "form-footer btns", children: _jsx("button", { type: "submit", name: "save", class: "primary", children: "Save" }) })] })] }));
|
|
93
|
+
}, children: "Delete" })] }), _jsxs("div", { class: "debug-compare", style: { display: "flex", gap: "1rem", width: "100%" }, children: [_jsxs("div", { style: { flex: "1 1 0", position: "relative" }, children: [_jsx("p", { children: "Original" }), _jsx("pre", { style: { overflowX: "scroll", width: "40rem", maxWidth: "100%" }, children: _jsx("code", { dangerouslySetInnerHTML: { __html: printJson(originalInstance.content) } }) })] }), _jsxs("div", { style: { flex: "1 1 0", position: "relative" }, children: [_jsx("p", { children: "Current" }), _jsx("pre", { style: { overflowX: "scroll", width: "40rem", maxWidth: "100%" }, children: _jsx("code", { dangerouslySetInnerHTML: { __html: printJson(instance.content) } }) })] })] }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx(TypeInput, { type: entityFromRoute.entity.type, value: instance.content, path: undefined, instanceNamesByEntity: instanceNamesByEntity, getDeclFromDeclName: getDeclFromDeclName, onChange: handleOnChange }), _jsx("div", { class: "form-footer btns", children: _jsx("button", { type: "submit", name: "save", class: "primary", children: "Save" }) })] })] }));
|
|
93
94
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const printJson: (data: unknown) => string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const printJson = (data) => JSON.stringify(data, undefined, 2)
|
|
2
|
+
.replace(/\n *([}\]],?)/g, " $1")
|
|
3
|
+
.replace(/((?:^|\n *)[{[])\n +/g, "$1 ")
|
|
4
|
+
.replace(/"(.+?)":/g, '<span style="color: darkorange">$1</span>:')
|
|
5
|
+
.replace(/ "(.*?)"([ ,])/g, ' <span style="color: darkgreen">"$1"</span>$2');
|
package/package.json
CHANGED
package/public/css/styles.css
CHANGED
|
@@ -292,13 +292,13 @@ input[type="checkbox"]:checked {
|
|
|
292
292
|
input[type="checkbox"]:checked::before {
|
|
293
293
|
content: "";
|
|
294
294
|
display: block;
|
|
295
|
-
border-width: 0 0
|
|
295
|
+
border-width: 0 0 0.125rem 0.125rem;
|
|
296
296
|
border-style: solid;
|
|
297
|
-
width: 0.
|
|
298
|
-
height: 0.
|
|
297
|
+
width: 0.8rem;
|
|
298
|
+
height: 0.4rem;
|
|
299
299
|
border-color: var(--background);
|
|
300
300
|
transform: rotate(-45deg);
|
|
301
|
-
margin: calc(-0.
|
|
301
|
+
margin: calc(-0.325rem) 0 0 calc(-0.4rem);
|
|
302
302
|
}
|
|
303
303
|
|
|
304
304
|
.select-wrapper {
|