decoders 2.4.2 → 2.6.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/dist/index.cjs +64 -2
- package/dist/index.d.cts +69 -1
- package/dist/index.d.ts +69 -1
- package/dist/index.js +63 -1
- package/package.json +16 -15
package/dist/index.cjs
CHANGED
|
@@ -242,6 +242,41 @@ ${annotation}`;
|
|
|
242
242
|
function formatShort(ann) {
|
|
243
243
|
return summarize(ann, []).join("\n");
|
|
244
244
|
}
|
|
245
|
+
function* iterAnnotation(ann, stack) {
|
|
246
|
+
if (ann.text) {
|
|
247
|
+
if (stack.length > 0) {
|
|
248
|
+
yield { message: ann.text, path: [...stack] };
|
|
249
|
+
} else {
|
|
250
|
+
yield { message: ann.text };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
switch (ann.type) {
|
|
254
|
+
case "array": {
|
|
255
|
+
let index = 0;
|
|
256
|
+
for (const item of ann.items) {
|
|
257
|
+
stack.push(index++);
|
|
258
|
+
yield* iterAnnotation(item, stack);
|
|
259
|
+
stack.pop();
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
case "object": {
|
|
264
|
+
for (const [key, value] of ann.fields) {
|
|
265
|
+
stack.push(key);
|
|
266
|
+
yield* iterAnnotation(value, stack);
|
|
267
|
+
stack.pop();
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
case "scalar":
|
|
272
|
+
case "opaque": {
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function formatAsIssues(ann) {
|
|
278
|
+
return Array.from(iterAnnotation(ann, []));
|
|
279
|
+
}
|
|
245
280
|
|
|
246
281
|
// src/core/Result.ts
|
|
247
282
|
function ok(value) {
|
|
@@ -342,7 +377,20 @@ function define(fn) {
|
|
|
342
377
|
reject,
|
|
343
378
|
describe,
|
|
344
379
|
then,
|
|
345
|
-
pipe
|
|
380
|
+
pipe,
|
|
381
|
+
"~standard": {
|
|
382
|
+
version: 1,
|
|
383
|
+
vendor: "decoders",
|
|
384
|
+
validate: (blob) => {
|
|
385
|
+
const result = decode(blob);
|
|
386
|
+
if (result.ok) {
|
|
387
|
+
return { value: result.value };
|
|
388
|
+
} else {
|
|
389
|
+
const issues = formatAsIssues(result.error);
|
|
390
|
+
return { issues };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
346
394
|
});
|
|
347
395
|
}
|
|
348
396
|
var _register2 = /* @__PURE__ */ new WeakSet();
|
|
@@ -709,6 +757,18 @@ var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
|
709
757
|
function regex(regex2, msg) {
|
|
710
758
|
return string.refine((s) => regex2.test(s), msg);
|
|
711
759
|
}
|
|
760
|
+
function startsWith(prefix) {
|
|
761
|
+
return string.refine(
|
|
762
|
+
(s) => s.startsWith(prefix),
|
|
763
|
+
`Must start with '${prefix}'`
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
function endsWith(suffix) {
|
|
767
|
+
return string.refine(
|
|
768
|
+
(s) => s.endsWith(suffix),
|
|
769
|
+
`Must end with '${suffix}'`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
712
772
|
var email = regex(
|
|
713
773
|
// The almost perfect email regex, taken from https://emailregex.com/
|
|
714
774
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
@@ -873,4 +933,6 @@ var json = either(
|
|
|
873
933
|
|
|
874
934
|
|
|
875
935
|
|
|
876
|
-
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
exports.always = always; exports.anyNumber = anyNumber; exports.array = array; exports.bigint = bigint; exports.boolean = boolean; exports.constant = constant; exports.date = date; exports.datelike = datelike; exports.decimal = decimal; exports.define = define; exports.dict = dict; exports.either = either; exports.email = email; exports.endsWith = endsWith; exports.enum_ = enum_; exports.err = err; exports.exact = exact; exports.fail = fail; exports.formatInline = formatInline; exports.formatShort = formatShort; exports.hardcoded = hardcoded; exports.hexadecimal = hexadecimal; exports.httpsUrl = httpsUrl; exports.identifier = identifier; exports.inexact = inexact; exports.instanceOf = instanceOf; exports.integer = integer; exports.iso8601 = iso8601; exports.json = json; exports.jsonArray = jsonArray; exports.jsonObject = jsonObject; exports.lazy = lazy; exports.mapping = mapping; exports.maybe = maybe; exports.mixed = mixed; exports.nanoid = nanoid; exports.never = never; exports.nonEmptyArray = nonEmptyArray; exports.nonEmptyString = nonEmptyString; exports.null_ = null_; exports.nullable = nullable; exports.nullish = nullish; exports.number = number; exports.numeric = numeric; exports.object = object; exports.ok = ok; exports.oneOf = oneOf; exports.optional = optional; exports.poja = poja; exports.pojo = pojo; exports.positiveInteger = positiveInteger; exports.positiveNumber = positiveNumber; exports.prep = prep; exports.record = record; exports.regex = regex; exports.select = select; exports.set = set; exports.setFromArray = setFromArray; exports.startsWith = startsWith; exports.string = string; exports.taggedUnion = taggedUnion; exports.truthy = truthy; exports.tuple = tuple; exports.undefined_ = undefined_; exports.unknown = unknown; exports.url = url; exports.uuid = uuid; exports.uuidv1 = uuidv1; exports.uuidv4 = uuidv4;
|
package/dist/index.d.cts
CHANGED
|
@@ -45,6 +45,62 @@ declare function ok<T>(value: T): Ok<T>;
|
|
|
45
45
|
*/
|
|
46
46
|
declare function err<E>(error: E): Err<E>;
|
|
47
47
|
|
|
48
|
+
/** The Standard Schema interface. */
|
|
49
|
+
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
50
|
+
/** The Standard Schema properties. */
|
|
51
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
52
|
+
}
|
|
53
|
+
declare namespace StandardSchemaV1 {
|
|
54
|
+
/** The Standard Schema properties interface. */
|
|
55
|
+
interface Props<Input = unknown, Output = Input> {
|
|
56
|
+
/** The version number of the standard. */
|
|
57
|
+
readonly version: 1;
|
|
58
|
+
/** The vendor name of the schema library. */
|
|
59
|
+
readonly vendor: string;
|
|
60
|
+
/** Validates unknown input values. */
|
|
61
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
62
|
+
/** Inferred types associated with the schema. */
|
|
63
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
64
|
+
}
|
|
65
|
+
/** The result interface of the validate function. */
|
|
66
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
67
|
+
/** The result interface if validation succeeds. */
|
|
68
|
+
interface SuccessResult<Output> {
|
|
69
|
+
/** The typed output value. */
|
|
70
|
+
readonly value: Output;
|
|
71
|
+
/** The non-existent issues. */
|
|
72
|
+
readonly issues?: undefined;
|
|
73
|
+
}
|
|
74
|
+
/** The result interface if validation fails. */
|
|
75
|
+
interface FailureResult {
|
|
76
|
+
/** The issues of failed validation. */
|
|
77
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
78
|
+
}
|
|
79
|
+
/** The issue interface of the failure output. */
|
|
80
|
+
interface Issue {
|
|
81
|
+
/** The error message of the issue. */
|
|
82
|
+
readonly message: string;
|
|
83
|
+
/** The path of the issue, if any. */
|
|
84
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
85
|
+
}
|
|
86
|
+
/** The path segment interface of the issue. */
|
|
87
|
+
interface PathSegment {
|
|
88
|
+
/** The key representing a path segment. */
|
|
89
|
+
readonly key: PropertyKey;
|
|
90
|
+
}
|
|
91
|
+
/** The Standard Schema types interface. */
|
|
92
|
+
interface Types<Input = unknown, Output = Input> {
|
|
93
|
+
/** The input type of the schema. */
|
|
94
|
+
readonly input: Input;
|
|
95
|
+
/** The output type of the schema. */
|
|
96
|
+
readonly output: Output;
|
|
97
|
+
}
|
|
98
|
+
/** Infers the input type of a Standard Schema. */
|
|
99
|
+
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
100
|
+
/** Infers the output type of a Standard Schema. */
|
|
101
|
+
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
102
|
+
}
|
|
103
|
+
|
|
48
104
|
type DecodeResult<T> = Result<T, Annotation>;
|
|
49
105
|
/**
|
|
50
106
|
* A function taking a untrusted input, and returning a DecodeResult<T>. The
|
|
@@ -114,6 +170,10 @@ interface Decoder<T> {
|
|
|
114
170
|
*/
|
|
115
171
|
pipe<V, D extends Decoder<V>>(next: D): Decoder<DecoderType<D>>;
|
|
116
172
|
pipe<V, D extends Decoder<V>>(next: (blob: T) => D): Decoder<DecoderType<D>>;
|
|
173
|
+
/**
|
|
174
|
+
* The Standard Schema interface for this decoder.
|
|
175
|
+
*/
|
|
176
|
+
'~standard': StandardSchemaV1.Props<unknown, T>;
|
|
117
177
|
}
|
|
118
178
|
/**
|
|
119
179
|
* Helper type to return the output type of a Decoder.
|
|
@@ -476,6 +536,14 @@ declare const nonEmptyString: Decoder<string>;
|
|
|
476
536
|
* Accepts and returns strings that match the given regular expression.
|
|
477
537
|
*/
|
|
478
538
|
declare function regex(regex: RegExp, msg: string): Decoder<string>;
|
|
539
|
+
/**
|
|
540
|
+
* Accepts and returns strings that start with the given prefix.
|
|
541
|
+
*/
|
|
542
|
+
declare function startsWith<P extends string>(prefix: P): Decoder<`${P}${string}`>;
|
|
543
|
+
/**
|
|
544
|
+
* Accepts and returns strings that end with the given suffix.
|
|
545
|
+
*/
|
|
546
|
+
declare function endsWith<S extends string>(suffix: S): Decoder<`${string}${S}`>;
|
|
479
547
|
/**
|
|
480
548
|
* Accepts and returns strings that are syntactically valid email addresses.
|
|
481
549
|
* (This will not mean that the email address actually exist.)
|
|
@@ -592,4 +660,4 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>>(field:
|
|
|
592
660
|
*/
|
|
593
661
|
declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
|
|
594
662
|
|
|
595
|
-
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
|
663
|
+
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,62 @@ declare function ok<T>(value: T): Ok<T>;
|
|
|
45
45
|
*/
|
|
46
46
|
declare function err<E>(error: E): Err<E>;
|
|
47
47
|
|
|
48
|
+
/** The Standard Schema interface. */
|
|
49
|
+
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
50
|
+
/** The Standard Schema properties. */
|
|
51
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
52
|
+
}
|
|
53
|
+
declare namespace StandardSchemaV1 {
|
|
54
|
+
/** The Standard Schema properties interface. */
|
|
55
|
+
interface Props<Input = unknown, Output = Input> {
|
|
56
|
+
/** The version number of the standard. */
|
|
57
|
+
readonly version: 1;
|
|
58
|
+
/** The vendor name of the schema library. */
|
|
59
|
+
readonly vendor: string;
|
|
60
|
+
/** Validates unknown input values. */
|
|
61
|
+
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
|
|
62
|
+
/** Inferred types associated with the schema. */
|
|
63
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
64
|
+
}
|
|
65
|
+
/** The result interface of the validate function. */
|
|
66
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
67
|
+
/** The result interface if validation succeeds. */
|
|
68
|
+
interface SuccessResult<Output> {
|
|
69
|
+
/** The typed output value. */
|
|
70
|
+
readonly value: Output;
|
|
71
|
+
/** The non-existent issues. */
|
|
72
|
+
readonly issues?: undefined;
|
|
73
|
+
}
|
|
74
|
+
/** The result interface if validation fails. */
|
|
75
|
+
interface FailureResult {
|
|
76
|
+
/** The issues of failed validation. */
|
|
77
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
78
|
+
}
|
|
79
|
+
/** The issue interface of the failure output. */
|
|
80
|
+
interface Issue {
|
|
81
|
+
/** The error message of the issue. */
|
|
82
|
+
readonly message: string;
|
|
83
|
+
/** The path of the issue, if any. */
|
|
84
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
85
|
+
}
|
|
86
|
+
/** The path segment interface of the issue. */
|
|
87
|
+
interface PathSegment {
|
|
88
|
+
/** The key representing a path segment. */
|
|
89
|
+
readonly key: PropertyKey;
|
|
90
|
+
}
|
|
91
|
+
/** The Standard Schema types interface. */
|
|
92
|
+
interface Types<Input = unknown, Output = Input> {
|
|
93
|
+
/** The input type of the schema. */
|
|
94
|
+
readonly input: Input;
|
|
95
|
+
/** The output type of the schema. */
|
|
96
|
+
readonly output: Output;
|
|
97
|
+
}
|
|
98
|
+
/** Infers the input type of a Standard Schema. */
|
|
99
|
+
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
|
|
100
|
+
/** Infers the output type of a Standard Schema. */
|
|
101
|
+
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
|
|
102
|
+
}
|
|
103
|
+
|
|
48
104
|
type DecodeResult<T> = Result<T, Annotation>;
|
|
49
105
|
/**
|
|
50
106
|
* A function taking a untrusted input, and returning a DecodeResult<T>. The
|
|
@@ -114,6 +170,10 @@ interface Decoder<T> {
|
|
|
114
170
|
*/
|
|
115
171
|
pipe<V, D extends Decoder<V>>(next: D): Decoder<DecoderType<D>>;
|
|
116
172
|
pipe<V, D extends Decoder<V>>(next: (blob: T) => D): Decoder<DecoderType<D>>;
|
|
173
|
+
/**
|
|
174
|
+
* The Standard Schema interface for this decoder.
|
|
175
|
+
*/
|
|
176
|
+
'~standard': StandardSchemaV1.Props<unknown, T>;
|
|
117
177
|
}
|
|
118
178
|
/**
|
|
119
179
|
* Helper type to return the output type of a Decoder.
|
|
@@ -476,6 +536,14 @@ declare const nonEmptyString: Decoder<string>;
|
|
|
476
536
|
* Accepts and returns strings that match the given regular expression.
|
|
477
537
|
*/
|
|
478
538
|
declare function regex(regex: RegExp, msg: string): Decoder<string>;
|
|
539
|
+
/**
|
|
540
|
+
* Accepts and returns strings that start with the given prefix.
|
|
541
|
+
*/
|
|
542
|
+
declare function startsWith<P extends string>(prefix: P): Decoder<`${P}${string}`>;
|
|
543
|
+
/**
|
|
544
|
+
* Accepts and returns strings that end with the given suffix.
|
|
545
|
+
*/
|
|
546
|
+
declare function endsWith<S extends string>(suffix: S): Decoder<`${string}${S}`>;
|
|
479
547
|
/**
|
|
480
548
|
* Accepts and returns strings that are syntactically valid email addresses.
|
|
481
549
|
* (This will not mean that the email address actually exist.)
|
|
@@ -592,4 +660,4 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>>(field:
|
|
|
592
660
|
*/
|
|
593
661
|
declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
|
|
594
662
|
|
|
595
|
-
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
|
663
|
+
export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, datelike, decimal, define, dict, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
|
package/dist/index.js
CHANGED
|
@@ -242,6 +242,41 @@ ${annotation}`;
|
|
|
242
242
|
function formatShort(ann) {
|
|
243
243
|
return summarize(ann, []).join("\n");
|
|
244
244
|
}
|
|
245
|
+
function* iterAnnotation(ann, stack) {
|
|
246
|
+
if (ann.text) {
|
|
247
|
+
if (stack.length > 0) {
|
|
248
|
+
yield { message: ann.text, path: [...stack] };
|
|
249
|
+
} else {
|
|
250
|
+
yield { message: ann.text };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
switch (ann.type) {
|
|
254
|
+
case "array": {
|
|
255
|
+
let index = 0;
|
|
256
|
+
for (const item of ann.items) {
|
|
257
|
+
stack.push(index++);
|
|
258
|
+
yield* iterAnnotation(item, stack);
|
|
259
|
+
stack.pop();
|
|
260
|
+
}
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
case "object": {
|
|
264
|
+
for (const [key, value] of ann.fields) {
|
|
265
|
+
stack.push(key);
|
|
266
|
+
yield* iterAnnotation(value, stack);
|
|
267
|
+
stack.pop();
|
|
268
|
+
}
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
case "scalar":
|
|
272
|
+
case "opaque": {
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function formatAsIssues(ann) {
|
|
278
|
+
return Array.from(iterAnnotation(ann, []));
|
|
279
|
+
}
|
|
245
280
|
|
|
246
281
|
// src/core/Result.ts
|
|
247
282
|
function ok(value) {
|
|
@@ -342,7 +377,20 @@ function define(fn) {
|
|
|
342
377
|
reject,
|
|
343
378
|
describe,
|
|
344
379
|
then,
|
|
345
|
-
pipe
|
|
380
|
+
pipe,
|
|
381
|
+
"~standard": {
|
|
382
|
+
version: 1,
|
|
383
|
+
vendor: "decoders",
|
|
384
|
+
validate: (blob) => {
|
|
385
|
+
const result = decode(blob);
|
|
386
|
+
if (result.ok) {
|
|
387
|
+
return { value: result.value };
|
|
388
|
+
} else {
|
|
389
|
+
const issues = formatAsIssues(result.error);
|
|
390
|
+
return { issues };
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
346
394
|
});
|
|
347
395
|
}
|
|
348
396
|
var _register2 = /* @__PURE__ */ new WeakSet();
|
|
@@ -709,6 +757,18 @@ var nonEmptyString = regex(/\S/, "Must be non-empty string");
|
|
|
709
757
|
function regex(regex2, msg) {
|
|
710
758
|
return string.refine((s) => regex2.test(s), msg);
|
|
711
759
|
}
|
|
760
|
+
function startsWith(prefix) {
|
|
761
|
+
return string.refine(
|
|
762
|
+
(s) => s.startsWith(prefix),
|
|
763
|
+
`Must start with '${prefix}'`
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
function endsWith(suffix) {
|
|
767
|
+
return string.refine(
|
|
768
|
+
(s) => s.endsWith(suffix),
|
|
769
|
+
`Must end with '${suffix}'`
|
|
770
|
+
);
|
|
771
|
+
}
|
|
712
772
|
var email = regex(
|
|
713
773
|
// The almost perfect email regex, taken from https://emailregex.com/
|
|
714
774
|
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
@@ -819,6 +879,7 @@ export {
|
|
|
819
879
|
dict,
|
|
820
880
|
either,
|
|
821
881
|
email,
|
|
882
|
+
endsWith,
|
|
822
883
|
enum_,
|
|
823
884
|
err,
|
|
824
885
|
exact,
|
|
@@ -863,6 +924,7 @@ export {
|
|
|
863
924
|
select,
|
|
864
925
|
set,
|
|
865
926
|
setFromArray,
|
|
927
|
+
startsWith,
|
|
866
928
|
string,
|
|
867
929
|
taggedUnion,
|
|
868
930
|
truthy,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "decoders",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Elegant and battle-tested validation library for type-safe input data for TypeScript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -61,27 +61,28 @@
|
|
|
61
61
|
"verify"
|
|
62
62
|
],
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@arethetypeswrong/cli": "^0.
|
|
65
|
-
"@release-it/keep-a-changelog": "^
|
|
64
|
+
"@arethetypeswrong/cli": "^0.17.3",
|
|
65
|
+
"@release-it/keep-a-changelog": "^6.0.0",
|
|
66
|
+
"@standard-schema/spec": "^1.0.0",
|
|
66
67
|
"@types/eslint": "^8.56.10",
|
|
67
68
|
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
68
69
|
"@typescript-eslint/parser": "^7.14.1",
|
|
69
|
-
"@vitest/coverage-istanbul": "^
|
|
70
|
+
"@vitest/coverage-istanbul": "^3.0.5",
|
|
70
71
|
"eslint": "^8.57.0",
|
|
71
72
|
"eslint-plugin-import": "^2.29.1",
|
|
72
73
|
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
73
|
-
"fast-check": "^3.
|
|
74
|
+
"fast-check": "^3.23.2",
|
|
74
75
|
"itertools": "^2.3.2",
|
|
75
|
-
"pkg-pr-new": "^0.0.
|
|
76
|
-
"prettier": "^3.
|
|
77
|
-
"publint": "^0.2
|
|
78
|
-
"release-it": "^
|
|
79
|
-
"ts-morph": "^
|
|
80
|
-
"tsd": "^0.31.
|
|
81
|
-
"tsup": "^8.
|
|
82
|
-
"typescript": "^5.
|
|
83
|
-
"vite-tsconfig-paths": "^
|
|
84
|
-
"vitest": "^
|
|
76
|
+
"pkg-pr-new": "^0.0.39",
|
|
77
|
+
"prettier": "^3.4.2",
|
|
78
|
+
"publint": "^0.3.2",
|
|
79
|
+
"release-it": "^18.1.2",
|
|
80
|
+
"ts-morph": "^25.0.0",
|
|
81
|
+
"tsd": "^0.31.2",
|
|
82
|
+
"tsup": "^8.3.6",
|
|
83
|
+
"typescript": "^5.7.3",
|
|
84
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
85
|
+
"vitest": "^3.0.5"
|
|
85
86
|
},
|
|
86
87
|
"githubUrl": "https://github.com/nvie/decoders",
|
|
87
88
|
"sideEffects": false
|