@golemui/schemas 1.2.1 → 1.3.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ ## 1.3.0-rc.0 (2026-08-14)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **schemas:** layer the published JSON schemas into a core and a gui tree ([#281](https://github.com/golemui/golemui/pull/281))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Mud Scientist @mudscientist
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GolemUI S.L.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- "use strict";const p=require("node:fs"),i=require("node:path"),g=require("node:readline/promises"),b=require("node:url"),v=require("./generate-implementation-schemas-D57DzM2J.cjs"),w="../src/lib/form.editor.schema.json",x=[{kind:"layout",type:"flex",uid:"#root",props:{direction:"column",gap:16},children:[{kind:"input",type:"__IMPLEMENTATION__-input",uid:"email",path:"email",label:"Email address",validator:{type:"string",required:!0,format:"email"},props:{placeholder:"you@example.com"}}]}],j={$schema:w,form:x},S="https://json-schema.org/draft/2020-12/schema",P="__ID_BASE__components/example-input.schema.json",T="STARTER TEMPLATE, owned by you. One component schema per widget type. Copy this file for each widget, then list it in schemas.config.mjs. The pattern to keep: allOf the baseWidget, `kind` and `type` consts, one `$defs` entry per prop, a `.state` suffixed pattern for every suffixable key, `additionalProperties: false` inside `props`, and `unevaluatedProperties: false` at the root.",E="__IMPLEMENTATION__ example input widget",_="object",I={labelDef:{$ref:"../core/common.schema.json#/$defs/localizable"},disabledDef:{$ref:"../core/common.schema.json#/$defs/boolOrWhen"},readonlyDef:{$ref:"../core/common.schema.json#/$defs/boolOrWhen"},hintProp:{type:"string"},placeholderProp:{type:"string"},maxlengthProp:{type:"number"}},q=[{$ref:"../core/common.schema.json#/$defs/baseWidget"}],A={kind:{const:"input"},type:{const:"__IMPLEMENTATION__-input"},path:{$ref:"../core/common.schema.json#/$defs/dotPath"},label:{$ref:"#/$defs/labelDef"},disabled:{$ref:"#/$defs/disabledDef"},readonly:{$ref:"#/$defs/readonlyDef"},on:{$ref:"../core/common.schema.json#/$defs/on"},validator:{$ref:"../validators.schema.json#/$defs/validator"},defaultValue:{type:"string"},props:{type:"object",properties:{hint:{$ref:"#/$defs/hintProp"},placeholder:{$ref:"#/$defs/placeholderProp"},maxlength:{$ref:"#/$defs/maxlengthProp"}},patternProperties:{"^hint\\.[^.]+$":{$ref:"#/$defs/hintProp"},"^placeholder\\.[^.]+$":{$ref:"#/$defs/placeholderProp"},"^maxlength\\.[^.]+$":{$ref:"#/$defs/maxlengthProp"}},additionalProperties:!1}},O={"^label\\.[^.]+$":{$ref:"#/$defs/labelDef"},"^disabled\\.[^.]+$":{$ref:"#/$defs/disabledDef"},"^readonly\\.[^.]+$":{$ref:"#/$defs/readonlyDef"},"^validator\\.[^.]+$":{$ref:"../validators.schema.json#/$defs/validator"}},M=["kind","type","path"],L=!1,N={$schema:S,$id:P,$comment:T,title:E,type:_,$defs:I,allOf:q,properties:A,patternProperties:O,required:M,unevaluatedProperties:L},k="https://json-schema.org/draft/2020-12/schema",z="__ID_BASE__components/flex.schema.json",R="STARTER TEMPLATE, owned by you. `flex` is a reserved widget type: keep the name and the `children` array, change the props to match your layout widget.",C="__IMPLEMENTATION__ flex widget",D="object",W={directionProp:{enum:["row","row-reverse","column","column-reverse"]},justifyProp:{enum:["start","center","end","stretch","space-between","space-around"]},alignProp:{enum:["start","center","end","stretch","baseline"]},wrapProp:{type:"boolean"},gapProp:{type:"number"},paddingProp:{type:"number"}},F=[{$ref:"../core/common.schema.json#/$defs/baseWidget"}],B={kind:{const:"layout"},type:{const:"flex"},children:{type:"array",minItems:1,items:{$ref:"../widgets.schema.json#/$defs/formWidget"}},props:{type:"object",properties:{direction:{$ref:"#/$defs/directionProp"},justify:{$ref:"#/$defs/justifyProp"},align:{$ref:"#/$defs/alignProp"},wrap:{$ref:"#/$defs/wrapProp"},gap:{$ref:"#/$defs/gapProp"},padding:{$ref:"#/$defs/paddingProp"}},patternProperties:{"^direction\\.[^.]+$":{$ref:"#/$defs/directionProp"},"^justify\\.[^.]+$":{$ref:"#/$defs/justifyProp"},"^align\\.[^.]+$":{$ref:"#/$defs/alignProp"},"^wrap\\.[^.]+$":{$ref:"#/$defs/wrapProp"},"^gap\\.[^.]+$":{$ref:"#/$defs/gapProp"},"^padding\\.[^.]+$":{$ref:"#/$defs/paddingProp"}},additionalProperties:!1}},V=["kind","type","children"],U=!1,J={$schema:k,$id:z,$comment:R,title:C,type:D,$defs:W,allOf:F,properties:B,required:V,unevaluatedProperties:U},Y="https://json-schema.org/draft/2020-12/schema",G="__ID_BASE__validators.schema.json",H="STARTER TEMPLATE, owned by you. Edit it freely. The only contract is that it exposes #/$defs/validator, which every component schema references. Copied from the golemui gui validators when the tree was scaffolded, it does not track them afterwards.",K="__IMPLEMENTATION__ validator definitions",Z={localizable:{$ref:"./core/common.schema.json#/$defs/localizable"},stringValidator:{type:"object",properties:{type:{const:"string"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is empty or absent"},minLength:{type:"number",description:"Minimum number of characters the string must contain"},maxLength:{type:"number",description:"Maximum number of characters the string may contain"},pattern:{type:"string",description:"A regular expression pattern the value must match"},format:{type:"string",description:"A named format the string must conform to (e.g. `email`, `url`, `date`, `uuid`)",enum:["email","hostname","ipv4","ipv6","url","uuid","date","time","date-time","duration"]},const:{description:"The string must equal exactly this value"},enum:{type:"array",description:"The string must be one of these allowed values"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},required:{$ref:"#/$defs/localizable",description:"Shown when a required field is empty"},minLength:{$ref:"#/$defs/localizable",description:"Shown when the value is shorter than `minLength`"},maxLength:{$ref:"#/$defs/localizable",description:"Shown when the value is longer than `maxLength`"},pattern:{$ref:"#/$defs/localizable",description:"Shown when the value does not match the `pattern` regex"},format:{$ref:"#/$defs/localizable",description:"Shown when the value does not conform to the specified `format`"},enum:{$ref:"#/$defs/localizable",description:"Shown when the value is not in the `enum` list"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},numberValidator:{type:"object",properties:{type:{type:"string",enum:["number","integer"]},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is absent"},minimum:{type:"number",description:"The value must be greater than or equal to this number (inclusive)"},maximum:{type:"number",description:"The value must be less than or equal to this number (inclusive)"},exclusiveMinimum:{type:"number",description:"The value must be strictly greater than this number (exclusive)"},exclusiveMaximum:{type:"number",description:"The value must be strictly less than this number (exclusive)"},multipleOf:{type:"number",description:"The value must be a multiple of this number"},const:{description:"The value must equal exactly this number"},enum:{type:"array",description:"The value must be one of these allowed numbers"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},minimum:{$ref:"#/$defs/localizable",description:"Shown when the value is below `minimum`"},maximum:{$ref:"#/$defs/localizable",description:"Shown when the value exceeds `maximum`"},exclusiveMinimum:{$ref:"#/$defs/localizable",description:"Shown when the value is not strictly above `exclusiveMinimum`"},exclusiveMaximum:{$ref:"#/$defs/localizable",description:"Shown when the value is not strictly below `exclusiveMaximum`"},multipleOf:{$ref:"#/$defs/localizable",description:"Shown when the value is not a multiple of `multipleOf`"},enum:{$ref:"#/$defs/localizable",description:"Shown when the value is not in the `enum` list"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},booleanValidator:{type:"object",properties:{type:{const:"boolean"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is absent or false (e.g. an unchecked required checkbox)"},const:{description:"The value must equal exactly this boolean (e.g. `true` to require acceptance)"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},arrayValidator:{type:"object",properties:{type:{const:"array"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the array is empty or absent"},minItems:{type:"number",description:"The array must contain at least this many items"},maxItems:{type:"number",description:"The array must contain no more than this many items"},uniqueItems:{type:"boolean",description:"When true, all items in the array must be distinct values"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},required:{$ref:"#/$defs/localizable",description:"Shown when a required array is empty or absent"},minItems:{$ref:"#/$defs/localizable",description:"Shown when the array has fewer items than `minItems`"},maxItems:{$ref:"#/$defs/localizable",description:"Shown when the array has more items than `maxItems`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},customValidator:{type:"object",description:"A custom validator that delegates validation to application code. The registered validator function receives these constraint keys and must return a Standard Schema V1-compliant schema object (https://standardschema.dev). Add arbitrary constraint keys alongside `type` - they are passed as-is to the registered validator function.",properties:{type:{const:"custom"},required:{type:"boolean",description:"Makes the field mandatory - evaluation is still delegated to the custom validator"}},required:["type"],additionalProperties:!0},validator:{description:"Validation rules for this field. The `type` discriminant selects the validator: `string`, `number`, `integer`, `boolean`, `array`, or `custom`.",oneOf:[{$ref:"#/$defs/stringValidator"},{$ref:"#/$defs/numberValidator"},{$ref:"#/$defs/booleanValidator"},{$ref:"#/$defs/arrayValidator"},{$ref:"#/$defs/customValidator"}]}},Q={$schema:Y,$id:G,$comment:H,title:K,$defs:Z};function X(e){return`${e}-input`}function ee(e,t){const r=e.replace(/__IMPLEMENTATION__/g,t.implementation).replace(/__ID_BASE__/g,t.idBase),o=r.match(/__[A-Z_]+__/);if(o!==null)throw new Error(`Unsubstituted placeholder ${o[0]} in a starter template.`);return r}function c(e,t){return ee(JSON.stringify(e,null,2),t)+`
3
- `}function te(e){return{"schemas.config.mjs":re(e),"src/lib/validators.schema.json":c(Q,e),"src/lib/components/flex.schema.json":c(J,e),"src/lib/components/example-input.schema.json":c(N,e),"examples/example.form.json":c(j,e),"test/schemas.spec.ts":oe(e)}}function re(e){return`// The manifest and configuration for this implementation's JSON schema tree.
2
+ "use strict";const p=require("node:fs"),i=require("node:path"),b=require("node:readline/promises"),v=require("node:url"),w=require("./generate-implementation-schemas-D57DzM2J.cjs"),x="../src/lib/form.editor.schema.json",j=[{kind:"layout",type:"flex",uid:"#root",props:{direction:"column",gap:16},children:[{kind:"input",type:"__IMPLEMENTATION__-input",uid:"email",path:"email",label:"Email address",validator:{type:"string",required:!0,format:"email"},props:{placeholder:"you@example.com"}}]}],S={$schema:x,form:j},P="https://json-schema.org/draft/2020-12/schema",T="__ID_BASE__components/example-input.schema.json",E="STARTER TEMPLATE, owned by you. One component schema per widget type. Copy this file for each widget, then list it in schemas.config.mjs. The pattern to keep: allOf the baseWidget, `kind` and `type` consts, one `$defs` entry per prop, a `.state` suffixed pattern for every suffixable key, `additionalProperties: false` inside `props`, and `unevaluatedProperties: false` at the root.",_="__IMPLEMENTATION__ example input widget",I="object",q={labelDef:{$ref:"../core/common.schema.json#/$defs/localizable"},disabledDef:{$ref:"../core/common.schema.json#/$defs/boolOrWhen"},readonlyDef:{$ref:"../core/common.schema.json#/$defs/boolOrWhen"},hintProp:{type:"string"},placeholderProp:{type:"string"},maxlengthProp:{type:"number"}},A=[{$ref:"../core/common.schema.json#/$defs/baseWidget"}],O={kind:{const:"input"},type:{const:"__IMPLEMENTATION__-input"},path:{$ref:"../core/common.schema.json#/$defs/dotPath"},label:{$ref:"#/$defs/labelDef"},disabled:{$ref:"#/$defs/disabledDef"},readonly:{$ref:"#/$defs/readonlyDef"},on:{$ref:"../core/common.schema.json#/$defs/on"},validator:{$ref:"../validators.schema.json#/$defs/validator"},defaultValue:{type:"string"},props:{type:"object",properties:{hint:{$ref:"#/$defs/hintProp"},placeholder:{$ref:"#/$defs/placeholderProp"},maxlength:{$ref:"#/$defs/maxlengthProp"}},patternProperties:{"^hint\\.[^.]+$":{$ref:"#/$defs/hintProp"},"^placeholder\\.[^.]+$":{$ref:"#/$defs/placeholderProp"},"^maxlength\\.[^.]+$":{$ref:"#/$defs/maxlengthProp"}},additionalProperties:!1}},M={"^label\\.[^.]+$":{$ref:"#/$defs/labelDef"},"^disabled\\.[^.]+$":{$ref:"#/$defs/disabledDef"},"^readonly\\.[^.]+$":{$ref:"#/$defs/readonlyDef"},"^validator\\.[^.]+$":{$ref:"../validators.schema.json#/$defs/validator"}},L=["kind","type","path"],N=!1,k={$schema:P,$id:T,$comment:E,title:_,type:I,$defs:q,allOf:A,properties:O,patternProperties:M,required:L,unevaluatedProperties:N},z="https://json-schema.org/draft/2020-12/schema",R="__ID_BASE__components/flex.schema.json",C="STARTER TEMPLATE, owned by you. `flex` is a reserved widget type: keep the name and the `children` array, change the props to match your layout widget.",D="__IMPLEMENTATION__ flex widget",W="object",F={directionProp:{enum:["row","row-reverse","column","column-reverse"]},justifyProp:{enum:["start","center","end","stretch","space-between","space-around"]},alignProp:{enum:["start","center","end","stretch","baseline"]},wrapProp:{type:"boolean"},gapProp:{type:"number"},paddingProp:{type:"number"}},B=[{$ref:"../core/common.schema.json#/$defs/baseWidget"}],V={kind:{const:"layout"},type:{const:"flex"},children:{type:"array",minItems:1,items:{$ref:"../widgets.schema.json#/$defs/formWidget"}},props:{type:"object",properties:{direction:{$ref:"#/$defs/directionProp"},justify:{$ref:"#/$defs/justifyProp"},align:{$ref:"#/$defs/alignProp"},wrap:{$ref:"#/$defs/wrapProp"},gap:{$ref:"#/$defs/gapProp"},padding:{$ref:"#/$defs/paddingProp"}},patternProperties:{"^direction\\.[^.]+$":{$ref:"#/$defs/directionProp"},"^justify\\.[^.]+$":{$ref:"#/$defs/justifyProp"},"^align\\.[^.]+$":{$ref:"#/$defs/alignProp"},"^wrap\\.[^.]+$":{$ref:"#/$defs/wrapProp"},"^gap\\.[^.]+$":{$ref:"#/$defs/gapProp"},"^padding\\.[^.]+$":{$ref:"#/$defs/paddingProp"}},additionalProperties:!1}},U=["kind","type","children"],J=!1,Y={$schema:z,$id:R,$comment:C,title:D,type:W,$defs:F,allOf:B,properties:V,required:U,unevaluatedProperties:J},G="https://json-schema.org/draft/2020-12/schema",H="__ID_BASE__validators.schema.json",K="STARTER TEMPLATE, owned by you. Edit it freely. The only contract is that it exposes #/$defs/validator, which every component schema references. Copied from the golemui gui validators when the tree was scaffolded, it does not track them afterwards.",Z="__IMPLEMENTATION__ validator definitions",Q={localizable:{$ref:"./core/common.schema.json#/$defs/localizable"},stringValidator:{type:"object",properties:{type:{const:"string"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is empty or absent"},minLength:{type:"number",description:"Minimum number of characters the string must contain"},maxLength:{type:"number",description:"Maximum number of characters the string may contain"},pattern:{type:"string",description:"A regular expression pattern the value must match"},format:{type:"string",description:"A named format the string must conform to (e.g. `email`, `url`, `date`, `uuid`)",enum:["email","hostname","ipv4","ipv6","url","uuid","date","time","date-time","duration"]},const:{description:"The string must equal exactly this value"},enum:{type:"array",description:"The string must be one of these allowed values"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},required:{$ref:"#/$defs/localizable",description:"Shown when a required field is empty"},minLength:{$ref:"#/$defs/localizable",description:"Shown when the value is shorter than `minLength`"},maxLength:{$ref:"#/$defs/localizable",description:"Shown when the value is longer than `maxLength`"},pattern:{$ref:"#/$defs/localizable",description:"Shown when the value does not match the `pattern` regex"},format:{$ref:"#/$defs/localizable",description:"Shown when the value does not conform to the specified `format`"},enum:{$ref:"#/$defs/localizable",description:"Shown when the value is not in the `enum` list"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},numberValidator:{type:"object",properties:{type:{type:"string",enum:["number","integer"]},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is absent"},minimum:{type:"number",description:"The value must be greater than or equal to this number (inclusive)"},maximum:{type:"number",description:"The value must be less than or equal to this number (inclusive)"},exclusiveMinimum:{type:"number",description:"The value must be strictly greater than this number (exclusive)"},exclusiveMaximum:{type:"number",description:"The value must be strictly less than this number (exclusive)"},multipleOf:{type:"number",description:"The value must be a multiple of this number"},const:{description:"The value must equal exactly this number"},enum:{type:"array",description:"The value must be one of these allowed numbers"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},minimum:{$ref:"#/$defs/localizable",description:"Shown when the value is below `minimum`"},maximum:{$ref:"#/$defs/localizable",description:"Shown when the value exceeds `maximum`"},exclusiveMinimum:{$ref:"#/$defs/localizable",description:"Shown when the value is not strictly above `exclusiveMinimum`"},exclusiveMaximum:{$ref:"#/$defs/localizable",description:"Shown when the value is not strictly below `exclusiveMaximum`"},multipleOf:{$ref:"#/$defs/localizable",description:"Shown when the value is not a multiple of `multipleOf`"},enum:{$ref:"#/$defs/localizable",description:"Shown when the value is not in the `enum` list"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},booleanValidator:{type:"object",properties:{type:{const:"boolean"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the value is absent or false (e.g. an unchecked required checkbox)"},const:{description:"The value must equal exactly this boolean (e.g. `true` to require acceptance)"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},const:{$ref:"#/$defs/localizable",description:"Shown when the value does not equal `const`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},arrayValidator:{type:"object",properties:{type:{const:"array"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if the array is empty or absent"},minItems:{type:"number",description:"The array must contain at least this many items"},maxItems:{type:"number",description:"The array must contain no more than this many items"},uniqueItems:{type:"boolean",description:"When true, all items in the array must be distinct values"},messages:{type:"object",description:"Custom error messages that override the default text for each constraint violation",properties:{invalid:{$ref:"#/$defs/localizable",description:"Shown when the value fails general type validation"},required:{$ref:"#/$defs/localizable",description:"Shown when a required array is empty or absent"},minItems:{$ref:"#/$defs/localizable",description:"Shown when the array has fewer items than `minItems`"},maxItems:{$ref:"#/$defs/localizable",description:"Shown when the array has more items than `maxItems`"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},customValidator:{type:"object",description:"A custom validator that delegates validation to application code. The registered validator function receives these constraint keys and must return a Standard Schema V1-compliant schema object (https://standardschema.dev). Add arbitrary constraint keys alongside `type` - they are passed as-is to the registered validator function.",properties:{type:{const:"custom"},required:{type:"boolean",description:"Makes the field mandatory - evaluation is still delegated to the custom validator"}},required:["type"],additionalProperties:!0},validator:{description:"Validation rules for this field. The `type` discriminant selects the validator: `string`, `number`, `integer`, `boolean`, `array`, or `custom`.",oneOf:[{$ref:"#/$defs/stringValidator"},{$ref:"#/$defs/numberValidator"},{$ref:"#/$defs/booleanValidator"},{$ref:"#/$defs/arrayValidator"},{$ref:"#/$defs/customValidator"}]}},X={$schema:G,$id:H,$comment:K,title:Z,$defs:Q};function $(e){return`${e}-input`}function ee(e,t){const r=e.replace(/__IMPLEMENTATION__/g,t.implementation).replace(/__ID_BASE__/g,t.idBase),a=r.match(/__[A-Z_]+__/);if(a!==null)throw new Error(`Unsubstituted placeholder ${a[0]} in a starter template.`);return r}function d(e,t){return ee(JSON.stringify(e,null,2),t)+`
3
+ `}function te(e){return{"schemas.config.mjs":re(e),"src/lib/validators.schema.json":d(X,e),"src/lib/components/flex.schema.json":d(Y,e),"src/lib/components/example-input.schema.json":d(k,e),"examples/example.form.json":d(S,e),"test/schemas.spec.ts":ae(e)}}function re(e){return`// The manifest and configuration for this implementation's JSON schema tree.
4
4
  // You own this file. Every file marked GENERATED is rebuilt from it by
5
5
  // \`npx @golemui/schemas generate\`, so add a widget by writing its component schema
6
6
  // under src/lib/components/ and listing it in \`manifest\` below.
@@ -24,7 +24,7 @@ export default {
24
24
  manifest: [
25
25
  { type: 'flex', schemaFile: 'flex.schema.json', kind: 'layout' },
26
26
  {
27
- type: '${X(e.implementation)}',
27
+ type: '${$(e.implementation)}',
28
28
  schemaFile: 'example-input.schema.json',
29
29
  kind: 'input',
30
30
  },
@@ -35,7 +35,7 @@ export default {
35
35
  includeCustomWidgetFallback: false,
36
36
  emitEditorBundle: true,
37
37
  };
38
- `}function oe(e){return`// Registers the whole schema tree into one Ajv 2020 instance and validates the
38
+ `}function ae(e){return`// Registers the whole schema tree into one Ajv 2020 instance and validates the
39
39
  // example form against it. Run it after every \`npx @golemui/schemas generate\`.
40
40
  //
41
41
  // Needs \`ajv\` and a test runner. This file is written for vitest, the assertions are
@@ -118,17 +118,19 @@ Options for init:
118
118
  Options for generate:
119
119
  --dir <path> directory holding ${l} (default: the current directory)
120
120
 
121
- Both commands accept --help.`;function ae(e){const t=new Map;let r;for(let o=0;o<e.length;o+=1){const a=e[o];if(!a.startsWith("--")){r??=a;continue}const s=a.slice(2),n=s.indexOf("=");if(n!==-1){t.set(s.slice(0,n),s.slice(n+1));continue}const d=e[o+1];d===void 0||d.startsWith("--")?t.set(s,!0):(t.set(s,d),o+=1)}return{command:r,flags:t}}function m(e,t){const r=e.get(t);return typeof r=="string"?r:void 0}async function f(e,t,r){if(process.stdin.isTTY!==!0)throw new Error(`Missing --${t}. There is no terminal to ask on.`);const o=g.createInterface({input:process.stdin,output:process.stdout});try{const a=(await o.question(`${e} [${r}] `)).trim();return a===""?r:a}finally{o.close()}}function se(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw new Error(`Invalid implementation name "${e}". Use lowercase letters, digits and hyphens, starting with a letter.`)}function ie(e){let t;try{t=new URL(e)}catch{throw new Error(`Invalid --id-base "${e}". It must be an absolute URL.`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Invalid --id-base "${e}". It must be an http or https URL.`);return e.endsWith("/")?e:`${e}/`}function ne(e,t,r){const o=i.join(e,t);p.mkdirSync(i.dirname(o),{recursive:!0}),p.writeFileSync(o,r,"utf-8"),console.log(`Wrote ${t}`)}async function le(e){const t=m(e,"name")??await f("Implementation name?","name","my-widgets");se(t);const r=ie(m(e,"id-base")??await f("Base URL of the published tree?","id-base",`https://example.com/schemas/${t}/`)),o=m(e,"dir")??await f("Directory?","dir","schemas"),a=i.resolve(process.cwd(),o),s=te({implementation:t,idBase:r}),n=Object.keys(s).filter(h=>p.existsSync(i.join(a,h)));if(n.length>0&&e.get("force")!==!0)throw new Error(`Refusing to overwrite starter files you may have edited: ${n.join(", ")}. Pass --force to replace them.`);for(const[h,y]of Object.entries(s))ne(a,h,y);await $(a);const d=i.relative(process.cwd(),a)||".";console.log(`
122
- Scaffolded the ${t} schema tree in ${d}.
121
+ Both commands accept --help.`;function oe(e){const t=new Map;let r;for(let a=0;a<e.length;a+=1){const o=e[a];if(!o.startsWith("--")){r??=o;continue}const s=o.slice(2),n=s.indexOf("=");if(n!==-1){t.set(s.slice(0,n),s.slice(n+1));continue}const c=e[a+1];c===void 0||c.startsWith("--")?t.set(s,!0):(t.set(s,c),a+=1)}return{command:r,flags:t}}function m(e,t){const r=e.get(t);return typeof r=="string"?r:void 0}async function f(e,t,r){if(process.stdin.isTTY!==!0)throw new Error(`Missing --${t}. There is no terminal to ask on.`);const a=b.createInterface({input:process.stdin,output:process.stdout});try{const o=(await a.question(`${e} [${r}] `)).trim();return o===""?r:o}finally{a.close()}}function se(e){if(!/^[a-z][a-z0-9-]*$/.test(e))throw new Error(`Invalid implementation name "${e}". Use lowercase letters, digits and hyphens, starting with a letter.`)}function ie(e){let t;try{t=new URL(e)}catch{throw new Error(`Invalid --id-base "${e}". It must be an absolute URL.`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error(`Invalid --id-base "${e}". It must be an http or https URL.`);return e.endsWith("/")?e:`${e}/`}function ne(e,t,r){const a=i.join(e,t);p.mkdirSync(i.dirname(a),{recursive:!0}),p.writeFileSync(a,r,"utf-8"),console.log(`Wrote ${t}`)}async function le(e){const t=m(e,"name")??await f("Implementation name?","name","my-widgets");se(t);const r=ie(m(e,"id-base")??await f("Base URL of the published tree?","id-base",`https://example.com/schemas/${t}/`)),a=m(e,"dir")??await f("Directory?","dir","schemas"),o=i.resolve(process.cwd(),a),s=te({implementation:t,idBase:r}),n=Object.keys(s).filter(h=>p.existsSync(i.join(o,h)));if(n.length>0&&e.get("force")!==!0)throw new Error(`Refusing to overwrite starter files you may have edited: ${n.join(", ")}. Pass --force to replace them.`);for(const[h,g]of Object.entries(s))ne(o,h,g);await y(o);const c=i.relative(process.cwd(),o)||".";console.log(`
122
+ Scaffolded the ${t} schema tree in ${c}.
123
123
 
124
124
  Next:
125
125
  1. Add @golemui/schemas to the project's dependencies.
126
126
  2. Write one component schema per widget under src/lib/components/, and list each one
127
127
  in ${l}. src/lib/components/example-input.schema.json is the pattern to copy.
128
+ examples/example.form.json uses the starter type ${$(t)}, so
129
+ replace it together with the manifest or test/schemas.spec.ts fails.
128
130
  3. Rerun \`npx @golemui/schemas generate\` after every edit to a component schema, to
129
131
  ${l} or to validators.schema.json. A CI step that regenerates and then runs
130
132
  \`git diff --exit-code\` catches a forgotten rerun.
131
133
  4. Point a form file's "$schema" at src/lib/form.editor.schema.json, as
132
- examples/example.form.json does. Editors need that bundle, Ajv uses the per-file tree.`)}function de(e,t){if(e===null||typeof e!="object")throw new Error(`${t} must export a configuration object as its default export.`);const r=e,a=["implementation","idBase","generatorPath","formTitle"].filter(s=>typeof r[s]!="string");if(a.length>0)throw new Error(`${t} is missing required string fields: ${a.join(", ")}.`);if(!Array.isArray(r.manifest)||r.manifest.length===0)throw new Error(`${t} must declare a non-empty \`manifest\` array.`);if(!r.idBase.endsWith("/"))throw new Error(`${t}: \`idBase\` must end with a slash.`);return e}async function $(e){const t=i.join(e,l);if(!p.existsSync(t))throw new Error(`No ${l} in ${e}. Run this from the directory holding it, pass --dir, or scaffold a new tree with \`npx @golemui/schemas init\`.`);const r=await import(b.pathToFileURL(t).href),o=de(r.default,l);await v.generateImplementationSchemas(o,e)}async function ce(e){const{command:t,flags:r}=ae(e);if(r.get("help")===!0||t==="help"||t===void 0)return console.log(u),t===void 0&&r.get("help")!==!0?1:0;try{switch(t){case"init":return await le(r),0;case"generate":return await $(i.resolve(process.cwd(),m(r,"dir")??".")),0;default:return console.error(`Unknown command "${t}".
134
+ examples/example.form.json does. Editors need that bundle, Ajv uses the per-file tree.`)}function ce(e,t){if(e===null||typeof e!="object")throw new Error(`${t} must export a configuration object as its default export.`);const r=e,o=["implementation","idBase","generatorPath","formTitle"].filter(s=>typeof r[s]!="string");if(o.length>0)throw new Error(`${t} is missing required string fields: ${o.join(", ")}.`);if(!Array.isArray(r.manifest)||r.manifest.length===0)throw new Error(`${t} must declare a non-empty \`manifest\` array.`);if(!r.idBase.endsWith("/"))throw new Error(`${t}: \`idBase\` must end with a slash.`);return e}async function y(e){const t=i.join(e,l);if(!p.existsSync(t))throw new Error(`No ${l} in ${e}. Run this from the directory holding it, pass --dir, or scaffold a new tree with \`npx @golemui/schemas init\`.`);const r=await import(v.pathToFileURL(t).href),a=ce(r.default,l);await w.generateImplementationSchemas(a,e)}async function de(e){const{command:t,flags:r}=oe(e);if(r.get("help")===!0||t==="help"||t===void 0)return console.log(u),t===void 0&&r.get("help")!==!0?1:0;try{switch(t){case"init":return await le(r),0;case"generate":return await y(i.resolve(process.cwd(),m(r,"dir")??".")),0;default:return console.error(`Unknown command "${t}".
133
135
 
134
- ${u}`),1}}catch(o){return console.error(o instanceof Error?o.message:o),1}}ce(process.argv.slice(2)).then(e=>{process.exitCode=e});
136
+ ${u}`),1}}catch(a){return console.error(a instanceof Error?a.message:a),1}}de(process.argv.slice(2)).then(e=>{process.exitCode=e});
package/cli.js CHANGED
@@ -1,65 +1,65 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync as u, mkdirSync as b, writeFileSync as v } from "node:fs";
3
- import { resolve as $, join as h, relative as w, dirname as x } from "node:path";
4
- import { createInterface as j } from "node:readline/promises";
5
- import { pathToFileURL as S } from "node:url";
6
- import { g as P } from "./generate-implementation-schemas-DxCUi0Jr.js";
7
- const T = "../src/lib/form.editor.schema.json", E = [{ kind: "layout", type: "flex", uid: "#root", props: { direction: "column", gap: 16 }, children: [{ kind: "input", type: "__IMPLEMENTATION__-input", uid: "email", path: "email", label: "Email address", validator: { type: "string", required: !0, format: "email" }, props: { placeholder: "you@example.com" } }] }], _ = {
8
- $schema: T,
9
- form: E
10
- }, I = "https://json-schema.org/draft/2020-12/schema", A = "__ID_BASE__components/example-input.schema.json", q = "STARTER TEMPLATE, owned by you. One component schema per widget type. Copy this file for each widget, then list it in schemas.config.mjs. The pattern to keep: allOf the baseWidget, `kind` and `type` consts, one `$defs` entry per prop, a `.state` suffixed pattern for every suffixable key, `additionalProperties: false` inside `props`, and `unevaluatedProperties: false` at the root.", O = "__IMPLEMENTATION__ example input widget", M = "object", L = { labelDef: { $ref: "../core/common.schema.json#/$defs/localizable" }, disabledDef: { $ref: "../core/common.schema.json#/$defs/boolOrWhen" }, readonlyDef: { $ref: "../core/common.schema.json#/$defs/boolOrWhen" }, hintProp: { type: "string" }, placeholderProp: { type: "string" }, maxlengthProp: { type: "number" } }, N = [{ $ref: "../core/common.schema.json#/$defs/baseWidget" }], k = { kind: { const: "input" }, type: { const: "__IMPLEMENTATION__-input" }, path: { $ref: "../core/common.schema.json#/$defs/dotPath" }, label: { $ref: "#/$defs/labelDef" }, disabled: { $ref: "#/$defs/disabledDef" }, readonly: { $ref: "#/$defs/readonlyDef" }, on: { $ref: "../core/common.schema.json#/$defs/on" }, validator: { $ref: "../validators.schema.json#/$defs/validator" }, defaultValue: { type: "string" }, props: { type: "object", properties: { hint: { $ref: "#/$defs/hintProp" }, placeholder: { $ref: "#/$defs/placeholderProp" }, maxlength: { $ref: "#/$defs/maxlengthProp" } }, patternProperties: { "^hint\\.[^.]+$": { $ref: "#/$defs/hintProp" }, "^placeholder\\.[^.]+$": { $ref: "#/$defs/placeholderProp" }, "^maxlength\\.[^.]+$": { $ref: "#/$defs/maxlengthProp" } }, additionalProperties: !1 } }, z = { "^label\\.[^.]+$": { $ref: "#/$defs/labelDef" }, "^disabled\\.[^.]+$": { $ref: "#/$defs/disabledDef" }, "^readonly\\.[^.]+$": { $ref: "#/$defs/readonlyDef" }, "^validator\\.[^.]+$": { $ref: "../validators.schema.json#/$defs/validator" } }, R = ["kind", "type", "path"], C = !1, D = {
11
- $schema: I,
12
- $id: A,
13
- $comment: q,
14
- title: O,
15
- type: M,
16
- $defs: L,
17
- allOf: N,
18
- properties: k,
19
- patternProperties: z,
20
- required: R,
21
- unevaluatedProperties: C
22
- }, W = "https://json-schema.org/draft/2020-12/schema", F = "__ID_BASE__components/flex.schema.json", B = "STARTER TEMPLATE, owned by you. `flex` is a reserved widget type: keep the name and the `children` array, change the props to match your layout widget.", V = "__IMPLEMENTATION__ flex widget", U = "object", J = { directionProp: { enum: ["row", "row-reverse", "column", "column-reverse"] }, justifyProp: { enum: ["start", "center", "end", "stretch", "space-between", "space-around"] }, alignProp: { enum: ["start", "center", "end", "stretch", "baseline"] }, wrapProp: { type: "boolean" }, gapProp: { type: "number" }, paddingProp: { type: "number" } }, Y = [{ $ref: "../core/common.schema.json#/$defs/baseWidget" }], G = { kind: { const: "layout" }, type: { const: "flex" }, children: { type: "array", minItems: 1, items: { $ref: "../widgets.schema.json#/$defs/formWidget" } }, props: { type: "object", properties: { direction: { $ref: "#/$defs/directionProp" }, justify: { $ref: "#/$defs/justifyProp" }, align: { $ref: "#/$defs/alignProp" }, wrap: { $ref: "#/$defs/wrapProp" }, gap: { $ref: "#/$defs/gapProp" }, padding: { $ref: "#/$defs/paddingProp" } }, patternProperties: { "^direction\\.[^.]+$": { $ref: "#/$defs/directionProp" }, "^justify\\.[^.]+$": { $ref: "#/$defs/justifyProp" }, "^align\\.[^.]+$": { $ref: "#/$defs/alignProp" }, "^wrap\\.[^.]+$": { $ref: "#/$defs/wrapProp" }, "^gap\\.[^.]+$": { $ref: "#/$defs/gapProp" }, "^padding\\.[^.]+$": { $ref: "#/$defs/paddingProp" } }, additionalProperties: !1 } }, H = ["kind", "type", "children"], K = !1, Z = {
23
- $schema: W,
24
- $id: F,
25
- $comment: B,
26
- title: V,
27
- type: U,
28
- $defs: J,
29
- allOf: Y,
30
- properties: G,
31
- required: H,
32
- unevaluatedProperties: K
33
- }, Q = "https://json-schema.org/draft/2020-12/schema", X = "__ID_BASE__validators.schema.json", ee = "STARTER TEMPLATE, owned by you. Edit it freely. The only contract is that it exposes #/$defs/validator, which every component schema references. Copied from the golemui gui validators when the tree was scaffolded, it does not track them afterwards.", te = "__IMPLEMENTATION__ validator definitions", re = { localizable: { $ref: "./core/common.schema.json#/$defs/localizable" }, stringValidator: { type: "object", properties: { type: { const: "string" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is empty or absent" }, minLength: { type: "number", description: "Minimum number of characters the string must contain" }, maxLength: { type: "number", description: "Maximum number of characters the string may contain" }, pattern: { type: "string", description: "A regular expression pattern the value must match" }, format: { type: "string", description: "A named format the string must conform to (e.g. `email`, `url`, `date`, `uuid`)", enum: ["email", "hostname", "ipv4", "ipv6", "url", "uuid", "date", "time", "date-time", "duration"] }, const: { description: "The string must equal exactly this value" }, enum: { type: "array", description: "The string must be one of these allowed values" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, required: { $ref: "#/$defs/localizable", description: "Shown when a required field is empty" }, minLength: { $ref: "#/$defs/localizable", description: "Shown when the value is shorter than `minLength`" }, maxLength: { $ref: "#/$defs/localizable", description: "Shown when the value is longer than `maxLength`" }, pattern: { $ref: "#/$defs/localizable", description: "Shown when the value does not match the `pattern` regex" }, format: { $ref: "#/$defs/localizable", description: "Shown when the value does not conform to the specified `format`" }, enum: { $ref: "#/$defs/localizable", description: "Shown when the value is not in the `enum` list" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, numberValidator: { type: "object", properties: { type: { type: "string", enum: ["number", "integer"] }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is absent" }, minimum: { type: "number", description: "The value must be greater than or equal to this number (inclusive)" }, maximum: { type: "number", description: "The value must be less than or equal to this number (inclusive)" }, exclusiveMinimum: { type: "number", description: "The value must be strictly greater than this number (exclusive)" }, exclusiveMaximum: { type: "number", description: "The value must be strictly less than this number (exclusive)" }, multipleOf: { type: "number", description: "The value must be a multiple of this number" }, const: { description: "The value must equal exactly this number" }, enum: { type: "array", description: "The value must be one of these allowed numbers" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, minimum: { $ref: "#/$defs/localizable", description: "Shown when the value is below `minimum`" }, maximum: { $ref: "#/$defs/localizable", description: "Shown when the value exceeds `maximum`" }, exclusiveMinimum: { $ref: "#/$defs/localizable", description: "Shown when the value is not strictly above `exclusiveMinimum`" }, exclusiveMaximum: { $ref: "#/$defs/localizable", description: "Shown when the value is not strictly below `exclusiveMaximum`" }, multipleOf: { $ref: "#/$defs/localizable", description: "Shown when the value is not a multiple of `multipleOf`" }, enum: { $ref: "#/$defs/localizable", description: "Shown when the value is not in the `enum` list" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, booleanValidator: { type: "object", properties: { type: { const: "boolean" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is absent or false (e.g. an unchecked required checkbox)" }, const: { description: "The value must equal exactly this boolean (e.g. `true` to require acceptance)" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, arrayValidator: { type: "object", properties: { type: { const: "array" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the array is empty or absent" }, minItems: { type: "number", description: "The array must contain at least this many items" }, maxItems: { type: "number", description: "The array must contain no more than this many items" }, uniqueItems: { type: "boolean", description: "When true, all items in the array must be distinct values" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, required: { $ref: "#/$defs/localizable", description: "Shown when a required array is empty or absent" }, minItems: { $ref: "#/$defs/localizable", description: "Shown when the array has fewer items than `minItems`" }, maxItems: { $ref: "#/$defs/localizable", description: "Shown when the array has more items than `maxItems`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, customValidator: { type: "object", description: "A custom validator that delegates validation to application code. The registered validator function receives these constraint keys and must return a Standard Schema V1-compliant schema object (https://standardschema.dev). Add arbitrary constraint keys alongside `type` - they are passed as-is to the registered validator function.", properties: { type: { const: "custom" }, required: { type: "boolean", description: "Makes the field mandatory - evaluation is still delegated to the custom validator" } }, required: ["type"], additionalProperties: !0 }, validator: { description: "Validation rules for this field. The `type` discriminant selects the validator: `string`, `number`, `integer`, `boolean`, `array`, or `custom`.", oneOf: [{ $ref: "#/$defs/stringValidator" }, { $ref: "#/$defs/numberValidator" }, { $ref: "#/$defs/booleanValidator" }, { $ref: "#/$defs/arrayValidator" }, { $ref: "#/$defs/customValidator" }] } }, oe = {
34
- $schema: Q,
35
- $id: X,
36
- $comment: ee,
37
- title: te,
38
- $defs: re
2
+ import { existsSync as u, mkdirSync as v, writeFileSync as w } from "node:fs";
3
+ import { resolve as $, join as h, relative as x, dirname as j } from "node:path";
4
+ import { createInterface as S } from "node:readline/promises";
5
+ import { pathToFileURL as P } from "node:url";
6
+ import { g as T } from "./generate-implementation-schemas-DxCUi0Jr.js";
7
+ const E = "../src/lib/form.editor.schema.json", _ = [{ kind: "layout", type: "flex", uid: "#root", props: { direction: "column", gap: 16 }, children: [{ kind: "input", type: "__IMPLEMENTATION__-input", uid: "email", path: "email", label: "Email address", validator: { type: "string", required: !0, format: "email" }, props: { placeholder: "you@example.com" } }] }], I = {
8
+ $schema: E,
9
+ form: _
10
+ }, A = "https://json-schema.org/draft/2020-12/schema", q = "__ID_BASE__components/example-input.schema.json", O = "STARTER TEMPLATE, owned by you. One component schema per widget type. Copy this file for each widget, then list it in schemas.config.mjs. The pattern to keep: allOf the baseWidget, `kind` and `type` consts, one `$defs` entry per prop, a `.state` suffixed pattern for every suffixable key, `additionalProperties: false` inside `props`, and `unevaluatedProperties: false` at the root.", M = "__IMPLEMENTATION__ example input widget", L = "object", N = { labelDef: { $ref: "../core/common.schema.json#/$defs/localizable" }, disabledDef: { $ref: "../core/common.schema.json#/$defs/boolOrWhen" }, readonlyDef: { $ref: "../core/common.schema.json#/$defs/boolOrWhen" }, hintProp: { type: "string" }, placeholderProp: { type: "string" }, maxlengthProp: { type: "number" } }, k = [{ $ref: "../core/common.schema.json#/$defs/baseWidget" }], z = { kind: { const: "input" }, type: { const: "__IMPLEMENTATION__-input" }, path: { $ref: "../core/common.schema.json#/$defs/dotPath" }, label: { $ref: "#/$defs/labelDef" }, disabled: { $ref: "#/$defs/disabledDef" }, readonly: { $ref: "#/$defs/readonlyDef" }, on: { $ref: "../core/common.schema.json#/$defs/on" }, validator: { $ref: "../validators.schema.json#/$defs/validator" }, defaultValue: { type: "string" }, props: { type: "object", properties: { hint: { $ref: "#/$defs/hintProp" }, placeholder: { $ref: "#/$defs/placeholderProp" }, maxlength: { $ref: "#/$defs/maxlengthProp" } }, patternProperties: { "^hint\\.[^.]+$": { $ref: "#/$defs/hintProp" }, "^placeholder\\.[^.]+$": { $ref: "#/$defs/placeholderProp" }, "^maxlength\\.[^.]+$": { $ref: "#/$defs/maxlengthProp" } }, additionalProperties: !1 } }, R = { "^label\\.[^.]+$": { $ref: "#/$defs/labelDef" }, "^disabled\\.[^.]+$": { $ref: "#/$defs/disabledDef" }, "^readonly\\.[^.]+$": { $ref: "#/$defs/readonlyDef" }, "^validator\\.[^.]+$": { $ref: "../validators.schema.json#/$defs/validator" } }, C = ["kind", "type", "path"], D = !1, W = {
11
+ $schema: A,
12
+ $id: q,
13
+ $comment: O,
14
+ title: M,
15
+ type: L,
16
+ $defs: N,
17
+ allOf: k,
18
+ properties: z,
19
+ patternProperties: R,
20
+ required: C,
21
+ unevaluatedProperties: D
22
+ }, F = "https://json-schema.org/draft/2020-12/schema", B = "__ID_BASE__components/flex.schema.json", V = "STARTER TEMPLATE, owned by you. `flex` is a reserved widget type: keep the name and the `children` array, change the props to match your layout widget.", U = "__IMPLEMENTATION__ flex widget", J = "object", Y = { directionProp: { enum: ["row", "row-reverse", "column", "column-reverse"] }, justifyProp: { enum: ["start", "center", "end", "stretch", "space-between", "space-around"] }, alignProp: { enum: ["start", "center", "end", "stretch", "baseline"] }, wrapProp: { type: "boolean" }, gapProp: { type: "number" }, paddingProp: { type: "number" } }, G = [{ $ref: "../core/common.schema.json#/$defs/baseWidget" }], H = { kind: { const: "layout" }, type: { const: "flex" }, children: { type: "array", minItems: 1, items: { $ref: "../widgets.schema.json#/$defs/formWidget" } }, props: { type: "object", properties: { direction: { $ref: "#/$defs/directionProp" }, justify: { $ref: "#/$defs/justifyProp" }, align: { $ref: "#/$defs/alignProp" }, wrap: { $ref: "#/$defs/wrapProp" }, gap: { $ref: "#/$defs/gapProp" }, padding: { $ref: "#/$defs/paddingProp" } }, patternProperties: { "^direction\\.[^.]+$": { $ref: "#/$defs/directionProp" }, "^justify\\.[^.]+$": { $ref: "#/$defs/justifyProp" }, "^align\\.[^.]+$": { $ref: "#/$defs/alignProp" }, "^wrap\\.[^.]+$": { $ref: "#/$defs/wrapProp" }, "^gap\\.[^.]+$": { $ref: "#/$defs/gapProp" }, "^padding\\.[^.]+$": { $ref: "#/$defs/paddingProp" } }, additionalProperties: !1 } }, K = ["kind", "type", "children"], Z = !1, Q = {
23
+ $schema: F,
24
+ $id: B,
25
+ $comment: V,
26
+ title: U,
27
+ type: J,
28
+ $defs: Y,
29
+ allOf: G,
30
+ properties: H,
31
+ required: K,
32
+ unevaluatedProperties: Z
33
+ }, X = "https://json-schema.org/draft/2020-12/schema", ee = "__ID_BASE__validators.schema.json", te = "STARTER TEMPLATE, owned by you. Edit it freely. The only contract is that it exposes #/$defs/validator, which every component schema references. Copied from the golemui gui validators when the tree was scaffolded, it does not track them afterwards.", re = "__IMPLEMENTATION__ validator definitions", ae = { localizable: { $ref: "./core/common.schema.json#/$defs/localizable" }, stringValidator: { type: "object", properties: { type: { const: "string" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is empty or absent" }, minLength: { type: "number", description: "Minimum number of characters the string must contain" }, maxLength: { type: "number", description: "Maximum number of characters the string may contain" }, pattern: { type: "string", description: "A regular expression pattern the value must match" }, format: { type: "string", description: "A named format the string must conform to (e.g. `email`, `url`, `date`, `uuid`)", enum: ["email", "hostname", "ipv4", "ipv6", "url", "uuid", "date", "time", "date-time", "duration"] }, const: { description: "The string must equal exactly this value" }, enum: { type: "array", description: "The string must be one of these allowed values" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, required: { $ref: "#/$defs/localizable", description: "Shown when a required field is empty" }, minLength: { $ref: "#/$defs/localizable", description: "Shown when the value is shorter than `minLength`" }, maxLength: { $ref: "#/$defs/localizable", description: "Shown when the value is longer than `maxLength`" }, pattern: { $ref: "#/$defs/localizable", description: "Shown when the value does not match the `pattern` regex" }, format: { $ref: "#/$defs/localizable", description: "Shown when the value does not conform to the specified `format`" }, enum: { $ref: "#/$defs/localizable", description: "Shown when the value is not in the `enum` list" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, numberValidator: { type: "object", properties: { type: { type: "string", enum: ["number", "integer"] }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is absent" }, minimum: { type: "number", description: "The value must be greater than or equal to this number (inclusive)" }, maximum: { type: "number", description: "The value must be less than or equal to this number (inclusive)" }, exclusiveMinimum: { type: "number", description: "The value must be strictly greater than this number (exclusive)" }, exclusiveMaximum: { type: "number", description: "The value must be strictly less than this number (exclusive)" }, multipleOf: { type: "number", description: "The value must be a multiple of this number" }, const: { description: "The value must equal exactly this number" }, enum: { type: "array", description: "The value must be one of these allowed numbers" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, minimum: { $ref: "#/$defs/localizable", description: "Shown when the value is below `minimum`" }, maximum: { $ref: "#/$defs/localizable", description: "Shown when the value exceeds `maximum`" }, exclusiveMinimum: { $ref: "#/$defs/localizable", description: "Shown when the value is not strictly above `exclusiveMinimum`" }, exclusiveMaximum: { $ref: "#/$defs/localizable", description: "Shown when the value is not strictly below `exclusiveMaximum`" }, multipleOf: { $ref: "#/$defs/localizable", description: "Shown when the value is not a multiple of `multipleOf`" }, enum: { $ref: "#/$defs/localizable", description: "Shown when the value is not in the `enum` list" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, booleanValidator: { type: "object", properties: { type: { const: "boolean" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the value is absent or false (e.g. an unchecked required checkbox)" }, const: { description: "The value must equal exactly this boolean (e.g. `true` to require acceptance)" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, const: { $ref: "#/$defs/localizable", description: "Shown when the value does not equal `const`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, arrayValidator: { type: "object", properties: { type: { const: "array" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if the array is empty or absent" }, minItems: { type: "number", description: "The array must contain at least this many items" }, maxItems: { type: "number", description: "The array must contain no more than this many items" }, uniqueItems: { type: "boolean", description: "When true, all items in the array must be distinct values" }, messages: { type: "object", description: "Custom error messages that override the default text for each constraint violation", properties: { invalid: { $ref: "#/$defs/localizable", description: "Shown when the value fails general type validation" }, required: { $ref: "#/$defs/localizable", description: "Shown when a required array is empty or absent" }, minItems: { $ref: "#/$defs/localizable", description: "Shown when the array has fewer items than `minItems`" }, maxItems: { $ref: "#/$defs/localizable", description: "Shown when the array has more items than `maxItems`" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, customValidator: { type: "object", description: "A custom validator that delegates validation to application code. The registered validator function receives these constraint keys and must return a Standard Schema V1-compliant schema object (https://standardschema.dev). Add arbitrary constraint keys alongside `type` - they are passed as-is to the registered validator function.", properties: { type: { const: "custom" }, required: { type: "boolean", description: "Makes the field mandatory - evaluation is still delegated to the custom validator" } }, required: ["type"], additionalProperties: !0 }, validator: { description: "Validation rules for this field. The `type` discriminant selects the validator: `string`, `number`, `integer`, `boolean`, `array`, or `custom`.", oneOf: [{ $ref: "#/$defs/stringValidator" }, { $ref: "#/$defs/numberValidator" }, { $ref: "#/$defs/booleanValidator" }, { $ref: "#/$defs/arrayValidator" }, { $ref: "#/$defs/customValidator" }] } }, oe = {
34
+ $schema: X,
35
+ $id: ee,
36
+ $comment: te,
37
+ title: re,
38
+ $defs: ae
39
39
  };
40
- function ae(e) {
40
+ function y(e) {
41
41
  return `${e}-input`;
42
42
  }
43
- function ie(e, t) {
44
- const r = e.replace(/__IMPLEMENTATION__/g, t.implementation).replace(/__ID_BASE__/g, t.idBase), o = r.match(/__[A-Z_]+__/);
45
- if (o !== null)
46
- throw new Error(`Unsubstituted placeholder ${o[0]} in a starter template.`);
43
+ function se(e, t) {
44
+ const r = e.replace(/__IMPLEMENTATION__/g, t.implementation).replace(/__ID_BASE__/g, t.idBase), a = r.match(/__[A-Z_]+__/);
45
+ if (a !== null)
46
+ throw new Error(`Unsubstituted placeholder ${a[0]} in a starter template.`);
47
47
  return r;
48
48
  }
49
49
  function d(e, t) {
50
- return ie(JSON.stringify(e, null, 2), t) + `
50
+ return se(JSON.stringify(e, null, 2), t) + `
51
51
  `;
52
52
  }
53
- function se(e) {
53
+ function ie(e) {
54
54
  return {
55
55
  "schemas.config.mjs": ne(e),
56
56
  "src/lib/validators.schema.json": d(oe, e),
57
- "src/lib/components/flex.schema.json": d(Z, e),
57
+ "src/lib/components/flex.schema.json": d(Q, e),
58
58
  "src/lib/components/example-input.schema.json": d(
59
- D,
59
+ W,
60
60
  e
61
61
  ),
62
- "examples/example.form.json": d(_, e),
62
+ "examples/example.form.json": d(I, e),
63
63
  "test/schemas.spec.ts": le(e)
64
64
  };
65
65
  }
@@ -88,7 +88,7 @@ export default {
88
88
  manifest: [
89
89
  { type: 'flex', schemaFile: 'flex.schema.json', kind: 'layout' },
90
90
  {
91
- type: '${ae(e.implementation)}',
91
+ type: '${y(e.implementation)}',
92
92
  schemaFile: 'example-input.schema.json',
93
93
  kind: 'input',
94
94
  },
@@ -191,19 +191,19 @@ Both commands accept --help.`;
191
191
  function de(e) {
192
192
  const t = /* @__PURE__ */ new Map();
193
193
  let r;
194
- for (let o = 0; o < e.length; o += 1) {
195
- const a = e[o];
196
- if (!a.startsWith("--")) {
197
- r ??= a;
194
+ for (let a = 0; a < e.length; a += 1) {
195
+ const o = e[a];
196
+ if (!o.startsWith("--")) {
197
+ r ??= o;
198
198
  continue;
199
199
  }
200
- const i = a.slice(2), s = i.indexOf("=");
201
- if (s !== -1) {
202
- t.set(i.slice(0, s), i.slice(s + 1));
200
+ const s = o.slice(2), i = s.indexOf("=");
201
+ if (i !== -1) {
202
+ t.set(s.slice(0, i), s.slice(i + 1));
203
203
  continue;
204
204
  }
205
- const l = e[o + 1];
206
- l === void 0 || l.startsWith("--") ? t.set(i, !0) : (t.set(i, l), o += 1);
205
+ const l = e[a + 1];
206
+ l === void 0 || l.startsWith("--") ? t.set(s, !0) : (t.set(s, l), a += 1);
207
207
  }
208
208
  return { command: r, flags: t };
209
209
  }
@@ -214,12 +214,12 @@ function c(e, t) {
214
214
  async function p(e, t, r) {
215
215
  if (process.stdin.isTTY !== !0)
216
216
  throw new Error(`Missing --${t}. There is no terminal to ask on.`);
217
- const o = j({ input: process.stdin, output: process.stdout });
217
+ const a = S({ input: process.stdin, output: process.stdout });
218
218
  try {
219
- const a = (await o.question(`${e} [${r}] `)).trim();
220
- return a === "" ? r : a;
219
+ const o = (await a.question(`${e} [${r}] `)).trim();
220
+ return o === "" ? r : o;
221
221
  } finally {
222
- o.close();
222
+ a.close();
223
223
  }
224
224
  }
225
225
  function ce(e) {
@@ -240,8 +240,8 @@ function me(e) {
240
240
  return e.endsWith("/") ? e : `${e}/`;
241
241
  }
242
242
  function pe(e, t, r) {
243
- const o = h(e, t);
244
- b(x(o), { recursive: !0 }), v(o, r, "utf-8"), console.log(`Wrote ${t}`);
243
+ const a = h(e, t);
244
+ v(j(a), { recursive: !0 }), w(a, r, "utf-8"), console.log(`Wrote ${t}`);
245
245
  }
246
246
  async function he(e) {
247
247
  const t = c(e, "name") ?? await p("Implementation name?", "name", "my-widgets");
@@ -252,15 +252,15 @@ async function he(e) {
252
252
  "id-base",
253
253
  `https://example.com/schemas/${t}/`
254
254
  )
255
- ), o = c(e, "dir") ?? await p("Directory?", "dir", "schemas"), a = $(process.cwd(), o), i = se({ implementation: t, idBase: r }), s = Object.keys(i).filter((m) => u(h(a, m)));
256
- if (s.length > 0 && e.get("force") !== !0)
255
+ ), a = c(e, "dir") ?? await p("Directory?", "dir", "schemas"), o = $(process.cwd(), a), s = ie({ implementation: t, idBase: r }), i = Object.keys(s).filter((m) => u(h(o, m)));
256
+ if (i.length > 0 && e.get("force") !== !0)
257
257
  throw new Error(
258
- `Refusing to overwrite starter files you may have edited: ${s.join(", ")}. Pass --force to replace them.`
258
+ `Refusing to overwrite starter files you may have edited: ${i.join(", ")}. Pass --force to replace them.`
259
259
  );
260
- for (const [m, g] of Object.entries(i))
261
- pe(a, m, g);
262
- await y(a);
263
- const l = w(process.cwd(), a) || ".";
260
+ for (const [m, b] of Object.entries(s))
261
+ pe(o, m, b);
262
+ await g(o);
263
+ const l = x(process.cwd(), o) || ".";
264
264
  console.log(`
265
265
  Scaffolded the ${t} schema tree in ${l}.
266
266
 
@@ -268,6 +268,8 @@ Next:
268
268
  1. Add @golemui/schemas to the project's dependencies.
269
269
  2. Write one component schema per widget under src/lib/components/, and list each one
270
270
  in ${n}. src/lib/components/example-input.schema.json is the pattern to copy.
271
+ examples/example.form.json uses the starter type ${y(t)}, so
272
+ replace it together with the manifest or test/schemas.spec.ts fails.
271
273
  3. Rerun \`npx @golemui/schemas generate\` after every edit to a component schema, to
272
274
  ${n} or to validators.schema.json. A CI step that regenerates and then runs
273
275
  \`git diff --exit-code\` catches a forgotten rerun.
@@ -277,16 +279,16 @@ Next:
277
279
  function fe(e, t) {
278
280
  if (e === null || typeof e != "object")
279
281
  throw new Error(`${t} must export a configuration object as its default export.`);
280
- const r = e, a = ["implementation", "idBase", "generatorPath", "formTitle"].filter((i) => typeof r[i] != "string");
281
- if (a.length > 0)
282
- throw new Error(`${t} is missing required string fields: ${a.join(", ")}.`);
282
+ const r = e, o = ["implementation", "idBase", "generatorPath", "formTitle"].filter((s) => typeof r[s] != "string");
283
+ if (o.length > 0)
284
+ throw new Error(`${t} is missing required string fields: ${o.join(", ")}.`);
283
285
  if (!Array.isArray(r.manifest) || r.manifest.length === 0)
284
286
  throw new Error(`${t} must declare a non-empty \`manifest\` array.`);
285
287
  if (!r.idBase.endsWith("/"))
286
288
  throw new Error(`${t}: \`idBase\` must end with a slash.`);
287
289
  return e;
288
290
  }
289
- async function y(e) {
291
+ async function g(e) {
290
292
  const t = h(e, n);
291
293
  if (!u(t))
292
294
  throw new Error(
@@ -294,9 +296,9 @@ async function y(e) {
294
296
  );
295
297
  const r = await import(
296
298
  /* @vite-ignore */
297
- S(t).href
298
- ), o = fe(r.default, n);
299
- await P(o, e);
299
+ P(t).href
300
+ ), a = fe(r.default, n);
301
+ await T(a, e);
300
302
  }
301
303
  async function ue(e) {
302
304
  const { command: t, flags: r } = de(e);
@@ -307,14 +309,14 @@ async function ue(e) {
307
309
  case "init":
308
310
  return await he(r), 0;
309
311
  case "generate":
310
- return await y($(process.cwd(), c(r, "dir") ?? ".")), 0;
312
+ return await g($(process.cwd(), c(r, "dir") ?? ".")), 0;
311
313
  default:
312
314
  return console.error(`Unknown command "${t}".
313
315
 
314
316
  ${f}`), 1;
315
317
  }
316
- } catch (o) {
317
- return console.error(o instanceof Error ? o.message : o), 1;
318
+ } catch (a) {
319
+ return console.error(a instanceof Error ? a.message : a), 1;
318
320
  }
319
321
  }
320
322
  ue(process.argv.slice(2)).then((e) => {
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./editor-bundle-yoVhdYIT.cjs"),t="https://json-schema.org/draft/2020-12/schema",i="https://golemui.com/schemas/core/common.schema.json",s="Owned by @golemui/schemas (libs/schemas/src/lib/core/). Implementation trees contain a generated vendored copy, identical apart from an `$id` rebased onto the implementation's own tree. Edit the source file, then run `npm run generate:schemas`.",n="Golem Common Definitions",a={reactiveExpression:{type:"string",description:"A reactive expression string. Use `$form` to access form data e.g. `$form.termsAccepted === true`"},dotPath:{type:"string",description:"A dot-separated path to a property in the form data"},uid:{type:"string",description:"Unique identifier for the widget"},chunkRef:{type:"object",description:"A reference to an external chunk file whose widget array will be inlined at this position in the form",properties:{$ref:{type:"string",description:"Relative path to a JSON chunk file"}},required:["$ref"],additionalProperties:!1},localizable:{description:"A value that can be a plain string or an i18n key object. Use a plain string for static text, or `{key, default, params}` to reference a translation key.",oneOf:[{type:"string"},{type:"object",properties:{key:{type:"string",description:"The i18n translation key"},default:{type:"string",description:"Fallback text shown when the translation key is not found"},params:{type:"object",description:"Interpolation parameters passed to the translation function"}},required:["key"],additionalProperties:!1}]},include:{description:"Show this widget only in certain form states (`{in: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is always shown.",oneOf:[{type:"object",properties:{in:{type:"array",items:{type:"string"},description:"List of state names (defined in the form `states` map) in which this widget should be visible"}},required:["in"],additionalProperties:!1},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},exclude:{description:"Hide this widget in certain form states (`{from: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is never hidden.",oneOf:[{type:"object",properties:{from:{type:"array",items:{type:"string"},description:"List of state names (defined in the form `states` map) in which this widget should be hidden"}},required:["from"],additionalProperties:!1},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},boolOrWhen:{description:"A static boolean or a conditional `{when: reactiveExpression}` object evaluated at runtime. Use `{when: '$form.someField === true'}` for dynamic behavior.",oneOf:[{type:"boolean"},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},on:{type:"object",description:'Event handlers for this widget. Values are action names dispatched to the form\'s event bus. Each key also accepts a state-suffixed variant (`"click.<stateName>"`) that overrides the base handler when the named state is active.',properties:{load:{type:"string",description:"Action dispatched when the widget is first mounted"},click:{type:"string",description:"Action dispatched when the user clicks the widget"},change:{type:"string",description:"Action dispatched when the widget value changes"},filter:{type:"string",description:"Action dispatched on search/filter input, typically used with async data sources"},blur:{type:"string",description:"Action dispatched when the widget loses focus"}},patternProperties:{"^load\\.[^.]+$":{type:"string",description:'State-suffixed load handler: used instead of `load` when the named state is active (e.g. `"load.myState"`)'},"^click\\.[^.]+$":{type:"string",description:'State-suffixed click handler: used instead of `click` when the named state is active (e.g. `"click.myState"`)'},"^change\\.[^.]+$":{type:"string",description:'State-suffixed change handler: used instead of `change` when the named state is active (e.g. `"change.myState"`)'},"^filter\\.[^.]+$":{type:"string",description:'State-suffixed filter handler: used instead of `filter` when the named state is active (e.g. `"filter.myState"`)'},"^blur\\.[^.]+$":{type:"string",description:'State-suffixed blur handler: used instead of `blur` when the named state is active (e.g. `"blur.myState"`)'}},additionalProperties:!1},baseWidget:{type:"object",description:'Base properties shared by all widgets. Root-level props that support state-suffixing (e.g. `"label.myState"`) are: `label`, `disabled`, `readonly`, `validator`, `size`. Any key inside `props` can also be suffixed. State names must be declared in the form `states` map.',properties:{$schema:{type:"string"},uid:{$ref:"#/$defs/uid"},type:{type:"string"},size:{type:"number",description:"Column span in the form grid (1-12). Defaults to full width when omitted.",minimum:1,maximum:12},include:{$ref:"#/$defs/include"},exclude:{$ref:"#/$defs/exclude"}},required:["type"]}},r={$schema:t,$id:i,$comment:s,title:n,$defs:a},o=r;exports.EDITOR_BUNDLE_ENTRY_FILE=e.EDITOR_BUNDLE_ENTRY_FILE;exports.EDITOR_BUNDLE_FILE=e.EDITOR_BUNDLE_FILE;exports.buildEditorBundle=e.buildEditorBundle;exports.buildFormEnvelope=e.buildFormEnvelope;exports.buildLayoutWidgetSchema=e.buildLayoutWidgetSchema;exports.buildSchemasPackageIndex=e.buildSchemasPackageIndex;exports.buildWidgetsSchema=e.buildWidgetsSchema;exports.commonSchema=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./editor-bundle-yoVhdYIT.cjs"),t="https://json-schema.org/draft/2020-12/schema",i="https://golemui.com/schemas/core/common.schema.json",s="Owned by @golemui/schemas (libs/schemas/src/lib/core/). Implementation trees contain a generated vendored copy, identical apart from an `$id` rebased onto the implementation's own tree. Edit the source file, then run `npm run generate:schemas`.",a="Golem Common Definitions",r={reactiveExpression:{type:"string",description:"A reactive expression string. Use `$form` to access form data e.g. `$form.termsAccepted === true`"},dotPath:{type:"string",description:"A dot-separated path to a property in the form data"},uid:{type:"string",description:"Unique identifier for the widget"},chunkRef:{type:"object",description:"A reference to an external chunk file whose widget array will be inlined at this position in the form",properties:{$ref:{type:"string",description:"Relative path to a JSON chunk file"}},required:["$ref"],additionalProperties:!1},localizable:{description:"A value that can be a plain string or an i18n key object. Use a plain string for static text, or `{key, default, params}` to reference a translation key.",oneOf:[{type:"string"},{type:"object",properties:{key:{type:"string",description:"The i18n translation key"},default:{type:"string",description:"Fallback text shown when the translation key is not found"},params:{type:"object",description:"Interpolation parameters passed to the translation function"}},required:["key"],additionalProperties:!1}]},include:{description:"Show this widget only in certain form states (`{in: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is always shown.",oneOf:[{type:"object",properties:{in:{type:"array",items:{type:"string"},description:"List of state names (defined in the form `states` map) in which this widget should be visible"}},required:["in"],additionalProperties:!1},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},exclude:{description:"Hide this widget in certain form states (`{from: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is never hidden.",oneOf:[{type:"object",properties:{from:{type:"array",items:{type:"string"},description:"List of state names (defined in the form `states` map) in which this widget should be hidden"}},required:["from"],additionalProperties:!1},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},boolOrWhen:{description:"A static boolean or a conditional `{when: reactiveExpression}` object evaluated at runtime. Use `{when: '$form.someField === true'}` for dynamic behavior.",oneOf:[{type:"boolean"},{type:"object",properties:{when:{$ref:"#/$defs/reactiveExpression"}},required:["when"],additionalProperties:!1}]},on:{type:"object",description:'Event handlers for this widget. Values are action names dispatched to the form\'s event bus. Each key also accepts a state-suffixed variant (`"click.<stateName>"`) that overrides the base handler when the named state is active.',properties:{load:{type:"string",description:"Action dispatched when the widget is first mounted"},click:{type:"string",description:"Action dispatched when the user clicks the widget"},change:{type:"string",description:"Action dispatched when the widget value changes"},filter:{type:"string",description:"Action dispatched on search/filter input, typically used with async data sources"},blur:{type:"string",description:"Action dispatched when the widget loses focus"}},patternProperties:{"^load\\.[^.]+$":{type:"string",description:'State-suffixed load handler: used instead of `load` when the named state is active (e.g. `"load.myState"`)'},"^click\\.[^.]+$":{type:"string",description:'State-suffixed click handler: used instead of `click` when the named state is active (e.g. `"click.myState"`)'},"^change\\.[^.]+$":{type:"string",description:'State-suffixed change handler: used instead of `change` when the named state is active (e.g. `"change.myState"`)'},"^filter\\.[^.]+$":{type:"string",description:'State-suffixed filter handler: used instead of `filter` when the named state is active (e.g. `"filter.myState"`)'},"^blur\\.[^.]+$":{type:"string",description:'State-suffixed blur handler: used instead of `blur` when the named state is active (e.g. `"blur.myState"`)'}},additionalProperties:!1},baseWidget:{type:"object",description:'Base properties shared by all widgets. Root-level props that support state-suffixing (e.g. `"label.myState"`) are: `label`, `disabled`, `readonly`, `validator`, `size`. Any key inside `props` can also be suffixed. State names must be declared in the form `states` map.',properties:{$schema:{type:"string"},uid:{$ref:"#/$defs/uid"},type:{type:"string"},size:{type:"number",description:"Relative width of the widget inside its layout, from 1 to 12, where 12 is the full width. Defaults to full width when omitted. gui maps it to a 12-column grid, other widget sets may map it to a flex ratio.",minimum:1,maximum:12},include:{$ref:"#/$defs/include"},exclude:{$ref:"#/$defs/exclude"}},required:["type"]}},n={$schema:t,$id:i,$comment:s,title:a,$defs:r},o=n;exports.EDITOR_BUNDLE_ENTRY_FILE=e.EDITOR_BUNDLE_ENTRY_FILE;exports.EDITOR_BUNDLE_FILE=e.EDITOR_BUNDLE_FILE;exports.buildEditorBundle=e.buildEditorBundle;exports.buildFormEnvelope=e.buildFormEnvelope;exports.buildLayoutWidgetSchema=e.buildLayoutWidgetSchema;exports.buildSchemasPackageIndex=e.buildSchemasPackageIndex;exports.buildWidgetsSchema=e.buildWidgetsSchema;exports.commonSchema=o;
package/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { f as c, E as p, d as l, a as h, c as f, e as m, b as u } from "./editor-bundle-Jb3IVFC3.js";
2
- const e = "https://json-schema.org/draft/2020-12/schema", t = "https://golemui.com/schemas/core/common.schema.json", i = "Owned by @golemui/schemas (libs/schemas/src/lib/core/). Implementation trees contain a generated vendored copy, identical apart from an `$id` rebased onto the implementation's own tree. Edit the source file, then run `npm run generate:schemas`.", s = "Golem Common Definitions", a = { reactiveExpression: { type: "string", description: "A reactive expression string. Use `$form` to access form data e.g. `$form.termsAccepted === true`" }, dotPath: { type: "string", description: "A dot-separated path to a property in the form data" }, uid: { type: "string", description: "Unique identifier for the widget" }, chunkRef: { type: "object", description: "A reference to an external chunk file whose widget array will be inlined at this position in the form", properties: { $ref: { type: "string", description: "Relative path to a JSON chunk file" } }, required: ["$ref"], additionalProperties: !1 }, localizable: { description: "A value that can be a plain string or an i18n key object. Use a plain string for static text, or `{key, default, params}` to reference a translation key.", oneOf: [{ type: "string" }, { type: "object", properties: { key: { type: "string", description: "The i18n translation key" }, default: { type: "string", description: "Fallback text shown when the translation key is not found" }, params: { type: "object", description: "Interpolation parameters passed to the translation function" } }, required: ["key"], additionalProperties: !1 }] }, include: { description: "Show this widget only in certain form states (`{in: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is always shown.", oneOf: [{ type: "object", properties: { in: { type: "array", items: { type: "string" }, description: "List of state names (defined in the form `states` map) in which this widget should be visible" } }, required: ["in"], additionalProperties: !1 }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, exclude: { description: "Hide this widget in certain form states (`{from: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is never hidden.", oneOf: [{ type: "object", properties: { from: { type: "array", items: { type: "string" }, description: "List of state names (defined in the form `states` map) in which this widget should be hidden" } }, required: ["from"], additionalProperties: !1 }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, boolOrWhen: { description: "A static boolean or a conditional `{when: reactiveExpression}` object evaluated at runtime. Use `{when: '$form.someField === true'}` for dynamic behavior.", oneOf: [{ type: "boolean" }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, on: { type: "object", description: 'Event handlers for this widget. Values are action names dispatched to the form\'s event bus. Each key also accepts a state-suffixed variant (`"click.<stateName>"`) that overrides the base handler when the named state is active.', properties: { load: { type: "string", description: "Action dispatched when the widget is first mounted" }, click: { type: "string", description: "Action dispatched when the user clicks the widget" }, change: { type: "string", description: "Action dispatched when the widget value changes" }, filter: { type: "string", description: "Action dispatched on search/filter input, typically used with async data sources" }, blur: { type: "string", description: "Action dispatched when the widget loses focus" } }, patternProperties: { "^load\\.[^.]+$": { type: "string", description: 'State-suffixed load handler: used instead of `load` when the named state is active (e.g. `"load.myState"`)' }, "^click\\.[^.]+$": { type: "string", description: 'State-suffixed click handler: used instead of `click` when the named state is active (e.g. `"click.myState"`)' }, "^change\\.[^.]+$": { type: "string", description: 'State-suffixed change handler: used instead of `change` when the named state is active (e.g. `"change.myState"`)' }, "^filter\\.[^.]+$": { type: "string", description: 'State-suffixed filter handler: used instead of `filter` when the named state is active (e.g. `"filter.myState"`)' }, "^blur\\.[^.]+$": { type: "string", description: 'State-suffixed blur handler: used instead of `blur` when the named state is active (e.g. `"blur.myState"`)' } }, additionalProperties: !1 }, baseWidget: { type: "object", description: 'Base properties shared by all widgets. Root-level props that support state-suffixing (e.g. `"label.myState"`) are: `label`, `disabled`, `readonly`, `validator`, `size`. Any key inside `props` can also be suffixed. State names must be declared in the form `states` map.', properties: { $schema: { type: "string" }, uid: { $ref: "#/$defs/uid" }, type: { type: "string" }, size: { type: "number", description: "Column span in the form grid (1-12). Defaults to full width when omitted.", minimum: 1, maximum: 12 }, include: { $ref: "#/$defs/include" }, exclude: { $ref: "#/$defs/exclude" } }, required: ["type"] } }, n = {
2
+ const e = "https://json-schema.org/draft/2020-12/schema", t = "https://golemui.com/schemas/core/common.schema.json", i = "Owned by @golemui/schemas (libs/schemas/src/lib/core/). Implementation trees contain a generated vendored copy, identical apart from an `$id` rebased onto the implementation's own tree. Edit the source file, then run `npm run generate:schemas`.", s = "Golem Common Definitions", a = { reactiveExpression: { type: "string", description: "A reactive expression string. Use `$form` to access form data e.g. `$form.termsAccepted === true`" }, dotPath: { type: "string", description: "A dot-separated path to a property in the form data" }, uid: { type: "string", description: "Unique identifier for the widget" }, chunkRef: { type: "object", description: "A reference to an external chunk file whose widget array will be inlined at this position in the form", properties: { $ref: { type: "string", description: "Relative path to a JSON chunk file" } }, required: ["$ref"], additionalProperties: !1 }, localizable: { description: "A value that can be a plain string or an i18n key object. Use a plain string for static text, or `{key, default, params}` to reference a translation key.", oneOf: [{ type: "string" }, { type: "object", properties: { key: { type: "string", description: "The i18n translation key" }, default: { type: "string", description: "Fallback text shown when the translation key is not found" }, params: { type: "object", description: "Interpolation parameters passed to the translation function" } }, required: ["key"], additionalProperties: !1 }] }, include: { description: "Show this widget only in certain form states (`{in: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is always shown.", oneOf: [{ type: "object", properties: { in: { type: "array", items: { type: "string" }, description: "List of state names (defined in the form `states` map) in which this widget should be visible" } }, required: ["in"], additionalProperties: !1 }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, exclude: { description: "Hide this widget in certain form states (`{from: [stateNames]}`) or when a reactive expression is true (`{when: expr}`). If omitted the widget is never hidden.", oneOf: [{ type: "object", properties: { from: { type: "array", items: { type: "string" }, description: "List of state names (defined in the form `states` map) in which this widget should be hidden" } }, required: ["from"], additionalProperties: !1 }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, boolOrWhen: { description: "A static boolean or a conditional `{when: reactiveExpression}` object evaluated at runtime. Use `{when: '$form.someField === true'}` for dynamic behavior.", oneOf: [{ type: "boolean" }, { type: "object", properties: { when: { $ref: "#/$defs/reactiveExpression" } }, required: ["when"], additionalProperties: !1 }] }, on: { type: "object", description: 'Event handlers for this widget. Values are action names dispatched to the form\'s event bus. Each key also accepts a state-suffixed variant (`"click.<stateName>"`) that overrides the base handler when the named state is active.', properties: { load: { type: "string", description: "Action dispatched when the widget is first mounted" }, click: { type: "string", description: "Action dispatched when the user clicks the widget" }, change: { type: "string", description: "Action dispatched when the widget value changes" }, filter: { type: "string", description: "Action dispatched on search/filter input, typically used with async data sources" }, blur: { type: "string", description: "Action dispatched when the widget loses focus" } }, patternProperties: { "^load\\.[^.]+$": { type: "string", description: 'State-suffixed load handler: used instead of `load` when the named state is active (e.g. `"load.myState"`)' }, "^click\\.[^.]+$": { type: "string", description: 'State-suffixed click handler: used instead of `click` when the named state is active (e.g. `"click.myState"`)' }, "^change\\.[^.]+$": { type: "string", description: 'State-suffixed change handler: used instead of `change` when the named state is active (e.g. `"change.myState"`)' }, "^filter\\.[^.]+$": { type: "string", description: 'State-suffixed filter handler: used instead of `filter` when the named state is active (e.g. `"filter.myState"`)' }, "^blur\\.[^.]+$": { type: "string", description: 'State-suffixed blur handler: used instead of `blur` when the named state is active (e.g. `"blur.myState"`)' } }, additionalProperties: !1 }, baseWidget: { type: "object", description: 'Base properties shared by all widgets. Root-level props that support state-suffixing (e.g. `"label.myState"`) are: `label`, `disabled`, `readonly`, `validator`, `size`. Any key inside `props` can also be suffixed. State names must be declared in the form `states` map.', properties: { $schema: { type: "string" }, uid: { $ref: "#/$defs/uid" }, type: { type: "string" }, size: { type: "number", description: "Relative width of the widget inside its layout, from 1 to 12, where 12 is the full width. Defaults to full width when omitted. gui maps it to a 12-column grid, other widget sets may map it to a flex ratio.", minimum: 1, maximum: 12 }, include: { $ref: "#/$defs/include" }, exclude: { $ref: "#/$defs/exclude" } }, required: ["type"] } }, r = {
3
3
  $schema: e,
4
4
  $id: t,
5
5
  $comment: i,
6
6
  title: s,
7
7
  $defs: a
8
- }, r = n;
8
+ }, n = r;
9
9
  export {
10
10
  c as EDITOR_BUNDLE_ENTRY_FILE,
11
11
  p as EDITOR_BUNDLE_FILE,
@@ -14,5 +14,5 @@ export {
14
14
  f as buildLayoutWidgetSchema,
15
15
  m as buildSchemasPackageIndex,
16
16
  u as buildWidgetsSchema,
17
- r as commonSchema
17
+ n as commonSchema
18
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golemui/schemas",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -192,7 +192,7 @@
192
192
  },
193
193
  "size": {
194
194
  "type": "number",
195
- "description": "Column span in the form grid (1-12). Defaults to full width when omitted.",
195
+ "description": "Relative width of the widget inside its layout, from 1 to 12, where 12 is the full width. Defaults to full width when omitted. gui maps it to a 12-column grid, other widget sets may map it to a flex ratio.",
196
196
  "minimum": 1,
197
197
  "maximum": 12
198
198
  },