@dxos/react-ui-form 0.8.4-main.a4bbb77 → 0.8.4-main.ae835ea
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/lib/browser/index.mjs +354 -306
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +354 -306
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +2 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +8 -8
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +1 -1
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +4 -2
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +82 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +7 -5
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +2 -2
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +2 -2
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +4 -3
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts +1 -1
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +1 -1
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/src/util/schema.d.ts +1 -1
- package/dist/types/src/util/schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -33
- package/src/components/ControlSection/ControlSection.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.tsx +1 -1
- package/src/components/Form/ArrayField.tsx +4 -3
- package/src/components/Form/Form.stories.tsx +3 -3
- package/src/components/Form/Form.tsx +13 -5
- package/src/components/Form/FormContent.tsx +5 -3
- package/src/components/Form/FormContext.tsx +2 -2
- package/src/components/Form/Input.tsx +1 -1
- package/src/components/Form/RefField.tsx +35 -115
- package/src/components/Form/custom/GeoPointInput.tsx +1 -1
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
- package/src/components/ObjectPicker/ObjectPicker.tsx +161 -0
- package/src/components/ObjectPicker/index.ts +5 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +41 -25
- package/src/components/ViewEditor/ViewEditor.test.tsx +3 -2
- package/src/components/ViewEditor/ViewEditor.tsx +45 -94
- package/src/components/index.ts +1 -0
- package/src/components/testing.tsx +2 -2
- package/src/hooks/useForm.ts +6 -4
- package/src/hooks/useQueryRefOptions.ts +9 -6
- package/src/hooks/useRefQueryLookupHandler.ts +3 -3
- package/src/util/field.ts +1 -1
- package/src/util/formatting.ts +1 -1
- package/src/util/refs.ts +2 -2
- package/src/util/schema.ts +2 -4
|
@@ -2,26 +2,20 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as Array from 'effect/Array';
|
|
6
|
+
import * as Match from 'effect/Match';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
6
9
|
import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react';
|
|
7
10
|
|
|
8
|
-
import {
|
|
9
|
-
import { EchoSchema, Format, type JsonProp, isMutable, toJsonSchema } from '@dxos/echo
|
|
11
|
+
import { QueryAST } from '@dxos/echo';
|
|
12
|
+
import { EchoSchema, Format, type JsonProp, isMutable, toJsonSchema } from '@dxos/echo/internal';
|
|
13
|
+
import { Filter, Query, type SchemaRegistry } from '@dxos/echo-db';
|
|
10
14
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
IconButton,
|
|
14
|
-
Input,
|
|
15
|
-
type ThemedClassName,
|
|
16
|
-
useDensityContext,
|
|
17
|
-
useElevationContext,
|
|
18
|
-
useThemeContext,
|
|
19
|
-
useTranslation,
|
|
20
|
-
} from '@dxos/react-ui';
|
|
21
|
-
import { Editor, createBasicExtensions, createThemeExtensions } from '@dxos/react-ui-editor';
|
|
15
|
+
import { Callout, IconButton, Input, type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
16
|
+
import { QueryForm, type QueryFormProps } from '@dxos/react-ui-components';
|
|
22
17
|
import { List } from '@dxos/react-ui-list';
|
|
23
18
|
import { cardSpacing } from '@dxos/react-ui-stack';
|
|
24
|
-
import { inputTheme } from '@dxos/react-ui-theme';
|
|
25
19
|
import { inputTextLabel, mx, subtleHover } from '@dxos/react-ui-theme';
|
|
26
20
|
import {
|
|
27
21
|
type DataType,
|
|
@@ -29,7 +23,7 @@ import {
|
|
|
29
23
|
type FieldType,
|
|
30
24
|
ProjectionModel,
|
|
31
25
|
VIEW_FIELD_LIMIT,
|
|
32
|
-
|
|
26
|
+
getTypenameFromQuery,
|
|
33
27
|
} from '@dxos/schema';
|
|
34
28
|
|
|
35
29
|
import { translationKey } from '../../translations';
|
|
@@ -47,9 +41,10 @@ export type ViewEditorProps = ThemedClassName<
|
|
|
47
41
|
registry?: SchemaRegistry;
|
|
48
42
|
readonly?: boolean;
|
|
49
43
|
showHeading?: boolean;
|
|
50
|
-
onQueryChanged?: (query:
|
|
44
|
+
onQueryChanged?: (query: QueryAST.Query, target?: string) => void;
|
|
51
45
|
onDelete?: (fieldId: string) => void;
|
|
52
|
-
} & Pick<FormProps<any>, 'outerSpacing'>
|
|
46
|
+
} & Pick<FormProps<any>, 'outerSpacing'> &
|
|
47
|
+
Pick<QueryFormProps, 'types' | 'tags'>
|
|
53
48
|
>;
|
|
54
49
|
|
|
55
50
|
/**
|
|
@@ -65,6 +60,8 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
65
60
|
registry,
|
|
66
61
|
readonly,
|
|
67
62
|
showHeading = false,
|
|
63
|
+
types,
|
|
64
|
+
tags,
|
|
68
65
|
onQueryChanged,
|
|
69
66
|
onDelete,
|
|
70
67
|
outerSpacing = true,
|
|
@@ -81,18 +78,6 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
81
78
|
useImperativeHandle(forwardedRef, () => projectionModel, [projectionModel]);
|
|
82
79
|
const [expandedField, setExpandedField] = useState<FieldType['id']>();
|
|
83
80
|
|
|
84
|
-
const serializedQuery = Match.value(mode).pipe(
|
|
85
|
-
Match.when('schema', () => typenameFromQuery(view.query.ast)),
|
|
86
|
-
Match.when('query', () => {
|
|
87
|
-
if (view.query.string) {
|
|
88
|
-
return view.query.string;
|
|
89
|
-
} else {
|
|
90
|
-
return 'Serializing query AST is not currently supported.';
|
|
91
|
-
}
|
|
92
|
-
}),
|
|
93
|
-
Match.exhaustive,
|
|
94
|
-
);
|
|
95
|
-
|
|
96
81
|
const queueTarget = Match.value(view.query.ast).pipe(
|
|
97
82
|
Match.when({ type: 'options' }, ({ options }) => {
|
|
98
83
|
return Option.fromNullable(options.queues).pipe(
|
|
@@ -108,7 +93,7 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
108
93
|
query:
|
|
109
94
|
mode === 'schema'
|
|
110
95
|
? Format.URL.annotations({ title: 'Record type' })
|
|
111
|
-
:
|
|
96
|
+
: QueryAST.Query.annotations({ title: 'Query' }),
|
|
112
97
|
});
|
|
113
98
|
|
|
114
99
|
if (mode === 'query') {
|
|
@@ -121,11 +106,16 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
121
106
|
|
|
122
107
|
return base.pipe(Schema.mutable);
|
|
123
108
|
}, [mode]);
|
|
109
|
+
|
|
124
110
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
125
111
|
// TODO(burdon): Settings should have domain name owned by user.
|
|
126
112
|
const viewValues = useMemo(
|
|
127
|
-
() => ({
|
|
128
|
-
|
|
113
|
+
() => ({
|
|
114
|
+
name: view.name,
|
|
115
|
+
query: mode === 'schema' ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
116
|
+
target: queueTarget,
|
|
117
|
+
}),
|
|
118
|
+
[view.name, mode, view.query.ast, queueTarget],
|
|
129
119
|
);
|
|
130
120
|
|
|
131
121
|
const handleToggleField = useCallback(
|
|
@@ -144,23 +134,19 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
144
134
|
}, [schema, projectionModel, readonly]);
|
|
145
135
|
|
|
146
136
|
const handleUpdate = useCallback(
|
|
147
|
-
(values:
|
|
137
|
+
(values: any) => {
|
|
148
138
|
invariant(!readonly);
|
|
149
139
|
requestAnimationFrame(() => {
|
|
150
140
|
if ('name' in values && view.name !== values.name) {
|
|
151
141
|
view.name = values.name;
|
|
142
|
+
return;
|
|
152
143
|
}
|
|
153
144
|
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
const targetChanged = 'target' in values && values.target && queueTarget !== targetValue;
|
|
157
|
-
|
|
158
|
-
if ((queryChanged || targetChanged) && !readonly) {
|
|
159
|
-
onQueryChanged?.(values.query, targetValue);
|
|
160
|
-
}
|
|
145
|
+
const query = mode === 'schema' ? Query.select(Filter.typename(values.query)).ast : values.query;
|
|
146
|
+
onQueryChanged?.(query, values.target);
|
|
161
147
|
});
|
|
162
148
|
},
|
|
163
|
-
[
|
|
149
|
+
[onQueryChanged, readonly, view, queueTarget, mode],
|
|
164
150
|
);
|
|
165
151
|
|
|
166
152
|
const handleDelete = useCallback(
|
|
@@ -205,58 +191,7 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
205
191
|
[projectionModel],
|
|
206
192
|
);
|
|
207
193
|
|
|
208
|
-
const custom:
|
|
209
|
-
() =>
|
|
210
|
-
mode === 'query'
|
|
211
|
-
? {
|
|
212
|
-
['query' satisfies keyof Schema.Schema.Type<typeof viewSchema>]: (props: InputProps) => {
|
|
213
|
-
const { themeMode } = useThemeContext();
|
|
214
|
-
const density = useDensityContext();
|
|
215
|
-
const elevation = useElevationContext();
|
|
216
|
-
|
|
217
|
-
// TODO(wittjosiah): Including props.onValueChange in deps causes infinite loop.
|
|
218
|
-
const handleChange = useCallback((text: string) => props.onValueChange('string', text), []);
|
|
219
|
-
|
|
220
|
-
const extensions = useMemo(
|
|
221
|
-
() => [
|
|
222
|
-
createBasicExtensions({ placeholder: t('query placeholder') }),
|
|
223
|
-
createThemeExtensions({ themeMode }),
|
|
224
|
-
],
|
|
225
|
-
[],
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
// TODO(wittjosiah): This is probably not the right way to do these styles.
|
|
229
|
-
return (
|
|
230
|
-
<Input.Root>
|
|
231
|
-
<InputHeader label={props.label} />
|
|
232
|
-
<Editor
|
|
233
|
-
classNames={mx(
|
|
234
|
-
inputTheme.input({ density, elevation }),
|
|
235
|
-
'flex items-center',
|
|
236
|
-
'focus-within:bg-focusSurface focus-within:border-separator focus-within:hover:bg-focusSurface',
|
|
237
|
-
)}
|
|
238
|
-
extensions={extensions}
|
|
239
|
-
value={props.getValue()}
|
|
240
|
-
onChange={handleChange}
|
|
241
|
-
/>
|
|
242
|
-
{/* TODO(wittjosiah): Support query editor.
|
|
243
|
-
<QueryEditor
|
|
244
|
-
classNames={mx(
|
|
245
|
-
inputTheme.input({ density, elevation }),
|
|
246
|
-
'flex items-center',
|
|
247
|
-
'focus-within:bg-focusSurface focus-within:border-separator focus-within:hover:bg-focusSurface',
|
|
248
|
-
)}
|
|
249
|
-
space={space}
|
|
250
|
-
value={props.getValue()}
|
|
251
|
-
onChange={handleChange}
|
|
252
|
-
/> */}
|
|
253
|
-
</Input.Root>
|
|
254
|
-
);
|
|
255
|
-
},
|
|
256
|
-
}
|
|
257
|
-
: {},
|
|
258
|
-
[],
|
|
259
|
-
);
|
|
194
|
+
const custom = useMemo(() => (mode === 'query' ? customFields({ types, tags }) : undefined), [types, tags, mode]);
|
|
260
195
|
|
|
261
196
|
return (
|
|
262
197
|
<div role='none' className={mx(classNames)}>
|
|
@@ -377,3 +312,19 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
|
|
|
377
312
|
);
|
|
378
313
|
},
|
|
379
314
|
);
|
|
315
|
+
|
|
316
|
+
const customFields = ({ types, tags }: Pick<ViewEditorProps, 'types' | 'tags'>): Record<string, InputComponent> => ({
|
|
317
|
+
query: (props: InputProps) => {
|
|
318
|
+
const handleChange = useCallback(
|
|
319
|
+
(query: Query.Any) => props.onValueChange('object', query.ast),
|
|
320
|
+
[props.onValueChange],
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<Input.Root>
|
|
325
|
+
<InputHeader label={props.label} />
|
|
326
|
+
<QueryForm initialQuery={props.getValue()} types={types} tags={tags} onChange={handleChange} />
|
|
327
|
+
</Input.Root>
|
|
328
|
+
);
|
|
329
|
+
},
|
|
330
|
+
});
|
package/src/components/index.ts
CHANGED
|
@@ -13,9 +13,9 @@ type TestLayoutProps = ThemedClassName<PropsWithChildren<{ json?: any }>>;
|
|
|
13
13
|
|
|
14
14
|
export const TestLayout = ({ classNames, children, json }: TestLayoutProps) => {
|
|
15
15
|
return (
|
|
16
|
-
<div className='
|
|
16
|
+
<div className='is-full bs-full grid grid-cols-[1fr_1fr] gap-2 overflow-hidden'>
|
|
17
17
|
<div className={mx('p-4 justify-center overflow-y-auto', classNames)}>{children}</div>
|
|
18
|
-
<JsonFilter data={json} classNames='
|
|
18
|
+
<JsonFilter data={json} classNames='is-full text-xs' testId='debug' />
|
|
19
19
|
</div>
|
|
20
20
|
);
|
|
21
21
|
};
|
package/src/hooks/useForm.ts
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as Schema from 'effect/Schema';
|
|
6
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
6
7
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
8
|
|
|
8
|
-
import { type BaseObject, getValue, setValue } from '@dxos/echo
|
|
9
|
+
import { type BaseObject, getValue, setValue } from '@dxos/echo/internal';
|
|
9
10
|
import { type JsonPath, type SimpleType, createJsonPath, fromEffectValidationPath } from '@dxos/effect';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
11
12
|
import { log } from '@dxos/log';
|
|
@@ -219,12 +220,13 @@ export const useForm = <T extends BaseObject>({
|
|
|
219
220
|
|
|
220
221
|
const newValues = { ...setValue(values, jsonPath, parsedValue) };
|
|
221
222
|
setValues(newValues);
|
|
222
|
-
|
|
223
|
+
const newChanged = { ...changed, [jsonPath]: true };
|
|
224
|
+
setChanged(newChanged);
|
|
223
225
|
onValuesChanged?.(newValues);
|
|
224
226
|
|
|
225
227
|
const isValid = validate(newValues);
|
|
226
228
|
if (isValid && onValid) {
|
|
227
|
-
onValid(newValues, { changed });
|
|
229
|
+
onValid(newValues, { changed: newChanged });
|
|
228
230
|
}
|
|
229
231
|
},
|
|
230
232
|
[values, onValuesChanged, validate, onValid, changed],
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { type TypeAnnotation } from '@dxos/echo
|
|
7
|
+
import { type TypeAnnotation } from '@dxos/echo/internal';
|
|
8
8
|
import { type DXN } from '@dxos/keys';
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
|
-
import { type
|
|
10
|
+
import { type Palette } from '@dxos/react-ui-types';
|
|
11
11
|
import { type MaybePromise } from '@dxos/util';
|
|
12
12
|
|
|
13
13
|
export type RefOption = { dxn: DXN; label?: string };
|
|
@@ -16,7 +16,7 @@ export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<RefOption[]
|
|
|
16
16
|
export type QueryTag = {
|
|
17
17
|
id: string;
|
|
18
18
|
label: string;
|
|
19
|
-
hue?:
|
|
19
|
+
hue?: Palette;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
type UseQueryRefOptionsProps = { refTypeInfo: TypeAnnotation | undefined; onQueryRefOptions?: QueryRefOptions };
|
|
@@ -25,9 +25,12 @@ type UseQueryRefOptionsProps = { refTypeInfo: TypeAnnotation | undefined; onQuer
|
|
|
25
25
|
* Hook to query reference options based on type information.
|
|
26
26
|
* Used internally within forms to fetch and format reference options for reference fields.
|
|
27
27
|
*/
|
|
28
|
+
// TODO(wittjosiah): This should be a reactive query so that the options are always up to date.
|
|
28
29
|
export const useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }: UseQueryRefOptionsProps) => {
|
|
29
30
|
const [options, setOptions] = useState<QueryTag[]>([]);
|
|
30
31
|
const [loading, setLoading] = useState(false);
|
|
32
|
+
const [state, setState] = useState({});
|
|
33
|
+
const update = useCallback(() => setState({}), []);
|
|
31
34
|
|
|
32
35
|
useEffect(() => {
|
|
33
36
|
if (!refTypeInfo || !onQueryRefOptions) {
|
|
@@ -53,7 +56,7 @@ export const useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }: UseQueryR
|
|
|
53
56
|
};
|
|
54
57
|
|
|
55
58
|
void fetchOptions();
|
|
56
|
-
}, [refTypeInfo, onQueryRefOptions]);
|
|
59
|
+
}, [refTypeInfo, onQueryRefOptions, state]);
|
|
57
60
|
|
|
58
|
-
return { options, loading };
|
|
61
|
+
return { options, update, loading };
|
|
59
62
|
};
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Obj } from '@dxos/echo';
|
|
8
|
+
import { type TypeAnnotation, getObjectDXN } from '@dxos/echo/internal';
|
|
8
9
|
import { Filter, type Space } from '@dxos/react-client/echo';
|
|
9
10
|
import { isNonNullable } from '@dxos/util';
|
|
10
11
|
|
|
@@ -28,8 +29,7 @@ export const useRefQueryLookupHandler = ({ space }: UseRefQueryLookupProps): Que
|
|
|
28
29
|
return undefined;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
const item = { dxn, label: object?.name ?? object?.id ?? '' };
|
|
32
|
+
const item = { dxn, label: Obj.getLabel(object) ?? object?.id ?? '' };
|
|
33
33
|
return item;
|
|
34
34
|
})
|
|
35
35
|
.filter(isNonNullable);
|
package/src/util/field.ts
CHANGED
package/src/util/formatting.ts
CHANGED
package/src/util/refs.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import type * as SchemaAST from 'effect/SchemaAST';
|
|
6
6
|
|
|
7
|
-
import { FormatEnum, ReferenceAnnotationId } from '@dxos/echo
|
|
7
|
+
import { FormatEnum, ReferenceAnnotationId } from '@dxos/echo/internal';
|
|
8
8
|
import { findAnnotation } from '@dxos/effect';
|
|
9
9
|
import { type SchemaProperty } from '@dxos/schema';
|
|
10
10
|
|
package/src/util/schema.ts
CHANGED
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
6
6
|
|
|
7
7
|
import { findNode } from '@dxos/effect';
|
|
8
8
|
|
|
9
9
|
export const findArrayElementType = (ast: SchemaAST.AST) => {
|
|
10
10
|
const tupleType = findNode(ast, SchemaAST.isTupleType);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return elementType;
|
|
11
|
+
return (tupleType as SchemaAST.TupleType | undefined)?.rest[0]?.type;
|
|
14
12
|
};
|