@ghentcdh/json-forms-core 0.8.6 → 1.0.2

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/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("zod");var z=(e=>(e.xs="xs",e.sm="sm",e.lg="lg",e.xl="xl",e))(z||{});const j=e=>{const t=e.anyOf;if(!Array.isArray(t)||t.length!==2)return;const r=t.find(o=>o.type!=="null"),s=t.some(o=>o.type==="null");r&&s&&(delete e.anyOf,Object.assign(e,r))},w=e=>{const t=n.toJSONSchema(e,{unrepresentable:"any",target:"draft-07"});t.additionalProperties=!0;const r=t.properties;if(r)for(const s of Object.keys(r))j(r[s]);return t},P=e=>{if(!e.schema)throw new Error("no schema provided");const t=e.schema,r=e.dtoSchema,s=w(r),o=w(t.partial());return{dtoSchema:r,responseSchema:e.responseSchema??r,schema:{form:{uiSchema:e.uiSchema,schema:s,modalSize:e.modalSize??"sm"},table:e.tableSchema?{uiSchema:e.tableSchema,schema:o}:void 0,filter:e.filterSchema?{uiSchema:e.filterSchema,schema:o}:void 0,uri:e.uri,searchUri:e.searchUri??`${e.uri}?filter=`}}},L=(e,t)=>{if(!e.scope)return{id:null,property:null};const r=e.scope?.substring(13),s=t?.properties?.[r]??{};return{id:r,property:s}},k=(e,t)=>{const{id:r,property:s}=L(e,t);return{...e,id:r,label:r,...s}};class p{constructor(t){this.type=t}}class m extends p{constructor(){super(...arguments),this.elements=[]}addControl(t){return this.elements.push(t),this}addControls(...t){return this.elements.push(...t),this}buildElements(){return this.elements.map(t=>t.build())}}const l={HorizontalLayout:"HorizontalLayout",VerticalLayout:"VerticalLayout",CollapseLayout:"CollapseLayout",GridLayout:"GridLayout"};class a extends m{constructor(t,r={}){super(t),this.options=r}static horizontal(){return new a(l.HorizontalLayout)}static collapse(){return new a(l.CollapseLayout)}static vertical(){return new a(l.VerticalLayout)}static grid(){return new a(l.GridLayout)}titleKey(t){return this.addOptions({titleKey:t})}title(t){return this.addOptions({title:t})}addOptions(t){return this.options={...this.options,...t},this}build(){return{type:this.type,elements:this.buildElements(),options:this.options}}}class y extends p{constructor(t,r="TextCell"){super(r),this.scope=t}static properties(t){return new y(`#/properties/${t}`)}key(t){return this.options={format:"keyValue",key:t},this}setSortId(t){return this.options={...this.options??{format:"TextCell"},sortId:t},this}build(){return{type:this.type,scope:this.scope,options:this.options}}}class b{constructor(){this.builder=a.horizontal()}static init(){return new b}addControl(t){return this.builder.addControls(t),this}addControls(...t){return this.builder.addControls(...t),this}build(){return this.builder.build()}}const i={number:"number",string:"string",integer:"Integer",autocomplete:"autocomplete",textArea:"textArea",markdown:"markdown",array:"array",custom:"custom",select:"select",mutliSelect:"mutliSelect",boolean:"boolean"};class u extends p{constructor(t,r="Control"){super(r),this.scope=t,this.options={format:"Control",styles:{}}}static asObject(t){return new u(`#/properties/${t}`,"Object")}static properties(t){return new u(`#/properties/${t}`)}static asCustom(t,r){const s=new u(`#/properties/${t}`);return s.addOptions({format:i.custom,type:r}),s}detail(t,r){return this._detail=t,this.addOptions({format:i.array,elementLabelProp:r}),this}addAction(t){const r=this.options?.actions??[];return r.push(t),this.addOptions({actions:r})}detailFixed(t,r={}){return this._detail=t,this.addOptions({hideActions:!0,format:i.array,layout:r.layout??"column",elementLabelProp:r.label})}labelKey(t){return this.addOptions({labelKey:t})}readonly(){return this.addOptions({format:i.string,readonly:!0})}markdown(t){return this.addOptions({format:i.markdown,...t??{}})}textArea(t){return this.addOptions({format:i.textArea,...t??{}})}autocomplete(t){return this.addOptions({format:i.autocomplete,dataField:"data",...t??{}})}control(t,r){return this.addOptions({format:t,...r})}select(t){return this.addOptions({format:i.select,...t})}mutliSelect(t){return this.addOptions({format:i.mutliSelect,...t})}width(t){return this.addOptions({styles:{...this.options?.styles,width:t,control:{wrapper:`input-${t}`}}})}customLabel(t){return this.addOptions({label:t})}placeHolder(t){return this.addOptions({placeholder:t})}hideLabel(){return this.addOptions({hideLabel:!0})}addOptions(t){return this.options={...this.options,...t},this}build(){return{type:this.type,scope:this.scope,options:{...this.options,detail:this._detail?this._detail?.build():void 0}}}}class f extends m{constructor(t){super(t),this.label=t,this.rule={effect:"SHOW",condition:{}}}static label(t){return new f(t)}build(){return{type:"Category",label:this.label,rule:this.rule,elements:this.buildElements()}}}class S extends m{constructor(t){super(t),this.label=t}static label(t){return new S(t)}build(){return{type:"Group",label:this.label,elements:this.buildElements()}}}const c=()=>n.z.coerce.number().int().positive().nonnegative(),v=()=>n.z.string().or(n.z.array(n.z.string())).transform(e=>Array.isArray(e)?e:[e]),A=n.z.enum(["asc","desc"]),O=n.z.object({page:c().optional().default(1),pageSize:c().optional().default(20),sort:n.z.string().optional().default("id"),sortDir:A.optional().default("asc"),filter:v().optional().default([])}),F=O.transform(e=>{const{page:t,pageSize:r,sort:s}=e;return{...e,sort:s||"id",offset:(t-1)*r}}),R=O.extend({count:c(),totalPages:c()}),K=n.z.object({data:n.z.array(n.z.unknown()),request:R}),q=["contains","equals"],E=e=>{const[t,r,s]=e.split(":"),o=q.includes(s)?s:"contains";return{key:t,value:r,operator:o}},T=(e,t)=>{if(e.length===1)return{key:e[0],filterObj:t};const r=e.pop();return T(e,{[r]:t})},N=(e,t)=>g(e.split("."),t),g=(e,t)=>{if(e.length===1)return{[e[0]]:t};const r=e.pop();return g(e,{[r]:t})},$=e=>{const t={};return e?.forEach(r=>{const{key:s,value:o,operator:d}=E(r);if(!s)return;const h=d||"contains",x={[d||"contains"]:o.toLowerCase()};h==="contains"&&(x.mode="insensitive");const C=T(s.split("."),x);t[C.key]=C.filterObj}),t},G=e=>{const t=[];return e.forEach(r=>{const{key:s,value:o,operator:d}=E(r);if(!s)return;const h=s;t.push({label:h,key:s,value:o,operator:d})}),t};exports.CategoryBuilder=f;exports.ControlBuilder=u;exports.ControlType=i;exports.GroupBuilder=S;exports.LayoutBuilder=a;exports.LayoutTypes=l;exports.Operator=q;exports.PositiveRequestNumber=c;exports.RequestSchema=O;exports.RequestSchemaWithOffset=F;exports.ResponseRequestSchema=R;exports.ResponseSchema=K;exports.Size=z;exports.SortDirEnum=A;exports.StringOrArray=v;exports.TableBuilder=b;exports.TextCellBuilder=y;exports.buildFilter=$;exports.buildSort=N;exports.buildSortKey=g;exports.createSchema=P;exports.extractFilters=G;exports.findColumnDef=k;exports.findProperty=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("zod");var z=(e=>(e.xs="xs",e.sm="sm",e.lg="lg",e.xl="xl",e))(z||{});const P=e=>{const t=e.anyOf;if(!Array.isArray(t)||t.length!==2)return;const r=t.find(s=>s.type!=="null"),o=t.some(s=>s.type==="null");r&&o&&(delete e.anyOf,Object.assign(e,r))},x=e=>{const t=i.toJSONSchema(e,{unrepresentable:"any",target:"draft-07"});t.additionalProperties=!0;const r=t.properties;if(r)for(const o of Object.keys(r))P(r[o]);return t},T=e=>{if(!e.schema)throw new Error("no schema provided");const t=e.schema,r=e.dtoSchema,o=x(r),s=x(t.partial());return{dtoSchema:r,responseSchema:e.responseSchema??r,schema:{form:{uiSchema:e.uiSchema,schema:o,modalSize:e.modalSize??"sm"},table:e.tableSchema?{uiSchema:e.tableSchema,schema:s}:void 0,filter:e.filterSchema?{uiSchema:e.filterSchema,schema:s}:void 0,uri:e.uri,searchUri:e.searchUri??`${e.uri}?filter=`}}},q=e=>{if(!e?.properties)return e;const t=e.required??[],r={...e.properties};let o=!1;for(const s of t){const n=r[s];!n||typeof n!="object"||n.type==="string"&&n.minLength===void 0&&(r[s]={...n,minLength:1},o=!0)}for(const s of Object.keys(r)){const n=r[s];if(n&&typeof n=="object"&&n.type==="object"){const u=q(n);u!==n&&(r[s]=u,o=!0)}}return o?{...e,properties:r}:e},j=(e,t)=>{if(!e.scope)return{id:null,property:null};const r=e.scope?.substring(13),o=t?.properties?.[r]??{};return{id:r,property:o}},K=(e,t)=>{const{id:r,property:o}=j(e,t);return{...e,id:r,label:r,...o}};class m{constructor(t){this.type=t}}class f extends m{constructor(){super(...arguments),this.elements=[]}addControl(t){return this.elements.push(t),this}addControls(...t){return this.elements.push(...t),this}buildElements(){return this.elements.map(t=>t.build())}}const d={HorizontalLayout:"HorizontalLayout",VerticalLayout:"VerticalLayout",CollapseLayout:"CollapseLayout",GridLayout:"GridLayout"};class l extends f{constructor(t,r={}){super(t),this.options=r}static horizontal(){return new l(d.HorizontalLayout)}static collapse(){return new l(d.CollapseLayout)}static vertical(){return new l(d.VerticalLayout)}static grid(){return new l(d.GridLayout)}titleKey(t){return this.addOptions({titleKey:t})}title(t){return this.addOptions({title:t})}addOptions(t){return this.options={...this.options,...t},this}build(){return{type:this.type,elements:this.buildElements(),options:this.options}}}class h extends m{constructor(t,r="TextCell"){super(r),this.scope=t}static properties(t){return new h(`#/properties/${t}`)}key(t){return this.options={format:"keyValue",key:t},this}setSortId(t){return this.options={...this.options??{format:this.type},sortId:t},this}build(){return{type:this.type,scope:this.scope,options:this.options}}}class y extends h{constructor(t){super(t,"BooleanCell")}static properties(t){return new y(`#/properties/${t}`)}}class b{constructor(){this.builder=l.horizontal()}static init(){return new b}addControl(t){return this.builder.addControls(t),this}addControls(...t){return this.builder.addControls(...t),this}build(){return this.builder.build()}}const a={number:"number",string:"string",integer:"Integer",autocomplete:"autocomplete",textArea:"textArea",markdown:"markdown",array:"array",custom:"custom",select:"select",mutliSelect:"mutliSelect",boolean:"boolean"};class c extends m{constructor(t,r="Control"){super(r),this.scope=t,this.options={format:"Control",styles:{}}}static asObject(t){return new c(`#/properties/${t}`,"Object")}static properties(t){return new c(`#/properties/${t}`)}static asCustom(t,r){const o=new c(`#/properties/${t}`);return o.addOptions({format:a.custom,type:r}),o}detail(t,r){return this._detail=t,this.addOptions({format:a.array,elementLabelProp:r}),this}addAction(t){const r=this.options?.actions??[];return r.push(t),this.addOptions({actions:r})}detailFixed(t,r={}){return this._detail=t,this.addOptions({hideActions:!0,format:a.array,layout:r.layout??"column",elementLabelProp:r.label})}labelKey(t){return this.addOptions({labelKey:t})}readonly(){return this.addOptions({format:a.string,readonly:!0})}markdown(t){return this.addOptions({format:a.markdown,...t??{}})}textArea(t){return this.addOptions({format:a.textArea,...t??{}})}autocomplete(t){return this.addOptions({format:a.autocomplete,dataField:"data",...t??{}})}control(t,r){return this.addOptions({format:t,...r})}select(t){return this.addOptions({format:a.select,...t})}mutliSelect(t){return this.addOptions({format:a.mutliSelect,...t})}width(t){return this.addOptions({styles:{...this.options?.styles,width:t,control:{wrapper:`input-${t}`}}})}customLabel(t){return this.addOptions({label:t})}placeHolder(t){return this.addOptions({placeholder:t})}hideLabel(){return this.addOptions({hideLabel:!0})}addOptions(t){return this.options={...this.options,...t},this}build(){return{type:this.type,scope:this.scope,options:{...this.options,detail:this._detail?this._detail?.build():void 0}}}}class S extends f{constructor(t){super(t),this.label=t,this.rule={effect:"SHOW",condition:{}}}static label(t){return new S(t)}build(){return{type:"Category",label:this.label,rule:this.rule,elements:this.buildElements()}}}class g extends f{constructor(t){super(t),this.label=t}static label(t){return new g(t)}build(){return{type:"Group",label:this.label,elements:this.buildElements()}}}const p=()=>i.z.coerce.number().int().positive().nonnegative(),v=()=>i.z.string().or(i.z.array(i.z.string())).transform(e=>Array.isArray(e)?e:[e]),R=i.z.enum(["asc","desc"]),O=i.z.object({page:p().optional().default(1),pageSize:p().optional().default(20),sort:i.z.string().optional().default("id"),sortDir:R.optional().default("asc"),filter:v().optional().default([])}),$=O.transform(e=>{const{page:t,pageSize:r,sort:o}=e;return{...e,sort:o||"id",offset:(t-1)*r}}),k=O.extend({count:p(),totalPages:p()}),B=i.z.object({data:i.z.array(i.z.unknown()),request:k}),A=["contains","equals"],E=e=>{const[t,r,o]=e.split(":"),s=A.includes(o)?o:"contains";return{key:t,value:r,operator:s}},F=(e,t)=>{if(e.length===1)return{key:e[0],filterObj:t};const r=e.pop();return F(e,{[r]:t})},N=(e,t)=>C(e.split("."),t),C=(e,t)=>{if(e.length===1)return{[e[0]]:t};const r=e.pop();return C(e,{[r]:t})},G=e=>{const t={};return e?.forEach(r=>{const{key:o,value:s,operator:n}=E(r);if(!o)return;const u=n||"contains",L={[n||"contains"]:s.toLowerCase()};u==="contains"&&(L.mode="insensitive");const w=F(o.split("."),L);t[w.key]=w.filterObj}),t},H=e=>{const t=[];return e.forEach(r=>{const{key:o,value:s,operator:n}=E(r);if(!o)return;const u=o;t.push({label:u,key:o,value:s,operator:n})}),t},V=e=>{const t=e.properties??{},r=l.grid();for(const o of Object.keys(t))r.addControl(c.properties(o));return r.build()};exports.BooleanCellBuilder=y;exports.CategoryBuilder=S;exports.ControlBuilder=c;exports.ControlType=a;exports.GroupBuilder=g;exports.LayoutBuilder=l;exports.LayoutTypes=d;exports.Operator=A;exports.PositiveRequestNumber=p;exports.RequestSchema=O;exports.RequestSchemaWithOffset=$;exports.ResponseRequestSchema=k;exports.ResponseSchema=B;exports.Size=z;exports.SortDirEnum=R;exports.StringOrArray=v;exports.TableBuilder=b;exports.TextCellBuilder=h;exports.buildFilter=G;exports.buildSort=N;exports.buildSortKey=C;exports.createSchema=T;exports.enforceRequiredStringMinLength=q;exports.extractFilters=H;exports.findColumnDef=K;exports.findProperty=j;exports.uiFromJsonSchema=V;
package/index.d.ts CHANGED
@@ -10,3 +10,4 @@ export * from './lib/response.model';
10
10
  export * from './lib/request.model';
