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.
Files changed (68) hide show
  1. package/dist/interfaces/Form/formSubmissionHandleInterface.d.ts +6 -0
  2. package/dist/interfaces/FormBuilder/DefaultEelement.js +76 -0
  3. package/dist/interfaces/FormBuilder/DefaultInputConfigInterface.d.ts +13 -0
  4. package/dist/interfaces/FormBuilder/FormInputKeys.d.ts +6 -0
  5. package/dist/interfaces/FormBuilder/FormInputKeys.js +6 -0
  6. package/dist/interfaces/FormBuilder/inputConfig/ElementEditConfig.js +188 -3
  7. package/dist/interfaces/Import/ImportIdentity.d.ts +32 -0
  8. package/dist/interfaces/Import/ImportIdentity.js +1 -0
  9. package/dist/interfaces/Import/ImportProgress.d.ts +12 -1
  10. package/dist/interfaces/Import/ImportRowState.d.ts +52 -1
  11. package/dist/interfaces/Import/index.d.ts +2 -1
  12. package/dist/interfaces/formInput/APIDataFetchingConfigurationInterface.d.ts +34 -0
  13. package/dist/interfaces/formInput/BasicFormInputInterface.d.ts +1 -0
  14. package/dist/interfaces/formInput/BasicFormInputInterface.js +1 -0
  15. package/dist/interfaces/formInput/IMscoaAccount.d.ts +19 -3
  16. package/dist/interfaces/formInput/ISelectInputInterface.d.ts +12 -0
  17. package/dist/interfaces/formInput/MultipleInterface.d.ts +10 -0
  18. package/dist/interfaces/formInput/WorkflowDocumentPicker.d.ts +2 -0
  19. package/dist/schemas/FormInputSchema.js +41 -2
  20. package/dist/schemas/MatOptionsSchema.js +7 -0
  21. package/dist/schemas/MscoaConfigSchema.js +1 -0
  22. package/dist/schemas/index.d.ts +2 -1
  23. package/dist/schemas/index.js +2 -1
  24. package/dist/skillet/authoring-rules.d.ts +41 -0
  25. package/dist/skillet/authoring-rules.js +61 -0
  26. package/dist/skillet/extra-members.d.ts +143 -0
  27. package/dist/skillet/extra-members.js +79 -0
  28. package/dist/skillet/form.d.ts +170 -0
  29. package/dist/skillet/form.js +139 -0
  30. package/dist/skillet/index.d.ts +43 -0
  31. package/dist/skillet/index.js +46 -0
  32. package/dist/skillet/input-members.d.ts +375 -0
  33. package/dist/skillet/input-members.js +186 -0
  34. package/dist/skillet/internal/coupling.d.ts +63 -0
  35. package/dist/skillet/internal/coupling.js +69 -0
  36. package/dist/skillet/internal/editor-guidance.d.ts +64 -0
  37. package/dist/skillet/internal/editor-guidance.js +291 -0
  38. package/dist/skillet/members/calculated-field.d.ts +155 -0
  39. package/dist/skillet/members/calculated-field.js +105 -0
  40. package/dist/skillet/members/conditional.d.ts +69 -0
  41. package/dist/skillet/members/conditional.js +16 -0
  42. package/dist/skillet/members/document-picker.d.ts +182 -0
  43. package/dist/skillet/members/document-picker.js +111 -0
  44. package/dist/skillet/members/mat-options.d.ts +187 -0
  45. package/dist/skillet/members/mat-options.js +92 -0
  46. package/dist/skillet/members/mscoa.d.ts +182 -0
  47. package/dist/skillet/members/mscoa.js +129 -0
  48. package/dist/skillet/members/pagination.d.ts +59 -0
  49. package/dist/skillet/members/pagination.js +16 -0
  50. package/dist/skillet/members/table.d.ts +178 -0
  51. package/dist/skillet/members/table.js +105 -0
  52. package/dist/skillet/members/validators.d.ts +197 -0
  53. package/dist/skillet/members/validators.js +74 -0
  54. package/dist/skillet/members/value.d.ts +154 -0
  55. package/dist/skillet/members/value.js +97 -0
  56. package/dist/skillet/shared-types.d.ts +57 -0
  57. package/dist/skillet/shared-types.js +69 -0
  58. package/dist/skillet/tests/house-rules.spec.d.ts +1 -0
  59. package/dist/skillet/tests/house-rules.spec.js +162 -0
  60. package/dist/skillet/tests/skillet-coupling.spec.d.ts +1 -0
  61. package/dist/skillet/tests/skillet-coupling.spec.js +191 -0
  62. package/dist/skillet/tests/variant-assembly.spec.d.ts +1 -0
  63. package/dist/skillet/tests/variant-assembly.spec.js +643 -0
  64. package/dist/skillet/variants.d.ts +138 -0
  65. package/dist/skillet/variants.js +536 -0
  66. package/dist/skillet/workflow-context.d.ts +95 -0
  67. package/dist/skillet/workflow-context.js +128 -0
  68. package/package.json +78 -60
