diff --git a/packages/core/src/generators/Generate.ts b/packages/core/src/generators/Generate.ts index ad1b17354d..4a8d9adebe 100644 --- a/packages/core/src/generators/Generate.ts +++ b/packages/core/src/generators/Generate.ts @@ -28,9 +28,7 @@ import { generateJsonSchema } from './schema'; import { createControlElement, generateDefaultUISchema } from './uischema'; export const Generate: { - // TODO fix @typescript-eslint/ban-types - // eslint-disable-next-line @typescript-eslint/ban-types - jsonSchema(instance: Object, options?: any): JsonSchema; + jsonSchema(instance: unknown, options?: any): JsonSchema; uiSchema( jsonSchema: JsonSchema, layoutType?: string, diff --git a/packages/core/src/generators/schema.ts b/packages/core/src/generators/schema.ts index f3b1d2324b..623966e97f 100644 --- a/packages/core/src/generators/schema.ts +++ b/packages/core/src/generators/schema.ts @@ -52,9 +52,7 @@ class Gen { private findOption: (props: Properties) => (optionName: string) => any ) {} - // TODO fix @typescript-eslint/ban-types - // eslint-disable-next-line @typescript-eslint/ban-types - schemaObject = (data: Object): JsonSchema4 => { + schemaObject = (data: Record): JsonSchema4 => { const props: Properties = this.properties(data); const schema: JsonSchema4 = { type: 'object', @@ -140,14 +138,12 @@ class Gen { /** * Generate a JSON schema based on the given data and any additional options. - * @param {Object} instance the data to create a JSON schema for + * @param {unknown} instance the data to create a JSON schema for * @param {any} options any additional options that may alter the generated JSON schema * @returns {JsonSchema} the generated schema */ export const generateJsonSchema = ( - // TODO fix @typescript-eslint/ban-types - // eslint-disable-next-line @typescript-eslint/ban-types - instance: Object, + instance: unknown, options: any = {} ): JsonSchema4 => { const findOption = @@ -177,5 +173,5 @@ export const generateJsonSchema = ( const gen = new Gen(findOption); - return gen.schemaObject(instance); + return gen.property(instance); }; diff --git a/packages/core/src/generators/uischema.ts b/packages/core/src/generators/uischema.ts index bb8fdec2f9..ff91662841 100644 --- a/packages/core/src/generators/uischema.ts +++ b/packages/core/src/generators/uischema.ts @@ -225,4 +225,4 @@ export const generateDefaultUISchema = ( wrapInLayoutIfNecessary( generateUISchema(jsonSchema, [], prefix, '', layoutType, rootSchema), layoutType - ); + ) ?? createLayout(layoutType); diff --git a/packages/core/test/generators/schema.test.ts b/packages/core/test/generators/schema.test.ts index 679defefa3..13ecf543b9 100644 --- a/packages/core/test/generators/schema.test.ts +++ b/packages/core/test/generators/schema.test.ts @@ -26,6 +26,38 @@ import test from 'ava'; import { generateJsonSchema } from '../../src/generators/schema'; +test('default schema generation root primitive types', (t) => { + t.deepEqual(generateJsonSchema(undefined), {}); + t.deepEqual(generateJsonSchema('hello'), { + type: 'string', + }); + t.deepEqual(generateJsonSchema(42), { + type: 'integer', + }); + t.deepEqual(generateJsonSchema(3.14), { + type: 'number', + }); + t.deepEqual(generateJsonSchema(true), { + type: 'boolean', + }); + t.deepEqual(generateJsonSchema(null), { + type: 'null', + }); +}); + +test('default schema generation root array types', (t) => { + t.deepEqual(generateJsonSchema([]), { + type: 'array', + items: {}, + }); + t.deepEqual(generateJsonSchema([1, 2]), { + type: 'array', + items: { + type: 'integer', + }, + }); +}); + test('default schema generation basic types', (t) => { const instance: any = { boolean: false, diff --git a/packages/core/test/generators/uischema.test.ts b/packages/core/test/generators/uischema.test.ts index 904f3b70b4..024c1e177f 100644 --- a/packages/core/test/generators/uischema.test.ts +++ b/packages/core/test/generators/uischema.test.ts @@ -496,19 +496,28 @@ test('generate unnamed array control w/o type', (t) => { test('generate for empty schema', (t) => { const schema: JsonSchema = {}; - const uischema: Layout = null; + const uischema: Layout = { + type: 'VerticalLayout', + elements: [], + }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); test('generate for null schema', (t) => { const schema: JsonSchema = null; - const uischema: Layout = null; + const uischema: Layout = { + type: 'VerticalLayout', + elements: [], + }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); test('generate for undefined schema', (t) => { const schema: JsonSchema = undefined; - const uischema: Layout = null; + const uischema: Layout = { + type: 'VerticalLayout', + elements: [], + }; t.deepEqual(generateDefaultUISchema(schema), uischema); }); diff --git a/packages/vue-vuetify/dev/components/ExampleForm.vue b/packages/vue-vuetify/dev/components/ExampleForm.vue index 25a2e4f6bc..4036503c4d 100644 --- a/packages/vue-vuetify/dev/components/ExampleForm.vue +++ b/packages/vue-vuetify/dev/components/ExampleForm.vue @@ -50,12 +50,16 @@ const resolvedSchema = shallowReactive({ error: undefined, }); -const emits = defineEmits(['jsfchange']); +const emits = defineEmits(['jsfchange', 'update:data']); const onChange = (event: JsonFormsChangeEvent): void => { emits('jsfchange', event); }; +const onUpdateData = (data: any): void => { + emits('update:data', data); +}; + watch( () => props.state.schema, (schema) => { @@ -101,6 +105,7 @@ const properties = computed(() => ({ v-if="resolvedSchema.resolved && resolvedSchema.error === undefined" v-bind="properties" @change="onChange" + @update:data="onUpdateData" > { monaco.Uri.parse(toDataUri(props.example.name)), event.data !== undefined ? JSON.stringify(event.data, null, 2) : '', ); - state.data = event.data; } errors.value = event.errors; }; +const onDataChange = (data: any): void => { + state.data = data; +}; + const reloadMonacoSchema = () => { const example = find( examples, @@ -346,7 +349,11 @@ const handleAction = (action: Action) => { - + @@ -392,7 +399,12 @@ const handleAction = (action: Action) => { - + @@ -505,7 +517,11 @@ const handleAction = (action: Action) => {
- +
diff --git a/packages/vue/README.md b/packages/vue/README.md index a2b4bf10fc..2e87b8b327 100644 --- a/packages/vue/README.md +++ b/packages/vue/README.md @@ -37,12 +37,13 @@ Optional props: Events: - `change: {data: any; errors: AJVError[]}` - Whenever data and/or errors change this event is emitted. +- `update:data: any` - Emits the current data alongside `change`, enabling `v-model:data`. Example: ```html