@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 CHANGED
@@ -1,14 +1,16 @@
1
1
  # @orkestrel/form
2
2
 
3
- The environment-agnostic form document for the `@orkestrel` line a schema of field controls, the
4
- answers given against it, declarative validation carried as data, and a submit that settles exactly
5
- once. A terminal prompt and a browser form ask the same thing in different places, so this package
6
- ships what they share and neither renders nor reads input itself. Its `answer` promise is the
7
- parking seam a server needs: hand the document out, wait, receive the answers back. A live form can
8
- take a field out and put it back with `disable` and `enable`, and exported budgets bound what one
9
- schema and its answers may retain, so a document that arrives from a wire costs a known maximum
10
- before anything decides to trust it.
11
- Built on `@orkestrel/contract` and `@orkestrel/emitter`.
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
 
@@ -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 instanceof FormError;
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 just filled.
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
- * Represents a form: a schema, the answers given against it, and the errors they carry.
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) {