11
11
  export * from './lib/filter';
12
12
  export * from './lib/zod.types';
13
+ export * from './lib/fromJson.builder';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { toJSONSchema as v, z as n } from "zod";
2
- var E = /* @__PURE__ */ ((e) => (e.xs = "xs", e.sm = "sm", e.lg = "lg", e.xl = "xl", e))(E || {});
3
- const j = (e) => {
1
+ import { toJSONSchema as v, z as i } from "zod";
2
+ var A = /* @__PURE__ */ ((e) => (e.xs = "xs", e.sm = "sm", e.lg = "lg", e.xl = "xl", e))(A || {});
3
+ const q = (e) => {
4
4
  const t = e.anyOf;
5
5
  if (!Array.isArray(t) || t.length !== 2) return;
6
6
  const r = t.find(
@@ -9,7 +9,7 @@ const j = (e) => {
9
9
  (o) => o.type === "null"
10
10
  );
11
11
  r && s && (delete e.anyOf, Object.assign(e, r));
12
- }, y = (e) => {
12
+ }, O = (e) => {
13
13
  const t = v(e, {
14
14
  unrepresentable: "any",
15
15
  target: "draft-07"
@@ -18,12 +18,12 @@ const j = (e) => {
18
18
  const r = t.properties;
19
19
  if (r)
20
20
  for (const s of Object.keys(r))
21
- j(r[s]);
21
+ q(r[s]);
22
22
  return t;
23
- }, R = (e) => {
23
+ }, H = (e) => {
24
24
  if (!e.schema)
25
25
  throw new Error("no schema provided");
26
- const t = e.schema, r = e.dtoSchema, s = y(r), o = y(t.partial());
26
+ const t = e.schema, r = e.dtoSchema, s = O(r), o = O(t.partial());
27
27
  return {
28
28
  dtoSchema: r,
29
29
  responseSchema: e.responseSchema ?? r,
@@ -45,21 +45,37 @@ const j = (e) => {
45
45
  searchUri: e.searchUri ?? `${e.uri}?filter=`
46
46
  }
47
47
  };
48
- }, k = (e, t) => {
48
+ }, E = (e) => {
49
+ if (!e?.properties) return e;
50
+ const t = e.required ?? [], r = { ...e.properties };
51
+ let s = !1;
52
+ for (const o of t) {
53
+ const n = r[o];
54
+ !n || typeof n != "object" || n.type === "string" && n.minLength === void 0 && (r[o] = { ...n, minLength: 1 }, s = !0);
55
+ }
56
+ for (const o of Object.keys(r)) {
57
+ const n = r[o];
58
+ if (n && typeof n == "object" && n.type === "object") {
59
+ const c = E(n);
60
+ c !== n && (r[o] = c, s = !0);
61
+ }
62
+ }
63
+ return s ? { ...e, properties: r } : e;
64
+ }, z = (e, t) => {
49
65
  if (!e.scope)
50
66
  return { id: null, property: null };
51
67
  const r = e.scope?.substring(13), s = t?.properties?.[r] ?? {};
52
68
  return { id: r, property: s };
53
- }, $ = (e, t) => {
54
- const { id: r, property: s } = k(e, t);
69
+ }, N = (e, t) => {
70
+ const { id: r, property: s } = z(e, t);
55
71
  return { ...e, id: r, label: r, ...s };
56
72
  };
57
- class p {
73
+ class h {
58
74
  constructor(t) {
59
75
  this.type = t;
60
76
  }
61
77
  }
62
- class m extends p {
78
+ class m extends h {
63
79
  constructor() {
64
80
  super(...arguments), this.elements = [];
65
81
  }
@@ -73,27 +89,27 @@ class m extends p {
73
89
  return this.elements.map((t) => t.build());
74
90
  }
75
91
  }
76
- const u = {
92
+ const d = {
77
93
  HorizontalLayout: "HorizontalLayout",
78
94
  VerticalLayout: "VerticalLayout",
79
95
  CollapseLayout: "CollapseLayout",
80
96
  GridLayout: "GridLayout"
81
97
  };
82
- class a extends m {
98
+ class l extends m {
83
99
  constructor(t, r = {}) {
84
100
  super(t), this.options = r;
85
101
  }
86
102
  static horizontal() {
87
- return new a(u.HorizontalLayout);
103
+ return new l(d.HorizontalLayout);
88
104
  }
89
105
  static collapse() {
90
- return new a(u.CollapseLayout);
106
+ return new l(d.CollapseLayout);
91
107
  }
92
108
  static vertical() {
93
- return new a(u.VerticalLayout);
109
+ return new l(d.VerticalLayout);
94
110
  }
95
111
  static grid() {
96
- return new a(u.GridLayout);
112
+ return new l(d.GridLayout);
97
113
  }
98
114
  titleKey(t) {
99
115
  return this.addOptions({ titleKey: t });
@@ -115,12 +131,12 @@ class a extends m {
115
131
  };
116
132
  }
117
133
  }
118
- class O extends p {
134
+ class f extends h {
119
135
  constructor(t, r = "TextCell") {
120
136
  super(r), this.scope = t;
121
137
  }
122
138
  static properties(t) {
123
- return new O(`#/properties/${t}`);
139
+ return new f(`#/properties/${t}`);
124
140
  }
125
141
  key(t) {
126
142
  return this.options = {
@@ -130,7 +146,7 @@ class O extends p {
130
146
  }
131
147
  setSortId(t) {
132
148
  return this.options = {
133
- ...this.options ?? { format: "TextCell" },
149
+ ...this.options ?? { format: this.type },
134
150
  sortId: t
135
151
  }, this;
136
152
  }
@@ -142,12 +158,20 @@ class O extends p {
142
158
  };
143
159
  }
144
160
  }
145
- class S {
161
+ class S extends f {
162
+ constructor(t) {
163
+ super(t, "BooleanCell");
164
+ }
165
+ static properties(t) {
166
+ return new S(`#/properties/${t}`);
167
+ }
168
+ }
169
+ class g {
146
170
  constructor() {
147
- this.builder = a.horizontal();
171
+ this.builder = l.horizontal();
148
172
  }
149
173
  static init() {
150
- return new S();
174
+ return new g();
151
175
  }
152
176
  addControl(t) {
153
177
  return this.builder.addControls(t), this;
@@ -159,7 +183,7 @@ class S {
159
183
  return this.builder.build();
160
184
  }
161
185
  }
162
- const i = {
186
+ const a = {
163
187
  number: "number",
164
188
  string: "string",
165
189
  integer: "Integer",
@@ -172,7 +196,7 @@ const i = {
172
196
  mutliSelect: "mutliSelect",
173
197
  boolean: "boolean"
174
198
  };
175
- class c extends p {
199
+ class u extends h {
176
200
  constructor(t, r = "Control") {
177
201
  super(r), this.scope = t, this.options = {
178
202
  format: "Control",
@@ -180,26 +204,26 @@ class c extends p {
180
204
  };
181
205
  }
182
206
  static asObject(t) {
183
- return new c(
207
+ return new u(
184
208
  `#/properties/${t}`,
185
209
  "Object"
186
210
  );
187
211
  }
188
212
  static properties(t) {
189
- return new c(`#/properties/${t}`);
213
+ return new u(`#/properties/${t}`);
190
214
  }
191
215
  static asCustom(t, r) {
192
- const s = new c(
216
+ const s = new u(
193
217
  `#/properties/${t}`
194
218
  );
195
219
  return s.addOptions({
196
- format: i.custom,
220
+ format: a.custom,
197
221
  type: r
198
222
  }), s;
199
223
  }
200
224
  detail(t, r) {
201
225
  return this._detail = t, this.addOptions({
202
- format: i.array,
226
+ format: a.array,
203
227
  elementLabelProp: r
204
228
  }), this;
205
229
  }
@@ -210,7 +234,7 @@ class c extends p {
210
234
  detailFixed(t, r = {}) {
211
235
  return this._detail = t, this.addOptions({
212
236
  hideActions: !0,
213
- format: i.array,
237
+ format: a.array,
214
238
  layout: r.layout ?? "column",
215
239
  elementLabelProp: r.label
216
240
  });
@@ -220,25 +244,25 @@ class c extends p {
220
244
  }
221
245
  readonly() {
222
246
  return this.addOptions({
223
- format: i.string,
247
+ format: a.string,
224
248
  readonly: !0
225
249
  });
226
250
  }
227
251
  markdown(t) {
228
252
  return this.addOptions({
229
- format: i.markdown,
253
+ format: a.markdown,
230
254
  ...t ?? {}
231
255
  });
232
256
  }
233
257
  textArea(t) {
234
258
  return this.addOptions({
235
- format: i.textArea,
259
+ format: a.textArea,
236
260
  ...t ?? {}
237
261
  });
238
262
  }
239
263
  autocomplete(t) {
240
264
  return this.addOptions({
241
- format: i.autocomplete,
265
+ format: a.autocomplete,
242
266
  dataField: "data",
243
267
  ...t ?? {}
244
268
  });
@@ -251,13 +275,13 @@ class c extends p {
251
275
  }
252
276
  select(t) {
253
277
  return this.addOptions({
254
- format: i.select,
278
+ format: a.select,
255
279
  ...t
256
280
  });
257
281
  }
258
282
  mutliSelect(t) {
259
283
  return this.addOptions({
260
- format: i.mutliSelect,
284
+ format: a.mutliSelect,
261
285
  ...t
262
286
  });
263
287
  }
@@ -298,7 +322,7 @@ class c extends p {
298
322
  };
299
323
  }
300
324
  }
301
- class g extends m {
325
+ class w extends m {
302
326
  constructor(t) {
303
327
  super(t), this.label = t, this.rule = {
304
328
  effect: "SHOW",
@@ -306,7 +330,7 @@ class g extends m {
306
330
  };
307
331
  }
308
332
  static label(t) {
309
- return new g(t);
333
+ return new w(t);
310
334
  }
311
335
  build() {
312
336
  return {
@@ -317,12 +341,12 @@ class g extends m {
317
341
  };
318
342
  }
319
343
  }
320
- class w extends m {
344
+ class x extends m {
321
345
  constructor(t) {
322
346
  super(t), this.label = t;
323
347
  }
324
348
  static label(t) {
325
- return new w(t);
349
+ return new x(t);
326
350
  }
327
351
  build() {
328
352
  return {
@@ -332,84 +356,94 @@ class w extends m {
332
356
  };
333
357
  }
334
358
  }
335
- const d = () => n.coerce.number().int().positive().nonnegative(), z = () => n.string().or(n.array(n.string())).transform((e) => Array.isArray(e) ? e : [e]), q = n.enum(["asc", "desc"]), x = n.object({
336
- page: d().optional().default(1),
337
- pageSize: d().optional().default(20),
359
+ const p = () => i.coerce.number().int().positive().nonnegative(), F = () => i.string().or(i.array(i.string())).transform((e) => Array.isArray(e) ? e : [e]), P = i.enum(["asc", "desc"]), L = i.object({
360
+ page: p().optional().default(1),
361
+ pageSize: p().optional().default(20),
338
362
  // TODO add sorting and so
339
- sort: n.string().optional().default("id"),
340
- sortDir: q.optional().default("asc"),
363
+ sort: i.string().optional().default("id"),
364
+ sortDir: P.optional().default("asc"),
341
365
  // Filter is of the format key:value:operator (e.g. name:john:eq) operator is optional
342
- filter: z().optional().default([])
343
- }), H = x.transform((e) => {
366
+ filter: F().optional().default([])
367
+ }), V = L.transform((e) => {
344
368
  const { page: t, pageSize: r, sort: s } = e;
345
369
  return {
346
370
  ...e,
347
371
  sort: s || "id",
348
372
  offset: (t - 1) * r
349
373
  };
350
- }), F = x.extend({
351
- count: d(),
352
- totalPages: d()
353
- }), N = n.object({
354
- data: n.array(n.unknown()),
355
- request: F
356
- }), K = ["contains", "equals"], C = (e) => {
357
- const [t, r, s] = e.split(":"), o = K.includes(s) ? s : "contains";
374
+ }), R = L.extend({
375
+ count: p(),
376
+ totalPages: p()
377
+ }), G = i.object({
378
+ data: i.array(i.unknown()),
379
+ request: R
380
+ }), $ = ["contains", "equals"], C = (e) => {
381
+ const [t, r, s] = e.split(":"), o = $.includes(s) ? s : "contains";
358
382
  return { key: t, value: r, operator: o };
359
- }, L = (e, t) => {
383
+ }, j = (e, t) => {
360
384
  if (e.length === 1)
361
385
  return { key: e[0], filterObj: t };
362
386
  const r = e.pop();
363
- return L(e, { [r]: t });
364
- }, T = (e, t) => A(e.split("."), t), A = (e, t) => {
387
+ return j(e, { [r]: t });
388
+ }, T = (e, t) => k(e.split("."), t), k = (e, t) => {
365
389
  if (e.length === 1)
366
390
  return { [e[0]]: t };
367
391
  const r = e.pop();
368
- return A(e, { [r]: t });
369
- }, V = (e) => {
392
+ return k(e, { [r]: t });
393
+ }, J = (e) => {
370
394
  const t = {};
371
395
  return e?.forEach((r) => {
372
- const { key: s, value: o, operator: l } = C(r);
396
+ const { key: s, value: o, operator: n } = C(r);
373
397
  if (!s) return;
374
- const h = l || "contains", f = {
375
- [l || "contains"]: o.toLowerCase()
398
+ const c = n || "contains", y = {
399
+ [n || "contains"]: o.toLowerCase()
376
400
  };
377
- h === "contains" && (f.mode = "insensitive");
378
- const b = L(s.split("."), f);
401
+ c === "contains" && (y.mode = "insensitive");
402
+ const b = j(s.split("."), y);
379
403
  t[b.key] = b.filterObj;
380
404
  }), t;
381
- }, G = (e) => {
405
+ }, W = (e) => {
382
406
  const t = [];
383
407
  return e.forEach((r) => {
384
- const { key: s, value: o, operator: l } = C(r);
408
+ const { key: s, value: o, operator: n } = C(r);
385
409
  if (!s) return;
386
- const h = s;
387
- t.push({ label: h, key: s, value: o, operator: l });
410
+ const c = s;
411
+ t.push({ label: c, key: s, value: o, operator: n });
388
412
  }), t;
413
+ }, D = (e) => {
414
+ const t = e.properties ?? {}, r = l.grid();
415
+ for (const s of Object.keys(t))
416
+ r.addControl(
417
+ u.properties(s)
418
+ );
419
+ return r.build();
389
420
  };
390
421
  export {
391
- g as CategoryBuilder,
392
- c as ControlBuilder,
393
- i as ControlType,
394
- w as GroupBuilder,
395
- a as LayoutBuilder,
396
- u as LayoutTypes,
397
- K as Operator,
398
- d as PositiveRequestNumber,
399
- x as RequestSchema,
400
- H as RequestSchemaWithOffset,
401
- F as ResponseRequestSchema,
402
- N as ResponseSchema,
403
- E as Size,
404
- q as SortDirEnum,
405
- z as StringOrArray,
406
- S as TableBuilder,
407
- O as TextCellBuilder,
408
- V as buildFilter,
422
+ S as BooleanCellBuilder,
423
+ w as CategoryBuilder,
424
+ u as ControlBuilder,
425
+ a as ControlType,
426
+ x as GroupBuilder,
427
+ l as LayoutBuilder,
428
+ d as LayoutTypes,
429
+ $ as Operator,
430
+ p as PositiveRequestNumber,
431
+ L as RequestSchema,
432
+ V as RequestSchemaWithOffset,
433
+ R as ResponseRequestSchema,
434
+ G as ResponseSchema,
435
+ A as Size,
436
+ P as SortDirEnum,
437
+ F as StringOrArray,
438
+ g as TableBuilder,
439
+ f as TextCellBuilder,
440
+ J as buildFilter,
409
441
  T as buildSort,
410
- A as buildSortKey,
411
- R as createSchema,
412
- G as extractFilters,
413
- $ as findColumnDef,
414
- k as findProperty
442
+ k as buildSortKey,
443
+ H as createSchema,
444
+ E as enforceRequiredStringMinLength,
445
+ W as extractFilters,
446
+ N as findColumnDef,
447
+ z as findProperty,
448
+ D as uiFromJsonSchema
415
449
  };
@@ -0,0 +1,13 @@
1
+ import { JsonSchema } from '@jsonforms/core';
2
+ import { LayoutType } from './layout/layout.builder';
3
+ /**
4
+ * Generates a GridLayout UI schema from a JSON Schema.
5
+ *
6
+ * Iterates over each property in the schema and creates a full-width
7
+ * `Control` element. When no custom UI schema is provided, this serves
8
+ * as the automatic fallback used by {@link ResourceSchema}.
9
+ *
10
+ * @param jsonSchema - JSON Schema whose `properties` will be converted to controls.
11
+ * @returns A built `GridLayout` UI schema with one control per property.
12
+ */
13
+ export declare const uiFromJsonSchema: (jsonSchema: JsonSchema) => LayoutType;
@@ -41,6 +41,12 @@ export interface AutocompleteRemoteOptions extends Omit<AutocompleteOptions, 'fo
41
41
  dataField?: string;
42
42
  skipAuth?: boolean;
43
43
  }
44
+ export interface AutocompleteResourceOptions extends Omit<AutocompleteOptions, 'format' | 'options'> {
45
+ format: 'autocomplete';
46
+ resource: string;
47
+ skipAuth?: boolean;
48
+ }
49
+ export type AutocompleteAllOptions = AutocompleteOptions | AutocompleteRemoteOptions | AutocompleteRemoteOptions;
44
50
  export type ArrayActionType = 'edit';
45
51
  export type ArrayAction = {
46
52
  type: ArrayActionType;
@@ -58,6 +64,15 @@ export interface ControlOption {
58
64
  placeholder?: string;
59
65
  hideLabel?: boolean;
60
66
  hideActions?: boolean;
67
+ layout?: 'row' | 'column';
68
+ labelKey?: string;
69
+ valueKey?: string;
70
+ options?: Array<any>;
71
+ dataField?: string;
72
+ uri?: string;
73
+ skipAuth?: boolean;
74
+ freeText?: boolean;
75
+ enableCreate?: boolean;
61
76
  }
62
77
  export type ControlTypes = {
63
78
  type: 'Control' | 'Object' | 'TextCell';
@@ -2,6 +2,13 @@ import { JsonSchema } from '@jsonforms/core';
2
2
  type Field = {
3
3
  scope: string;
4
4
  };
5
+ /**
6
+ * Adds `minLength: 1` to required string properties that lack an explicit `minLength`.
7
+ * JSON Schema `required` only means "must be present" — an empty string `""` is valid.
8
+ * This bridges the gap so required string fields reject empty values during validation.
9
+ * Recurses into nested object properties.
10
+ */
11
+ export declare const enforceRequiredStringMinLength: (schema: JsonSchema) => JsonSchema;
5
12
  export declare const findProperty: <F extends Field>(column: F, schema: JsonSchema) => {
6
13
  id: string;
7
14
  property: any;
@@ -15,12 +15,16 @@ export type TextCellType = {
15
15
  export declare class TextCellBuilder<TYPE> extends Builder<TextCellType> {
16
16
  private readonly scope;
17
17
  private options;
18
- private constructor();
18
+ protected constructor(scope: string, type?: string);
19
19
  static properties<TYPE>(property: keyof TYPE): TextCellBuilder<TYPE>;
20
20
  key(key: string): TextCellBuilder<TYPE>;
21
21
  setSortId(sortId: string): TextCellBuilder<TYPE>;
22
22
  build(): TextCellType;
23
23
  }
24
+ export declare class BooleanCellBuilder extends TextCellBuilder<boolean> {
25
+ protected constructor(scope: string);
26
+ static properties<TYPE>(property: keyof TYPE): BooleanCellBuilder;
27
+ }
24
28
  export declare class TableBuilder<TYPE> {
25
29
  private builder;
26
30
  private constructor();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghentcdh/json-forms-core",
3
- "version": "0.8.6",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -12,15 +12,17 @@
12
12
  }
13
13
  },
14
14
  "peerDependencies": {
15
- "@anatine/zod-openapi": "^2.2.0",
16
- "@jsonforms/core": "^3.4.0",
17
- "zod": "^3.24.0"
15
+ "@jsonforms/core": "3.7.0",
16
+ "zod": "4.3.6"
18
17
  },
19
18
  "devDependencies": {
20
19
  "@anatine/zod-openapi": "2.2.8",
21
20
  "@jsonforms/core": "3.7.0",
22
21
  "zod": "4.3.6"
23
22
  },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
24
26
  "repository": {
25
27
  "type": "git",
26
28
  "url": "https://github.com/GhentCDH/ghentcdh-monorepo.git"