@orkestrel/form 0.0.5 → 0.0.7
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/README.md +11 -9
- package/dist/src/core/index.cjs +42 -14
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +66 -33
- package/dist/src/core/index.d.ts +66 -33
- package/dist/src/core/index.js +43 -15
- package/dist/src/core/index.js.map +1 -1
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# @orkestrel/form
|
|
2
2
|
|
|
3
|
-
The environment-agnostic form document
|
|
4
|
-
answers given against it, declarative
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
> The environment-agnostic form document: a `FormSchema` stating what is asked, a `Form` holding
|
|
4
|
+
> the answers given against it, declarative `FieldRule` data stating what those answers must
|
|
5
|
+
> satisfy, and one submit that settles the form exactly once.
|
|
6
|
+
|
|
7
|
+
A terminal prompt and a browser form ask the same thing in different places, so this package ships
|
|
8
|
+
what they share and neither renders nor reads input itself. Its `answer` promise is the parking seam
|
|
9
|
+
a server needs: hand the document out, wait, receive the answers back. A live form can take a field
|
|
10
|
+
out and put it back with `disable` and `enable`, and exported budgets bound what one schema and its
|
|
11
|
+
answers may retain, so a document that arrives from a wire costs a known maximum before anything
|
|
12
|
+
decides to trust it. Built on `@orkestrel/contract` and `@orkestrel/emitter`, and part of the
|
|
13
|
+
`@orkestrel` line.
|
|
12
14
|
|
|
13
15
|
## Install
|
|
14
16
|
|
package/dist/src/core/index.cjs
CHANGED
|
@@ -107,23 +107,23 @@ var DATE_PATTERN = Object.freeze(/^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01
|
|
|
107
107
|
var TIME_PATTERN = Object.freeze(/^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/);
|
|
108
108
|
/** Matches an ISO local date and time string with optional seconds. */
|
|
109
109
|
var DATETIME_PATTERN = Object.freeze(/^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/);
|
|
110
|
-
/** Caps the accepted source length for an authored regular expression. */
|
|
110
|
+
/** Caps the accepted source length for an authored regular expression, at 256. */
|
|
111
111
|
var PATTERN_LIMIT = 256;
|
|
112
|
-
/** Caps the number of fields one schema may declare. */
|
|
112
|
+
/** Caps the number of fields one schema may declare, at 512. */
|
|
113
113
|
var FIELD_LIMIT = 512;
|
|
114
|
-
/** Caps the number of groups one schema may declare. */
|
|
114
|
+
/** Caps the number of groups one schema may declare, at 64. */
|
|
115
115
|
var GROUP_LIMIT = 64;
|
|
116
|
-
/** Caps the number of choices one `select` or `checkbox` field may offer. */
|
|
116
|
+
/** Caps the number of choices one `select` or `checkbox` field may offer, at 1024. */
|
|
117
117
|
var CHOICE_LIMIT = 1024;
|
|
118
|
-
/** Caps the number of entries one list-valued answer may hold. */
|
|
118
|
+
/** Caps the number of entries one list-valued answer may hold, at 1024. */
|
|
119
119
|
var LIST_LIMIT = 1024;
|
|
120
|
-
/** Caps the length, in UTF-16 code units, of a schema, group, or field name. */
|
|
120
|
+
/** Caps the length, in UTF-16 code units, of a schema, group, or field name, at 128. */
|
|
121
121
|
var NAME_LIMIT = 128;
|
|
122
|
-
/** Caps the length, in UTF-16 code units, of any single retained string. */
|
|
122
|
+
/** Caps the length, in UTF-16 code units, of any single retained string, at 65536. */
|
|
123
123
|
var STRING_LIMIT = 65536;
|
|
124
|
-
/** Caps the total length, in UTF-16 code units, of every string one schema retains. */
|
|
124
|
+
/** Caps the total length, in UTF-16 code units, of every string one schema retains, at 1048576. */
|
|
125
125
|
var TEXT_LIMIT = 1048576;
|
|
126
|
-
/** Caps the total number of records, arrays, and leaves one schema retains. */
|
|
126
|
+
/** Caps the total number of records, arrays, and leaves one schema retains, at 16384. */
|
|
127
127
|
var NODE_LIMIT = 16384;
|
|
128
128
|
//#endregion
|
|
129
129
|
//#region src/core/errors.ts
|
|
@@ -166,7 +166,7 @@ var FormError = class extends Error {
|
|
|
166
166
|
* @returns True if the value is a {@link FormError} instance; false otherwise.
|
|
167
167
|
*/
|
|
168
168
|
function isFormError(input) {
|
|
169
|
-
return input
|
|
169
|
+
return (0, _orkestrel_contract.isInstance)(input, FormError);
|
|
170
170
|
}
|
|
171
171
|
//#endregion
|
|
172
172
|
//#region src/core/validators.ts
|
|
@@ -191,6 +191,10 @@ function isFormStatus(input) {
|
|
|
191
191
|
/**
|
|
192
192
|
* Determines whether an unknown value has a form field value shape.
|
|
193
193
|
*
|
|
194
|
+
* @remarks
|
|
195
|
+
* A string, a finite number, a boolean, and a list of strings each qualify. A number that is not
|
|
196
|
+
* finite does not, so `NaN` and `Infinity` are refused.
|
|
197
|
+
*
|
|
194
198
|
* @param input - The value to inspect.
|
|
195
199
|
* @returns True if the value is a field value; false otherwise.
|
|
196
200
|
*/
|
|
@@ -350,6 +354,10 @@ function isFormGroup(input) {
|
|
|
350
354
|
/**
|
|
351
355
|
* Determines whether an unknown value is one exact structural form schema.
|
|
352
356
|
*
|
|
357
|
+
* @remarks
|
|
358
|
+
* Structure alone is read. Domain soundness — a duplicate name, a bound no answer satisfies, a
|
|
359
|
+
* breached budget — is {@link auditSchema}'s question.
|
|
360
|
+
*
|
|
353
361
|
* @param input - The value to inspect.
|
|
354
362
|
* @returns True if the value is a structurally valid form schema; false otherwise.
|
|
355
363
|
*/
|
|
@@ -514,7 +522,7 @@ function defineEntry(target, name, value) {
|
|
|
514
522
|
*
|
|
515
523
|
* @remarks
|
|
516
524
|
* The prototype-safe write of {@link defineEntry}, frozen: the entry is neither writable nor
|
|
517
|
-
* configurable, so the record a parser hands back cannot be edited through the key it
|
|
525
|
+
* configurable, so the record a parser hands back cannot be edited through the key it filled.
|
|
518
526
|
*
|
|
519
527
|
* @example
|
|
520
528
|
* ```ts
|
|
@@ -534,6 +542,10 @@ function freezeEntry(target, name, value) {
|
|
|
534
542
|
/**
|
|
535
543
|
* Checks whether a value has the shape required by one field control.
|
|
536
544
|
*
|
|
545
|
+
* @remarks
|
|
546
|
+
* Every write and every seeded value passes through this gate, and it reads `STRING_LIMIT` and
|
|
547
|
+
* `LIST_LIMIT` before it consults the control, so no regular expression sees an over-long value.
|
|
548
|
+
*
|
|
537
549
|
* @param field - The field that owns the value.
|
|
538
550
|
* @param value - The unknown value to inspect.
|
|
539
551
|
* @returns True if the control can hold the value; false otherwise.
|
|
@@ -714,6 +726,10 @@ function evaluateForm(schema, values, options) {
|
|
|
714
726
|
/**
|
|
715
727
|
* Computes the values explicitly seeded by a schema.
|
|
716
728
|
*
|
|
729
|
+
* @remarks
|
|
730
|
+
* `password` and `file` declare no default, so a field of either control never appears in the
|
|
731
|
+
* result.
|
|
732
|
+
*
|
|
717
733
|
* @param schema - The schema whose defaults to collect.
|
|
718
734
|
* @returns A value record containing only fields with defaults.
|
|
719
735
|
*/
|
|
@@ -787,6 +803,10 @@ function matchesValues(a, b) {
|
|
|
787
803
|
/**
|
|
788
804
|
* Resolves and interpolates one rule message.
|
|
789
805
|
*
|
|
806
|
+
* @remarks
|
|
807
|
+
* A replacement in `messages` is read first and {@link RULE_MESSAGES} supplies the copy otherwise,
|
|
808
|
+
* and `{limit}` in whichever text wins is replaced with the rule's operand.
|
|
809
|
+
*
|
|
790
810
|
* @param rule - The rule whose message to resolve.
|
|
791
811
|
* @param limit - The optional operand substituted for `{limit}`.
|
|
792
812
|
* @param messages - Optional rule-specific message replacements.
|
|
@@ -1166,6 +1186,10 @@ function parseForm(input) {
|
|
|
1166
1186
|
/**
|
|
1167
1187
|
* Parses one answer against its field control.
|
|
1168
1188
|
*
|
|
1189
|
+
* @remarks
|
|
1190
|
+
* A numeric string coerces to a number for a `number` field, and `'true'` and `'false'` coerce to
|
|
1191
|
+
* a boolean for a `confirm` field. Every other value must already have its control's shape.
|
|
1192
|
+
*
|
|
1169
1193
|
* @param field - The field that defines the accepted value.
|
|
1170
1194
|
* @param input - The unknown value to parse.
|
|
1171
1195
|
* @returns The typed or lexically coerced field value, or `undefined` on refusal.
|
|
@@ -1211,7 +1235,8 @@ function parseValues(schema, input) {
|
|
|
1211
1235
|
//#endregion
|
|
1212
1236
|
//#region src/core/Form.ts
|
|
1213
1237
|
/**
|
|
1214
|
-
*
|
|
1238
|
+
* Implements `FormInterface` exactly, over an owned schema, the answers given against it, and the
|
|
1239
|
+
* errors they carry.
|
|
1215
1240
|
*
|
|
1216
1241
|
* @remarks
|
|
1217
1242
|
* The form owns its schema, so a later edit to the schema the caller passed changes nothing here.
|
|
@@ -1623,8 +1648,10 @@ var Form = class {
|
|
|
1623
1648
|
* @throws A {@link FormError} coded `SCHEMA` when the schema is malformed, `FIELD` when
|
|
1624
1649
|
* `options.values` names a field the schema does not declare, and `CONTROL` when a seeded value
|
|
1625
1650
|
* is one its field's control cannot hold.
|
|
1626
|
-
* @example
|
|
1651
|
+
* @example Open a form, answer it, and settle it
|
|
1627
1652
|
* ```ts
|
|
1653
|
+
* import { createForm } from '@orkestrel/form'
|
|
1654
|
+
*
|
|
1628
1655
|
* const form = createForm({
|
|
1629
1656
|
* label: 'Sign up',
|
|
1630
1657
|
* fields: [
|
|
@@ -1634,7 +1661,8 @@ var Form = class {
|
|
|
1634
1661
|
* })
|
|
1635
1662
|
*
|
|
1636
1663
|
* form.fill({ email: 'ada@example.com', terms: true })
|
|
1637
|
-
* form.submit() // { success: true, value: { email: 'ada@example.com', terms: true } }
|
|
1664
|
+
* const result = form.submit() // { success: true, value: { email: 'ada@example.com', terms: true } }
|
|
1665
|
+
* const answers = await form.answer // { email: 'ada@example.com', terms: true }
|
|
1638
1666
|
* ```
|
|
1639
1667
|
*/
|
|
1640
1668
|
function createForm(schema, options) {
|