@lucania/schema 3.0.4 → 3.1.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/README.md CHANGED
@@ -1,126 +1,126 @@
1
- # Schema
2
-
3
- | TECHNICAL | |
4
- | :-------: | -------------------------------------------------------------------------- |
5
- | _noun_ | _a representation of a plan or theory in the form of an outline or model._ |
6
-
7
- This library allows you to specify the schema for your data, and get compile time typings _(help from your IDE)_ and runtime validation _(throw errors if your data isn't in the right format)_.
8
-
9
- With this library, you create objects that serve as a blueprint for what your data should look like. These objects are called `Schema`s.
10
-
11
- | _Schema Type_ | Description | Usage | Example Data |
12
- | :-------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
13
- | `StringSchema` | Used to represent a string. | `$.String(required?: boolean, default?: StringSource)` | `"Moaaz"`, `"The cow jumped over the moon."` |
14
- | `NumberSchema` | Used to represent a number. | `$.Number(required?: boolean, default?: NumberSource)` | `-30`, `0`, `10` |
15
- | `BooleanSchema` | Used to represent a boolean. | `$.Boolean(required?: boolean, default?: BooleanSource)` | `true`, `false` |
16
- | `DateSchema` | Used to represent a Date. | `$.Date(required?: boolean, default?: DateSource)` | `new Date(2000, 9, 29)`, `new Date("1998-09-04")` |
17
- | `ObjectSchema` | Used to represent an Object. | `$.Object(subschema: { <key>: Schema }, required?: boolean, default?: ObjectSource)` | `<depends on subschema>`, `{ name: "Jeremy", age: 23 }`, `{ make: "Toyota", model: "Sienna", year: 2011 }` |
18
- | `ArraySchema` | Used to represent an array | `$.Array(subschema: Schema, required?: boolean, default?: ArraySource)` | `<depends on subschema>`, `[]`, `[1, 2, 3]`, `["Ben", "Amit", "Dean"]` |
19
- | `EnumerationSchema` | Used to represent an enumeration value, otherwise known as a set of possible strings values. | `$.Enumeration(members: Members, required?: boolean, default?: EnumerationSource)` | `<depends on members>`, `"MAGENTA"`, `"CA"`, `"male"` |
20
- | `OrSetSchema` | Used to represent a value that should be validated by one of many possible schemas. This is used to represent a value that is allowed to be multiple types. | `$.OrSet(members: Members, required?: boolean, default?: OrSetSource)` | `<depends on members>` |
21
- | `DynamicObjectSchema` | Used to represent an object that could have many different keys. | `$.DynamicObject(subschema: Schema, required?: boolean, default?: DynamicObjectSource)` | `{ <any key>: <depends on subschema> }` |
22
- | `AnySchema` | Used to represent a value that could be any type. | `$.Any(required?: boolean, default?: AnySource)` | `1`, `"Omar"`, `false`, `{}`, `[]`, `<any type>` |
23
-
24
- ## Validation
25
-
26
- The simplest possible validation:
27
-
28
- ```typescript
29
- import { $ } from "@lucania/schema";
30
-
31
- // Create a Schema to represent a number.
32
- const numberSchema = $.Number();
33
-
34
- // Some data with an unknown type, likely coming from a file, network or untyped library.
35
- const dataOfUnknownType: any = 123;
36
-
37
- // Using our number Schema to validate that our untyped data is what we expect it to be, a number. "dataOfNumberType" now has the "number" type.
38
- const dataOfNumberType = numberSchema.validate(dataOfUnknownType);
39
- ```
40
-
41
- With this collection of Schemas, we can now start building more complex data structures. There are multiple way to represent different scenarios. This is done with the following constructs.
42
-
43
- ## Creating Hierarchical Schema
44
-
45
- These schemas can come together to allow you to define a blueprint for more complex data structures.
46
-
47
- ```typescript
48
- import { $ } from "@lucania/schema";
49
-
50
- const WeaponSchema = $.Object({
51
- damage: $.Number(true).clamp(0, 100),
52
- forged: $.Date(false),
53
- affixtures: $.DynamicObject($.String())
54
- });
55
-
56
- const PersonSchema = $.Object({
57
- name: $.Object({
58
- first: $.String(true),
59
- middle: $.String(false),
60
- last: $.String(true)
61
- }),
62
- favoriteNumber: $.Number(true).ensure((data, pass) => data % 2 === 0, "Your favorite number must be a multiple of 2!"),
63
- age: $.Number(true).min(16, "You must be at least 16 years old!").max(100, "You must be at most 100 years old!"),
64
- weapon: WeaponSchema
65
- });
66
- ```
67
-
68
- ## Using Schema
69
-
70
- With the schema definitions created, they can be used to validate data where the types are unknown. This data might come from fetch requests, information read from disk, or even JavaScript libraries that don't export their own type definitions, just to name a few examples.
71
-
72
- ```typescript
73
- import fs from "fs";
74
-
75
- const personData = JSON.parse(fs.readFileSync("person.json", "utf8"));
76
- const person = PersonSchema.validate(personData);
77
- ```
78
-
79
- `person` now has the following compile-time type annotation based on [`PersonSchema`](#creating-hierarchical-schema).
80
-
81
- At runtime, the object parsed from the `person.json` file will be validated to match this generated typing. If it does not match, a `Schema.ValidationError` will be thrown.
82
-
83
- ## Additional Validation Passes
84
-
85
- Sometimes it's necessary to validate not only a type, but also specifics about the value. I.E. a value is a `$.Number` _and_ is between 0 and 100. You can add additional type-specific validation passes (I.E. `.clamp(...)`) or custom ones (`.custom(...)`):
86
-
87
- ```typescript
88
- const numberData: any = ...;
89
-
90
- const ScoreSchema = $.Number().clamp(0, 100).custom((data, pass) => {
91
- pass.assert(data % 2 === 0, "Your score must be even!");
92
- return data;
93
- });
94
-
95
- // The above custom() validation pass can alternately be defined using the .ensure() shorthand.
96
-
97
- const ScoreSchema = $.Number().clamp(0, 100).ensure((data, pass) => data % 2 === 0, "Your score must be even!");
98
-
99
- const number: number = ScoreSchema.validate(numberData);
100
- ```
101
-
102
- ## Custom Schema Types
103
-
104
- You can define your own Schema types by creating a subclass of `BaseSchema`. But first, `BaseSchema` relies on 4 generic parameters for TypeScript's type checker to understand your Schema at compile time. These parameters are as follows:
105
-
106
- - Source - Represents the typing for a source input to your schema.
107
- - Model - Represents the typing for an output value from your schema.
108
- - Required - Represents the presence optionality of your schema's Source/Model. (Is `undefined` a valid Source and Model)
109
- - Default - Represents the typing for default values.
110
-
111
- Typically, when developing your own Schema types, you'll hardcode Source and Model for your specific Schema's requirements, but pass over `Required` and `Default` generics to `BaseSchema` to allow them to be inferred from your Schema definitions.
112
-
113
- ```typescript
114
- export type CowModel = { name: string, numberOfSpots: number };
115
-
116
- export type CowSource = string | CowModel;
117
-
118
- export class CowSchema<
119
- Required extends boolean, // Taking in "Required" generic.
120
- Default extends DefaultValue<CowSource> // Taking in "Default" generic.
121
-
122
- // Handing over hardcoded Source, Model and CowSchema generics to BaseSchema.
123
- > extends BaseSchema<CowSource, CowModel, Required, Default> { ... }
124
- ```
125
-
126
- These declarations are enough to have the TypeScript type checker understand the compile-time typing for `CowSchema`. Next, lets implement our runtime checks.
1
+ # Schema
2
+
3
+ | TECHNICAL | |
4
+ | :-------: | -------------------------------------------------------------------------- |
5
+ | _noun_ | _a representation of a plan or theory in the form of an outline or model._ |
6
+
7
+ This library allows you to specify the schema for your data, and get compile time typings _(help from your IDE)_ and runtime validation _(throw errors if your data isn't in the right format)_.
8
+
9
+ With this library, you create objects that serve as a blueprint for what your data should look like. These objects are called `Schema`s.
10
+
11
+ | _Schema Type_ | Description | Usage | Example Data |
12
+ | :-------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- |
13
+ | `StringSchema` | Used to represent a string. | `$.String(required?: boolean, default?: StringSource)` | `"Moaaz"`, `"The cow jumped over the moon."` |
14
+ | `NumberSchema` | Used to represent a number. | `$.Number(required?: boolean, default?: NumberSource)` | `-30`, `0`, `10` |
15
+ | `BooleanSchema` | Used to represent a boolean. | `$.Boolean(required?: boolean, default?: BooleanSource)` | `true`, `false` |
16
+ | `DateSchema` | Used to represent a Date. | `$.Date(required?: boolean, default?: DateSource)` | `new Date(2000, 9, 29)`, `new Date("1998-09-04")` |
17
+ | `ObjectSchema` | Used to represent an Object. | `$.Object(subschema: { <key>: Schema }, required?: boolean, default?: ObjectSource)` | `<depends on subschema>`, `{ name: "Jeremy", age: 23 }`, `{ make: "Toyota", model: "Sienna", year: 2011 }` |
18
+ | `ArraySchema` | Used to represent an array | `$.Array(subschema: Schema, required?: boolean, default?: ArraySource)` | `<depends on subschema>`, `[]`, `[1, 2, 3]`, `["Ben", "Amit", "Dean"]` |
19
+ | `EnumerationSchema` | Used to represent an enumeration value, otherwise known as a set of possible strings values. | `$.Enumeration(members: Members, required?: boolean, default?: EnumerationSource)` | `<depends on members>`, `"MAGENTA"`, `"CA"`, `"male"` |
20
+ | `OrSetSchema` | Used to represent a value that should be validated by one of many possible schemas. This is used to represent a value that is allowed to be multiple types. | `$.OrSet(members: Members, required?: boolean, default?: OrSetSource)` | `<depends on members>` |
21
+ | `DynamicObjectSchema` | Used to represent an object that could have many different keys. | `$.DynamicObject(subschema: Schema, required?: boolean, default?: DynamicObjectSource)` | `{ <any key>: <depends on subschema> }` |
22
+ | `AnySchema` | Used to represent a value that could be any type. | `$.Any(required?: boolean, default?: AnySource)` | `1`, `"Omar"`, `false`, `{}`, `[]`, `<any type>` |
23
+
24
+ ## Validation
25
+
26
+ The simplest possible validation:
27
+
28
+ ```typescript
29
+ import { $ } from "@lucania/schema";
30
+
31
+ // Create a Schema to represent a number.
32
+ const numberSchema = $.Number();
33
+
34
+ // Some data with an unknown type, likely coming from a file, network or untyped library.
35
+ const dataOfUnknownType: any = 123;
36
+
37
+ // Using our number Schema to validate that our untyped data is what we expect it to be, a number. "dataOfNumberType" now has the "number" type.
38
+ const dataOfNumberType = numberSchema.validate(dataOfUnknownType);
39
+ ```
40
+
41
+ With this collection of Schemas, we can now start building more complex data structures. There are multiple way to represent different scenarios. This is done with the following constructs.
42
+
43
+ ## Creating Hierarchical Schema
44
+
45
+ These schemas can come together to allow you to define a blueprint for more complex data structures.
46
+
47
+ ```typescript
48
+ import { $ } from "@lucania/schema";
49
+
50
+ const WeaponSchema = $.Object({
51
+ damage: $.Number(true).clamp(0, 100),
52
+ forged: $.Date(false),
53
+ affixtures: $.DynamicObject($.String())
54
+ });
55
+
56
+ const PersonSchema = $.Object({
57
+ name: $.Object({
58
+ first: $.String(true),
59
+ middle: $.String(false),
60
+ last: $.String(true)
61
+ }),
62
+ favoriteNumber: $.Number(true).ensure((data, pass) => data % 2 === 0, "Your favorite number must be a multiple of 2!"),
63
+ age: $.Number(true).min(16, "You must be at least 16 years old!").max(100, "You must be at most 100 years old!"),
64
+ weapon: WeaponSchema
65
+ });
66
+ ```
67
+
68
+ ## Using Schema
69
+
70
+ With the schema definitions created, they can be used to validate data where the types are unknown. This data might come from fetch requests, information read from disk, or even JavaScript libraries that don't export their own type definitions, just to name a few examples.
71
+
72
+ ```typescript
73
+ import fs from "fs";
74
+
75
+ const personData = JSON.parse(fs.readFileSync("person.json", "utf8"));
76
+ const person = PersonSchema.validate(personData);
77
+ ```
78
+
79
+ `person` now has the following compile-time type annotation based on [`PersonSchema`](#creating-hierarchical-schema).
80
+
81
+ At runtime, the object parsed from the `person.json` file will be validated to match this generated typing. If it does not match, a `Schema.ValidationError` will be thrown.
82
+
83
+ ## Additional Validation Passes
84
+
85
+ Sometimes it's necessary to validate not only a type, but also specifics about the value. I.E. a value is a `$.Number` _and_ is between 0 and 100. You can add additional type-specific validation passes (I.E. `.clamp(...)`) or custom ones (`.custom(...)`):
86
+
87
+ ```typescript
88
+ const numberData: any = ...;
89
+
90
+ const ScoreSchema = $.Number().clamp(0, 100).custom((data, pass) => {
91
+ pass.assert(data % 2 === 0, "Your score must be even!");
92
+ return data;
93
+ });
94
+
95
+ // The above custom() validation pass can alternately be defined using the .ensure() shorthand.
96
+
97
+ const ScoreSchema = $.Number().clamp(0, 100).ensure((data, pass) => data % 2 === 0, "Your score must be even!");
98
+
99
+ const number: number = ScoreSchema.validate(numberData);
100
+ ```
101
+
102
+ ## Custom Schema Types
103
+
104
+ You can define your own Schema types by creating a subclass of `BaseSchema`. But first, `BaseSchema` relies on 4 generic parameters for TypeScript's type checker to understand your Schema at compile time. These parameters are as follows:
105
+
106
+ - Source - Represents the typing for a source input to your schema.
107
+ - Model - Represents the typing for an output value from your schema.
108
+ - Required - Represents the presence optionality of your schema's Source/Model. (Is `undefined` a valid Source and Model)
109
+ - Default - Represents the typing for default values.
110
+
111
+ Typically, when developing your own Schema types, you'll hardcode Source and Model for your specific Schema's requirements, but pass over `Required` and `Default` generics to `BaseSchema` to allow them to be inferred from your Schema definitions.
112
+
113
+ ```typescript
114
+ export type CowModel = { name: string, numberOfSpots: number };
115
+
116
+ export type CowSource = string | CowModel;
117
+
118
+ export class CowSchema<
119
+ Required extends boolean, // Taking in "Required" generic.
120
+ Default extends DefaultValue<CowSource> // Taking in "Default" generic.
121
+
122
+ // Handing over hardcoded Source, Model and CowSchema generics to BaseSchema.
123
+ > extends BaseSchema<CowSource, CowModel, Required, Default> { ... }
124
+ ```
125
+
126
+ These declarations are enough to have the TypeScript type checker understand the compile-time typing for `CowSchema`. Next, lets implement our runtime checks.
@@ -1,18 +1,18 @@
1
- import { BaseSchema, SourceValue } from ".";
2
1
  import { AnySchema } from "./schema/AnySchema";
3
2
  import { ArraySchema, ArraySource } from "./schema/ArraySchema";
3
+ import { BaseSchema } from "./schema/BaseSchema";
4
4
  import { BooleanSchema, BooleanSource } from "./schema/BooleanSchema";
5
5
  import { ConstantSchema, ConstantSource } from "./schema/ConstantSchema";
6
6
  import { DateSchema, DateSource } from "./schema/DateSchema";
7
7
  import { DynamicObjectSchema, DynamicObjectSource } from "./schema/DynamicObjectSchema";
8
- import { EnumerationSchema } from "./schema/EnumerationSchema";
8
+ import { EnumerationSchema, EnumerationSource } from "./schema/EnumerationSchema";
9
9
  import { LenientObjectModel, LenientObjectSchema, LenientObjectSource, LenientObjectSubschema } from "./schema/LenientObject";
10
10
  import { NumberSchema, NumberSource } from "./schema/NumberSchema";
11
11
  import { ObjectSchema, ObjectSource, ObjectSubschema } from "./schema/ObjectSchema";
12
12
  import { OrSetSchema, OrSetSchemaSource } from "./schema/OrSetSchema";
13
13
  import { StringSchema, StringSource } from "./schema/StringSchema";
14
14
  import { BaseSchemaAny } from "./typing/extended";
15
- import { DefaultValue, ModelValue } from "./typing/toolbox";
15
+ import { DefaultValue, ModelValue, SourceValue } from "./typing/toolbox";
16
16
  /**
17
17
  * A collection of helper functions used to create the standard set of schemas.
18
18
  */
@@ -144,21 +144,19 @@ export declare namespace Schema {
144
144
  function Array<Subschema extends BaseSchemaAny>(subschema: Subschema): ArraySchema<Subschema, true, undefined>;
145
145
  function Array<Subschema extends BaseSchemaAny, Required extends boolean>(subschema: Subschema, required: Required): ArraySchema<Subschema, Required, undefined>;
146
146
  function Array<Subschema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<ArraySource<Subschema>>>(subschema: Subschema, required: Required, defaultValue: Default): ArraySchema<Subschema, Required, Default>;
147
- function Enumeration<Member extends string>(subschema: TypedMembers<Member>): EnumerationSchema<Member, true, undefined>;
148
- function Enumeration<Member extends string, Required extends boolean>(subschema: TypedMembers<Member>, required: Required): EnumerationSchema<Member, Required, undefined>;
149
- function Enumeration<Member extends string, Required extends boolean, Default extends DefaultValue<Member>>(subschema: TypedMembers<Member>, required: Required, defaultValue: Default): EnumerationSchema<Member, Required, Default>;
150
- function OrSet<MemberSchema extends BaseSchemaAny>(subschema: TypedMembers<MemberSchema>): OrSetSchema<MemberSchema, true, undefined>;
151
- function OrSet<MemberSchema extends BaseSchemaAny, Required extends boolean>(subschema: TypedMembers<MemberSchema>, required: Required): OrSetSchema<MemberSchema, Required, undefined>;
152
- function OrSet<MemberSchema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchema>>>(subschema: TypedMembers<MemberSchema>, required: Required, defaultValue: Default): OrSetSchema<MemberSchema, Required, Default>;
147
+ function Enumeration<Members extends string[]>(subschema: TypedMembers<Members>): EnumerationSchema<Members, true, undefined>;
148
+ function Enumeration<Members extends string[], Required extends boolean>(subschema: TypedMembers<Members>, required: Required): EnumerationSchema<Members, Required, undefined>;
149
+ function Enumeration<Members extends string[], Required extends boolean, Default extends DefaultValue<EnumerationSource<Members>>>(subschema: TypedMembers<Members>, required: Required, defaultValue: Default): EnumerationSchema<Members, Required, Default>;
150
+ function OrSet<MemberSchemas extends BaseSchemaAny[]>(subschema: TypedMembers<MemberSchemas>): OrSetSchema<MemberSchemas, true, undefined>;
151
+ function OrSet<MemberSchemas extends BaseSchemaAny[], Required extends boolean>(subschema: TypedMembers<MemberSchemas>, required: Required): OrSetSchema<MemberSchemas, Required, undefined>;
152
+ function OrSet<MemberSchemas extends BaseSchemaAny[], Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchemas>>>(subschema: TypedMembers<MemberSchemas>, required: Required, defaultValue: Default): OrSetSchema<MemberSchemas, Required, Default>;
153
153
  function Constant<Constant extends ConstantSource>(constant: Constant): ConstantSchema<Constant, true, undefined>;
154
154
  function Constant<Constant extends ConstantSource, Required extends boolean>(constant: Constant, required: Required): ConstantSchema<Constant, Required, undefined>;
155
155
  function Constant<Constant extends ConstantSource, Required extends boolean, Default extends DefaultValue<Constant>>(constant: Constant, required: Required, defaultValue: Default): ConstantSchema<Constant, Required, Default>;
156
- type TypedMembers<Member extends any> = {
157
- $members: Member[];
156
+ type TypedMembers<Members extends readonly any[]> = {
157
+ $members: Members;
158
158
  };
159
- function Members<Member extends string[]>(...members: Member): TypedMembers<Member[number]>;
160
- function Members<Member extends number[]>(...members: Member): TypedMembers<Member[number]>;
161
- function Members<Member extends any[]>(...members: Member): TypedMembers<Member[number]>;
159
+ function Members<const Members extends any[]>(...members: Members): TypedMembers<Members>;
162
160
  function Keys<Object extends object>(object: Object): (keyof Object)[];
163
161
  function Values<Object extends object>(object: Object): (Object[keyof Object])[];
164
162
  type Model<Schema extends BaseSchemaAny> = Schema extends BaseSchema<infer Source, infer Model, infer Require, infer Default> ? (ModelValue<Source, Model, Require, Default>) : never;
package/build/index.js CHANGED
@@ -755,7 +755,7 @@
755
755
  this.schemas = schemas;
756
756
  }
757
757
  get type() {
758
- return "string";
758
+ return "OrSet";
759
759
  }
760
760
  _validate(source, options, pass) {
761
761
  const errors = {};
@@ -775,35 +775,6 @@
775
775
  throw pass.causeError(`Provided value (${BaseSchema.getType(source)}) matched no schemas ` +
776
776
  `(${this.schemas.map((schema) => schema.type).join(", ")}).\n` +
777
777
  `${errorMessages.join("\n")}`);
778
- // let result = source;
779
- // if (result !== undefined) {
780
- // let done = false;
781
- // const failureMessages: string[] = [];
782
- // for (let i = 0; i < this.schemas.length && !done; i++) {
783
- // const schema = this.schemas[i];
784
- // try {
785
- // if (BaseSchema.getType(result) === schema.type) {
786
- // result = schema.validate(result, options, pass);
787
- // done = true;
788
- // }
789
- // } catch (error) {
790
- // if (error instanceof Error) {
791
- // failureMessages.push(`Schema #${i + 1}: ${error.message}`);
792
- // } else {
793
- // failureMessages.push(`Schema #${i + 1}: ${String(error)}`);
794
- // }
795
- // }
796
- // }
797
- // if (!done) {
798
- // failureMessages.push(`Conversions for schemas in an OrSet are disabled.`);
799
- // }
800
- // pass.assert(
801
- // failureMessages.length === 0,
802
- // `Provided value (${BaseSchema.getType(result)}) matched no schemas ` +
803
- // `(${this.schemas.map((schema) => schema.type).join(", ")}).\n${failureMessages.join("\n")}`
804
- // );
805
- // }
806
- // return result;
807
778
  }
808
779
  convert(value, pass) {
809
780
  return value;
@@ -926,12 +897,12 @@
926
897
  return new ArraySchema(subschema, required, defaultValue);
927
898
  }
928
899
  Schema.Array = Array;
929
- function Enumeration(members, required = true, defaultValue = undefined) {
930
- return new EnumerationSchema(members.$members, required, defaultValue);
900
+ function Enumeration({ $members }, required = true, defaultValue = undefined) {
901
+ return new EnumerationSchema($members, required, defaultValue);
931
902
  }
932
903
  Schema.Enumeration = Enumeration;
933
- function OrSet(members, required = true, defaultValue = undefined) {
934
- return new OrSetSchema(members.$members, required, defaultValue);
904
+ function OrSet({ $members }, required = true, defaultValue = undefined) {
905
+ return new OrSetSchema($members, required, defaultValue);
935
906
  }
936
907
  Schema.OrSet = OrSet;
937
908
  function Constant(value, required = true, defaultValue = undefined) {
@@ -939,15 +910,6 @@
939
910
  }
940
911
  Schema.Constant = Constant;
941
912
  function Members(...members) {
942
- /*
943
- * HACK START: The hermes JS engine doesn't use globalThis.Array when interpreting `...members`
944
- * It uses `Array`, which is already defined in this namespace.
945
- */
946
- if (!globalThis.Array.isArray(members)) {
947
- const validArrayEntries = globalThis.Object.entries(members).filter(([key]) => !isNaN(key));
948
- members = validArrayEntries.map(([_, value]) => value);
949
- }
950
- /* HACK END */
951
913
  return { $members: members };
952
914
  }
953
915
  Schema.Members = Members;
@@ -1,12 +1,14 @@
1
1
  import { ValidationPass } from "../error/ValidationPass";
2
- import { AdditionalValidationPasses, DefaultValue, ModelValue, ValidationOptions } from "../typing/toolbox";
2
+ import { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue, ValidationOptions } from "../typing/toolbox";
3
3
  import { BaseSchema } from "./BaseSchema";
4
- export declare class EnumerationSchema<Members extends string, Required extends boolean, Default extends DefaultValue<Members>> extends BaseSchema<Members, Members, Required, Default> {
5
- readonly members: Members[];
6
- constructor(members: Members[], required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<Members, Members>);
4
+ export type EnumerationSource<Members extends string[]> = Members[number];
5
+ export type EnumerationModel<Members extends string[]> = Members[number];
6
+ export declare class EnumerationSchema<Members extends string[], Required extends boolean, Default extends DefaultValue<EnumerationSource<Members>>> extends BaseSchema<EnumerationSource<Members>, EnumerationModel<Members>, Required, Default> {
7
+ readonly members: Members;
8
+ constructor(members: Members, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<Members[number], Members[number]>);
7
9
  get type(): string;
8
- protected _validate(source: ModelValue<Members, Members, Required, Default>, options: ValidationOptions, pass: ValidationPass): ModelValue<Members, Members, Required, Default>;
9
- convert(value: Members, pass: ValidationPass): Members;
10
+ protected _validate(source: SourceValue<EnumerationSource<Members>, Required, Default>, options: ValidationOptions, pass: ValidationPass): ModelValue<EnumerationSource<Members>, EnumerationModel<Members>, Required, Default>;
11
+ convert(value: EnumerationSource<Members>, pass: ValidationPass): EnumerationModel<Members>;
10
12
  clone(): EnumerationSchema<Members, Required, Default>;
11
13
  getJsonSchema(): object;
12
14
  }
@@ -2,14 +2,14 @@ import { ValidationPass } from "../error/ValidationPass";
2
2
  import { BaseSchemaAny } from "../typing/extended";
3
3
  import { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue, ValidationOptions } from "../typing/toolbox";
4
4
  import { BaseSchema } from "./BaseSchema";
5
- export type OrSetSchemaSource<MemberSchema extends BaseSchemaAny> = (MemberSchema extends BaseSchema<infer Source, any, infer Required, infer Default> ? SourceValue<Source, Required, Default> : never);
6
- export type OrSetSchemaModel<MemberSchema extends BaseSchemaAny> = (MemberSchema extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? ModelValue<Source, Model, Required, Default> : never);
7
- export declare class OrSetSchema<MemberSchema extends BaseSchemaAny, Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchema>>> extends BaseSchema<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default> {
8
- readonly schemas: MemberSchema[];
9
- constructor(schemas: MemberSchema[], required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>>);
5
+ export type OrSetSchemaSource<MemberSchemas extends BaseSchemaAny[]> = (MemberSchemas[number] extends infer MemberSchema ? (MemberSchema extends BaseSchema<infer Source, any, infer Required, infer Default> ? (SourceValue<Source, Required, Default>) : never) : never);
6
+ export type OrSetSchemaModel<MemberSchemas extends BaseSchemaAny[]> = (MemberSchemas[number] extends infer MemberSchema ? (MemberSchema extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? (ModelValue<Source, Model, Required, Default>) : never) : never);
7
+ export declare class OrSetSchema<MemberSchemas extends BaseSchemaAny[], Required extends boolean, Default extends DefaultValue<OrSetSchemaSource<MemberSchemas>>> extends BaseSchema<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default> {
8
+ readonly schemas: MemberSchemas;
9
+ constructor(schemas: MemberSchemas, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>>);
10
10
  get type(): string;
11
- protected _validate(source: ModelValue<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default>, options: ValidationOptions, pass: ValidationPass): ModelValue<OrSetSchemaSource<MemberSchema>, OrSetSchemaModel<MemberSchema>, Required, Default>;
12
- convert(value: OrSetSchemaSource<MemberSchema>, pass: ValidationPass): OrSetSchemaModel<MemberSchema>;
13
- clone(): OrSetSchema<MemberSchema, Required, Default>;
11
+ protected _validate(source: ModelValue<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default>, options: ValidationOptions, pass: ValidationPass): ModelValue<OrSetSchemaSource<MemberSchemas>, OrSetSchemaModel<MemberSchemas>, Required, Default>;
12
+ convert(value: OrSetSchemaSource<MemberSchemas>, pass: ValidationPass): OrSetSchemaModel<MemberSchemas>;
13
+ clone(): OrSetSchema<MemberSchemas, Required, Default>;
14
14
  getJsonSchema(): object;
15
15
  }
@@ -0,0 +1,20 @@
1
+ import { ValidationPass } from "../error/ValidationPass";
2
+ import { BaseSchemaAny } from "../typing/extended";
3
+ import { AdditionalValidationPasses, DefaultValue, ModelValue, SourceValue, ValidationOptions } from "../typing/toolbox";
4
+ import { BaseSchema } from "./BaseSchema";
5
+ export type TupleSubschema = BaseSchemaAny[];
6
+ export type TupleSource<Subschema extends TupleSubschema> = ({
7
+ [Key in keyof Subschema]: (Subschema[Key] extends BaseSchema<infer Source, any, infer Required, infer Default> ? (SourceValue<Source, Required, Default>) : never);
8
+ });
9
+ export type TupleModel<Subschema extends TupleSubschema> = ({
10
+ [Key in keyof Subschema]: (Subschema[Key] extends BaseSchema<infer Source, infer Model, infer Required, infer Default> ? (ModelValue<Source, Model, Required, Default>) : never);
11
+ });
12
+ export declare class TupleSchema<Subschema extends BaseSchemaAny[], Required extends boolean, Default extends DefaultValue<TupleSource<Subschema>>> extends BaseSchema<TupleSource<Subschema>, TupleModel<Subschema>, Required, Default> {
13
+ readonly subschema: Subschema;
14
+ constructor(subschema: Subschema, required: Required, defaultValue: Default, additionalValidationPasses?: AdditionalValidationPasses<TupleSource<Subschema>, TupleModel<Subschema>>);
15
+ get type(): string;
16
+ protected _validate(source: ModelValue<TupleSource<Subschema>, TupleModel<Subschema>, Required, Default>, options: ValidationOptions, pass: ValidationPass): ModelValue<TupleSource<Subschema>, TupleModel<Subschema>, Required, Default>;
17
+ convert(value: TupleSource<Subschema>, pass: ValidationPass): TupleModel<Subschema>;
18
+ clone(): TupleSchema<Subschema, Required, Default>;
19
+ getJsonSchema(): object;
20
+ }
@@ -4,4 +4,4 @@ import { ObjectSchema } from "../schema/ObjectSchema";
4
4
  import { DefaultValue } from "./toolbox";
5
5
  export type BaseSchemaAny = BaseSchema<any, any, boolean, DefaultValue<any>>;
6
6
  export type ObjectSchemaAny = ObjectSchema<any, boolean, DefaultValue<any>>;
7
- export type EnumerationSchemaAny = EnumerationSchema<string, boolean, DefaultValue<any>>;
7
+ export type EnumerationSchemaAny = EnumerationSchema<string[], boolean, DefaultValue<any>>;
package/package.json CHANGED
@@ -1,40 +1,40 @@
1
- {
2
- "name": "@lucania/schema",
3
- "version": "3.0.4",
4
- "description": "A schema module for compile-time and runtime type checking.",
5
- "main": "./build/index.js",
6
- "types": "./build/index.d.ts",
7
- "files": [
8
- "/build"
9
- ],
10
- "scripts": {
11
- "setup": "npm install",
12
- "clean": "erase /F /S /Q build",
13
- "build": "npx rollup --bundleConfigAsCjs --config rollup.config.js",
14
- "build:clean": "npm run clean && npm run build",
15
- "build:watch": "npx rollup --watch --bundleConfigAsCjs --config rollup.config.js",
16
- "push": "npm run build:clean && npm publish --access public"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/lucania-software/schema.git"
21
- },
22
- "keywords": [
23
- "Schema"
24
- ],
25
- "author": "Jeremy Bankes",
26
- "license": "GPL-3.0-or-later",
27
- "bugs": {
28
- "url": "https://github.com/lucania-software/schema/issues"
29
- },
30
- "homepage": "https://github.com/lucania-software/schema#readme",
31
- "devDependencies": {
32
- "@babel/preset-env": "^7.24.7",
33
- "@rollup/plugin-typescript": "^11.1.6",
34
- "@types/node": "^20.14.2",
35
- "nodemon": "^3.1.3",
36
- "rollup": "^4.18.0",
37
- "tslib": "^2.6.3",
38
- "typescript": "^5.4.5"
39
- }
40
- }
1
+ {
2
+ "name": "@lucania/schema",
3
+ "version": "3.1.0",
4
+ "description": "A schema module for compile-time and runtime type checking.",
5
+ "main": "./build/index.js",
6
+ "types": "./build/index.d.ts",
7
+ "files": [
8
+ "/build"
9
+ ],
10
+ "scripts": {
11
+ "setup": "npm install",
12
+ "clean": "rm -rf build",
13
+ "build": "npx rollup --bundleConfigAsCjs --config rollup.config.js",
14
+ "build:clean": "npm run clean && npm run build",
15
+ "build:watch": "npx rollup --watch --bundleConfigAsCjs --config rollup.config.js",
16
+ "push": "npm run build:clean && npm publish --access public"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/lucania-software/schema.git"
21
+ },
22
+ "keywords": [
23
+ "Schema"
24
+ ],
25
+ "author": "Jeremy Bankes",
26
+ "license": "GPL-3.0-or-later",
27
+ "bugs": {
28
+ "url": "https://github.com/lucania-software/schema/issues"
29
+ },
30
+ "homepage": "https://github.com/lucania-software/schema#readme",
31
+ "devDependencies": {
32
+ "@babel/preset-env": "^7.24.7",
33
+ "@rollup/plugin-typescript": "^11.1.6",
34
+ "@types/node": "^20.14.2",
35
+ "nodemon": "^3.1.3",
36
+ "rollup": "^4.18.0",
37
+ "tslib": "^2.6.3",
38
+ "typescript": "^5.4.5"
39
+ }
40
+ }