@@ -0,0 +1,170 @@
1
+ import { s } from '@hashbrownai/core';
2
+ import { type AssertNever } from './internal/coupling.js';
3
+ import { type AvailableApiEndpoint } from './members/mat-options.js';
4
+ import { type ColumnSchemaOptions } from './variants.js';
5
+ import { type WorkflowStepContext } from './workflow-context.js';
6
+ /**
7
+ * The whole-form schema: slides of columns, plus how the form submits.
8
+ *
9
+ * ## This produces a draft, and it cannot not
10
+ *
11
+ * `FormSchema` requires `submissionHandle.submissionAPI` — an array of at least
12
+ * one full `APIDataFetchingConfiguration`, complete with `_id`, `httpEndPoint`
13
+ * and `httpMethod`. It is the same problem `matOptions` has, except mandatory:
14
+ * there is no valid form without it, and no model can author it from a prompt.
15
+ * `FormSlide.sectionId` is the same story on a smaller scale — an identifier
16
+ * the builder assigns, which a model can only fabricate.
17
+ *
18
+ * So a generated form is a {@link FormDraft}. The application supplies section
19
+ * ids and expands the chosen endpoint ids into stored configurations, and only
20
+ * then does `validateForm()` have something it can pass. Any pipeline built on
21
+ * this needs that expansion step; there is no arrangement of the schema that
22
+ * removes it.
23
+ *
24
+ * ## Streaming
25
+ *
26
+ * `streaming: true` switches the slide and column arrays to their streaming
27
+ * variants, so a client parses each slide as it arrives instead of waiting for
28
+ * the closing brace of a large form. It changes nothing about the data — only
29
+ * when a consumer can first see it.
30
+ */
31
+ export interface SubmissionHandleDraft {
32
+ submissionAPI: string[];
33
+ /**
34
+ * The pre-submit gate, as an endpoint id, expanded into
35
+ * `FormSubmissionHandleInterface.canSubmitAPI`.
36
+ *
37
+ * Absent — not empty — on most drafts, and on every draft generated without
38
+ * `FormSchemaOptions.canSubmitEndpoints`: the key is only put to the model
39
+ * when the caller has gate endpoints to offer, and a hand-built form carries
40
+ * no `canSubmitAPI` key either, so a schema that always emitted one would
41
+ * make every generated form differ from an authored one over a member the
42
+ * form does not use.
43
+ */
44
+ canSubmitAPI?: string[];
45
+ submissionMessage: string | null;
46
+ }
47
+ export interface FormDraft {
48
+ formTitle: string;
49
+ /**
50
+ * Columns are typed loosely on purpose. The per-element variants are
51
+ * assembled at runtime from `DefaultInputConfig`, whose property arrays are
52
+ * `string[]` rather than const tuples, so there is no literal type for
53
+ * `s.Infer` to reconstruct. The compiler cannot describe these; the schema
54
+ * and `validateForm()` still constrain them.
55
+ */
56
+ slides: {
57
+ label: string;
58
+ columns: unknown[];
59
+ }[];
60
+ submissionHandle: SubmissionHandleDraft;
61
+ }
62
+ export interface FormSchemaOptions extends ColumnSchemaOptions {
63
+ /**
64
+ * Endpoints the form may submit to. As with `matOptions`, an empty list means
65
+ * the model is not asked to choose one — it emits an empty `submissionAPI`
66
+ * and the application fills it in.
67
+ */
68
+ submissionEndpoints?: readonly AvailableApiEndpoint[];
69
+ /**
70
+ * Endpoints that may gate submission — called with the form data, and their
71
+ * answer decides whether the submission proceeds.
72
+ *
73
+ * Unlike {@link submissionEndpoints} this one is genuinely optional at the
74
+ * schema level: `canSubmitAPI` is optional on
75
+ * `FormSubmissionHandleInterface` and most forms have no pre-submit check, so
76
+ * an empty list here removes the key from the schema entirely rather than
77
+ * degrading it to an empty array. That follows `matOptions`, where a source
78
+ * with no candidates is not offered at all — the alternative is asking a
79
+ * model to pick an endpoint out of an empty list, which it answers by
80
+ * inventing one.
81
+ */
82
+ canSubmitEndpoints?: readonly AvailableApiEndpoint[];
83
+ /**
84
+ * The workflow step this form serves, and the control names the workflow
85
+ * already fixes. See {@link WorkflowStepContext}: none of it is knowable
86
+ * from a prompt, and all of it decides what the form must contain.
87
+ */
88
+ step?: WorkflowStepContext;
89
+ /** Parse slides and columns incrementally as they stream in. */
90
+ streaming?: boolean;
91
+ }
92
+ declare function submissionHandleSchema(endpoints: readonly AvailableApiEndpoint[], canSubmitEndpoints: readonly AvailableApiEndpoint[]): s.ObjectType<{
93
+ submissionAPI: s.ArrayType<s.StringType | s.EnumType<string[]>>;
94
+ canSubmitAPI: s.ArrayType<s.EnumType<string[]>>;
95
+ submissionMessage: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
96
+ }> | s.ObjectType<{
97
+ submissionAPI: s.ArrayType<s.StringType | s.EnumType<string[]>>;
98
+ submissionMessage: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
99
+ }>;
100
+ /** The submission-handle node, whichever endpoints the factory was given. */
101
+ type SubmissionHandleSchema = ReturnType<typeof submissionHandleSchema>;
102
+ /**
103
+ * The submission handle produces the draft it declares.
104
+ *
105
+ * The same check the per-member modules run on themselves, applied to the one
106
+ * nested object this file owns. It earns its keep on the `canSubmitAPI` branch
107
+ * in particular: that key exists only when the caller supplies
108
+ * `canSubmitEndpoints`, so the node's inferred type is a UNION of the two
109
+ * shapes, and a member added to either branch without a matching member on
110
+ * {@link SubmissionHandleDraft} fails here rather than at the application's
111
+ * expansion step.
112
+ */
113
+ export type _NoSubmissionHandleDraftDrift = AssertNever<[
114
+ s.Infer<SubmissionHandleSchema>
115
+ ] extends [SubmissionHandleDraft] ? never : 'submissionHandle'>;
116
+ /**
117
+ * Builds the form-draft schema.
118
+ *
119
+ * @param options which elements and data sources to offer, which endpoints the
120
+ * form may submit to and which may gate that submission, and whether to
121
+ * stream.
122
+ */
123
+ export declare function createFormDraftSchema(options?: FormSchemaOptions): s.ObjectType<{
124
+ formTitle: s.StringType;
125
+ slides: s.ArrayType<s.ObjectType<{
126
+ label: s.StringType;
127
+ columns: s.ArrayType<s.HashbrownType<unknown>>;
128
+ }>>;
129
+ submissionHandle: s.ObjectType<{
130
+ submissionAPI: s.ArrayType<s.StringType | s.EnumType<string[]>>;
131
+ canSubmitAPI: s.ArrayType<s.EnumType<string[]>>;
132
+ submissionMessage: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
133
+ }> | s.ObjectType<{
134
+ submissionAPI: s.ArrayType<s.StringType | s.EnumType<string[]>>;
135
+ submissionMessage: import("@hashbrownai/core/src/schema/base").SchemaForUnion<string | null>;
136
+ }>;
137
+ }>;
138
+ /**
139
+ * Members of a generated draft the application must supply before the form is
140
+ * valid. Listed so the expansion step has something to check itself against.
141
+ *
142
+ * The per-member lists are pulled in rather than restated, so a module that
143
+ * takes on a new obligation adds it here by existing. Each entry is prefixed
144
+ * with the column path it hangs off, since the modules describe their own
145
+ * shape and do not know where in a form they sit.
146
+ *
147
+ * A module's own entries must therefore start at the MEMBER it owns —
148
+ * `validators[].id`, not `id` — because everything before that is added here
149
+ * and everything after is the module's to state. A list that skips its member
150
+ * name yields a path with a hole in it, which is worse than no list: it reads
151
+ * as authoritative and points nowhere.
152
+ *
153
+ * Three entries are not from any module and are worth reading twice:
154
+ *
155
+ * - `isCalculatedField` is derived, not authored — see `calculatedFieldSplit`
156
+ * in `variants.ts`. It is required by the interface on EVERY column, so
157
+ * expansion must set it on plain columns too, not only calculated ones.
158
+ * - `onlySetTempErrorOnTouch` is required by the interface but optional in the
159
+ * schema (offered on every value-capturing element through the always-shown
160
+ * editor rows), so a model may leave it null. Expansion then sets it, and the
161
+ * guide's house rule says what to: true, so errors appear only after the
162
+ * user leaves a field. The builder's own element templates default it to
163
+ * false; the guide is explicit that this is the wrong default for nearly
164
+ * every field.
165
+ * - the nulls. Skillet has no optional, so every unset member arrives as an
166
+ * explicit `null`, and Joi rejects `null` for a typed optional key. Stripping
167
+ * them is not tidying; a draft that keeps them fails validation.
168
+ */
169
+ export declare const DRAFT_COMPLETION_REQUIRED: readonly ["slides[].sectionId", "slides[].columns[].id", "slides[].columns[].sectionId", "slides[].columns[].isCalculatedField (derived: calculatedFieldRules != null)", "slides[].columns[].onlySetTempErrorOnTouch (required by the interface and offered as optional; when the model leaves it null the application sets true)", "submissionHandle.submissionAPI[] (endpoint id expanded to its configuration)", "submissionHandle.canSubmitAPI[] (endpoint id expanded to its configuration; the key is present only when canSubmitEndpoints were offered, and an empty array is dropped)", ...string[], "every member emitted as null is stripped before validation"];
170
+ export {};
@@ -0,0 +1,139 @@
1
+ import { s } from '@hashbrownai/core';
2
+ import { ElementTypes } from '../interfaces/formInput/index.js';
3
+ import { describeAuthoringRules } from './authoring-rules.js';
4
+ import { optional } from './internal/coupling.js';
5
+ import { CALCULATED_FIELD_DRAFT_COMPLETION } from './members/calculated-field.js';
6
+ import { CONDITIONAL_DRAFT_COMPLETION } from './members/conditional.js';
7
+ import { WORKFLOW_PICKER_DRAFT_COMPLETION } from './members/document-picker.js';
8
+ import { MAT_OPTIONS_DRAFT_COMPLETION, } from './members/mat-options.js';
9
+ import { MSCOA_DRAFT_COMPLETION } from './members/mscoa.js';
10
+ import { PAGINATION_DRAFT_COMPLETION } from './members/pagination.js';
11
+ import { TABLE_DRAFT_COMPLETION } from './members/table.js';
12
+ import { VALIDATOR_DRAFT_COMPLETION } from './members/validators.js';
13
+ import { CALCULATE_LIST_DRAFT_COMPLETION } from './members/value.js';
14
+ import { createColumnSchema } from './variants.js';
15
+ import { describeWorkflowStep, } from './workflow-context.js';
16
+ function submissionHandleSchema(endpoints, canSubmitEndpoints) {
17
+ const endpointNode = endpoints.length
18
+ ? s.enumeration(`Which configured endpoint the completed form is submitted to. Choose by meaning: ${endpoints
19
+ .map((e) => `${e.id} (${e.name})`)
20
+ .join('; ')}.`, endpoints.map((e) => e.id))
21
+ : s.string('Leave this list empty. No submission endpoints were offered, so one cannot be chosen and must not be invented.');
22
+ const submissionAPI = s.array(endpoints.length
23
+ ? 'The endpoint the form submits to. Choose exactly one.'
24
+ : 'Leave empty — the application supplies the submission endpoint.', endpointNode, endpoints.length ? { minItems: 1, maxItems: 1 } : { maxItems: 0 });
25
+ // `innerComponentShowSubmitButton` is deliberately absent: it is deprecated,
26
+ // and a deprecated property left in a generation schema comes back on every
27
+ // form the model writes.
28
+ const submissionMessage = optional(s.string("Message shown to the user after a successful submission. One sentence, past tense, saying what happened and what happens next: 'Your requisition has been submitted and sent to your line manager for approval'."));
29
+ const description = 'How the completed form is submitted.';
30
+ // Two whole object nodes rather than one with a conditionally spread key:
31
+ // an optional key in a Skillet shape infers as `unknown`, which would leave
32
+ // the assertion at the foot of this file passing while proving nothing.
33
+ return canSubmitEndpoints.length
34
+ ? s.object(description, {
35
+ submissionAPI,
36
+ canSubmitAPI: s.array('An optional check run before the form is submitted: the endpoint is called with the form data and must approve before the submission proceeds. Leave this empty unless the form genuinely needs a gate — most do not. Choose at most one.', s.enumeration(`Which configured endpoint decides whether the form may be submitted. Choose by meaning: ${canSubmitEndpoints
37
+ .map((e) => `${e.id} (${e.name})`)
38
+ .join('; ')}.`, canSubmitEndpoints.map((e) => e.id)), { maxItems: 1 }),
39
+ submissionMessage,
40
+ })
41
+ : s.object(description, {
42
+ submissionAPI,
43
+ submissionMessage,
44
+ });
45
+ }
46
+ /**
47
+ * Builds the form-draft schema.
48
+ *
49
+ * @param options which elements and data sources to offer, which endpoints the
50
+ * form may submit to and which may gate that submission, and whether to
51
+ * stream.
52
+ */
53
+ export function createFormDraftSchema(options = {}) {
54
+ const column = createColumnSchema(options);
55
+ const array = options.streaming ? s.streaming.array : s.array;
56
+ const object = options.streaming ? s.streaming.object : s.object;
57
+ // The guide's grouping rule names section titles, so it is only stated when
58
+ // that element is actually on offer — a sentence pointing a model at an
59
+ // element it cannot choose is an invitation to invent one.
60
+ const offersHeadings = (options.elements ?? Object.values(ElementTypes)).includes(ElementTypes.SectionTitle);
61
+ const slide = object('A page of the form: one topic, with five to seven fields, an item list counting as one. Over eight, split it. Its label becomes a section heading when the transaction is read back.', {
62
+ label: s.string("The heading for this page: a short statement of what it holds, in sentence case — 'Requester details', 'Items required' — never a question, a verb, or a number such as 'Section 3'."),
63
+ columns: array([
64
+ 'The fields on this page, in the order they are shown: identifiers and choices first, free text, uploads, calculations and signatures last.',
65
+ offersHeadings
66
+ ? 'Start each group of three to five related fields with a sectionTitle whose hintLabel carries the guidance for the group.'
67
+ : null,
68
+ 'Fields that belong together share one row by sharing out the 12 grid columns between them, and a field revealed by a condition sits immediately after the field that reveals it.',
69
+ ]
70
+ .filter((part) => part !== null)
71
+ .join(' '), column, { minItems: 1 }),
72
+ });
73
+ // The root is emitted exactly once, so it is where the form-wide rules go;
74
+ // see `authoring-rules.ts` for why they are not on the members themselves.
75
+ const formDescription = [
76
+ 'A complete dynamic form. Group related fields onto slides rather than one long page; a form of fewer than about seven fields fits on one slide. Make the system do everything it can: prefill what it knows, calculate what it can derive, and let the user pick rather than type.',
77
+ describeAuthoringRules(),
78
+ options.step ? describeWorkflowStep(options.step) : null,
79
+ ]
80
+ .filter((part) => part !== null)
81
+ .join(' ');
82
+ return object(formDescription, {
83
+ formTitle: s.string('The title of the form, in sentence case. Name what the form is for.'),
84
+ slides: array('The pages of the form, in order.', slide, { minItems: 1 }),
85
+ submissionHandle: submissionHandleSchema(options.submissionEndpoints ?? [], options.canSubmitEndpoints ?? []),
86
+ });
87
+ }
88
+ /**
89
+ * Members of a generated draft the application must supply before the form is
90
+ * valid. Listed so the expansion step has something to check itself against.
91
+ *
92
+ * The per-member lists are pulled in rather than restated, so a module that
93
+ * takes on a new obligation adds it here by existing. Each entry is prefixed
94
+ * with the column path it hangs off, since the modules describe their own
95
+ * shape and do not know where in a form they sit.
96
+ *
97
+ * A module's own entries must therefore start at the MEMBER it owns —
98
+ * `validators[].id`, not `id` — because everything before that is added here
99
+ * and everything after is the module's to state. A list that skips its member
100
+ * name yields a path with a hole in it, which is worse than no list: it reads
101
+ * as authoritative and points nowhere.
102
+ *
103
+ * Three entries are not from any module and are worth reading twice:
104
+ *
105
+ * - `isCalculatedField` is derived, not authored — see `calculatedFieldSplit`
106
+ * in `variants.ts`. It is required by the interface on EVERY column, so
107
+ * expansion must set it on plain columns too, not only calculated ones.
108
+ * - `onlySetTempErrorOnTouch` is required by the interface but optional in the
109
+ * schema (offered on every value-capturing element through the always-shown
110
+ * editor rows), so a model may leave it null. Expansion then sets it, and the
111
+ * guide's house rule says what to: true, so errors appear only after the
112
+ * user leaves a field. The builder's own element templates default it to
113
+ * false; the guide is explicit that this is the wrong default for nearly
114
+ * every field.
115
+ * - the nulls. Skillet has no optional, so every unset member arrives as an
116
+ * explicit `null`, and Joi rejects `null` for a typed optional key. Stripping
117
+ * them is not tidying; a draft that keeps them fails validation.
118
+ */
119
+ export const DRAFT_COMPLETION_REQUIRED = [
120
+ 'slides[].sectionId',
121
+ 'slides[].columns[].id',
122
+ 'slides[].columns[].sectionId',
123
+ 'slides[].columns[].isCalculatedField (derived: calculatedFieldRules != null)',
124
+ 'slides[].columns[].onlySetTempErrorOnTouch (required by the interface and offered as optional; when the model leaves it null the application sets true)',
125
+ 'submissionHandle.submissionAPI[] (endpoint id expanded to its configuration)',
126
+ 'submissionHandle.canSubmitAPI[] (endpoint id expanded to its configuration; the key is present only when canSubmitEndpoints were offered, and an empty array is dropped)',
127
+ ...[
128
+ ...CALCULATED_FIELD_DRAFT_COMPLETION,
129
+ ...VALIDATOR_DRAFT_COMPLETION,
130
+ ...CONDITIONAL_DRAFT_COMPLETION,
131
+ ...PAGINATION_DRAFT_COMPLETION,
132
+ ...MSCOA_DRAFT_COMPLETION,
133
+ ...WORKFLOW_PICKER_DRAFT_COMPLETION,
134
+ ...MAT_OPTIONS_DRAFT_COMPLETION,
135
+ ...CALCULATE_LIST_DRAFT_COMPLETION,
136
+ ...TABLE_DRAFT_COMPLETION,
137
+ ].map((path) => `slides[].columns[].${path}`),
138
+ 'every member emitted as null is stripped before validation',
139
+ ];
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Skillet schemas for LLM-driven form authoring.
3
+ *
4
+ * Published as the `ngx-t-forms-types/skillet` subpath, NOT from the package
5
+ * root, because it is the only part of these typings that needs
6
+ * `@hashbrownai/core`. That dependency is an optional peer: consumers who never
7
+ * generate forms — the Node API, existing Angular apps — resolve the root entry
8
+ * and never load it.
9
+ *
10
+ * ## What this is for
11
+ *
12
+ * These schemas describe form structure to a model so it can author one. They
13
+ * are a GENERATION contract, not a validation contract. The Joi schemas under
14
+ * `src/schemas` remain the source of truth: a generated form is validated with
15
+ * `validateForm()` exactly like a hand-built one, and failures are fed back to
16
+ * the model as a repair turn. Where the two disagree, Joi wins.
17
+ *
18
+ * ## How drift is prevented
19
+ *
20
+ * Enum-backed nodes read their entries from the live enums at evaluation, so
21
+ * they cannot fall behind. Everything else is checked at compile time: see the
22
+ * assertions at the foot of `input-members.ts`, which fail the build — by
23
+ * name — when a key is added to `AllFormInputPrimaryKeys`, when a member is
24
+ * left unclassified, or when a node starts producing a value its interface
25
+ * cannot hold.
26
+ */
27
+ export { enumValues, exhaustive, matches, optional, type AssertNever, } from './internal/coupling.js';
28
+ export * from './shared-types.js';
29
+ export * from './input-members.js';
30
+ export * from './extra-members.js';
31
+ export * from './members/mat-options.js';
32
+ export * from './members/calculated-field.js';
33
+ export * from './members/validators.js';
34
+ export * from './members/conditional.js';
35
+ export * from './members/document-picker.js';
36
+ export * from './members/mscoa.js';
37
+ export * from './members/pagination.js';
38
+ export * from './members/table.js';
39
+ export * from './members/value.js';
40
+ export * from './variants.js';
41
+ export * from './form.js';
42
+ export * from './workflow-context.js';
43
+ export * from './authoring-rules.js';
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Skillet schemas for LLM-driven form authoring.
3
+ *
4
+ * Published as the `ngx-t-forms-types/skillet` subpath, NOT from the package
5
+ * root, because it is the only part of these typings that needs
6
+ * `@hashbrownai/core`. That dependency is an optional peer: consumers who never
7
+ * generate forms — the Node API, existing Angular apps — resolve the root entry
8
+ * and never load it.
9
+ *
10
+ * ## What this is for
11
+ *
12
+ * These schemas describe form structure to a model so it can author one. They
13
+ * are a GENERATION contract, not a validation contract. The Joi schemas under
14
+ * `src/schemas` remain the source of truth: a generated form is validated with
15
+ * `validateForm()` exactly like a hand-built one, and failures are fed back to
16
+ * the model as a repair turn. Where the two disagree, Joi wins.
17
+ *
18
+ * ## How drift is prevented
19
+ *
20
+ * Enum-backed nodes read their entries from the live enums at evaluation, so
21
+ * they cannot fall behind. Everything else is checked at compile time: see the
22
+ * assertions at the foot of `input-members.ts`, which fail the build — by
23
+ * name — when a key is added to `AllFormInputPrimaryKeys`, when a member is
24
+ * left unclassified, or when a node starts producing a value its interface
25
+ * cannot hold.
26
+ */
27
+ export { enumValues, exhaustive, matches, optional, } from './internal/coupling.js';
28
+ export * from './shared-types.js';
29
+ export * from './input-members.js';
30
+ export * from './extra-members.js';
31
+ // Per-member modules. Each owns one nested configuration object, states why it
32
+ // produces a draft where it does, and lists what the application must supply
33
+ // before that draft is valid.
34
+ export * from './members/mat-options.js';
35
+ export * from './members/calculated-field.js';
36
+ export * from './members/validators.js';
37
+ export * from './members/conditional.js';
38
+ export * from './members/document-picker.js';
39
+ export * from './members/mscoa.js';
40
+ export * from './members/pagination.js';
41
+ export * from './members/table.js';
42
+ export * from './members/value.js';
43
+ export * from './variants.js';
44
+ export * from './form.js';
45
+ export * from './workflow-context.js';
46
+ export * from './authoring-rules.js';