Skip to content

Commit 474a160

Browse files
fix(vue-vuetify): resolve $ref on propertyNames (#2603)
Resolve the `$ref` against the real root schema before spreading, so the nested form gets a self-contained subschema. Adds a regression test mounting such a map and asserting the mount does not throw.
1 parent baf09e7 commit 474a160

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

packages/vue-vuetify/src/complex/components/AdditionalProperties.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,17 @@ export default defineComponent({
302302
// TODO: create issue against jsonforms to add propertyNames into the JsonSchema interface
303303
// propertyNames exist in draft-6 but not defined in the JsonSchema
304304
if (typeof (control.value.schema as any).propertyNames === 'object') {
305+
let propertyNames = (control.value.schema as any).propertyNames;
306+
if (typeof propertyNames.$ref === 'string') {
307+
propertyNames =
308+
Resolve.schema(
309+
control.value.rootSchema,
310+
propertyNames.$ref,
311+
control.value.rootSchema,
312+
) ?? propertyNames;
313+
}
305314
result = {
306-
...(control.value.schema as any).propertyNames,
315+
...propertyNames,
307316
...result,
308317
};
309318
} else if (
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { describe, it, expect, beforeEach } from 'vitest';
2+
import { clearAllIds } from '@jsonforms/core';
3+
import { extendedVuetifyRenderers } from '../../../src';
4+
import { mountJsonForms } from '../util';
5+
6+
// Test use of `$ref` in additional-properties `propertyNames`
7+
describe('AdditionalProperties nested $ref propertyNames', () => {
8+
const schema = {
9+
type: 'object' as const,
10+
$defs: {
11+
attrName: {
12+
type: 'string' as const,
13+
pattern: '^[A-Za-z_][A-Za-z0-9_]*$',
14+
},
15+
},
16+
properties: {
17+
secretFiles: {
18+
type: 'object' as const,
19+
additionalProperties: { type: 'string' as const },
20+
propertyNames: { $ref: '#/$defs/attrName' },
21+
},
22+
},
23+
};
24+
const uischema = { type: 'Control' as const, scope: '#' };
25+
26+
beforeEach(() => {
27+
clearAllIds();
28+
});
29+
30+
it('mounts a map whose key type is a `$ref` into the root `$defs`', () => {
31+
expect(() =>
32+
mountJsonForms({ secretFiles: {} }, schema, extendedVuetifyRenderers, uischema),
33+
).not.toThrow();
34+
});
35+
});

0 commit comments

Comments
 (0)