formspec 0.1.0-alpha.27 → 0.1.0-alpha.29

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mike North
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/README.md CHANGED
@@ -65,7 +65,6 @@ const resolvers = defineResolvers(OrderForm, {});
65
65
  - `generateJsonSchema`
66
66
  - `generateUiSchema`
67
67
  - `writeSchemas`
68
- - `buildMixedAuthoringSchemas`
69
68
 
70
69
  ### Runtime
71
70
 
@@ -76,14 +75,21 @@ const resolvers = defineResolvers(OrderForm, {});
76
75
  - `InferSchema`
77
76
  - `InferFormSchema`
78
77
  - core field, layout, and state types
78
+ - resolver and validation helper types
79
+
80
+ ### Utilities
81
+
82
+ - `createInitialFieldState`
83
+ - `validateForm`
84
+ - `logValidationIssues`
79
85
 
80
86
  ## When To Use Individual Packages
81
87
 
82
- - Use `@formspec/build` directly for `generateSchemas()` and static TypeScript analysis.
88
+ - Use `@formspec/build` directly for `generateSchemas()`, `generateSchemasFromClass()`, `generateSchemasFromProgram()`, `buildMixedAuthoringSchemas()`, and static TypeScript analysis.
83
89
  - Use `@formspec/eslint-plugin` for lint rules.
84
90
  - Use `@formspec/cli` for build-time artifact generation from files.
85
91
  - Use `@formspec/validator` for runtime JSON Schema validation.
86
92
 
87
93
  ## License
88
94
 
89
- UNLICENSED
95
+ This package is part of the FormSpec monorepo and is released under the MIT License. See [LICENSE](./LICENSE) for details.
@@ -80,6 +80,10 @@ export declare interface ArrayField<N extends string, Items extends readonly For
80
80
  readonly items: Items;
81
81
  /** Display label for the field */
82
82
  readonly label?: string;
83
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
84
+ readonly displayName?: string;
85
+ /** JSON-facing serialized name for the field. */
86
+ readonly apiName?: string;
83
87
  /** Whether this field is required for form submission */
84
88
  readonly required?: boolean;
85
89
  /** Minimum number of items required */
@@ -104,6 +108,10 @@ export declare interface BooleanField<N extends string> {
104
108
  readonly name: N;
105
109
  /** Display label for the field */
106
110
  readonly label?: string;
111
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
112
+ readonly displayName?: string;
113
+ /** JSON-facing serialized name for the field. */
114
+ readonly apiName?: string;
107
115
  /** Whether this field is required for form submission */
108
116
  readonly required?: boolean;
109
117
  }
