ngx-t-forms-types 0.0.30 → 0.0.34
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/dist/interfaces/Form/formSubmissionHandleInterface.d.ts +6 -0
- package/dist/interfaces/FormBuilder/DefaultEelement.js +76 -0
- package/dist/interfaces/FormBuilder/DefaultInputConfigInterface.d.ts +13 -0
- package/dist/interfaces/FormBuilder/FormInputKeys.d.ts +6 -0
- package/dist/interfaces/FormBuilder/FormInputKeys.js +6 -0
- package/dist/interfaces/FormBuilder/inputConfig/ElementEditConfig.js +188 -3
- package/dist/interfaces/Import/ImportIdentity.d.ts +32 -0
- package/dist/interfaces/Import/ImportIdentity.js +1 -0
- package/dist/interfaces/Import/ImportProgress.d.ts +12 -1
- package/dist/interfaces/Import/ImportRowState.d.ts +52 -1
- package/dist/interfaces/Import/index.d.ts +2 -1
- package/dist/interfaces/formInput/APIDataFetchingConfigurationInterface.d.ts +34 -0
- package/dist/interfaces/formInput/BasicFormInputInterface.d.ts +1 -0
- package/dist/interfaces/formInput/BasicFormInputInterface.js +1 -0
- package/dist/interfaces/formInput/IMscoaAccount.d.ts +19 -3
- package/dist/interfaces/formInput/ISelectInputInterface.d.ts +12 -0
- package/dist/interfaces/formInput/MultipleInterface.d.ts +10 -0
- package/dist/interfaces/formInput/WorkflowDocumentPicker.d.ts +2 -0
- package/dist/schemas/FormInputSchema.js +41 -2
- package/dist/schemas/MatOptionsSchema.js +7 -0
- package/dist/schemas/MscoaConfigSchema.js +1 -0
- package/dist/schemas/index.d.ts +2 -1
- package/dist/schemas/index.js +2 -1
- package/dist/skillet/authoring-rules.d.ts +41 -0
- package/dist/skillet/authoring-rules.js +61 -0
- package/dist/skillet/extra-members.d.ts +143 -0
- package/dist/skillet/extra-members.js +79 -0
- package/dist/skillet/form.d.ts +170 -0
- package/dist/skillet/form.js +139 -0
- package/dist/skillet/index.d.ts +43 -0
- package/dist/skillet/index.js +46 -0
- package/dist/skillet/input-members.d.ts +375 -0
- package/dist/skillet/input-members.js +186 -0
- package/dist/skillet/internal/coupling.d.ts +63 -0
- package/dist/skillet/internal/coupling.js +69 -0
- package/dist/skillet/internal/editor-guidance.d.ts +64 -0
- package/dist/skillet/internal/editor-guidance.js +291 -0
- package/dist/skillet/members/calculated-field.d.ts +155 -0
- package/dist/skillet/members/calculated-field.js +105 -0
- package/dist/skillet/members/conditional.d.ts +69 -0
- package/dist/skillet/members/conditional.js +16 -0
- package/dist/skillet/members/document-picker.d.ts +182 -0
- package/dist/skillet/members/document-picker.js +111 -0
- package/dist/skillet/members/mat-options.d.ts +187 -0
- package/dist/skillet/members/mat-options.js +92 -0
- package/dist/skillet/members/mscoa.d.ts +182 -0
- package/dist/skillet/members/mscoa.js +129 -0
- package/dist/skillet/members/pagination.d.ts +59 -0
- package/dist/skillet/members/pagination.js +16 -0
- package/dist/skillet/members/table.d.ts +178 -0
- package/dist/skillet/members/table.js +105 -0
- package/dist/skillet/members/validators.d.ts +197 -0
- package/dist/skillet/members/validators.js +74 -0
- package/dist/skillet/members/value.d.ts +154 -0
- package/dist/skillet/members/value.js +97 -0
- package/dist/skillet/shared-types.d.ts +57 -0
- package/dist/skillet/shared-types.js +69 -0
- package/dist/skillet/tests/house-rules.spec.d.ts +1 -0
- package/dist/skillet/tests/house-rules.spec.js +162 -0
- package/dist/skillet/tests/skillet-coupling.spec.d.ts +1 -0
- package/dist/skillet/tests/skillet-coupling.spec.js +191 -0
- package/dist/skillet/tests/variant-assembly.spec.d.ts +1 -0
- package/dist/skillet/tests/variant-assembly.spec.js +643 -0
- package/dist/skillet/variants.d.ts +138 -0
- package/dist/skillet/variants.js +536 -0
- package/dist/skillet/workflow-context.d.ts +95 -0
- package/dist/skillet/workflow-context.js +128 -0
- package/package.json +78 -60
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { s } from '@hashbrownai/core';
|
|
2
|
+
import type { FormColumnInputs } from '../interfaces/Form/index.js';
|
|
3
|
+
import { AllFormInputPrimaryKeys } from '../interfaces/FormBuilder/FormInputKeys.js';
|
|
4
|
+
import { type MatOptionsDraft } from './members/mat-options.js';
|
|
5
|
+
import { type CalculatedFieldRulesDraft } from './members/calculated-field.js';
|
|
6
|
+
import { type ValidatorEntryDraft } from './members/validators.js';
|
|
7
|
+
import { type ConditionalRuleDraft } from './members/conditional.js';
|
|
8
|
+
import { type MscoaConfigDraft } from './members/mscoa.js';
|
|
9
|
+
import { type PaginationSelectionConfigDraft } from './members/pagination.js';
|
|
10
|
+
import { type CalculateListFunctionsDraft } from './members/value.js';
|
|
11
|
+
import { AssertNever } from './internal/coupling.js';
|
|
12
|
+
/**
|
|
13
|
+
* One Skillet node per member a form input can carry.
|
|
14
|
+
*
|
|
15
|
+
* This registry is the single place a property's LLM-facing shape is defined.
|
|
16
|
+
* Per-element variants are assembled by PICKING from it — they never redeclare
|
|
17
|
+
* a node — so a property means the same thing everywhere it appears.
|
|
18
|
+
*
|
|
19
|
+
* ## Nodes are unwrapped
|
|
20
|
+
*
|
|
21
|
+
* Every node here describes the value as it looks WHEN PRESENT. Optionality is
|
|
22
|
+
* not encoded, because it is not a property of the member — it is a property of
|
|
23
|
+
* the member *within an element*. `colSize` is required on an input and absent
|
|
24
|
+
* on a section title. Variant assembly consults
|
|
25
|
+
* `DefaultInputConfig[element].requiredProperties` and wraps the optional ones
|
|
26
|
+
* with `optional()` at that point.
|
|
27
|
+
*
|
|
28
|
+
* ## Descriptions are composed, not written twice
|
|
29
|
+
*
|
|
30
|
+
* Each authored description is passed through `describe()`, which layers on the
|
|
31
|
+
* hint and the applicability rules the form-builder's own editor config already
|
|
32
|
+
* carries for that property. See `internal/editor-guidance.ts` for what is
|
|
33
|
+
* drawn from there and what was inspected and deliberately rejected.
|
|
34
|
+
*
|
|
35
|
+
* ## The five categories are exhaustive
|
|
36
|
+
*
|
|
37
|
+
* Every `AllFormInputPrimaryKeys` member belongs to exactly one of
|
|
38
|
+
* {@link inputMemberSchemas}, {@link draftMemberSchemas},
|
|
39
|
+
* {@link PENDING_INPUT_MEMBERS}, {@link SYSTEM_OWNED_INPUT_MEMBERS}, or
|
|
40
|
+
* {@link DEPRECATED_INPUT_MEMBERS}. The assertions at the foot of this file
|
|
41
|
+
* prove it, so a key added to the enum breaks the build until it is
|
|
42
|
+
* classified. Nothing can be silently forgotten.
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* The type a member is required to produce, read off the real interface.
|
|
46
|
+
*
|
|
47
|
+
* Keys the interfaces do not declare resolve to `unknown`, which imposes no
|
|
48
|
+
* constraint — see {@link UnbackedInputMember} for why that is a finding rather
|
|
49
|
+
* than a feature.
|
|
50
|
+
*/
|
|
51
|
+
type MemberValue<K extends AllFormInputPrimaryKeys> = K extends keyof FormColumnInputs ? NonNullable<FormColumnInputs[K]> : unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Members a model must never author: identifiers the builder assigns and
|
|
54
|
+
* runtime state the form owns while it is open. These are excluded from
|
|
55
|
+
* generation schemas entirely and stitched in afterwards.
|
|
56
|
+
*/
|
|
57
|
+
export declare const SYSTEM_OWNED_INPUT_MEMBERS: readonly [AllFormInputPrimaryKeys.Id, AllFormInputPrimaryKeys.SectionId, AllFormInputPrimaryKeys.SystemDefault, AllFormInputPrimaryKeys.Status, AllFormInputPrimaryKeys.ValueUpdatedAt, AllFormInputPrimaryKeys.TemporaryHint, AllFormInputPrimaryKeys.FormIsOpen, AllFormInputPrimaryKeys.MultipleInputInEditId, AllFormInputPrimaryKeys.CanReload];
|
|
58
|
+
/**
|
|
59
|
+
* Members kept only so stored forms keep deserialising. They are excluded from
|
|
60
|
+
* generation entirely: a model must never author a property the codebase has
|
|
61
|
+
* already moved on from, and leaving one in the schema would see it reappear on
|
|
62
|
+
* every newly generated input.
|
|
63
|
+
*/
|
|
64
|
+
export declare const DEPRECATED_INPUT_MEMBERS: readonly [AllFormInputPrimaryKeys.IServeInputWithRequisitionItems];
|
|
65
|
+
/**
|
|
66
|
+
* Members whose shape is a nested configuration object deserving its own
|
|
67
|
+
* module. Listed rather than stubbed: a placeholder node would compile and then
|
|
68
|
+
* quietly feed the model a wrong shape, which is worse than an absent one.
|
|
69
|
+
*/
|
|
70
|
+
export declare const PENDING_INPUT_MEMBERS: readonly [AllFormInputPrimaryKeys.AdjudicationReviewFeedbackTemplate];
|
|
71
|
+
/**
|
|
72
|
+
* Members whose node cannot be built until assembly, because its shape depends
|
|
73
|
+
* on something only the caller knows.
|
|
74
|
+
*
|
|
75
|
+
* These differ from {@link DRAFT_INPUT_MEMBERS} in that there is no sensible
|
|
76
|
+
* default node to publish at all:
|
|
77
|
+
*
|
|
78
|
+
* - `workflowPickerConfig` needs the workflows available in the caller's
|
|
79
|
+
* context. With none, the member is not offered — the same reasoning that
|
|
80
|
+
* withholds the `api` source in `members/mat-options.ts`, and for the same
|
|
81
|
+
* reason: a fabricated `workflowId` produces a picker that looks right and
|
|
82
|
+
* points at nothing.
|
|
83
|
+
* - `formInputs` is the contents of a repeatable list, which is itself a list
|
|
84
|
+
* of columns. It can only be built once the remaining nesting depth is known,
|
|
85
|
+
* because Skillet has no way to express a recursive schema and the recursion
|
|
86
|
+
* has to be unrolled to a fixed depth instead.
|
|
87
|
+
*
|
|
88
|
+
* `variants.ts` resolves both while it walks an element's properties.
|
|
89
|
+
*/
|
|
90
|
+
export declare const ASSEMBLED_INPUT_MEMBERS: readonly [AllFormInputPrimaryKeys.WorkflowPickerConfig, AllFormInputPrimaryKeys.FormInputs];
|
|
91
|
+
/**
|
|
92
|
+
* Members whose schema produces an AUTHORING DRAFT rather than the stored
|
|
93
|
+
* shape, because some part of the stored shape is not knowable from a prompt.
|
|
94
|
+
*
|
|
95
|
+
* `matOptions` is the first of these: an api source is stored as a full
|
|
96
|
+
* endpoint configuration — `_id`, `httpEndPoint`, `httpMethod`, headers — and a
|
|
97
|
+
* model asked for that invents a URL. So the draft carries the id of an
|
|
98
|
+
* endpoint the caller supplied, and the application expands it before the form
|
|
99
|
+
* is validated.
|
|
100
|
+
*
|
|
101
|
+
* These are checked against their declared draft type rather than against the
|
|
102
|
+
* interface member, so the compiler still holds them to something. What it
|
|
103
|
+
* cannot check is the expansion itself; that contract lives with the caller.
|
|
104
|
+
*/
|
|
105
|
+
export declare const DRAFT_INPUT_MEMBERS: readonly [AllFormInputPrimaryKeys.MatOptions, AllFormInputPrimaryKeys.CalculatedFieldRules, AllFormInputPrimaryKeys.Validators, AllFormInputPrimaryKeys.ConditionalInputConfig, AllFormInputPrimaryKeys.MscoaConfig, AllFormInputPrimaryKeys.PaginationSelectionConfig, AllFormInputPrimaryKeys.CalculateListFunctions];
|
|
106
|
+
type SystemOwnedKey = (typeof SYSTEM_OWNED_INPUT_MEMBERS)[number];
|
|
107
|
+
type DeprecatedKey = (typeof DEPRECATED_INPUT_MEMBERS)[number];
|
|
108
|
+
type PendingKey = (typeof PENDING_INPUT_MEMBERS)[number];
|
|
109
|
+
type DraftKey = (typeof DRAFT_INPUT_MEMBERS)[number];
|
|
110
|
+
type AssembledKey = (typeof ASSEMBLED_INPUT_MEMBERS)[number];
|
|
111
|
+
/**
|
|
112
|
+
* The draft each drafted member is held to.
|
|
113
|
+
*
|
|
114
|
+
* Every one of these exists because the stored shape carries an identifier the
|
|
115
|
+
* builder assigns — an input's `id`, a rule's `id`, a segment's row key. A
|
|
116
|
+
* model authoring a form that does not exist yet cannot know any of them, so it
|
|
117
|
+
* binds by `formControlName` and the application resolves the pair. Each
|
|
118
|
+
* module states its own version of this; the list is here so the compiler
|
|
119
|
+
* checks them all in one place.
|
|
120
|
+
*/
|
|
121
|
+
interface MemberDrafts {
|
|
122
|
+
[AllFormInputPrimaryKeys.MatOptions]: MatOptionsDraft;
|
|
123
|
+
[AllFormInputPrimaryKeys.CalculatedFieldRules]: CalculatedFieldRulesDraft;
|
|
124
|
+
[AllFormInputPrimaryKeys.Validators]: ValidatorEntryDraft[];
|
|
125
|
+
[AllFormInputPrimaryKeys.ConditionalInputConfig]: ConditionalRuleDraft[];
|
|
126
|
+
[AllFormInputPrimaryKeys.MscoaConfig]: MscoaConfigDraft;
|
|
127
|
+
[AllFormInputPrimaryKeys.PaginationSelectionConfig]: PaginationSelectionConfigDraft;
|
|
128
|
+
[AllFormInputPrimaryKeys.CalculateListFunctions]: CalculateListFunctionsDraft;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Members whose model output must be expanded before it satisfies the
|
|
132
|
+
* interfaces. Kept apart from {@link inputMemberSchemas} so that consuming code
|
|
133
|
+
* cannot treat a draft as a finished value by accident.
|
|
134
|
+
*/
|
|
135
|
+
export declare const draftMemberSchemas: {
|
|
136
|
+
matOptions: s.ObjectType<{
|
|
137
|
+
optionType: import("@hashbrownai/core/src/schema/base").SchemaForUnion<"user" | null>;
|
|
138
|
+
options: s.ArrayType<s.ObjectType<{
|
|
139
|
+
label: s.StringType;
|
|
140
|
+
value: s.StringType;
|
|
141
|
+
}>>;
|
|
142
|
+
fetch: s.ObjectType<{
|
|
143
|
+
value: import("@hashbrownai/core/src/schema/base").SchemaForUnion<{
|
|
144
|
+
source: import("..").DataSources.Local;
|
|
145
|
+
inputSourceId: string;
|
|
146
|
+
allowManualValueEntry: boolean;
|
|
147
|
+
} | {
|
|
148
|
+
source: import("..").DataSources.CustomOptions;
|
|
149
|
+
} | {
|
|
150
|
+
source: import("..").DataSources.Api;
|
|
151
|
+
endpointId: string;
|
|
152
|
+
allowManualValueEntry: boolean;
|
|
153
|
+
} | {
|
|
154
|
+
source: import("..").DataSources.MongoDb;
|
|
155
|
+
workflowId: string;
|
|
156
|
+
} | null>;
|
|
157
|
+
options: import("@hashbrownai/core/src/schema/base").SchemaForUnion<{
|
|
158
|
+
source: import("..").DataSources.Local;
|
|
159
|
+
inputSourceId: string;
|
|
160
|
+
allowManualValueEntry: boolean;
|
|
161
|
+
} | {
|
|
162
|
+
source: import("..").DataSources.CustomOptions;
|
|
163
|
+
} | {
|
|
164
|
+
source: import("..").DataSources.Api;
|
|
165
|
+
endpointId: string;
|
|
166
|
+
allowManualValueEntry: boolean;
|
|
167
|
+
} | {
|
|
168
|
+
source: import("..").DataSources.MongoDb;
|
|
169
|
+
workflowId: string;
|
|
170
|
+
} | null>;
|
|
171
|
+
}>;
|
|
172
|
+
}>;
|
|
173
|
+
calculatedFieldRules: s.ObjectType<{
|
|
174
|
+
formula: s.StringType;
|
|
175
|
+
variables: s.ArrayType<import("@hashbrownai/core/src/schema/base").SchemaForUnion<{
|
|
176
|
+
bindingType: "field";
|
|
177
|
+
variable: string;
|
|
178
|
+
label: string;
|
|
179
|
+
formControlName: string;
|
|
180
|
+
} | {
|
|
181
|
+
bindingType: "listAggregate";
|
|
182
|
+
variable: string;
|
|
183
|
+
label: string;
|
|
184
|
+
formControlName: string;
|
|
185
|
+
parentInputFormControl: string;
|
|
186
|
+
function: import("..").CalculationFunctions;
|
|
187
|
+
applyFunctionToCol: string;
|
|
188
|
+
applyFunctionToLabel: string | null;
|
|
189
|
+
filterValuesByCol: string | null;
|
|
190
|
+
filterValuesByThisColLabel: string | null;
|
|
191
|
+
tableCell: boolean | null;
|
|
192
|
+
}>>;
|
|
193
|
+
decimalPlaces: import("@hashbrownai/core/src/schema/base").SchemaForUnion<number | null>;
|
|
194
|
+
roundingMode: import("@hashbrownai/core/src/schema/base").SchemaForUnion<"FLOOR" | "CEIL" | "ROUND" | null>;
|
|
195
|
+
getFormulaFromAFormInput: import("@hashbrownai/core/src/schema/base").SchemaForUnion<boolean | null>;
|
|
196
|
+
formControlWithFormula: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
|
|
197
|
+
}>;
|
|
198
|
+
validators: s.ArrayType<import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | {
|
|
199
|
+
message: string;
|
|
200
|
+
expression: string;
|
|
201
|
+
canOverride: boolean;
|
|
202
|
+
inputsObservedForChanges: {
|
|
203
|
+
formControlName: string;
|
|
204
|
+
variable: string;
|
|
205
|
+
parentInputFormControl: string | null;
|
|
206
|
+
function: import("..").CalculationFunctions | null;
|
|
207
|
+
}[];
|
|
208
|
+
}>> | s.ArrayType<s.ObjectType<{
|
|
209
|
+
message: s.StringType;
|
|
210
|
+
expression: s.StringType;
|
|
211
|
+
canOverride: s.BooleanType;
|
|
212
|
+
inputsObservedForChanges: s.ArrayType<s.ObjectType<{
|
|
213
|
+
formControlName: s.StringType;
|
|
214
|
+
variable: s.StringType;
|
|
215
|
+
parentInputFormControl: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
|
|
216
|
+
function: import("@hashbrownai/core/src/schema/base").SchemaForUnion<import("..").CalculationFunctions | null>;
|
|
217
|
+
}>>;
|
|
218
|
+
}>>;
|
|
219
|
+
conditionalInputConfig: s.ArrayType<s.ObjectType<{
|
|
220
|
+
expression: s.StringType;
|
|
221
|
+
inputsObservedForChanges: s.ArrayType<s.ObjectType<{
|
|
222
|
+
formControlName: s.StringType;
|
|
223
|
+
variable: s.StringType;
|
|
224
|
+
parentInputFormControl: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
|
|
225
|
+
function: import("@hashbrownai/core/src/schema/base").SchemaForUnion<import("..").CalculationFunctions | null>;
|
|
226
|
+
}>>;
|
|
227
|
+
}>>;
|
|
228
|
+
mscoaConfig: s.ObjectType<{
|
|
229
|
+
accountingBasis: import("@hashbrownai/core/src/schema/base").SchemaForUnion<import("..").AccountingBasis | null>;
|
|
230
|
+
segments: s.ArrayType<s.ObjectType<{
|
|
231
|
+
segment: s.StringType;
|
|
232
|
+
customSegment: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
|
|
233
|
+
label: s.StringType;
|
|
234
|
+
readOnly: s.BooleanType;
|
|
235
|
+
singleSelect: s.BooleanType;
|
|
236
|
+
additionalAccounts: s.ArrayType<s.StringType>;
|
|
237
|
+
inheritValueFromAccrual: import("@hashbrownai/core/src/schema/base").SchemaForUnion<boolean | null>;
|
|
238
|
+
vatSelectonActive: import("@hashbrownai/core/src/schema/base").SchemaForUnion<boolean | null>;
|
|
239
|
+
segmentExtension: s.BooleanType;
|
|
240
|
+
}>>;
|
|
241
|
+
cashSegments: import("@hashbrownai/core/src/schema/base").SchemaForUnion<{
|
|
242
|
+
segment: string;
|
|
243
|
+
customSegment: string | null;
|
|
244
|
+
label: string;
|
|
245
|
+
readOnly: boolean;
|
|
246
|
+
singleSelect: boolean;
|
|
247
|
+
additionalAccounts: string[];
|
|
248
|
+
inheritValueFromAccrual: boolean | null;
|
|
249
|
+
vatSelectonActive: boolean | null;
|
|
250
|
+
segmentExtension: boolean;
|
|
251
|
+
}[] | null>;
|
|
252
|
+
accountValueLabel: s.EnumType<string[]>;
|
|
253
|
+
showAllSegments: s.BooleanType;
|
|
254
|
+
extensionAccountsForSegments: s.ArrayType<s.StringType>;
|
|
255
|
+
dualCashExclusion: import("@hashbrownai/core/src/schema/base").SchemaForUnion<{
|
|
256
|
+
rules: {
|
|
257
|
+
pattern: string;
|
|
258
|
+
flags: string | null;
|
|
259
|
+
matchField: string | null;
|
|
260
|
+
segment: string | null;
|
|
261
|
+
description: string | null;
|
|
262
|
+
}[] | null;
|
|
263
|
+
matchMode: "any" | "all" | null;
|
|
264
|
+
} | null>;
|
|
265
|
+
}>;
|
|
266
|
+
paginationSelectionConfig: s.ObjectType<{
|
|
267
|
+
useLocalPagination: import("@hashbrownai/core/src/schema/base").SchemaForUnion<boolean | null>;
|
|
268
|
+
columns: s.ArrayType<s.ObjectType<{
|
|
269
|
+
key: s.StringType;
|
|
270
|
+
label: s.StringType;
|
|
271
|
+
}>>;
|
|
272
|
+
}>;
|
|
273
|
+
calculateListFunctions: s.ArrayType<s.ObjectType<{
|
|
274
|
+
formControlName: s.StringType;
|
|
275
|
+
func: s.EnumType<import("..").CalculationFunctions[]>;
|
|
276
|
+
}>>;
|
|
277
|
+
};
|
|
278
|
+
/** Every key this registry is obliged to cover. */
|
|
279
|
+
export type ModelledKey = Exclude<AllFormInputPrimaryKeys, SystemOwnedKey | PendingKey | DeprecatedKey | DraftKey | AssembledKey>;
|
|
280
|
+
export declare const inputMemberSchemas: {
|
|
281
|
+
element: s.EnumType<import("..").ElementTypes[]>;
|
|
282
|
+
label: s.StringType;
|
|
283
|
+
formControlName: s.StringType;
|
|
284
|
+
colSize: s.IntegerType;
|
|
285
|
+
appearance: s.EnumType<["fill", "outline"]>;
|
|
286
|
+
dataType: s.EnumType<import("..").InputDataTypes[]>;
|
|
287
|
+
type: s.EnumType<import("..").InputTypes[]>;
|
|
288
|
+
viewType: s.EnumType<import("../interfaces/formInput/BasicFormInputInterface.js").InputViewTypes.ViewOnly[]>;
|
|
289
|
+
required: s.BooleanType;
|
|
290
|
+
readonly: s.BooleanType;
|
|
291
|
+
showAsLabel: s.BooleanType;
|
|
292
|
+
onlySetTempErrorOnTouch: s.BooleanType;
|
|
293
|
+
isCalculatedField: s.BooleanType;
|
|
294
|
+
hintLabel: s.StringType;
|
|
295
|
+
tourContent: s.StringType;
|
|
296
|
+
spellcheck: s.BooleanType;
|
|
297
|
+
autocapitalize: s.EnumType<import("..").AutocapitalizeOptions[]>;
|
|
298
|
+
rows: s.IntegerType;
|
|
299
|
+
wrap: s.EnumType<["hard", "soft"]>;
|
|
300
|
+
richTextEditorLibrary: s.EnumType<import("..").RichTextEditorType[]>;
|
|
301
|
+
min: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | number>;
|
|
302
|
+
max: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | number>;
|
|
303
|
+
minLength: s.IntegerType;
|
|
304
|
+
maxLength: s.IntegerType;
|
|
305
|
+
optionSelectType: s.EnumType<import("..").OptionSelectTypes[]>;
|
|
306
|
+
allowMultipleSelection: s.BooleanType;
|
|
307
|
+
singleSelect: s.BooleanType;
|
|
308
|
+
groupBy: s.ArrayType<s.StringType>;
|
|
309
|
+
labelPosition: s.EnumType<import("../interfaces/formInput/ToggleInputInterface.js").LabelPosition[]>;
|
|
310
|
+
trueLabel: s.StringType;
|
|
311
|
+
falseLabel: s.StringType;
|
|
312
|
+
startDateControl: s.StringType;
|
|
313
|
+
endDateControl: s.StringType;
|
|
314
|
+
fileType: s.EnumType<import("..").InputFileType[]>;
|
|
315
|
+
accept: s.StringType;
|
|
316
|
+
handleLabel: s.StringType;
|
|
317
|
+
pipe: s.ObjectType<{
|
|
318
|
+
pipeType: s.EnumType<import("..").InputPipeTypes[]>;
|
|
319
|
+
param: s.StringType;
|
|
320
|
+
}>;
|
|
321
|
+
linkedSegmentId: s.StringType;
|
|
322
|
+
adjudicationStep: s.EnumType<import("..").AdjudicationSteps[]>;
|
|
323
|
+
adjudicationPointTypes: s.ArrayType<s.StringType>;
|
|
324
|
+
workflowFormForScoreSheet: s.StringType;
|
|
325
|
+
value: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | number | boolean>;
|
|
326
|
+
script: s.ObjectType<{
|
|
327
|
+
onChange: s.StringType;
|
|
328
|
+
}>;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Every key is classified. Adding a member to `AllFormInputPrimaryKeys` fails
|
|
332
|
+
* here until it is modelled, deferred, or declared system-owned.
|
|
333
|
+
*/
|
|
334
|
+
export type _EveryKeyClassified = AssertNever<Exclude<AllFormInputPrimaryKeys, ModelledKey | PendingKey | SystemOwnedKey | DeprecatedKey | DraftKey | AssembledKey>>;
|
|
335
|
+
/**
|
|
336
|
+
* No key may be claimed by two categories at once.
|
|
337
|
+
*
|
|
338
|
+
* Written as each category against the union of those after it rather than as
|
|
339
|
+
* every pair spelled out: the pairwise form needed ten lines for five
|
|
340
|
+
* categories and would need fifteen for six, which is the kind of list that
|
|
341
|
+
* quietly loses an entry when the next category is added.
|
|
342
|
+
*/
|
|
343
|
+
export type _CategoriesDisjoint = AssertNever<(ModelledKey & (PendingKey | SystemOwnedKey | DeprecatedKey | DraftKey | AssembledKey)) | (PendingKey & (SystemOwnedKey | DeprecatedKey | DraftKey | AssembledKey)) | (SystemOwnedKey & (DeprecatedKey | DraftKey | AssembledKey)) | (DeprecatedKey & (DraftKey | AssembledKey)) | (DraftKey & AssembledKey)>;
|
|
344
|
+
/**
|
|
345
|
+
* Every drafted node produces the draft it declares. The expansion from draft
|
|
346
|
+
* to stored shape is the caller's, but the draft itself stays checked.
|
|
347
|
+
*/
|
|
348
|
+
export type _NoDraftDrift = AssertNever<{
|
|
349
|
+
[K in DraftKey]: [s.Infer<(typeof draftMemberSchemas)[K]>] extends [
|
|
350
|
+
MemberDrafts[K]
|
|
351
|
+
] ? never : K;
|
|
352
|
+
}[DraftKey]>;
|
|
353
|
+
/**
|
|
354
|
+
* Every modelled node still produces a value its interface member can hold.
|
|
355
|
+
* Retyping a member in the interfaces surfaces here, by name, as a constraint
|
|
356
|
+
* violation on the offending key.
|
|
357
|
+
*
|
|
358
|
+
* Narrowing is permitted by design — several nodes deliberately refuse value
|
|
359
|
+
* shapes the interface tolerates but a model should never invent.
|
|
360
|
+
*/
|
|
361
|
+
export type _NoValueDrift = AssertNever<{
|
|
362
|
+
[K in ModelledKey]: [s.Infer<(typeof inputMemberSchemas)[K]>] extends [
|
|
363
|
+
MemberValue<K>
|
|
364
|
+
] ? never : K;
|
|
365
|
+
}[ModelledKey]>;
|
|
366
|
+
/**
|
|
367
|
+
* Keys the enum declares but no interface in this package backs, so
|
|
368
|
+
* {@link MemberValue} cannot constrain them and their nodes go unverified.
|
|
369
|
+
* Exported deliberately: this is pre-existing drift the schemas inherit, not
|
|
370
|
+
* something they introduce.
|
|
371
|
+
*/
|
|
372
|
+
export type UnbackedInputMember = Exclude<AllFormInputPrimaryKeys, keyof FormColumnInputs>;
|
|
373
|
+
/** Runtime access to the full key list, derived from the enum. */
|
|
374
|
+
export declare const ALL_INPUT_MEMBER_KEYS: AllFormInputPrimaryKeys[];
|
|
375
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { s } from '@hashbrownai/core';
|
|
2
|
+
import { AllFormInputPrimaryKeys } from '../interfaces/FormBuilder/FormInputKeys.js';
|
|
3
|
+
import { matOptionsSchema } from './members/mat-options.js';
|
|
4
|
+
import { calculatedFieldRulesDraftSchema, } from './members/calculated-field.js';
|
|
5
|
+
import { validatorsDraftSchema, } from './members/validators.js';
|
|
6
|
+
import { conditionalInputConfigDraftSchema, } from './members/conditional.js';
|
|
7
|
+
import { mscoaConfigSchema } from './members/mscoa.js';
|
|
8
|
+
import { paginationSelectionConfigDraftSchema, } from './members/pagination.js';
|
|
9
|
+
import { calculateListFunctionsSchema, scriptSchema, valueSchema, } from './members/value.js';
|
|
10
|
+
import { enumValues } from './internal/coupling.js';
|
|
11
|
+
import { CONTROL_NAME_PATTERN } from './authoring-rules.js';
|
|
12
|
+
import { describe, rangeFor } from './internal/editor-guidance.js';
|
|
13
|
+
import { adjudicationStepSchema, appearanceSchema, autocapitalizeSchema, elementTypeSchema, inputDataTypeSchema, inputFileTypeSchema, inputPipeTypeSchema, inputTypeSchema, inputViewTypeSchema, labelPositionSchema, optionSelectTypeSchema, richTextEditorTypeSchema, textareaWrapSchema, } from './shared-types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Members a model must never author: identifiers the builder assigns and
|
|
16
|
+
* runtime state the form owns while it is open. These are excluded from
|
|
17
|
+
* generation schemas entirely and stitched in afterwards.
|
|
18
|
+
*/
|
|
19
|
+
export const SYSTEM_OWNED_INPUT_MEMBERS = [
|
|
20
|
+
AllFormInputPrimaryKeys.Id,
|
|
21
|
+
AllFormInputPrimaryKeys.SectionId,
|
|
22
|
+
AllFormInputPrimaryKeys.SystemDefault,
|
|
23
|
+
AllFormInputPrimaryKeys.Status,
|
|
24
|
+
AllFormInputPrimaryKeys.ValueUpdatedAt,
|
|
25
|
+
AllFormInputPrimaryKeys.TemporaryHint,
|
|
26
|
+
AllFormInputPrimaryKeys.FormIsOpen,
|
|
27
|
+
AllFormInputPrimaryKeys.MultipleInputInEditId,
|
|
28
|
+
AllFormInputPrimaryKeys.CanReload,
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Members kept only so stored forms keep deserialising. They are excluded from
|
|
32
|
+
* generation entirely: a model must never author a property the codebase has
|
|
33
|
+
* already moved on from, and leaving one in the schema would see it reappear on
|
|
34
|
+
* every newly generated input.
|
|
35
|
+
*/
|
|
36
|
+
export const DEPRECATED_INPUT_MEMBERS = [
|
|
37
|
+
AllFormInputPrimaryKeys.IServeInputWithRequisitionItems,
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Members whose shape is a nested configuration object deserving its own
|
|
41
|
+
* module. Listed rather than stubbed: a placeholder node would compile and then
|
|
42
|
+
* quietly feed the model a wrong shape, which is worse than an absent one.
|
|
43
|
+
*/
|
|
44
|
+
export const PENDING_INPUT_MEMBERS = [
|
|
45
|
+
AllFormInputPrimaryKeys.AdjudicationReviewFeedbackTemplate,
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Members whose node cannot be built until assembly, because its shape depends
|
|
49
|
+
* on something only the caller knows.
|
|
50
|
+
*
|
|
51
|
+
* These differ from {@link DRAFT_INPUT_MEMBERS} in that there is no sensible
|
|
52
|
+
* default node to publish at all:
|
|
53
|
+
*
|
|
54
|
+
* - `workflowPickerConfig` needs the workflows available in the caller's
|
|
55
|
+
* context. With none, the member is not offered — the same reasoning that
|
|
56
|
+
* withholds the `api` source in `members/mat-options.ts`, and for the same
|
|
57
|
+
* reason: a fabricated `workflowId` produces a picker that looks right and
|
|
58
|
+
* points at nothing.
|
|
59
|
+
* - `formInputs` is the contents of a repeatable list, which is itself a list
|
|
60
|
+
* of columns. It can only be built once the remaining nesting depth is known,
|
|
61
|
+
* because Skillet has no way to express a recursive schema and the recursion
|
|
62
|
+
* has to be unrolled to a fixed depth instead.
|
|
63
|
+
*
|
|
64
|
+
* `variants.ts` resolves both while it walks an element's properties.
|
|
65
|
+
*/
|
|
66
|
+
export const ASSEMBLED_INPUT_MEMBERS = [
|
|
67
|
+
AllFormInputPrimaryKeys.WorkflowPickerConfig,
|
|
68
|
+
AllFormInputPrimaryKeys.FormInputs,
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* Members whose schema produces an AUTHORING DRAFT rather than the stored
|
|
72
|
+
* shape, because some part of the stored shape is not knowable from a prompt.
|
|
73
|
+
*
|
|
74
|
+
* `matOptions` is the first of these: an api source is stored as a full
|
|
75
|
+
* endpoint configuration — `_id`, `httpEndPoint`, `httpMethod`, headers — and a
|
|
76
|
+
* model asked for that invents a URL. So the draft carries the id of an
|
|
77
|
+
* endpoint the caller supplied, and the application expands it before the form
|
|
78
|
+
* is validated.
|
|
79
|
+
*
|
|
80
|
+
* These are checked against their declared draft type rather than against the
|
|
81
|
+
* interface member, so the compiler still holds them to something. What it
|
|
82
|
+
* cannot check is the expansion itself; that contract lives with the caller.
|
|
83
|
+
*/
|
|
84
|
+
export const DRAFT_INPUT_MEMBERS = [
|
|
85
|
+
AllFormInputPrimaryKeys.MatOptions,
|
|
86
|
+
AllFormInputPrimaryKeys.CalculatedFieldRules,
|
|
87
|
+
AllFormInputPrimaryKeys.Validators,
|
|
88
|
+
AllFormInputPrimaryKeys.ConditionalInputConfig,
|
|
89
|
+
AllFormInputPrimaryKeys.MscoaConfig,
|
|
90
|
+
AllFormInputPrimaryKeys.PaginationSelectionConfig,
|
|
91
|
+
AllFormInputPrimaryKeys.CalculateListFunctions,
|
|
92
|
+
];
|
|
93
|
+
/**
|
|
94
|
+
* Members whose model output must be expanded before it satisfies the
|
|
95
|
+
* interfaces. Kept apart from {@link inputMemberSchemas} so that consuming code
|
|
96
|
+
* cannot treat a draft as a finished value by accident.
|
|
97
|
+
*/
|
|
98
|
+
export const draftMemberSchemas = {
|
|
99
|
+
[AllFormInputPrimaryKeys.MatOptions]: matOptionsSchema,
|
|
100
|
+
[AllFormInputPrimaryKeys.CalculatedFieldRules]: calculatedFieldRulesDraftSchema,
|
|
101
|
+
[AllFormInputPrimaryKeys.Validators]: validatorsDraftSchema,
|
|
102
|
+
[AllFormInputPrimaryKeys.ConditionalInputConfig]: conditionalInputConfigDraftSchema,
|
|
103
|
+
[AllFormInputPrimaryKeys.MscoaConfig]: mscoaConfigSchema,
|
|
104
|
+
[AllFormInputPrimaryKeys.PaginationSelectionConfig]: paginationSelectionConfigDraftSchema,
|
|
105
|
+
[AllFormInputPrimaryKeys.CalculateListFunctions]: calculateListFunctionsSchema,
|
|
106
|
+
};
|
|
107
|
+
// Descriptions on the members every element shares are kept SHORT on purpose:
|
|
108
|
+
// each is repeated once per element per nesting level in the emitted schema,
|
|
109
|
+
// because Hashbrown names `$defs` entries by their description. The
|
|
110
|
+
// definition and the one rule that belongs at the member stay here; the
|
|
111
|
+
// form-wide rules live in `authoring-rules.ts`, emitted once at the root.
|
|
112
|
+
export const inputMemberSchemas = {
|
|
113
|
+
// --- identity and layout --------------------------------------------------
|
|
114
|
+
[AllFormInputPrimaryKeys.Element]: elementTypeSchema,
|
|
115
|
+
[AllFormInputPrimaryKeys.Label]: s.string(describe("The visible field label: a noun phrase of one to three words in sentence case, in the words of the people who fill the form in ('Cost centre', not 'cc_code'), with no colon or trailing punctuation. It is also the heading the answer is printed under, so it must make sense on its own.", AllFormInputPrimaryKeys.Label)),
|
|
116
|
+
[AllFormInputPrimaryKeys.FormControlName]: s.string(describe("The key this value is stored under, derived from the label so that it identifies the field on its own: 'budgetReview', not 'toggle1'. Unique across the whole form; never a reserved name; never changed once the form is live.", AllFormInputPrimaryKeys.FormControlName), { pattern: CONTROL_NAME_PATTERN }),
|
|
117
|
+
[AllFormInputPrimaryKeys.ColSize]: s.integer(describe('How many of the 12 grid columns this control spans. Size it to the data: 12 for long text, a textarea, an item list, a picker, an uploader or a signature; 6, 4 or 3 for a date, an amount, a quantity, a short code or a toggle.', AllFormInputPrimaryKeys.ColSize), rangeFor(AllFormInputPrimaryKeys.ColSize) ?? { minimum: 1, maximum: 12 }),
|
|
118
|
+
[AllFormInputPrimaryKeys.Appearance]: appearanceSchema,
|
|
119
|
+
[AllFormInputPrimaryKeys.DataType]: inputDataTypeSchema,
|
|
120
|
+
[AllFormInputPrimaryKeys.Type]: inputTypeSchema,
|
|
121
|
+
[AllFormInputPrimaryKeys.ViewType]: inputViewTypeSchema,
|
|
122
|
+
// --- obligation and state -------------------------------------------------
|
|
123
|
+
[AllFormInputPrimaryKeys.Required]: s.boolean(describe('Whether the user must supply a value before the form can be submitted. Required when the next step cannot proceed without it; if in doubt, not required; if required only sometimes, use a validator or a conditional display rule instead.', AllFormInputPrimaryKeys.Required)),
|
|
124
|
+
[AllFormInputPrimaryKeys.Readonly]: s.boolean(describe("Whether the value is displayed but cannot be edited: for an earlier step's answer, a profile value, a fetched figure. The value is still submitted.", AllFormInputPrimaryKeys.Readonly)),
|
|
125
|
+
[AllFormInputPrimaryKeys.ShowAsLabel]: s.boolean(describe('Renders the value as plain text instead of a form control.', AllFormInputPrimaryKeys.ShowAsLabel)),
|
|
126
|
+
[AllFormInputPrimaryKeys.OnlySetTempErrorOnTouch]: s.boolean(describe('Withholds validation errors until the user has interacted with the field. True on nearly every field.', AllFormInputPrimaryKeys.OnlySetTempErrorOnTouch)),
|
|
127
|
+
[AllFormInputPrimaryKeys.IsCalculatedField]: s.boolean(describe('Whether this value is computed from other fields rather than entered by the user.', AllFormInputPrimaryKeys.IsCalculatedField)),
|
|
128
|
+
// --- guidance -------------------------------------------------------------
|
|
129
|
+
[AllFormInputPrimaryKeys.HintLabel]: s.string(describe('Short helper text shown under the field permanently: one sentence with no full stop, giving the format, the source, or the reason for asking. On a sectionTitle it is the guidance for the whole group that follows and may run to two sentences.', AllFormInputPrimaryKeys.HintLabel)),
|
|
130
|
+
[AllFormInputPrimaryKeys.TourContent]: s.string(describe('Guided-tour copy shown when the form is first walked through. Only for a genuinely unfamiliar control such as an account picker or a document picker: two sentences, what it is and what to do.', AllFormInputPrimaryKeys.TourContent)),
|
|
131
|
+
// --- text behaviour -------------------------------------------------------
|
|
132
|
+
[AllFormInputPrimaryKeys.Spellcheck]: s.boolean(describe('Whether the browser spell-checks the typed text. Enable for prose, disable for codes and identifiers.', AllFormInputPrimaryKeys.Spellcheck)),
|
|
133
|
+
[AllFormInputPrimaryKeys.Autocapitalize]: autocapitalizeSchema,
|
|
134
|
+
[AllFormInputPrimaryKeys.Rows]: s.integer(describe('Visible height of a textarea, in lines.', AllFormInputPrimaryKeys.Rows), { minimum: 1 }),
|
|
135
|
+
[AllFormInputPrimaryKeys.Wrap]: textareaWrapSchema,
|
|
136
|
+
[AllFormInputPrimaryKeys.RichTextEditorLibrary]: richTextEditorTypeSchema,
|
|
137
|
+
// --- constraints ----------------------------------------------------------
|
|
138
|
+
// A union node has no description slot of its own, so the applicability rule
|
|
139
|
+
// the editor declares for these — they mean nothing unless the input is
|
|
140
|
+
// numeric or a date — is composed onto each branch instead. Dropping it would
|
|
141
|
+
// lose the single most useful thing the editor config knows about them.
|
|
142
|
+
[AllFormInputPrimaryKeys.Min]: s.anyOf([
|
|
143
|
+
s.number(describe('A numeric lower bound: 1 for a quantity, 0 for an amount or a percentage.', AllFormInputPrimaryKeys.Min)),
|
|
144
|
+
s.string(describe('A lower bound as an ISO date, for date controls.', AllFormInputPrimaryKeys.Min)),
|
|
145
|
+
]),
|
|
146
|
+
[AllFormInputPrimaryKeys.Max]: s.anyOf([
|
|
147
|
+
s.number(describe('A numeric upper bound: 100 for a percentage.', AllFormInputPrimaryKeys.Max)),
|
|
148
|
+
s.string(describe('An upper bound as an ISO date, for date controls.', AllFormInputPrimaryKeys.Max)),
|
|
149
|
+
]),
|
|
150
|
+
[AllFormInputPrimaryKeys.MinLength]: s.integer(describe('The fewest characters the value may contain.', AllFormInputPrimaryKeys.MinLength), { minimum: 0 }),
|
|
151
|
+
[AllFormInputPrimaryKeys.MaxLength]: s.integer(describe('The most characters the value may contain. Match the limit of the system the value is stored in, and say so in the hint when it matters.', AllFormInputPrimaryKeys.MaxLength), { minimum: 1 }),
|
|
152
|
+
// --- options and selection ------------------------------------------------
|
|
153
|
+
[AllFormInputPrimaryKeys.OptionSelectType]: optionSelectTypeSchema,
|
|
154
|
+
[AllFormInputPrimaryKeys.AllowMultipleSelection]: s.boolean(describe('Whether more than one option may be chosen at once.', AllFormInputPrimaryKeys.AllowMultipleSelection)),
|
|
155
|
+
[AllFormInputPrimaryKeys.SingleSelect]: s.boolean(describe('Restricts the control to exactly one selection.', AllFormInputPrimaryKeys.SingleSelect)),
|
|
156
|
+
[AllFormInputPrimaryKeys.GroupBy]: s.array(describe('Option properties to group the list under, outermost first. Leave empty for a flat list.', AllFormInputPrimaryKeys.GroupBy), s.string('An option property name to group by.')),
|
|
157
|
+
// --- toggle ---------------------------------------------------------------
|
|
158
|
+
[AllFormInputPrimaryKeys.LabelPosition]: labelPositionSchema,
|
|
159
|
+
[AllFormInputPrimaryKeys.TrueLabel]: s.string(describe("Text shown when a toggle is on. Name the real state — 'Approve', 'VAT registered' — never a bare 'Yes', which forces the user to re-read the label.", AllFormInputPrimaryKeys.TrueLabel)),
|
|
160
|
+
[AllFormInputPrimaryKeys.FalseLabel]: s.string(describe("Text shown when a toggle is off: the direct opposite of the true label — 'Reject', 'Not VAT registered' — never a bare 'No'.", AllFormInputPrimaryKeys.FalseLabel)),
|
|
161
|
+
// --- dates ----------------------------------------------------------------
|
|
162
|
+
[AllFormInputPrimaryKeys.StartDateControl]: s.string(describe('The formControlName holding the start of a date range. A range stores two values, so both this and endDateControl must be set, or the field is dropped from prefill, export and print.', AllFormInputPrimaryKeys.StartDateControl)),
|
|
163
|
+
[AllFormInputPrimaryKeys.EndDateControl]: s.string(describe('The formControlName holding the end of a date range. Both this and startDateControl must be set.', AllFormInputPrimaryKeys.EndDateControl)),
|
|
164
|
+
// --- files ----------------------------------------------------------------
|
|
165
|
+
[AllFormInputPrimaryKeys.FileType]: inputFileTypeSchema,
|
|
166
|
+
[AllFormInputPrimaryKeys.Accept]: s.string(describe('Accepted upload types as an HTML accept attribute, for example ".pdf,.docx" or "image/*". Match it to the documents actually expected, and name the accepted types in the hint as well.', AllFormInputPrimaryKeys.Accept)),
|
|
167
|
+
[AllFormInputPrimaryKeys.HandleLabel]: s.string(describe("The text of the button that adds a row to an item list. Name the action — 'Add item', 'Add attendee' — not the default 'Add to list'.", AllFormInputPrimaryKeys.HandleLabel)),
|
|
168
|
+
// --- display transform ----------------------------------------------------
|
|
169
|
+
[AllFormInputPrimaryKeys.Pipe]: s.object(describe('A display transform applied when the value is shown back to the user: currency for an amount, percent for a rate, date for a date. Presentation only; the stored value is unchanged.', AllFormInputPrimaryKeys.Pipe), {
|
|
170
|
+
pipeType: inputPipeTypeSchema,
|
|
171
|
+
param: s.string('The pipe argument, such as a date format like "dd MMM yyyy" or a currency code like "ZAR".'),
|
|
172
|
+
}),
|
|
173
|
+
// --- domain ---------------------------------------------------------------
|
|
174
|
+
[AllFormInputPrimaryKeys.LinkedSegmentId]: s.string(describe('Identifier of the mSCOA segment this control resolves against.', AllFormInputPrimaryKeys.LinkedSegmentId)),
|
|
175
|
+
[AllFormInputPrimaryKeys.AdjudicationStep]: adjudicationStepSchema,
|
|
176
|
+
[AllFormInputPrimaryKeys.AdjudicationPointTypes]: s.array(describe('The scoring categories available at this adjudication step.', AllFormInputPrimaryKeys.AdjudicationPointTypes), s.string('A scoring category name.')),
|
|
177
|
+
[AllFormInputPrimaryKeys.WorkflowFormForScoreSheet]: s.string(describe('Identifier of the form supplying the score sheet for this adjudication.', AllFormInputPrimaryKeys.WorkflowFormForScoreSheet)),
|
|
178
|
+
// --- prefilled value and behaviour ---------------------------------------
|
|
179
|
+
// Both are modelled rather than drafted: they carry no builder-assigned
|
|
180
|
+
// identifier, so what the model emits is what gets stored. See
|
|
181
|
+
// `members/value.ts` for the narrowing each one applies.
|
|
182
|
+
[AllFormInputPrimaryKeys.Value]: valueSchema,
|
|
183
|
+
[AllFormInputPrimaryKeys.Script]: scriptSchema,
|
|
184
|
+
};
|
|
185
|
+
/** Runtime access to the full key list, derived from the enum. */
|
|
186
|
+
export const ALL_INPUT_MEMBER_KEYS = enumValues(AllFormInputPrimaryKeys);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { s } from '@hashbrownai/core';
|
|
2
|
+
/**
|
|
3
|
+
* Compile-time coupling primitives that bind the Skillet schemas to the
|
|
4
|
+
* interfaces they describe.
|
|
5
|
+
*
|
|
6
|
+
* The rule these enforce, stated once:
|
|
7
|
+
*
|
|
8
|
+
* `s.Infer<node>` must be ASSIGNABLE TO the interface member's type.
|
|
9
|
+
*
|
|
10
|
+
* Assignability — not equality — is deliberate. A Skillet node is allowed to be
|
|
11
|
+
* NARROWER than the interface (we routinely refuse to let a model emit a `Date`
|
|
12
|
+
* object or a custom-script sentinel even where the interface permits one), but
|
|
13
|
+
* it may never be WIDER. Widening is precisely the drift that produces a value
|
|
14
|
+
* the rest of the codebase cannot hold, so that is the direction we fail on.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Guards a Skillet node against the type it is meant to produce.
|
|
18
|
+
*
|
|
19
|
+
* Curried so the expected type is written explicitly and the node type is
|
|
20
|
+
* inferred:
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const colSize = matches<number>()(s.integer('Grid width', { minimum: 1 }));
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* If the node's inferred output stops being assignable to `Expected` — because
|
|
27
|
+
* someone retyped the interface member, or loosened the node — the argument
|
|
28
|
+
* collapses to `never` and the call fails to compile.
|
|
29
|
+
*/
|
|
30
|
+
export declare function matches<Expected>(): <Node extends s.HashbrownType>(node: [s.Infer<Node>] extends [Expected] ? Node : never) => Node;
|
|
31
|
+
/**
|
|
32
|
+
* Derives Skillet enum entries from a TypeScript string enum at runtime, so the
|
|
33
|
+
* two can never disagree: add a member to the enum and it appears in the schema
|
|
34
|
+
* on the next evaluation, with `s.Infer` widening to match.
|
|
35
|
+
*
|
|
36
|
+
* The `Record<string, string>` constraint rejects numeric and mixed enums —
|
|
37
|
+
* `Object.values` on those also yields the reverse-mapped numeric keys, which
|
|
38
|
+
* would silently poison the entry list. Skillet enumerations are string-only.
|
|
39
|
+
*/
|
|
40
|
+
export declare function enumValues<E extends Record<string, string>>(enumObject: E): E[keyof E][];
|
|
41
|
+
/**
|
|
42
|
+
* Asserts a literal tuple covers a string union exactly.
|
|
43
|
+
*
|
|
44
|
+
* Needed for union *types* (`'hard' | 'soft'`), which — unlike enums — have no
|
|
45
|
+
* runtime representation to derive from, so the members must be restated. This
|
|
46
|
+
* makes restating them safe: drop one and the argument becomes `never`.
|
|
47
|
+
*
|
|
48
|
+
* ```ts
|
|
49
|
+
* const WRAP = exhaustive<'hard' | 'soft'>()(['hard', 'soft'] as const);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function exhaustive<Union extends string>(): <Tuple extends readonly Union[]>(entries: [Exclude<Union, Tuple[number]>] extends [never] ? Tuple : never) => Tuple;
|
|
53
|
+
/**
|
|
54
|
+
* Wraps a node as an absent-able member.
|
|
55
|
+
*
|
|
56
|
+
* Skillet has no `optional()`: every declared key must appear in the model's
|
|
57
|
+
* response. Optionality is therefore modelled as an explicit null branch — the
|
|
58
|
+
* key is always emitted, and `null` is how the model says "not set". Strip the
|
|
59
|
+
* nulls when converting a generated column into a `FormColumnInputs`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function optional<Node extends s.HashbrownType>(node: Node): import("@hashbrownai/core/src/schema/base").SchemaForUnion<(Node | s.NullType)["~schema"]["result"]>;
|
|
62
|
+
/** Resolves to `never` unless `T` is `never`; used to prove a set is empty. */
|
|
63
|
+
export type AssertNever<T extends never> = T;
|