@oscarpalmer/jhunal 0.19.0 → 0.21.0

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/package.json CHANGED
@@ -1,54 +1,54 @@
1
1
  {
2
- "name": "@oscarpalmer/jhunal",
3
- "version": "0.19.0",
4
- "description": "Flies free beneath the glistening moons…",
5
- "keywords": [
6
- "schema",
7
- "validation"
8
- ],
9
- "license": "MIT",
10
- "author": {
11
- "name": "Oscar Palmér",
12
- "url": "https://oscarpalmer.se"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/oscarpalmer/jhunal.git"
17
- },
18
- "files": [
19
- "dist",
20
- "src"
21
- ],
22
- "type": "module",
23
- "module": "./dist/index.mjs",
24
- "types": "./dist/index.d.mts",
25
- "exports": {
26
- "./package.json": "./package.json",
27
- ".": {
28
- "types": "./dist/index.d.mts",
29
- "default": "./dist/index.mjs"
30
- }
31
- },
32
- "scripts": {
33
- "build": "npx vp pack && npm run tsdown:build",
34
- "tsdown:build": "npx tsdown -c ./tsdown.config.ts",
35
- "tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
36
- "test": "npx vp test run --coverage",
37
- "test:leak": "npx vp test run --detect-async-leaks --coverage",
38
- "watch": "npx vite build --watch"
39
- },
40
- "dependencies": {
41
- "@oscarpalmer/atoms": "^0.169"
42
- },
43
- "devDependencies": {
44
- "@types/node": "^25.5",
45
- "@vitest/coverage-istanbul": "^4.1",
46
- "jsdom": "^29.0",
47
- "tsdown": "^0.21",
48
- "typescript": "^5.9",
49
- "vite": "npm:@voidzero-dev/vite-plus-core@latest",
50
- "vite-plus": "latest",
51
- "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
52
- },
53
- "packageManager": "npm@11.11.1"
2
+ "name": "@oscarpalmer/jhunal",
3
+ "version": "0.21.0",
4
+ "description": "Flies free beneath the glistening moons…",
5
+ "keywords": [
6
+ "schema",
7
+ "validation"
8
+ ],
9
+ "license": "MIT",
10
+ "author": {
11
+ "name": "Oscar Palmér",
12
+ "url": "https://oscarpalmer.se"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/oscarpalmer/jhunal.git"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
22
+ "type": "module",
23
+ "module": "./dist/index.mjs",
24
+ "types": "./dist/index.d.mts",
25
+ "exports": {
26
+ "./package.json": "./package.json",
27
+ ".": {
28
+ "types": "./dist/index.d.mts",
29
+ "default": "./dist/index.mjs"
30
+ }
31
+ },
32
+ "scripts": {
33
+ "build": "npx vp pack && npm run tsdown:build",
34
+ "tsdown:build": "npx tsdown -c ./tsdown.config.ts",
35
+ "tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
36
+ "test": "npx vp test run --coverage",
37
+ "test:leak": "npx vp test run --detect-async-leaks --coverage",
38
+ "watch": "npx vite build --watch"
39
+ },
40
+ "dependencies": {
41
+ "@oscarpalmer/atoms": "^0.170"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^25.5",
45
+ "@vitest/coverage-istanbul": "^4.1",
46
+ "jsdom": "^29.0",
47
+ "tsdown": "^0.21",
48
+ "typescript": "^5.9",
49
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
50
+ "vite-plus": "latest",
51
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
52
+ },
53
+ "packageManager": "npm@11.11.1"
54
54
  }
package/src/constants.ts CHANGED
@@ -1,6 +1,20 @@
1
1
  import type {ValueName} from './models/misc.model';
2
2
  import type {ReportingType} from './models/validation.model';
3
3
 
4
+ // #region Grammar
5
+
6
+ export const COMMA = ', ';
7
+
8
+ export const CONJUNCTION_OR = ' or ';
9
+
10
+ export const CONJUNCTION_OR_COMMA = ', or ';
11
+
12
+ export const CONJUNCTION_AND = ' and ';
13
+
14
+ export const CONJUNCTION_AND_COMMA = ', and ';
15
+
16
+ // #endregion
17
+
4
18
  // #region Misc.
5
19
 
6
20
  export const MESSAGE_CONSTRUCTOR = 'Expected a constructor function';
@@ -42,6 +56,8 @@ export const VALIDATION_MESSAGE_INVALID_VALUE =
42
56
 
43
57
  export const VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX = ' at index <>';
44
58
 
59
+ export const VALIDATION_MESSAGE_UNKNOWN_KEYS = 'Found keys that are not defined in the schema: <>';
60
+
45
61
  // #endregion
46
62
 
47
63
  // #region Reporting
package/src/helpers.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import {isConstructor, isPlainObject} from '@oscarpalmer/atoms/is';
2
2
  import type {Constructor} from '@oscarpalmer/atoms/models';
3
3
  import {
4
+ COMMA,
5
+ CONJUNCTION_AND,
6
+ CONJUNCTION_AND_COMMA,
7
+ CONJUNCTION_OR,
8
+ CONJUNCTION_OR_COMMA,
4
9
  MESSAGE_CONSTRUCTOR,
5
10
  NAME_SCHEMATIC,
6
11
  PROPERTY_SCHEMATIC,
@@ -19,6 +24,7 @@ import {
19
24
  VALIDATION_MESSAGE_INVALID_TYPE,
20
25
  VALIDATION_MESSAGE_INVALID_VALUE,
21
26
  VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX,
27
+ VALIDATION_MESSAGE_UNKNOWN_KEYS,
22
28
  } from './constants';
23
29
  import type {ValueName} from './models/misc.model';
24
30
  import type {
@@ -26,6 +32,7 @@ import type {
26
32
  ReportingType,
27
33
  ValidatedProperty,
28
34
  ValidatedPropertyType,
35
+ ValidationParameters,
29
36
  } from './models/validation.model';
30
37
  import type {Schematic} from './schematic';
31
38
 
@@ -33,36 +40,34 @@ export function getInvalidInputMessage(actual: unknown): string {
33
40
  return VALIDATION_MESSAGE_INVALID_INPUT.replace(TEMPLATE_PATTERN, getValueType(actual));
34
41
  }
35
42
 
36
- export function getInvalidMissingMessage(property: ValidatedProperty): string {
37
- let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(
38
- TEMPLATE_PATTERN,
39
- renderTypes(property.types),
40
- );
43
+ export function getInvalidMissingMessage(key: string, types: ValidatedPropertyType[]): string {
44
+ let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(TEMPLATE_PATTERN, renderTypes(types));
41
45
 
42
- message = message.replace(TEMPLATE_PATTERN, property.key.full);
46
+ message = message.replace(TEMPLATE_PATTERN, key);
43
47
 
44
48
  return message;
45
49
  }
46
50
 
47
- export function getInvalidTypeMessage(property: ValidatedProperty, actual: unknown): string {
48
- let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(
49
- TEMPLATE_PATTERN,
50
- renderTypes(property.types),
51
- );
51
+ export function getInvalidTypeMessage(
52
+ key: string,
53
+ types: ValidatedPropertyType[],
54
+ actual: unknown,
55
+ ): string {
56
+ let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(TEMPLATE_PATTERN, renderTypes(types));
52
57
 
53
- message = message.replace(TEMPLATE_PATTERN, property.key.full);
58
+ message = message.replace(TEMPLATE_PATTERN, key);
54
59
  message = message.replace(TEMPLATE_PATTERN, getValueType(actual));
55
60
 
56
61
  return message;
57
62
  }
58
63
 
59
64
  export function getInvalidValidatorMessage(
60
- property: ValidatedProperty,
65
+ key: string,
61
66
  type: ValueName,
62
67
  index: number,
63
68
  length: number,
64
69
  ): string {
65
- let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, property.key.full);
70
+ let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, key);
66
71
 
67
72
  message = message.replace(TEMPLATE_PATTERN, type);
68
73
 
@@ -73,6 +78,32 @@ export function getInvalidValidatorMessage(
73
78
  return message;
74
79
  }
75
80
 
81
+ export function getParameters(input?: unknown): ValidationParameters {
82
+ if (typeof input === 'boolean') {
83
+ return {
84
+ output: {},
85
+ reporting: getReporting(REPORTING_NONE),
86
+ strict: input,
87
+ };
88
+ }
89
+
90
+ if (REPORTING_TYPES.has(input as ReportingType)) {
91
+ return {
92
+ output: {},
93
+ reporting: getReporting(input as ReportingType),
94
+ strict: false,
95
+ };
96
+ }
97
+
98
+ const options = isPlainObject(input) ? input : {};
99
+
100
+ return {
101
+ output: {},
102
+ reporting: getReporting(options.errors),
103
+ strict: typeof options.strict === 'boolean' ? options.strict : false,
104
+ };
105
+ }
106
+
76
107
  function getPropertyType(original: ValidatedPropertyType): string {
77
108
  if (typeof original === 'function') {
78
109
  return 'a validated value';
@@ -95,6 +126,7 @@ export function getReporting(value: unknown): ReportingInformation {
95
126
  : REPORTING_NONE;
96
127
 
97
128
  return {
129
+ type,
98
130
  [REPORTING_ALL]: type === REPORTING_ALL,
99
131
  [REPORTING_FIRST]: type === REPORTING_FIRST,
100
132
  [REPORTING_NONE]: type === REPORTING_NONE,
@@ -102,6 +134,10 @@ export function getReporting(value: unknown): ReportingInformation {
102
134
  } as ReportingInformation;
103
135
  }
104
136
 
137
+ export function getUnknownKeysMessage(keys: string[]): string {
138
+ return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace(TEMPLATE_PATTERN, renderKeys(keys));
139
+ }
140
+
105
141
  function getValueType(value: unknown): string {
106
142
  const valueType = typeof value;
107
143
 
@@ -161,34 +197,50 @@ export function isSchematic(value: unknown): value is Schematic<never> {
161
197
  );
162
198
  }
163
199
 
164
- function renderTypes(types: ValidatedPropertyType[]): string {
165
- const unique = new Set<string>();
166
- const parts: string[] = [];
167
-
168
- for (let index = 0; index < types.length; index += 1) {
169
- const rendered = getPropertyType(types[index]);
200
+ function renderKeys(keys: string[]): string {
201
+ return renderParts(
202
+ keys.map(key => `'${key}'`),
203
+ CONJUNCTION_AND,
204
+ CONJUNCTION_AND_COMMA,
205
+ );
206
+ }
170
207
 
171
- if (unique.has(rendered)) {
172
- continue;
173
- }
208
+ function renderParts(parts: string[], delimiterShort: string, delimiterLong: string): string {
209
+ const {length} = parts;
174
210
 
175
- unique.add(rendered);
176
- parts.push(rendered);
211
+ if (length === 1) {
212
+ return parts[0];
177
213
  }
178
214
 
179
- const {length} = parts;
180
-
181
215
  let rendered = '';
182
216
 
183
217
  for (let index = 0; index < length; index += 1) {
184
218
  rendered += parts[index];
185
219
 
186
220
  if (index < length - 2) {
187
- rendered += ', ';
221
+ rendered += COMMA;
188
222
  } else if (index === length - 2) {
189
- rendered += parts.length > 2 ? ', or ' : ' or ';
223
+ rendered += parts.length > 2 ? delimiterLong : delimiterShort;
190
224
  }
191
225
  }
192
226
 
193
227
  return rendered;
194
228
  }
229
+
230
+ function renderTypes(types: ValidatedPropertyType[]): string {
231
+ const unique = new Set<string>();
232
+ const parts: string[] = [];
233
+
234
+ for (let index = 0; index < types.length; index += 1) {
235
+ const rendered = getPropertyType(types[index]);
236
+
237
+ if (unique.has(rendered)) {
238
+ continue;
239
+ }
240
+
241
+ unique.add(rendered);
242
+ parts.push(rendered);
243
+ }
244
+
245
+ return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
246
+ }
@@ -6,7 +6,7 @@ import type {PlainSchema, Schema, SchemaProperty} from './schema.plain.model';
6
6
  /**
7
7
  * Infers the TypeScript type from a {@link Schema} definition
8
8
  *
9
- * @template Model - Schema to infer types from
9
+ * @template Model Schema to infer types from
10
10
  *
11
11
  * @example
12
12
  * ```ts
@@ -38,20 +38,20 @@ export type InferOptionalKeys<Model extends Schema> = keyof {
38
38
  };
39
39
 
40
40
  /**
41
- * Infers the TypeScript type of a {@link SchemaProperty}'s `$type` field, unwrapping arrays to infer their item type
41
+ * Infers the TypeScript type from a {@link SchemaProperty}'s `$type` field
42
42
  *
43
- * @template Value - `$type` value _(single or array)_
43
+ * @template Value `$type` value _(single or array)_
44
44
  */
45
45
  export type InferPropertyType<Value> = Value extends (infer Item)[]
46
46
  ? InferPropertyValue<Item>
47
47
  : InferPropertyValue<Value>;
48
48
 
49
49
  /**
50
- * Maps a single type definition to its TypeScript equivalent
50
+ * Maps a single `$type` definition to its TypeScript equivalent
51
51
  *
52
- * Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link Schema} objects
52
+ * Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link PlainSchema} objects
53
53
  *
54
- * @template Value - single type definition
54
+ * @template Value single type definition
55
55
  */
56
56
  export type InferPropertyValue<Value> =
57
57
  Value extends Constructor<infer Instance>
@@ -67,27 +67,27 @@ export type InferPropertyValue<Value> =
67
67
  /**
68
68
  * Extracts keys from a {@link Schema} whose entries are required _(i.e., `$required` is not `false`)_
69
69
  *
70
- * @template Model - Schema to extract required keys from
70
+ * @template Model Schema to extract required keys from
71
71
  */
72
72
  export type InferRequiredKeys<Model extends Schema> = keyof {
73
73
  [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never;
74
74
  };
75
75
 
76
76
  /**
77
- * Infers the type for a top-level {@link Schema} entry, unwrapping arrays to infer their item type
77
+ * Infers the TypeScript type from a top-level {@link Schema} entry
78
78
  *
79
- * @template Value - Schema entry value _(single or array)_
79
+ * @template Value Schema entry value _(single or array)_
80
80
  */
81
81
  export type InferSchemaEntry<Value> = Value extends (infer Item)[]
82
82
  ? InferSchemaEntryValue<Item>
83
83
  : InferSchemaEntryValue<Value>;
84
84
 
85
85
  /**
86
- * Resolves a single schema entry to its TypeScript type
86
+ * Maps a single top-level schema entry to its TypeScript type
87
87
  *
88
- * Handles, in order: {@link Constructor} instances, {@link Schematic} models, {@link SchemaProperty} objects, {@link NestedSchema} objects, {@link ValueName} strings, and plain {@link Schema} objects
88
+ * Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link SchemaProperty} objects, {@link PlainSchema} objects, and {@link ValueName} strings
89
89
  *
90
- * @template Value - single schema entry
90
+ * @template Value single schema entry
91
91
  */
92
92
  export type InferSchemaEntryValue<Value> =
93
93
  Value extends Constructor<infer Instance>
@@ -3,8 +3,8 @@ import type {SchemaProperty} from './schema.plain.model';
3
3
  /**
4
4
  * Removes duplicate types from a tuple, preserving first occurrence order
5
5
  *
6
- * @template Value - Tuple to deduplicate
7
- * @template Seen - Accumulator for already-seen types _(internal)_
6
+ * @template Value Tuple to deduplicate
7
+ * @template Seen Accumulator for already-seen types _(internal)_
8
8
  *
9
9
  * @example
10
10
  * ```ts
@@ -24,7 +24,7 @@ export type DeduplicateTuple<Value extends unknown[], Seen extends unknown[] = [
24
24
  /**
25
25
  * Recursively extracts {@link ValueName} strings from a type, unwrapping arrays and readonly arrays
26
26
  *
27
- * @template Value - Type to extract value names from
27
+ * @template Value Type to extract value names from
28
28
  *
29
29
  * @example
30
30
  * ```ts
@@ -43,9 +43,9 @@ export type ExtractValueNames<Value> = Value extends ValueName
43
43
  /**
44
44
  * Determines whether a schema entry is optional
45
45
  *
46
- * Returns `true` if the entry is a {@link SchemaProperty} or {@link NestedSchema} with `$required` set to `false`; otherwise returns `false`
46
+ * Returns `true` if the entry is a {@link SchemaProperty} with `$required` set to `false`; otherwise returns `false`
47
47
  *
48
- * @template Value - Schema entry to check
48
+ * @template Value Schema entry to check
49
49
  */
50
50
  export type IsOptionalProperty<Value> = Value extends SchemaProperty
51
51
  ? Value['$required'] extends false
@@ -54,9 +54,9 @@ export type IsOptionalProperty<Value> = Value extends SchemaProperty
54
54
  : false;
55
55
 
56
56
  /**
57
- * Extracts the last member from a union type by leveraging intersection of function return types
57
+ * Extracts the last member from a union type by leveraging contravariance of function parameter types
58
58
  *
59
- * @template Value - Union type
59
+ * @template Value Union type
60
60
  */
61
61
  export type LastOfUnion<Value> =
62
62
  UnionToIntersection<Value extends unknown ? () => Value : never> extends () => infer Item
@@ -66,7 +66,7 @@ export type LastOfUnion<Value> =
66
66
  /**
67
67
  * Extracts keys from an object type that are optional
68
68
  *
69
- * @template Value - Object type to inspect
69
+ * @template Value Object type to inspect
70
70
  */
71
71
  export type OptionalKeys<Value> = {
72
72
  [Key in keyof Value]-?: {} extends Pick<Value, Key> ? Key : never;
@@ -75,7 +75,7 @@ export type OptionalKeys<Value> = {
75
75
  /**
76
76
  * Extracts keys from an object type that are required _(i.e., not optional)_
77
77
  *
78
- * @template Value - Object type to inspect
78
+ * @template Value Object type to inspect
79
79
  */
80
80
  export type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
81
81
 
@@ -84,8 +84,8 @@ export type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
84
84
  *
85
85
  * Used by {@link UnwrapSingle} to allow schema types in any order for small tuples _(length ≤ 5)_
86
86
  *
87
- * @template Tuple - Tuple to permute
88
- * @template Elput - Accumulator for the current permutation _(internal; name is Tuple backwards)_
87
+ * @template Tuple Tuple to permute
88
+ * @template Elput Accumulator for the current permutation _(internal; name is Tuple backwards)_
89
89
  *
90
90
  * @example
91
91
  * ```ts
@@ -110,9 +110,9 @@ export type TuplePermutations<
110
110
  *
111
111
  * Used internally by {@link TuplePermutations}
112
112
  *
113
- * @template Items - Tuple to remove from
114
- * @template Item - Stringified index to remove
115
- * @template Prefix - Accumulator for elements before the target _(internal)_
113
+ * @template Items Tuple to remove from
114
+ * @template Item Index as a string literal
115
+ * @template Prefix Accumulator for elements before the target _(internal)_
116
116
  */
117
117
  export type TupleRemoveAt<
118
118
  Items extends unknown[],
@@ -129,7 +129,7 @@ export type TupleRemoveAt<
129
129
  *
130
130
  * Uses the contravariance of function parameter types to collapse a union into an intersection
131
131
  *
132
- * @template Value - Union type to convert
132
+ * @template Value Union type to convert
133
133
  *
134
134
  * @example
135
135
  * ```ts
@@ -148,8 +148,8 @@ export type UnionToIntersection<Value> = (
148
148
  *
149
149
  * Repeatedly extracts the {@link LastOfUnion} member and prepends it to the accumulator
150
150
  *
151
- * @template Value - Union type to convert
152
- * @template Items - Accumulator for the resulting tuple _(internal)_
151
+ * @template Value Union type to convert
152
+ * @template Items Accumulator for the resulting tuple _(internal)_
153
153
  *
154
154
  * @example
155
155
  * ```ts
@@ -166,7 +166,7 @@ export type UnionToTuple<Value, Items extends unknown[] = []> = [Value] extends
166
166
  *
167
167
  * For tuples of length 2–5, returns all {@link TuplePermutations} to allow types in any order. Longer tuples are returned as-is
168
168
  *
169
- * @template Value - Tuple to potentially unwrap
169
+ * @template Value Tuple to potentially unwrap
170
170
  *
171
171
  * @example
172
172
  * ```ts
@@ -181,21 +181,12 @@ export type UnwrapSingle<Value extends unknown[]> = Value extends [infer Only]
181
181
  : Value;
182
182
 
183
183
  /**
184
- * Basic value types
184
+ * A union of valid type name strings, e.g. `'string'`, `'number'`, `'date'`
185
185
  */
186
186
  export type ValueName = keyof Values;
187
187
 
188
188
  /**
189
- * Maps type name strings to their TypeScript equivalents
190
- *
191
- * Used by the type system to resolve {@link ValueName} strings into actual types
192
- *
193
- * @example
194
- * ```ts
195
- * // Values['string'] => string
196
- * // Values['date'] => Date
197
- * // Values['null'] => null
198
- * ```
189
+ * Maps {@link ValueName} strings to their TypeScript equivalents
199
190
  */
200
191
  export type Values = {
201
192
  array: unknown[];
@@ -3,7 +3,7 @@ import type {Schematic} from '../schematic';
3
3
  import type {ExtractValueNames, ValueName, Values} from './misc.model';
4
4
 
5
5
  /**
6
- * A generic schema allowing {@link NestedSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry} as values
6
+ * A generic schema allowing nested schemas, {@link SchemaEntry} values, or arrays of {@link SchemaEntry} as values
7
7
  */
8
8
  export type PlainSchema = {
9
9
  [key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
@@ -30,7 +30,7 @@ export type Schema = SchemaIndex;
30
30
  /**
31
31
  * A union of all valid types for a single schema entry
32
32
  *
33
- * Can be a {@link Constructor}, nested {@link Schema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
33
+ * Can be a {@link Constructor}, {@link PlainSchema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
34
34
  */
35
35
  export type SchemaEntry =
36
36
  | Constructor
@@ -41,7 +41,7 @@ export type SchemaEntry =
41
41
  | ((value: unknown) => boolean);
42
42
 
43
43
  /**
44
- * Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link NestedSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
44
+ * Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link PlainSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
45
45
  */
46
46
  export interface SchemaIndex {
47
47
  [key: string]: PlainSchema | SchemaEntry | SchemaEntry[];
@@ -94,7 +94,7 @@ export type SchemaPropertyType =
94
94
  *
95
95
  * Each key may hold a single validator or an array of validators that receive the typed value
96
96
  *
97
- * @template Value - `$type` value(s) to derive validator keys from
97
+ * @template Value `$type` value(s) to derive validator keys from
98
98
  *
99
99
  * @example
100
100
  * ```ts
@@ -7,7 +7,7 @@ import type {ToSchemaPropertyType, ToSchemaType} from './transform.model';
7
7
  /**
8
8
  * A typed optional property definition generated by {@link TypedSchema} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
9
9
  *
10
- * @template Value - Property's type _(including `undefined`)_
10
+ * @template Value Property's type _(including `undefined`)_
11
11
  *
12
12
  * @example
13
13
  * ```ts
@@ -17,24 +17,15 @@ import type {ToSchemaPropertyType, ToSchemaType} from './transform.model';
17
17
  * ```
18
18
  */
19
19
  export type TypedPropertyOptional<Value> = {
20
- /**
21
- * The property is not required
22
- */
23
20
  $required: false;
24
- /**
25
- * The type(s) of the property
26
- */
27
21
  $type: ToSchemaPropertyType<Exclude<Value, undefined>>;
28
- /**
29
- * Custom validators for the property and its types
30
- */
31
22
  $validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
32
23
  };
33
24
 
34
25
  /**
35
26
  * A typed required property definition generated by {@link TypedSchema} for required keys, with `$required` defaulting to `true`
36
27
  *
37
- * @template Value - Property's type
28
+ * @template Value Property's type
38
29
  *
39
30
  * @example
40
31
  * ```ts
@@ -44,17 +35,8 @@ export type TypedPropertyOptional<Value> = {
44
35
  * ```
45
36
  */
46
37
  export type TypedPropertyRequired<Value> = {
47
- /**
48
- * The property is required _(defaults to `true`)_
49
- */
50
38
  $required?: true;
51
- /**
52
- * The type(s) of the property
53
- */
54
39
  $type: ToSchemaPropertyType<Value>;
55
- /**
56
- * Custom validators for the property and its types
57
- */
58
40
  $validators?: PropertyValidators<ToSchemaPropertyType<Value>>;
59
41
  };
60
42
 
@@ -63,7 +45,7 @@ export type TypedPropertyRequired<Value> = {
63
45
  *
64
46
  * Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link Schematic}. Optional keys map to {@link TypedPropertyOptional} or, for plain objects, {@link TypedSchemaOptional}
65
47
  *
66
- * @template Model - Object type to generate a schema for
48
+ * @template Model Object type to generate a schema for
67
49
  *
68
50
  * @example
69
51
  * ```ts
@@ -93,7 +75,7 @@ export type TypedSchema<Model extends PlainObject> = Simplify<
93
75
  /**
94
76
  * A {@link TypedSchema} variant for optional nested objects, with `$required` fixed to `false`
95
77
  *
96
- * @template Model - Nested object type
78
+ * @template Model Nested object type
97
79
  */
98
80
  type TypedSchemaOptional<Model extends PlainObject> = {
99
81
  $required: false;
@@ -102,7 +84,7 @@ type TypedSchemaOptional<Model extends PlainObject> = {
102
84
  /**
103
85
  * A {@link TypedSchema} variant for required nested objects, with `$required` defaulting to `true`
104
86
  *
105
- * @template Model - Nested object type
87
+ * @template Model Nested object type
106
88
  */
107
89
  type TypedSchemaRequired<Model extends PlainObject> = {
108
90
  $required?: true;