@@ -123,7 +131,8 @@ export declare function buildFormSchemas<E extends readonly FormElement[]>(form:
123
131
  *
124
132
  * @public
125
133
  */
126
- export declare type BuildFormSchemasOptions = GenerateJsonSchemaOptions;
134
+ export declare interface BuildFormSchemasOptions extends GenerateJsonSchemaOptions, GenerateUiSchemaOptions {
135
+ }
127
136
 
128
137
  /**
129
138
  * Result of building form schemas.
@@ -283,6 +292,18 @@ export declare type DataSourceValueType<Source extends string> = Source extends
283
292
  id: infer ID;
284
293
  } ? ID : string : string;
285
294
 
295
+ /**
296
+ * Per-declaration metadata policy input.
297
+ *
298
+ * @public
299
+ */
300
+ export declare interface DeclarationMetadataPolicyInput {
301
+ /** Policy for JSON-facing serialized names. */
302
+ readonly apiName?: MetadataValuePolicyInput | undefined;
303
+ /** Policy for human-facing labels and titles. */
304
+ readonly displayName?: MetadataValuePolicyInput | undefined;
305
+ }
306
+
286
307
  /**
287
308
  * Defines resolvers for a form's dynamic data sources.
288
309
  *
@@ -309,6 +330,10 @@ export declare interface DynamicEnumField<N extends string, Source extends strin
309
330
  readonly source: Source;
310
331
  /** Display label for the field */
311
332
  readonly label?: string;
333
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
334
+ readonly displayName?: string;
335
+ /** JSON-facing serialized name for the field. */
336
+ readonly apiName?: string;
312
337
  /** Whether this field is required for form submission */
313
338
  readonly required?: boolean;
314
339
  /** Field names whose values are needed to fetch options */
@@ -333,6 +358,10 @@ export declare interface DynamicSchemaField<N extends string> {
333
358
  readonly schemaSource: string;
334
359
  /** Display label for the field */
335
360
  readonly label?: string;
361
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
362
+ readonly displayName?: string;
363
+ /** JSON-facing serialized name for the field. */
364
+ readonly apiName?: string;
336
365
  /** Whether this field is required for form submission */
337
366
  readonly required?: boolean;
338
367
  /** Field names whose values are needed to configure the schema */
@@ -611,6 +640,8 @@ export declare interface GenerateJsonSchemaOptions {
611
640
  * @defaultValue "x-formspec"
612
641
  */
613
642
  readonly vendorPrefix?: string | undefined;
643
+ /** Metadata resolution policy for chain DSL generation. */
644
+ readonly metadata?: MetadataPolicyInput | undefined;
614
645
  }
615
646
 
616
647
  /**
@@ -618,7 +649,17 @@ export declare interface GenerateJsonSchemaOptions {
618
649
  *
619
650
  * @public
620
651
  */
621
- export declare function generateUiSchema<E extends readonly FormElement[]>(form: FormSpec<E>): UISchema;
652
+ export declare function generateUiSchema<E extends readonly FormElement[]>(form: FormSpec<E>, options?: GenerateUiSchemaOptions): UISchema;
653
+
654
+ /**
655
+ * Options for generating a UI Schema from a Chain DSL form.
656
+ *
657
+ * @public
658
+ */
659
+ export declare interface GenerateUiSchemaOptions {
660
+ /** Metadata resolution policy for chain DSL UI generation. */
661
+ readonly metadata?: MetadataPolicyInput | undefined;
662
+ }
622
663
 
623
664
  /**
624
665
  * A visual grouping of form elements.
@@ -887,6 +928,180 @@ export declare interface LabelElement {
887
928
  */
888
929
  export declare function logValidationIssues(result: ValidationResult, formName?: string): void;
889
930
 
931
+ /**
932
+ * Authoring surfaces that can contribute metadata.
933
+ *
934
+ * @public
935
+ */
936
+ export declare type MetadataAuthoringSurface = "tsdoc" | "chain-dsl";
937
+
938
+ /**
939
+ * Declaration categories that metadata policy can target.
940
+ *
941
+ * @public
942
+ */
943
+ export declare type MetadataDeclarationKind = "type" | "field" | "method";
944
+
945
+ /**
946
+ * Build-facing context passed to metadata inference callbacks.
947
+ *
948
+ * `buildContext` is intentionally opaque so browser/runtime packages do not
949
+ * need to depend on TypeScript compiler types.
950
+ *
951
+ * @public
952
+ */
953
+ export declare interface MetadataInferenceContext {
954
+ /** Authoring surface the metadata is being resolved for. */
955
+ readonly surface: MetadataAuthoringSurface;
956
+ /** Declaration kind currently being resolved. */
957
+ readonly declarationKind: MetadataDeclarationKind;
958
+ /** Logical identifier before any metadata policy is applied. */
959
+ readonly logicalName: string;
960
+ /** Optional build-only context supplied by the resolver. */
961
+ readonly buildContext?: unknown;
962
+ }
963
+
964
+ /**
965
+ * Callback used to infer a scalar metadata value.
966
+ *
967
+ * @public
968
+ */
969
+ export declare type MetadataInferenceFn = (context: MetadataInferenceContext) => string;
970
+
971
+ /**
972
+ * Context passed to pluralization callbacks.
973
+ *
974
+ * @public
975
+ */
976
+ export declare interface MetadataPluralizationContext extends MetadataInferenceContext {
977
+ /** Singular value that pluralization should derive from. */
978
+ readonly singular: string;
979
+ }
980
+
981
+ /**
982
+ * Pluralization disabled.
983
+ *
984
+ * @public
985
+ */
986
+ export declare interface MetadataPluralizationDisabledPolicyInput {
987
+ /** Disables automatic plural-value generation. */
988
+ readonly mode?: "disabled" | undefined;
989
+ }
990
+
991
+ /**
992
+ * Callback used to derive plural metadata from a singular value.
993
+ *
994
+ * @public
995
+ */
996
+ export declare type MetadataPluralizationFn = (context: MetadataPluralizationContext) => string;
997
+
998
+ /**
999
+ * Pluralization may be inferred when absent.
1000
+ *
1001
+ * @public
1002
+ */
1003
+ export declare interface MetadataPluralizationInferIfMissingPolicyInput {
1004
+ /** Infers plural values whenever no explicit plural is present. */
1005
+ readonly mode: "infer-if-missing";
1006
+ /** Callback that derives a plural form from the resolved singular value. */
1007
+ readonly inflect: MetadataPluralizationFn;
1008
+ }
1009
+
1010
+ /**
1011
+ * Pluralization policy input.
1012
+ *
1013
+ * @public
1014
+ */
1015
+ export declare type MetadataPluralizationPolicyInput = MetadataPluralizationDisabledPolicyInput | MetadataPluralizationRequireExplicitPolicyInput | MetadataPluralizationInferIfMissingPolicyInput;
1016
+
1017
+ /**
1018
+ * Pluralization must be authored explicitly.
1019
+ *
1020
+ * @public
1021
+ */
1022
+ export declare interface MetadataPluralizationRequireExplicitPolicyInput {
1023
+ /** Requires plural values to be authored directly. */
1024
+ readonly mode: "require-explicit";
1025
+ }
1026
+
1027
+ /**
1028
+ * User-facing metadata policy configuration.
1029
+ *
1030
+ * @public
1031
+ */
1032
+ export declare interface MetadataPolicyInput {
1033
+ /** Policy applied to named types and the analyzed root declaration. */
1034
+ readonly type?: DeclarationMetadataPolicyInput | undefined;
1035
+ /** Policy applied to fields and object properties. */
1036
+ readonly field?: DeclarationMetadataPolicyInput | undefined;
1037
+ /** Policy applied to callable/method declarations. */
1038
+ readonly method?: DeclarationMetadataPolicyInput | undefined;
1039
+ }
1040
+
1041
+ /**
1042
+ * Scalar metadata resolution modes.
1043
+ *
1044
+ * @public
1045
+ */
1046
+ export declare type MetadataResolutionMode = "disabled" | "require-explicit" | "infer-if-missing";
1047
+
1048
+ /**
1049
+ * Shared metadata model and policy types.
1050
+ *
1051
+ * @public
1052
+ */
1053
+ /**
1054
+ * Whether a resolved metadata value was authored directly or inferred by policy.
1055
+ *
1056
+ * @public
1057
+ */
1058
+ export declare type MetadataSource = "explicit" | "inferred";
1059
+
1060
+ /**
1061
+ * Scalar metadata disabled unless provided explicitly elsewhere.
1062
+ *
1063
+ * @public
1064
+ */
1065
+ export declare interface MetadataValueDisabledPolicyInput {
1066
+ /** Disables inference for this scalar metadata value. */
1067
+ readonly mode?: "disabled" | undefined;
1068
+ /** Optional policy controlling plural forms of this scalar value. */
1069
+ readonly pluralization?: MetadataPluralizationPolicyInput | undefined;
1070
+ }
1071
+
1072
+ /**
1073
+ * Scalar metadata may be inferred when missing.
1074
+ *
1075
+ * @public
1076
+ */
1077
+ export declare interface MetadataValueInferIfMissingPolicyInput {
1078
+ /** Infers this scalar metadata value when it is not authored explicitly. */
1079
+ readonly mode: "infer-if-missing";
1080
+ /** Callback used to infer the missing singular value. */
1081
+ readonly infer: MetadataInferenceFn;
1082
+ /** Optional policy controlling plural forms of this scalar value. */
1083
+ readonly pluralization?: MetadataPluralizationPolicyInput | undefined;
1084
+ }
1085
+
1086
+ /**
1087
+ * Scalar metadata policy input.
1088
+ *
1089
+ * @public
1090
+ */
1091
+ export declare type MetadataValuePolicyInput = MetadataValueDisabledPolicyInput | MetadataValueRequireExplicitPolicyInput | MetadataValueInferIfMissingPolicyInput;
1092
+
1093
+ /**
1094
+ * Scalar metadata must be authored explicitly.
1095
+ *
1096
+ * @public
1097
+ */
1098
+ export declare interface MetadataValueRequireExplicitPolicyInput {
1099
+ /** Requires this scalar metadata value to be authored directly. */
1100
+ readonly mode: "require-explicit";
1101
+ /** Optional policy controlling plural forms of this scalar value. */
1102
+ readonly pluralization?: MetadataPluralizationPolicyInput | undefined;
1103
+ }
1104
+
890
1105
  /**
891
1106
  * A numeric input field.
892
1107
  *
@@ -903,6 +1118,10 @@ export declare interface NumberField<N extends string> {
903
1118
  readonly name: N;
904
1119
  /** Display label for the field */
905
1120
  readonly label?: string;
1121
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
1122
+ readonly displayName?: string;
1123
+ /** JSON-facing serialized name for the field. */
1124
+ readonly apiName?: string;
906
1125
  /** Minimum allowed value */
907
1126
  readonly min?: number;
908
1127
  /** Maximum allowed value */
@@ -934,6 +1153,10 @@ export declare interface ObjectField<N extends string, Properties extends readon
934
1153
  readonly properties: Properties;
935
1154
  /** Display label for the field */
936
1155
  readonly label?: string;
1156
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
1157
+ readonly displayName?: string;
1158
+ /** JSON-facing serialized name for the field. */
1159
+ readonly apiName?: string;
937
1160
  /** Whether this field is required for form submission */
938
1161
  readonly required?: boolean;
939
1162
  }
@@ -950,6 +1173,35 @@ export declare interface ObjectField<N extends string, Properties extends readon
950
1173
  */
951
1174
  export declare type Predicate<K extends string = string, V = unknown> = EqualsPredicate<K, V>;
952
1175
 
1176
+ /**
1177
+ * Shared resolved metadata model carried through canonicalization and
1178
+ * generation.
1179
+ *
1180
+ * @public
1181
+ */
1182
+ export declare interface ResolvedMetadata {
1183
+ /** Effective JSON-facing singular name. */
1184
+ readonly apiName?: ResolvedScalarMetadata;
1185
+ /** Effective human-facing singular label. */
1186
+ readonly displayName?: ResolvedScalarMetadata;
1187
+ /** Effective JSON-facing plural name, where applicable. */
1188
+ readonly apiNamePlural?: ResolvedScalarMetadata;
1189
+ /** Effective human-facing plural label, where applicable. */
1190
+ readonly displayNamePlural?: ResolvedScalarMetadata;
1191
+ }
1192
+
1193
+ /**
1194
+ * A single resolved scalar metadata value plus its provenance.
1195
+ *
1196
+ * @public
1197
+ */
1198
+ export declare interface ResolvedScalarMetadata {
1199
+ /** Effective metadata value after policy resolution. */
1200
+ readonly value: string;
1201
+ /** Whether the value came from author intent or inference. */
1202
+ readonly source: MetadataSource;
1203
+ }
1204
+
953
1205
  /**
954
1206
  * A resolver function that fetches options for a data source.
955
1207
  *
@@ -1088,6 +1340,10 @@ export declare interface StaticEnumField<N extends string, O extends readonly En
1088
1340
  readonly options: O;
1089
1341
  /** Display label for the field */
1090
1342
  readonly label?: string;
1343
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
1344
+ readonly displayName?: string;
1345
+ /** JSON-facing serialized name for the field. */
1346
+ readonly apiName?: string;
1091
1347
  /** Whether this field is required for form submission */
1092
1348
  readonly required?: boolean;
1093
1349
  }
@@ -1114,6 +1370,10 @@ export declare interface TextField<N extends string> {
1114
1370
  readonly name: N;
1115
1371
  /** Display label for the field */
1116
1372
  readonly label?: string;
1373
+ /** Canonical display name for the field. Alias of `label` in the chain DSL. */
1374
+ readonly displayName?: string;
1375
+ /** JSON-facing serialized name for the field. */
1376
+ readonly apiName?: string;
1117
1377
  /** Placeholder text shown when field is empty */
1118
1378
  readonly placeholder?: string;
1119
1379
  /** Whether this field is required for form submission */