@golemui/schemas 1.4.0 → 1.5.0-rc.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 +4 -0
- package/cli.cjs +8 -8
- package/cli.js +75 -75
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
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"),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":
|
|
2
|
+
"use strict";const p=require("node:fs"),s=require("node:path"),b=require("node:readline/promises"),w=require("node:url"),v=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"}},z=[{$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}},M={"^label\\.[^.]+$":{$ref:"#/$defs/labelDef"},"^disabled\\.[^.]+$":{$ref:"#/$defs/disabledDef"},"^readonly\\.[^.]+$":{$ref:"#/$defs/readonlyDef"},"^validator\\.[^.]+$":{$ref:"../validators.schema.json#/$defs/validator"}},O=["kind","type","path"],k=!1,L={$schema:P,$id:T,$comment:E,title:_,type:I,$defs:q,allOf:z,properties:A,patternProperties:M,required:O,unevaluatedProperties:k},N="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.",V="__IMPLEMENTATION__ flex widget",U="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"}},D=[{$ref:"../core/common.schema.json#/$defs/baseWidget"}],F={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}},B=["kind","type","children"],J=!1,Y={$schema:N,$id:R,$comment:C,title:V,type:U,$defs:W,allOf:D,properties:F,required:B,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},fileValidator:{type:"object",description:"Validates the file envelope stored by the `fileUpload` widget (`{ id, name, size, type, status, error?, data? }` or `null`).",properties:{type:{const:"file"},required:{type:"boolean",description:"Makes the field mandatory - validation fails if no file is set"},blockPendingUploads:{type:"boolean",description:"When true (the default), validation fails while the file's status is `uploading` or `error`, so an unfinished upload cannot be submitted"},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 is not a file envelope"},required:{$ref:"#/$defs/localizable",description:"Shown when a required field has no file"},pendingUploads:{$ref:"#/$defs/localizable",description:"Shown while the file is still uploading or failed to upload"}},additionalProperties:!1}},required:["type"],additionalProperties:!1},filesValidator:{type:"object",description:"Validates the array of file envelopes stored by the `multiFileUpload` widget.",properties:{type:{const:"files"},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 files"},maxItems:{type:"number",description:"The array must contain no more than this many files"},blockPendingUploads:{type:"boolean",description:"When true (the default), validation fails while any file's status is `uploading` or `error`, so an unfinished upload cannot be submitted"},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 is not an array of file envelopes"},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 files than `minItems`"},maxItems:{$ref:"#/$defs/localizable",description:"Shown when the array has more files than `maxItems`"},pendingUploads:{$ref:"#/$defs/localizable",description:"Shown while any file is still uploading or failed to upload"}},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`, `file`, `files`, or `custom`.",oneOf:[{$ref:"#/$defs/stringValidator"},{$ref:"#/$defs/numberValidator"},{$ref:"#/$defs/booleanValidator"},{$ref:"#/$defs/arrayValidator"},{$ref:"#/$defs/fileValidator"},{$ref:"#/$defs/filesValidator"},{$ref:"#/$defs/customValidator"}]}},X={$schema:G,$id:H,$comment:K,title:Z,$defs:Q};function y(e){return`${e}-input`}function ee(e,t){const i=e.replace(/__IMPLEMENTATION__/g,t.implementation).replace(/__ID_BASE__/g,t.idBase),a=i.match(/__[A-Z_]+__/);if(a!==null)throw new Error(`Unsubstituted placeholder ${a[0]} in a starter template.`);return i}function c(e,t){return ee(JSON.stringify(e,null,2),t)+`
|
|
3
|
+
`}function te(e){return{"schemas.config.mjs":ie(e),"src/lib/validators.schema.json":c(X,e),"src/lib/components/flex.schema.json":c(Y,e),"src/lib/components/example-input.schema.json":c(L,e),"examples/example.form.json":c(S,e),"test/schemas.spec.ts":ae(e)}}function ie(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: '${
|
|
27
|
+
type: '${y(e.implementation)}',
|
|
28
28
|
schemaFile: 'example-input.schema.json',
|
|
29
29
|
kind: 'input',
|
|
30
30
|
},
|
|
@@ -118,19 +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
|
|
122
|
-
Scaffolded the ${t} schema tree in ${
|
|
121
|
+
Both commands accept --help.`;function re(e){const t=new Map;let i;for(let a=0;a<e.length;a+=1){const r=e[a];if(!r.startsWith("--")){i??=r;continue}const o=r.slice(2),n=o.indexOf("=");if(n!==-1){t.set(o.slice(0,n),o.slice(n+1));continue}const d=e[a+1];d===void 0||d.startsWith("--")?t.set(o,!0):(t.set(o,d),a+=1)}return{command:i,flags:t}}function m(e,t){const i=e.get(t);return typeof i=="string"?i:void 0}async function f(e,t,i){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 r=(await a.question(`${e} [${i}] `)).trim();return r===""?i:r}finally{a.close()}}function oe(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 se(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,i){const a=s.join(e,t);p.mkdirSync(s.dirname(a),{recursive:!0}),p.writeFileSync(a,i,"utf-8"),console.log(`Wrote ${t}`)}async function le(e){const t=m(e,"name")??await f("Implementation name?","name","my-widgets");oe(t);const i=se(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"),r=s.resolve(process.cwd(),a),o=te({implementation:t,idBase:i}),n=Object.keys(o).filter(h=>p.existsSync(s.join(r,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(o))ne(r,h,g);await $(r);const d=s.relative(process.cwd(),r)||".";console.log(`
|
|
122
|
+
Scaffolded the ${t} schema tree in ${d}.
|
|
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 ${
|
|
128
|
+
examples/example.form.json uses the starter type ${y(t)}, so
|
|
129
129
|
replace it together with the manifest or test/schemas.spec.ts fails.
|
|
130
130
|
3. Rerun \`npx @golemui/schemas generate\` after every edit to a component schema, to
|
|
131
131
|
${l} or to validators.schema.json. A CI step that regenerates and then runs
|
|
132
132
|
\`git diff --exit-code\` catches a forgotten rerun.
|
|
133
133
|
4. Point a form file's "$schema" at src/lib/form.editor.schema.json, as
|
|
134
|
-
examples/example.form.json does. Editors need that bundle, Ajv uses the per-file tree.`)}function
|
|
134
|
+
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 i=e,r=["implementation","idBase","generatorPath","formTitle"].filter(o=>typeof i[o]!="string");if(r.length>0)throw new Error(`${t} is missing required string fields: ${r.join(", ")}.`);if(!Array.isArray(i.manifest)||i.manifest.length===0)throw new Error(`${t} must declare a non-empty \`manifest\` array.`);if(!i.idBase.endsWith("/"))throw new Error(`${t}: \`idBase\` must end with a slash.`);return e}async function $(e){const t=s.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 i=await import(w.pathToFileURL(t).href),a=de(i.default,l);await v.generateImplementationSchemas(a,e)}async function ce(e){const{command:t,flags:i}=re(e);if(i.get("help")===!0||t==="help"||t===void 0)return console.log(u),t===void 0&&i.get("help")!==!0?1:0;try{switch(t){case"init":return await le(i),0;case"generate":return await $(s.resolve(process.cwd(),m(i,"dir")??".")),0;default:return console.error(`Unknown command "${t}".
|
|
135
135
|
|
|
136
|
-
${u}`),1}}catch(a){return console.error(a instanceof Error?a.message:a),1}}
|
|
136
|
+
${u}`),1}}catch(a){return console.error(a instanceof Error?a.message:a),1}}ce(process.argv.slice(2)).then(e=>{process.exitCode=e});
|
package/cli.js
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync as u, mkdirSync as
|
|
3
|
-
import { resolve as
|
|
2
|
+
import { existsSync as u, mkdirSync as w, writeFileSync as v } from "node:fs";
|
|
3
|
+
import { resolve as y, join as h, relative as x, dirname as j } from "node:path";
|
|
4
4
|
import { createInterface as S } from "node:readline/promises";
|
|
5
5
|
import { pathToFileURL as P } from "node:url";
|
|
6
6
|
import { g as T } from "./generate-implementation-schemas-DxCUi0Jr.js";
|
|
7
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
8
|
$schema: E,
|
|
9
9
|
form: _
|
|
10
|
-
},
|
|
11
|
-
$schema:
|
|
12
|
-
$id:
|
|
13
|
-
$comment:
|
|
10
|
+
}, q = "https://json-schema.org/draft/2020-12/schema", z = "__ID_BASE__components/example-input.schema.json", A = "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", O = "object", k = { 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" } }, L = [{ $ref: "../core/common.schema.json#/$defs/baseWidget" }], N = { 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"], V = !1, U = {
|
|
11
|
+
$schema: q,
|
|
12
|
+
$id: z,
|
|
13
|
+
$comment: A,
|
|
14
14
|
title: M,
|
|
15
|
-
type:
|
|
16
|
-
$defs:
|
|
17
|
-
allOf:
|
|
18
|
-
properties:
|
|
15
|
+
type: O,
|
|
16
|
+
$defs: k,
|
|
17
|
+
allOf: L,
|
|
18
|
+
properties: N,
|
|
19
19
|
patternProperties: R,
|
|
20
20
|
required: C,
|
|
21
|
-
unevaluatedProperties:
|
|
22
|
-
},
|
|
23
|
-
$schema:
|
|
24
|
-
$id:
|
|
25
|
-
$comment:
|
|
26
|
-
title:
|
|
21
|
+
unevaluatedProperties: V
|
|
22
|
+
}, W = "https://json-schema.org/draft/2020-12/schema", D = "__ID_BASE__components/flex.schema.json", F = "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.", B = "__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: W,
|
|
24
|
+
$id: D,
|
|
25
|
+
$comment: F,
|
|
26
|
+
title: B,
|
|
27
27
|
type: J,
|
|
28
28
|
$defs: Y,
|
|
29
29
|
allOf: G,
|
|
30
30
|
properties: H,
|
|
31
31
|
required: K,
|
|
32
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.",
|
|
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.", ae = "__IMPLEMENTATION__ validator definitions", ie = { 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 }, fileValidator: { type: "object", description: "Validates the file envelope stored by the `fileUpload` widget (`{ id, name, size, type, status, error?, data? }` or `null`).", properties: { type: { const: "file" }, required: { type: "boolean", description: "Makes the field mandatory - validation fails if no file is set" }, blockPendingUploads: { type: "boolean", description: "When true (the default), validation fails while the file's status is `uploading` or `error`, so an unfinished upload cannot be submitted" }, 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 is not a file envelope" }, required: { $ref: "#/$defs/localizable", description: "Shown when a required field has no file" }, pendingUploads: { $ref: "#/$defs/localizable", description: "Shown while the file is still uploading or failed to upload" } }, additionalProperties: !1 } }, required: ["type"], additionalProperties: !1 }, filesValidator: { type: "object", description: "Validates the array of file envelopes stored by the `multiFileUpload` widget.", properties: { type: { const: "files" }, 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 files" }, maxItems: { type: "number", description: "The array must contain no more than this many files" }, blockPendingUploads: { type: "boolean", description: "When true (the default), validation fails while any file's status is `uploading` or `error`, so an unfinished upload cannot be submitted" }, 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 is not an array of file envelopes" }, 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 files than `minItems`" }, maxItems: { $ref: "#/$defs/localizable", description: "Shown when the array has more files than `maxItems`" }, pendingUploads: { $ref: "#/$defs/localizable", description: "Shown while any file is still uploading or failed to upload" } }, 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`, `file`, `files`, or `custom`.", oneOf: [{ $ref: "#/$defs/stringValidator" }, { $ref: "#/$defs/numberValidator" }, { $ref: "#/$defs/booleanValidator" }, { $ref: "#/$defs/arrayValidator" }, { $ref: "#/$defs/fileValidator" }, { $ref: "#/$defs/filesValidator" }, { $ref: "#/$defs/customValidator" }] } }, re = {
|
|
34
34
|
$schema: X,
|
|
35
35
|
$id: ee,
|
|
36
36
|
$comment: te,
|
|
37
|
-
title:
|
|
38
|
-
$defs:
|
|
37
|
+
title: ae,
|
|
38
|
+
$defs: ie
|
|
39
39
|
};
|
|
40
|
-
function
|
|
40
|
+
function $(e) {
|
|
41
41
|
return `${e}-input`;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
throw new Error(`Unsubstituted placeholder ${
|
|
47
|
-
return
|
|
43
|
+
function oe(e, t) {
|
|
44
|
+
const a = e.replace(/__IMPLEMENTATION__/g, t.implementation).replace(/__ID_BASE__/g, t.idBase), i = a.match(/__[A-Z_]+__/);
|
|
45
|
+
if (i !== null)
|
|
46
|
+
throw new Error(`Unsubstituted placeholder ${i[0]} in a starter template.`);
|
|
47
|
+
return a;
|
|
48
48
|
}
|
|
49
49
|
function d(e, t) {
|
|
50
|
-
return
|
|
50
|
+
return oe(JSON.stringify(e, null, 2), t) + `
|
|
51
51
|
`;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function se(e) {
|
|
54
54
|
return {
|
|
55
55
|
"schemas.config.mjs": ne(e),
|
|
56
|
-
"src/lib/validators.schema.json": d(
|
|
56
|
+
"src/lib/validators.schema.json": d(re, e),
|
|
57
57
|
"src/lib/components/flex.schema.json": d(Q, e),
|
|
58
58
|
"src/lib/components/example-input.schema.json": d(
|
|
59
|
-
|
|
59
|
+
U,
|
|
60
60
|
e
|
|
61
61
|
),
|
|
62
62
|
"examples/example.form.json": d(I, e),
|
|
@@ -88,7 +88,7 @@ export default {
|
|
|
88
88
|
manifest: [
|
|
89
89
|
{ type: 'flex', schemaFile: 'flex.schema.json', kind: 'layout' },
|
|
90
90
|
{
|
|
91
|
-
type: '${
|
|
91
|
+
type: '${$(e.implementation)}',
|
|
92
92
|
schemaFile: 'example-input.schema.json',
|
|
93
93
|
kind: 'input',
|
|
94
94
|
},
|
|
@@ -190,36 +190,36 @@ Options for generate:
|
|
|
190
190
|
Both commands accept --help.`;
|
|
191
191
|
function de(e) {
|
|
192
192
|
const t = /* @__PURE__ */ new Map();
|
|
193
|
-
let
|
|
194
|
-
for (let
|
|
195
|
-
const
|
|
196
|
-
if (!
|
|
197
|
-
|
|
193
|
+
let a;
|
|
194
|
+
for (let i = 0; i < e.length; i += 1) {
|
|
195
|
+
const r = e[i];
|
|
196
|
+
if (!r.startsWith("--")) {
|
|
197
|
+
a ??= r;
|
|
198
198
|
continue;
|
|
199
199
|
}
|
|
200
|
-
const
|
|
201
|
-
if (
|
|
202
|
-
t.set(
|
|
200
|
+
const o = r.slice(2), s = o.indexOf("=");
|
|
201
|
+
if (s !== -1) {
|
|
202
|
+
t.set(o.slice(0, s), o.slice(s + 1));
|
|
203
203
|
continue;
|
|
204
204
|
}
|
|
205
|
-
const l = e[
|
|
206
|
-
l === void 0 || l.startsWith("--") ? t.set(
|
|
205
|
+
const l = e[i + 1];
|
|
206
|
+
l === void 0 || l.startsWith("--") ? t.set(o, !0) : (t.set(o, l), i += 1);
|
|
207
207
|
}
|
|
208
|
-
return { command:
|
|
208
|
+
return { command: a, flags: t };
|
|
209
209
|
}
|
|
210
210
|
function c(e, t) {
|
|
211
|
-
const
|
|
212
|
-
return typeof
|
|
211
|
+
const a = e.get(t);
|
|
212
|
+
return typeof a == "string" ? a : void 0;
|
|
213
213
|
}
|
|
214
|
-
async function p(e, t,
|
|
214
|
+
async function p(e, t, a) {
|
|
215
215
|
if (process.stdin.isTTY !== !0)
|
|
216
216
|
throw new Error(`Missing --${t}. There is no terminal to ask on.`);
|
|
217
|
-
const
|
|
217
|
+
const i = S({ input: process.stdin, output: process.stdout });
|
|
218
218
|
try {
|
|
219
|
-
const
|
|
220
|
-
return
|
|
219
|
+
const r = (await i.question(`${e} [${a}] `)).trim();
|
|
220
|
+
return r === "" ? a : r;
|
|
221
221
|
} finally {
|
|
222
|
-
|
|
222
|
+
i.close();
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
function ce(e) {
|
|
@@ -239,28 +239,28 @@ function me(e) {
|
|
|
239
239
|
throw new Error(`Invalid --id-base "${e}". It must be an http or https URL.`);
|
|
240
240
|
return e.endsWith("/") ? e : `${e}/`;
|
|
241
241
|
}
|
|
242
|
-
function pe(e, t,
|
|
243
|
-
const
|
|
244
|
-
|
|
242
|
+
function pe(e, t, a) {
|
|
243
|
+
const i = h(e, t);
|
|
244
|
+
w(j(i), { recursive: !0 }), v(i, a, "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");
|
|
248
248
|
ce(t);
|
|
249
|
-
const
|
|
249
|
+
const a = me(
|
|
250
250
|
c(e, "id-base") ?? await p(
|
|
251
251
|
"Base URL of the published tree?",
|
|
252
252
|
"id-base",
|
|
253
253
|
`https://example.com/schemas/${t}/`
|
|
254
254
|
)
|
|
255
|
-
),
|
|
256
|
-
if (
|
|
255
|
+
), i = c(e, "dir") ?? await p("Directory?", "dir", "schemas"), r = y(process.cwd(), i), o = se({ implementation: t, idBase: a }), s = Object.keys(o).filter((m) => u(h(r, m)));
|
|
256
|
+
if (s.length > 0 && e.get("force") !== !0)
|
|
257
257
|
throw new Error(
|
|
258
|
-
`Refusing to overwrite starter files you may have edited: ${
|
|
258
|
+
`Refusing to overwrite starter files you may have edited: ${s.join(", ")}. Pass --force to replace them.`
|
|
259
259
|
);
|
|
260
|
-
for (const [m, b] of Object.entries(
|
|
261
|
-
pe(
|
|
262
|
-
await g(
|
|
263
|
-
const l = x(process.cwd(),
|
|
260
|
+
for (const [m, b] of Object.entries(o))
|
|
261
|
+
pe(r, m, b);
|
|
262
|
+
await g(r);
|
|
263
|
+
const l = x(process.cwd(), r) || ".";
|
|
264
264
|
console.log(`
|
|
265
265
|
Scaffolded the ${t} schema tree in ${l}.
|
|
266
266
|
|
|
@@ -268,7 +268,7 @@ 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 ${
|
|
271
|
+
examples/example.form.json uses the starter type ${$(t)}, so
|
|
272
272
|
replace it together with the manifest or test/schemas.spec.ts fails.
|
|
273
273
|
3. Rerun \`npx @golemui/schemas generate\` after every edit to a component schema, to
|
|
274
274
|
${n} or to validators.schema.json. A CI step that regenerates and then runs
|
|
@@ -279,12 +279,12 @@ Next:
|
|
|
279
279
|
function fe(e, t) {
|
|
280
280
|
if (e === null || typeof e != "object")
|
|
281
281
|
throw new Error(`${t} must export a configuration object as its default export.`);
|
|
282
|
-
const
|
|
283
|
-
if (
|
|
284
|
-
throw new Error(`${t} is missing required string fields: ${
|
|
285
|
-
if (!Array.isArray(
|
|
282
|
+
const a = e, r = ["implementation", "idBase", "generatorPath", "formTitle"].filter((o) => typeof a[o] != "string");
|
|
283
|
+
if (r.length > 0)
|
|
284
|
+
throw new Error(`${t} is missing required string fields: ${r.join(", ")}.`);
|
|
285
|
+
if (!Array.isArray(a.manifest) || a.manifest.length === 0)
|
|
286
286
|
throw new Error(`${t} must declare a non-empty \`manifest\` array.`);
|
|
287
|
-
if (!
|
|
287
|
+
if (!a.idBase.endsWith("/"))
|
|
288
288
|
throw new Error(`${t}: \`idBase\` must end with a slash.`);
|
|
289
289
|
return e;
|
|
290
290
|
}
|
|
@@ -294,29 +294,29 @@ async function g(e) {
|
|
|
294
294
|
throw new Error(
|
|
295
295
|
`No ${n} in ${e}. Run this from the directory holding it, pass --dir, or scaffold a new tree with \`npx @golemui/schemas init\`.`
|
|
296
296
|
);
|
|
297
|
-
const
|
|
297
|
+
const a = await import(
|
|
298
298
|
/* @vite-ignore */
|
|
299
299
|
P(t).href
|
|
300
|
-
),
|
|
301
|
-
await T(
|
|
300
|
+
), i = fe(a.default, n);
|
|
301
|
+
await T(i, e);
|
|
302
302
|
}
|
|
303
303
|
async function ue(e) {
|
|
304
|
-
const { command: t, flags:
|
|
305
|
-
if (
|
|
306
|
-
return console.log(f), t === void 0 &&
|
|
304
|
+
const { command: t, flags: a } = de(e);
|
|
305
|
+
if (a.get("help") === !0 || t === "help" || t === void 0)
|
|
306
|
+
return console.log(f), t === void 0 && a.get("help") !== !0 ? 1 : 0;
|
|
307
307
|
try {
|
|
308
308
|
switch (t) {
|
|
309
309
|
case "init":
|
|
310
|
-
return await he(
|
|
310
|
+
return await he(a), 0;
|
|
311
311
|
case "generate":
|
|
312
|
-
return await g(
|
|
312
|
+
return await g(y(process.cwd(), c(a, "dir") ?? ".")), 0;
|
|
313
313
|
default:
|
|
314
314
|
return console.error(`Unknown command "${t}".
|
|
315
315
|
|
|
316
316
|
${f}`), 1;
|
|
317
317
|
}
|
|
318
|
-
} catch (
|
|
319
|
-
return console.error(
|
|
318
|
+
} catch (i) {
|
|
319
|
+
return console.error(i instanceof Error ? i.message : i), 1;
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
ue(process.argv.slice(2)).then((e) => {
|