typebox 1.1.6 → 1.1.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.
Files changed (30) hide show
  1. package/build/type/script/token/bigint.d.mts +1 -1
  2. package/build/type/script/token/bigint.mjs +3 -9
  3. package/build/type/script/token/ident.mjs +4 -13
  4. package/build/type/script/token/index.d.mts +3 -0
  5. package/build/type/script/token/index.mjs +3 -0
  6. package/build/type/script/token/integer.d.mts +5 -13
  7. package/build/type/script/token/integer.mjs +7 -33
  8. package/build/type/script/token/internal/many.mjs +4 -7
  9. package/build/type/script/token/internal/match.d.mts +6 -0
  10. package/build/type/script/token/internal/match.mjs +11 -0
  11. package/build/type/script/token/internal/optional.mjs +2 -5
  12. package/build/type/script/token/internal/take.mjs +23 -8
  13. package/build/type/script/token/number.d.mts +5 -14
  14. package/build/type/script/token/number.mjs +7 -53
  15. package/build/type/script/token/rest.d.mts +4 -0
  16. package/build/type/script/token/rest.mjs +9 -0
  17. package/build/type/script/token/span.d.mts +3 -2
  18. package/build/type/script/token/span.mjs +8 -19
  19. package/build/type/script/token/string.mjs +2 -6
  20. package/build/type/script/token/unsigned_integer.d.mts +16 -0
  21. package/build/type/script/token/unsigned_integer.mjs +26 -0
  22. package/build/type/script/token/unsigned_number.d.mts +17 -0
  23. package/build/type/script/token/unsigned_number.mjs +38 -0
  24. package/build/type/script/token/until.d.mts +3 -2
  25. package/build/type/script/token/until.mjs +11 -8
  26. package/build/type/script/token/until_1.mjs +4 -8
  27. package/package.json +29 -29
  28. package/readme.md +3 -5
  29. package/build/type/script/token/internal/result.d.mts +0 -2
  30. package/build/type/script/token/internal/result.mjs +0 -7
@@ -1,6 +1,6 @@
1
1
  import { type TTake } from './internal/take.mjs';
2
2
  import { type TInteger } from './integer.mjs';
3
- type TTakeBigInt<Input extends string> = (TInteger<Input> extends [infer Integer extends string, infer IntegerRest extends string] ? TTake<['n'], IntegerRest> extends [infer N extends string, infer NRest extends string] ? [`${Integer}`, NRest] : [] : []);
3
+ type TTakeBigInt<Input extends string> = (TInteger<Input> extends [infer Integer extends string, infer IntegerRest extends string] ? TTake<['n'], IntegerRest> extends [infer _N extends string, infer NRest extends string] ? [`${Integer}`, NRest] : [] : []);
4
4
  /** Matches if next is a Integer literal with trailing 'n'. Trailing 'n' is omitted in result. */
5
5
  export type TBigInt<Input extends string> = (TTakeBigInt<Input>);
6
6
  /** Matches if next is a Integer literal with trailing 'n'. Trailing 'n' is omitted in result. */
@@ -1,17 +1,11 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
4
4
  import { Take } from './internal/take.mjs';
5
5
  import { Integer } from './integer.mjs';
6
6
  function TakeBigInt(input) {
7
- const integer = Integer(input);
8
- return (IsResult(integer) ? (() => {
9
- const n = Take(['n'], integer[1]);
10
- return IsResult(n)
11
- ? [`${integer[0]}`, n[1]]
12
- : []; // fail: did not match 'n'
13
- })() : [] // fail: did not match Integer
14
- );
7
+ return Match(Integer(input), (Integer, IntegerRest) => Match(Take(['n'], IntegerRest), (_N, NRest) => [`${Integer}`, NRest], () => []), // fail: did not match 'n'
8
+ () => []); // fail: did not match Integer
15
9
  }
16
10
  /** Matches if next is a Integer literal with trailing 'n'. Trailing 'n' is omitted in result. */
17
11
  export function BigInt(input) {
@@ -1,6 +1,6 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
4
4
  import { Trim } from './internal/trim.mjs';
5
5
  import { Take } from './internal/take.mjs';
6
6
  import { Alpha } from './internal/char.mjs';
@@ -13,20 +13,11 @@ function TakeInitial(input) {
13
13
  }
14
14
  const Remaining = [...Initial, ...Digit];
15
15
  function TakeRemaining(input, result = '') {
16
- const remaining = Take(Remaining, input);
17
- return (IsResult(remaining)
18
- ? TakeRemaining(remaining[1], `${result}${remaining[0]}`)
19
- : [result, input]);
16
+ return Match(Take(Remaining, input), (Remaining, RemainingRest) => TakeRemaining(RemainingRest, `${result}${Remaining}`), () => [result, input]);
20
17
  }
21
18
  function TakeIdent(input) {
22
- const initial = TakeInitial(input);
23
- return (IsResult(initial) ? (() => {
24
- const remaining = TakeRemaining(initial[1]);
25
- return IsResult(remaining)
26
- ? [`${initial[0]}${remaining[0]}`, remaining[1]]
27
- : []; // fail: did not match Remaining
28
- })() : [] // fail: did not match Initial
29
- );
19
+ return Match(TakeInitial(input), (Initial, InitialRest) => Match(TakeRemaining(InitialRest), (Remaining, RemainingRest) => [`${Initial}${Remaining}`, RemainingRest], () => []), // fail: did not match Remaining
20
+ () => []); // fail: did not match Initial
30
21
  }
31
22
  /** Matches if next is an Ident */
32
23
  export function Ident(input) {
@@ -3,7 +3,10 @@ export * from './const.mjs';
3
3
  export * from './ident.mjs';
4
4
  export * from './integer.mjs';
5
5
  export * from './number.mjs';
6
+ export * from './rest.mjs';
6
7
  export * from './span.mjs';
7
8
  export * from './string.mjs';
9
+ export * from './unsigned_integer.mjs';
10
+ export * from './unsigned_number.mjs';
8
11
  export * from './until_1.mjs';
9
12
  export * from './until.mjs';
@@ -3,7 +3,10 @@ export * from './const.mjs';
3
3
  export * from './ident.mjs';
4
4
  export * from './integer.mjs';
5
5
  export * from './number.mjs';
6
+ export * from './rest.mjs';
6
7
  export * from './span.mjs';
7
8
  export * from './string.mjs';
9
+ export * from './unsigned_integer.mjs';
10
+ export * from './unsigned_number.mjs';
8
11
  export * from './until_1.mjs';
9
12
  export * from './until.mjs';
@@ -1,19 +1,11 @@
1
1
  import { type TTrim } from './internal/trim.mjs';
2
- import { type TTake } from './internal/take.mjs';
3
- import { type TMany } from './internal/many.mjs';
4
2
  import { type TOptional } from './internal/optional.mjs';
5
- import { type TDigit } from './internal/char.mjs';
6
3
  import { type THyphen } from './internal/char.mjs';
7
- import { type TZero } from './internal/char.mjs';
8
- import { type TNonZero } from './internal/char.mjs';
9
- import { type TUnderScore } from './internal/char.mjs';
4
+ import { type TUnsignedInteger } from './unsigned_integer.mjs';
10
5
  type TTakeSign<Input extends string> = (TOptional<THyphen, Input>);
11
- type TTakeNonZero<Input extends string> = (TTake<TNonZero, Input>);
12
- type TAllowedDigits = [...TDigit, TUnderScore];
13
- type TTakeDigits<Input extends string> = (TMany<TAllowedDigits, [TUnderScore], Input>);
14
- type TTakeInteger<Input extends string> = (TTakeSign<Input> extends [infer Sign extends string, infer SignRest extends string] ? TTake<[TZero], SignRest> extends [infer Zero extends string, infer ZeroRest extends string] ? [`${Sign}${Zero}`, ZeroRest] : TTakeNonZero<SignRest> extends [infer NonZero extends string, infer NonZeroRest extends string] ? TTakeDigits<NonZeroRest> extends [infer Digits extends string, infer DigitsRest extends string] ? [`${Sign}${NonZero}${Digits}`, DigitsRest] : [] : [] : []);
15
- /** Matches if next is a Integer */
16
- export type TInteger<Input extends string> = (TTakeInteger<TTrim<Input>>);
17
- /** Matches if next is a Integer */
6
+ type TTakeSignedInteger<Input extends string> = (TTakeSign<Input> extends [infer Sign extends string, infer SignRest extends string] ? TUnsignedInteger<SignRest> extends [infer UnsignedInteger extends string, infer UnsignedIntegerRest extends string] ? [`${Sign}${UnsignedInteger}`, UnsignedIntegerRest] : [] : []);
7
+ /** Matches if next is a signed or unsigned Integer */
8
+ export type TInteger<Input extends string> = (TTakeSignedInteger<TTrim<Input>>);
9
+ /** Matches if next is a signed or unsigned Integer */
18
10
  export declare function Integer<Input extends string>(input: Input): TInteger<Input>;
19
11
  export {};
@@ -1,45 +1,19 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
4
4
  import { Trim } from './internal/trim.mjs';
5
- import { Take } from './internal/take.mjs';
6
- import { Many } from './internal/many.mjs';
7
5
  import { Optional } from './internal/optional.mjs';
8
- import { Digit } from './internal/char.mjs';
9
6
  import { Hyphen } from './internal/char.mjs';
10
- import { Zero } from './internal/char.mjs';
11
- import { NonZero } from './internal/char.mjs';
12
- import { UnderScore } from './internal/char.mjs';
7
+ import { UnsignedInteger } from './unsigned_integer.mjs';
13
8
  function TakeSign(input) {
14
9
  return Optional(Hyphen, input);
15
10
  }
16
- function TakeNonZero(input) {
17
- return Take(NonZero, input);
11
+ function TakeSignedInteger(input) {
12
+ return Match(TakeSign(input), (Sign, SignRest) => Match(UnsignedInteger(SignRest), (UnsignedInteger, UnsignedIntegerRest) => [`${Sign}${UnsignedInteger}`, UnsignedIntegerRest], () => []), // fail: did not match unsigned integer
13
+ () => []); // fail: did not match Sign
18
14
  }
19
- const AllowedDigits = [...Digit, UnderScore];
20
- function TakeDigits(input) {
21
- return Many(AllowedDigits, [UnderScore], input);
22
- }
23
- function TakeInteger(input) {
24
- const sign = TakeSign(input);
25
- return (IsResult(sign) ? (() => {
26
- const zero = Take([Zero], sign[1]);
27
- return IsResult(zero)
28
- ? [`${sign[0]}${zero[0]}`, zero[1]]
29
- : (() => {
30
- const nonZero = TakeNonZero(sign[1]);
31
- return IsResult(nonZero) ? (() => {
32
- const digits = TakeDigits(nonZero[1]);
33
- return IsResult(digits)
34
- ? [`${sign[0]}${nonZero[0]}${digits[0]}`, digits[1]]
35
- : []; // fail: did not match Digits
36
- })() : []; // fail: did not match NonZero
37
- })();
38
- })() : [] // fail: did not match Sign
39
- );
40
- }
41
- /** Matches if next is a Integer */
15
+ /** Matches if next is a signed or unsigned Integer */
42
16
  export function Integer(input) {
43
- return TakeInteger(Trim(input));
17
+ return TakeSignedInteger(Trim(input));
44
18
  }
45
19
  // deno-coverage-ignore-stop
@@ -1,17 +1,14 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './result.mjs';
3
+ import { Match } from './match.mjs';
4
4
  import { Take } from './take.mjs';
5
5
  function IsDiscard(discard, input) {
6
6
  return discard.includes(input);
7
7
  }
8
8
  /** Takes characters from the Input until no-match. The Discard set is used to omit characters from the match */
9
9
  export function Many(allowed, discard, input, result = '') {
10
- const takeResult = Take(allowed, input);
11
- return (IsResult(takeResult)
12
- ? IsDiscard(discard, takeResult[0])
13
- ? Many(allowed, discard, takeResult[1], result)
14
- : Many(allowed, discard, takeResult[1], `${result}${takeResult[0]}`)
15
- : [result, input]);
10
+ return Match(Take(allowed, input), (Char, Rest) => IsDiscard(discard, Char)
11
+ ? Many(allowed, discard, Rest, result)
12
+ : Many(allowed, discard, Rest, `${result}${Char}`), () => [result, input]);
16
13
  }
17
14
  // deno-coverage-ignore-stop
@@ -0,0 +1,6 @@
1
+ type TResult = [string, string] | [];
2
+ /** Checks the value is a Tuple-2 [string, string] result */
3
+ export declare function IsMatch(value: TResult): value is [string, string];
4
+ /** Matches on a result and dispatches either left or right arm */
5
+ export declare function Match(input: TResult, ok: (value: string, rest: string) => TResult, fail: () => TResult): TResult;
6
+ export {};
@@ -0,0 +1,11 @@
1
+ // deno-coverage-ignore-start - parsebox tested
2
+ import { IsEqual } from './guard.mjs';
3
+ /** Checks the value is a Tuple-2 [string, string] result */
4
+ export function IsMatch(value) {
5
+ return IsEqual(value.length, 2);
6
+ }
7
+ /** Matches on a result and dispatches either left or right arm */
8
+ export function Match(input, ok, fail) {
9
+ return IsMatch(input) ? ok(input[0], input[1]) : fail();
10
+ }
11
+ // deno-coverage-ignore-stop
@@ -1,12 +1,9 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './result.mjs';
3
+ import { Match } from './match.mjs';
4
4
  import { Take } from './take.mjs';
5
5
  /** Matches the given Value or empty string if no match. This function never fails */
6
6
  export function Optional(value, input) {
7
- const result = Take([value], input);
8
- return (IsResult(result)
9
- ? result
10
- : ['', input]);
7
+ return Match(Take([value], input), (Optional, Rest) => [Optional, Rest], () => ['', input]);
11
8
  }
12
9
  // deno-coverage-ignore-stop
@@ -1,6 +1,7 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsEqual, IsString } from './guard.mjs';
3
+ import { IsMatch } from './match.mjs';
4
+ import { IsEqual } from './guard.mjs';
4
5
  function TakeVariant(variant, input) {
5
6
  return (IsEqual(input.indexOf(variant), 0)
6
7
  ? [variant, input.slice(variant.length)]
@@ -8,12 +9,26 @@ function TakeVariant(variant, input) {
8
9
  }
9
10
  /** Takes one of the given variants or fail */
10
11
  export function Take(variants, input) {
11
- const [left, ...right] = variants;
12
- return (IsString(left)
13
- ? (() => {
14
- const result = TakeVariant(left, input);
15
- return IsEqual(result.length, 2) ? result : Take(right, input);
16
- })()
17
- : []);
12
+ // ----------------------------------------------------------------
13
+ // Symmetric
14
+ // ----------------------------------------------------------------
15
+ // const [left, ...right] = variants
16
+ // return (
17
+ // IsString(left)
18
+ // ? (() => {
19
+ // const result = TakeVariant(left, input)
20
+ // return IsEqual(result.length, 2) ? result : Take(right, input)
21
+ // })()
22
+ // : []
23
+ // ) as never
24
+ // ----------------------------------------------------------------
25
+ // Inline
26
+ // ----------------------------------------------------------------
27
+ for (let i = 0; i < variants.length; i++) {
28
+ const result = TakeVariant(variants[i], input);
29
+ if (IsMatch(result))
30
+ return result;
31
+ }
32
+ return [];
18
33
  }
19
34
  // deno-coverage-ignore-stop
@@ -1,20 +1,11 @@
1
1
  import { type TTrim } from './internal/trim.mjs';
2
- import { type TTake } from './internal/take.mjs';
3
- import { type TMany } from './internal/many.mjs';
4
2
  import { type TOptional } from './internal/optional.mjs';
5
- import { type TDigit, TUnderScore } from './internal/char.mjs';
6
- import { type TDot } from './internal/char.mjs';
7
3
  import { type THyphen } from './internal/char.mjs';
8
- import { type TInteger } from './integer.mjs';
9
- type TAllowedDigits = [...TDigit, TUnderScore];
4
+ import { type TUnsignedNumber } from './unsigned_number.mjs';
10
5
  type TTakeSign<Input extends string> = (TOptional<THyphen, Input>);
11
- type TIsLeadingDot<Input extends string> = (TTake<[TDot], Input> extends [string, string] ? true : false);
12
- type TTakeFractional<Input extends string> = (TMany<TAllowedDigits, [TUnderScore], Input> extends [infer Digits extends string, infer Rest extends string] ? Digits extends '' ? [] : [Digits, Rest] : []);
13
- type TLeadingDot<Sign extends string, Input extends string> = (TTake<[TDot], Input> extends [infer Dot extends string, infer Rest extends string] ? TTakeFractional<Rest> extends [infer Fractional extends string, infer Rest extends string] ? [`${Sign}0${Dot}${Fractional}`, Rest] : [] : []);
14
- type TLeadingInteger<Sign extends string, Input extends string> = (TInteger<Input> extends [infer Integer extends string, infer IntegerRest extends string] ? TTake<[TDot], IntegerRest> extends [infer Dot extends string, infer DotRest extends string] ? TTakeFractional<DotRest> extends [infer Fractional extends string, infer FractionalRest extends string] ? [`${Sign}${Integer}${Dot}${Fractional}`, FractionalRest] : [`${Sign}${Integer}`, DotRest] : [`${Sign}${Integer}`, IntegerRest] : []);
15
- type TTakeNumber<Input extends string> = (TTakeSign<Input> extends [infer Sign extends string, infer SignRest extends string] ? TIsLeadingDot<SignRest> extends true ? TLeadingDot<Sign, SignRest> : TLeadingInteger<Sign, SignRest> : []);
16
- /** Matches if next is a literal Number */
17
- export type TNumber<Input extends string> = (TTakeNumber<TTrim<Input>>);
18
- /** Matches if next is a literal Number */
6
+ type TTakeSignedNumber<Input extends string> = (TTakeSign<Input> extends [infer Sign extends string, infer SignRest extends string] ? TUnsignedNumber<SignRest> extends [infer UnsignedInteger extends string, infer UnsignedIntegerRest extends string] ? [`${Sign}${UnsignedInteger}`, UnsignedIntegerRest] : [] : []);
7
+ /** Matches if next is a signed or unsigned Number */
8
+ export type TNumber<Input extends string> = (TTakeSignedNumber<TTrim<Input>>);
9
+ /** Matches if next is a signed or unsigned Number */
19
10
  export declare function Number<Input extends string>(input: Input): TNumber<Input>;
20
11
  export {};
@@ -1,65 +1,19 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsEqual } from './internal/guard.mjs';
4
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
5
4
  import { Trim } from './internal/trim.mjs';
6
- import { Take } from './internal/take.mjs';
7
- import { Many } from './internal/many.mjs';
8
5
  import { Optional } from './internal/optional.mjs';
9
- import { Digit, UnderScore } from './internal/char.mjs';
10
- import { Dot } from './internal/char.mjs';
11
6
  import { Hyphen } from './internal/char.mjs';
12
- import { Integer } from './integer.mjs';
13
- const AllowedDigits = [...Digit, UnderScore];
7
+ import { UnsignedNumber } from './unsigned_number.mjs';
14
8
  function TakeSign(input) {
15
9
  return Optional(Hyphen, input);
16
10
  }
17
- function IsLeadingDot(input) {
18
- return IsResult(Take([Dot], input));
11
+ function TakeSignedNumber(input) {
12
+ return Match(TakeSign(input), (Sign, SignRest) => Match(UnsignedNumber(SignRest), (UnsignedInteger, UnsignedIntegerRest) => [`${Sign}${UnsignedInteger}`, UnsignedIntegerRest], () => []), // fail: did not match unsigned integer
13
+ () => []); // fail: did not match Sign
19
14
  }
20
- function TakeFractional(input) {
21
- const digits = Many(AllowedDigits, [UnderScore], input);
22
- return (IsResult(digits)
23
- ? IsEqual(digits[0], '')
24
- ? [] // fail: no Digits
25
- : [digits[0], digits[1]]
26
- : [] // fail: did not match Digits
27
- );
28
- }
29
- function LeadingDot(sign, input) {
30
- const dot = Take([Dot], input);
31
- return (IsResult(dot) ? (() => {
32
- const fractional = TakeFractional(dot[1]);
33
- return IsResult(fractional)
34
- ? [`${sign}0${dot[0]}${fractional[0]}`, fractional[1]]
35
- : []; // fail: did not match Fractional
36
- })() : [] // fail: did not match Dot
37
- );
38
- }
39
- function LeadingInteger(sign, input) {
40
- const integer = Integer(input);
41
- return (IsResult(integer) ? (() => {
42
- const dot = Take([Dot], integer[1]);
43
- return IsResult(dot) ? (() => {
44
- const fractional = TakeFractional(dot[1]);
45
- return IsResult(fractional)
46
- ? [`${sign}${integer[0]}${dot[0]}${fractional[0]}`, fractional[1]]
47
- : [`${sign}${integer[0]}`, dot[1]]; // fail: did not match Fractional, use Integer
48
- })() : [`${sign}${integer[0]}`, integer[1]]; // fail: did not match Dot, use Integer
49
- })() : [] // fail: did not match Integer
50
- );
51
- }
52
- function TakeNumber(input) {
53
- const sign = TakeSign(input);
54
- return (IsResult(sign)
55
- ? IsLeadingDot(sign[1])
56
- ? LeadingDot(sign[0], sign[1])
57
- : LeadingInteger(sign[0], sign[1])
58
- : [] // fail: did not match Sign
59
- );
60
- }
61
- /** Matches if next is a literal Number */
15
+ /** Matches if next is a signed or unsigned Number */
62
16
  export function Number(input) {
63
- return TakeNumber(Trim(input));
17
+ return TakeSignedNumber(Trim(input));
64
18
  }
65
19
  // deno-coverage-ignore-stop
@@ -0,0 +1,4 @@
1
+ /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
2
+ export type TRest<Input extends string> = (Input extends '' ? [] : [Input, '']);
3
+ /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
4
+ export declare function Rest<Input extends string>(input: Input): TRest<Input>;
@@ -0,0 +1,9 @@
1
+ // deno-coverage-ignore-start - parsebox tested
2
+ // deno-fmt-ignore-file
3
+ import { IsEqual } from './internal/guard.mjs';
4
+ /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
5
+ export function Rest(input) {
6
+ const result = IsEqual(input, '') ? [] : [input, ''];
7
+ return result;
8
+ }
9
+ // deno-coverage-ignore-stop
@@ -1,8 +1,9 @@
1
1
  import { type TTrim } from './internal/trim.mjs';
2
2
  import { type TNewLine } from './internal/char.mjs';
3
+ import { type TTake } from './internal/take.mjs';
3
4
  import { type TUntil } from './until.mjs';
4
- type TMultiLine<Start extends string, End extends string, Input extends string> = (Input extends `${Start}${infer Rest extends string}` ? TUntil<[End], Rest> extends [infer Until extends string, infer UntilRest extends string] ? UntilRest extends `${End}${infer Rest extends string}` ? [`${Until}`, Rest] : [] : [] : []);
5
- type TSingleLine<Start extends string, End extends string, Input extends string> = (Input extends `${Start}${infer Rest extends string}` ? TUntil<[TNewLine, End], Rest> extends [infer Until extends string, infer UntilRest extends string] ? UntilRest extends `${End}${infer EndRest extends string}` ? [`${Until}`, EndRest] : [] : [] : []);
5
+ type TMultiLine<Start extends string, End extends string, Input extends string> = (TTake<[Start], Input> extends [infer _, infer Rest extends string] ? TUntil<[End], Rest> extends [infer Until extends string, infer UntilRest extends string] ? TTake<[End], UntilRest> extends [infer _ extends string, infer Rest extends string] ? [`${Until}`, Rest] : [] : [] : []);
6
+ type TSingleLine<Start extends string, End extends string, Input extends string> = (TTake<[Start], Input> extends [infer _ extends string, infer Rest extends string] ? TUntil<[TNewLine, End], Rest> extends [infer Until extends string, infer UntilRest extends string] ? TTake<[End], UntilRest> extends [infer _ extends string, infer EndRest extends string] ? [`${Until}`, EndRest] : [] : [] : []);
6
7
  /** Matches from Start and End capturing everything in-between. Start and End are consumed. */
7
8
  export type TSpan<Start extends string, End extends string, MultiLine extends boolean, Input extends string> = (MultiLine extends true ? TMultiLine<Start, End, TTrim<Input>> : TSingleLine<Start, End, TTrim<Input>>);
8
9
  /** Matches from Start and End capturing everything in-between. Start and End are consumed. */
@@ -1,30 +1,19 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
4
4
  import { Trim } from './internal/trim.mjs';
5
5
  import { NewLine } from './internal/char.mjs';
6
+ import { Take } from './internal/take.mjs';
6
7
  import { Until } from './until.mjs';
7
8
  function MultiLine(start, end, input) {
8
- return (input.startsWith(start) ? (() => {
9
- const until = Until([end], input.slice(start.length));
10
- return IsResult(until) ? (() => {
11
- return until[1].startsWith(end)
12
- ? [`${until[0]}`, until[1].slice(end.length)]
13
- : []; // fail: did not match End
14
- })() : []; // fail: did not match Until
15
- })() : [] // fail: did not match Start
16
- );
9
+ return Match(Take([start], input), (_, Rest) => Match(Until([end], Rest), (Until, UntilRest) => Match(Take([end], UntilRest), (_, Rest) => [`${Until}`, Rest], () => []), // fail: did not match End
10
+ () => []), // fail: did not match Until
11
+ () => []); // fail: did not match Start
17
12
  }
18
13
  function SingleLine(start, end, input) {
19
- return (input.startsWith(start) ? (() => {
20
- const until = Until([NewLine, end], input.slice(start.length));
21
- return IsResult(until) ? (() => {
22
- return until[1].startsWith(end)
23
- ? [`${until[0]}`, until[1].slice(end.length)]
24
- : []; // fail: did not match End
25
- })() : []; // fail: did not match Until
26
- })() : [] // fail: not match Start
27
- );
14
+ return Match(Take([start], input), (_, Rest) => Match(Until([NewLine, end], Rest), (Until, UntilRest) => Match(Take([end], UntilRest), (_, EndRest) => [`${Until}`, EndRest], () => []), // fail: did not match End
15
+ () => []), // fail: did not match Until
16
+ () => []); // fail: not match Start
28
17
  }
29
18
  /** Matches from Start and End capturing everything in-between. Start and End are consumed. */
30
19
  export function Span(start, end, multiLine, input) {
@@ -1,6 +1,6 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
- import { IsResult } from './internal/result.mjs';
3
+ import { Match } from './internal/match.mjs';
4
4
  import { Take } from './internal/take.mjs';
5
5
  import { Trim } from './internal/trim.mjs';
6
6
  import { Span } from './span.mjs';
@@ -11,11 +11,7 @@ function TakeSpan(quote, input) {
11
11
  return Span(quote, quote, false, input);
12
12
  }
13
13
  function TakeString(quotes, input) {
14
- const initial = TakeInitial(quotes, input);
15
- return (IsResult(initial)
16
- ? TakeSpan(initial[0], `${initial[0]}${initial[1]}`)
17
- : [] // fail: did not match Initial
18
- );
14
+ return Match(TakeInitial(quotes, input), (Initial, InitialRest) => TakeSpan(Initial, `${Initial}${InitialRest}`), () => []); // fail: did not match Initial
19
15
  }
20
16
  /** Matches a literal String with the given quotes */
21
17
  export function String(quotes, input) {
@@ -0,0 +1,16 @@
1
+ import { type TTrim } from './internal/trim.mjs';
2
+ import { type TTake } from './internal/take.mjs';
3
+ import { type TMany } from './internal/many.mjs';
4
+ import { type TDigit } from './internal/char.mjs';
5
+ import { type TZero } from './internal/char.mjs';
6
+ import { type TNonZero } from './internal/char.mjs';
7
+ import { type TUnderScore } from './internal/char.mjs';
8
+ type TTakeNonZero<Input extends string> = (TTake<TNonZero, Input>);
9
+ type TAllowedDigits = [...TDigit, TUnderScore];
10
+ type TTakeDigits<Input extends string> = (TMany<TAllowedDigits, [TUnderScore], Input>);
11
+ type TTakeUnsignedInteger<Input extends string> = (TTake<[TZero], Input> extends [infer Zero extends string, infer ZeroRest extends string] ? [Zero, ZeroRest] : TTakeNonZero<Input> extends [infer NonZero extends string, infer NonZeroRest extends string] ? TTakeDigits<NonZeroRest> extends [infer Digits extends string, infer DigitsRest extends string] ? [`${NonZero}${Digits}`, DigitsRest] : [] : []);
12
+ /** Matches if next is a UnsignedInteger */
13
+ export type TUnsignedInteger<Input extends string> = (TTakeUnsignedInteger<TTrim<Input>>);
14
+ /** Matches if next is a UnsignedInteger */
15
+ export declare function UnsignedInteger<Input extends string>(input: Input): TUnsignedInteger<Input>;
16
+ export {};
@@ -0,0 +1,26 @@
1
+ // deno-coverage-ignore-start - parsebox tested
2
+ // deno-fmt-ignore-file
3
+ import { Match } from './internal/match.mjs';
4
+ import { Trim } from './internal/trim.mjs';
5
+ import { Take } from './internal/take.mjs';
6
+ import { Many } from './internal/many.mjs';
7
+ import { Digit } from './internal/char.mjs';
8
+ import { Zero } from './internal/char.mjs';
9
+ import { NonZero } from './internal/char.mjs';
10
+ import { UnderScore } from './internal/char.mjs';
11
+ function TakeNonZero(input) {
12
+ return Take(NonZero, input);
13
+ }
14
+ const AllowedDigits = [...Digit, UnderScore];
15
+ function TakeDigits(input) {
16
+ return Many(AllowedDigits, [UnderScore], input);
17
+ }
18
+ function TakeUnsignedInteger(input) {
19
+ return Match(Take([Zero], input), (Zero, ZeroRest) => [Zero, ZeroRest], () => Match(TakeNonZero(input), (NonZero, NonZeroRest) => Match(TakeDigits(NonZeroRest), (Digits, DigitsRest) => [`${NonZero}${Digits}`, DigitsRest], () => []), // fail: did not match Digits
20
+ () => [])); // fail: did not match NonZero
21
+ }
22
+ /** Matches if next is a UnsignedInteger */
23
+ export function UnsignedInteger(input) {
24
+ return TakeUnsignedInteger(Trim(input));
25
+ }
26
+ // deno-coverage-ignore-stop
@@ -0,0 +1,17 @@
1
+ import { type TTrim } from './internal/trim.mjs';
2
+ import { type TTake } from './internal/take.mjs';
3
+ import { type TMany } from './internal/many.mjs';
4
+ import { type TDigit, type TUnderScore } from './internal/char.mjs';
5
+ import { type TDot } from './internal/char.mjs';
6
+ import { type TUnsignedInteger } from './unsigned_integer.mjs';
7
+ type TAllowedDigits = [...TDigit, TUnderScore];
8
+ type TIsLeadingDot<Input extends string> = (TTake<[TDot], Input> extends [string, string] ? true : false);
9
+ type TTakeFractional<Input extends string> = (TMany<TAllowedDigits, [TUnderScore], Input> extends [infer Digits extends string, infer DigitsRest extends string] ? Digits extends '' ? [] : [Digits, DigitsRest] : []);
10
+ type TLeadingDot<Input extends string> = (TTake<[TDot], Input> extends [infer Dot extends string, infer DotRest extends string] ? TTakeFractional<DotRest> extends [infer Fractional extends string, infer FractionalRest extends string] ? [`0${Dot}${Fractional}`, FractionalRest] : [] : []);
11
+ type TLeadingInteger<Input extends string> = (TUnsignedInteger<Input> extends [infer Integer extends string, infer IntegerRest extends string] ? TTake<[TDot], IntegerRest> extends [infer Dot extends string, infer DotRest extends string] ? TTakeFractional<DotRest> extends [infer Fractional extends string, infer FractionalRest extends string] ? [`${Integer}${Dot}${Fractional}`, FractionalRest] : [`${Integer}`, DotRest] : [`${Integer}`, IntegerRest] : []);
12
+ type TTakeUnsignedNumber<Input extends string> = (TIsLeadingDot<Input> extends true ? TLeadingDot<Input> : TLeadingInteger<Input>);
13
+ /** Matches if next is a UnsignedNumber */
14
+ export type TUnsignedNumber<Input extends string> = (TTakeUnsignedNumber<TTrim<Input>>);
15
+ /** Matches if next is a UnsignedNumber */
16
+ export declare function UnsignedNumber<Input extends string>(input: Input): TUnsignedNumber<Input>;
17
+ export {};
@@ -0,0 +1,38 @@
1
+ // deno-coverage-ignore-start - parsebox tested
2
+ // deno-fmt-ignore-file
3
+ import { IsEqual } from './internal/guard.mjs';
4
+ import { IsMatch, Match } from './internal/match.mjs';
5
+ import { Trim } from './internal/trim.mjs';
6
+ import { Take } from './internal/take.mjs';
7
+ import { Many } from './internal/many.mjs';
8
+ import { Digit, UnderScore } from './internal/char.mjs';
9
+ import { Dot } from './internal/char.mjs';
10
+ import { UnsignedInteger } from './unsigned_integer.mjs';
11
+ const AllowedDigits = [...Digit, UnderScore];
12
+ function IsLeadingDot(input) {
13
+ return IsMatch(Take([Dot], input));
14
+ }
15
+ function TakeFractional(input) {
16
+ return Match(Many(AllowedDigits, [UnderScore], input), (Digits, DigitsRest) => IsEqual(Digits, '')
17
+ ? [] // fail: no Digits
18
+ : [Digits, DigitsRest], () => []); // fail: did not match Digits
19
+ }
20
+ function LeadingDot(input) {
21
+ return Match(Take([Dot], input), (Dot, DotRest) => Match(TakeFractional(DotRest), (Fractional, FractionalRest) => [`0${Dot}${Fractional}`, FractionalRest], () => []), // fail: did not match Fractional
22
+ () => []); // fail: did not match Dot
23
+ }
24
+ function LeadingInteger(input) {
25
+ return Match(UnsignedInteger(input), (Integer, IntegerRest) => Match(Take([Dot], IntegerRest), (Dot, DotRest) => Match(TakeFractional(DotRest), (Fractional, FractionalRest) => [`${Integer}${Dot}${Fractional}`, FractionalRest], () => [`${Integer}`, DotRest]), // fail: did not match Fractional, use Integer
26
+ () => [`${Integer}`, IntegerRest]), // fail: did not match Dot, use Integer
27
+ () => []); // fail: did not match Integer
28
+ }
29
+ function TakeUnsignedNumber(input) {
30
+ return (IsLeadingDot(input)
31
+ ? LeadingDot(input)
32
+ : LeadingInteger(input));
33
+ }
34
+ /** Matches if next is a UnsignedNumber */
35
+ export function UnsignedNumber(input) {
36
+ return TakeUnsignedNumber(Trim(input));
37
+ }
38
+ // deno-coverage-ignore-stop
@@ -1,6 +1,7 @@
1
- type TIsEnd<End extends string[], Input extends string> = (End extends [infer Left extends string, ...infer Right extends string[]] ? Input extends `${Left}${string}` ? true : TIsEnd<Right, Input> : false);
1
+ type TTakeOne<Input extends string> = (Input extends `${infer Left extends string}${infer Right extends string}` ? [Left, Right] : []);
2
+ type TIsInputMatchSentinal<End extends string[], Input extends string> = (End extends [infer Left extends string, ...infer Right extends string[]] ? Input extends `${Left}${string}` ? true : TIsInputMatchSentinal<Right, Input> : false);
2
3
  /** Match Input until but not including End. No match if End not found. */
3
- export type TUntil<End extends string[], Input extends string, Result extends string = ''> = (Input extends `` ? [] : TIsEnd<End, Input> extends true ? [Result, Input] : Input extends `${infer Left extends string}${infer Right extends string}` ? TUntil<End, Right, `${Result}${Left}`> : []);
4
+ export type TUntil<End extends string[], Input extends string, Result extends string = ''> = (TTakeOne<Input> extends [infer One extends string, infer Rest extends string] ? TIsInputMatchSentinal<End, Input> extends true ? [Result, Input] : TUntil<End, Rest, `${Result}${One}`> : []);
4
5
  /** Match Input until but not including End. No match if End not found. */
5
6
  export declare function Until<End extends string[], Input extends string>(end: [...End], input: Input, result?: string): TUntil<End, Input>;
6
7
  export {};
@@ -1,21 +1,24 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
+ import { Match } from './internal/match.mjs';
3
4
  import { IsEqual, IsString } from './internal/guard.mjs';
4
- function IsEnd(end, input) {
5
+ function TakeOne(input) {
6
+ const result = IsEqual(input, '') ? [] : [input.slice(0, 1), input.slice(1)];
7
+ return result;
8
+ }
9
+ function IsInputMatchSentinal(end, input) {
5
10
  const [left, ...right] = end;
6
11
  return (IsString(left)
7
12
  ? input.startsWith(left)
8
13
  ? true
9
- : IsEnd(right, input)
14
+ : IsInputMatchSentinal(right, input)
10
15
  : false);
11
16
  }
12
17
  /** Match Input until but not including End. No match if End not found. */
13
18
  export function Until(end, input, result = '') {
14
- return (IsEqual(input, '')
15
- ? [] // fail: Input is empty
16
- : IsEnd(end, input) ? [result, input] : (() => {
17
- const [left, right] = [input.slice(0, 1), input.slice(1)];
18
- return Until(end, right, `${result}${left}`);
19
- })());
19
+ return Match(TakeOne(input), (One, Rest) => IsInputMatchSentinal(end, input)
20
+ ? [result, input] // ok: at sentinal
21
+ : Until(end, Rest, `${result}${One}`) // fail: advance + 1
22
+ , () => []);
20
23
  }
21
24
  // deno-coverage-ignore-stop
@@ -1,16 +1,12 @@
1
1
  // deno-coverage-ignore-start - parsebox tested
2
2
  // deno-fmt-ignore-file
3
3
  import { IsEqual } from './internal/guard.mjs';
4
- import { IsResult } from './internal/result.mjs';
4
+ import { Match } from './internal/match.mjs';
5
5
  import { Until } from './until.mjs';
6
6
  /** Match Input until but not including End. No match if End not found or match is zero-length. */
7
7
  export function Until_1(end, input) {
8
- const until = Until(end, input);
9
- return (IsResult(until)
10
- ? IsEqual(until[0], '')
11
- ? [] // fail: match has no characters
12
- : until
13
- : [] // fail: did not match Until
14
- );
8
+ return Match(Until(end, input), (Until, UntilRest) => IsEqual(Until, '')
9
+ ? [] // fail: match has no characters
10
+ : [Until, UntilRest], () => []); // fail: did not match Until
15
11
  }
16
12
  // deno-coverage-ignore-stop
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.1.6",
4
+ "version": "1.1.7",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
@@ -16,38 +16,38 @@
16
16
  "types": "./build/index.d.mts",
17
17
  "module": "./build/index.mjs",
18
18
  "exports": {
19
- "./type": {
20
- "import": "./build/type/index.mjs",
21
- "default": "./build/type/index.mjs"
22
- },
23
- "./value": {
24
- "import": "./build/value/index.mjs",
25
- "default": "./build/value/index.mjs"
26
- },
27
- "./guard": {
28
- "import": "./build/guard/index.mjs",
29
- "default": "./build/guard/index.mjs"
30
- },
31
19
  "./system": {
32
20
  "import": "./build/system/index.mjs",
33
21
  "default": "./build/system/index.mjs"
34
22
  },
35
- "./format": {
36
- "import": "./build/format/index.mjs",
37
- "default": "./build/format/index.mjs"
38
- },
39
23
  "./compile": {
40
24
  "import": "./build/compile/index.mjs",
41
25
  "default": "./build/compile/index.mjs"
42
26
  },
27
+ "./value": {
28
+ "import": "./build/value/index.mjs",
29
+ "default": "./build/value/index.mjs"
30
+ },
43
31
  "./error": {
44
32
  "import": "./build/error/index.mjs",
45
33
  "default": "./build/error/index.mjs"
46
34
  },
35
+ "./guard": {
36
+ "import": "./build/guard/index.mjs",
37
+ "default": "./build/guard/index.mjs"
38
+ },
47
39
  "./schema": {
48
40
  "import": "./build/schema/index.mjs",
49
41
  "default": "./build/schema/index.mjs"
50
42
  },
43
+ "./format": {
44
+ "import": "./build/format/index.mjs",
45
+ "default": "./build/format/index.mjs"
46
+ },
47
+ "./type": {
48
+ "import": "./build/type/index.mjs",
49
+ "default": "./build/type/index.mjs"
50
+ },
51
51
  ".": {
52
52
  "import": "./build/index.mjs",
53
53
  "default": "./build/index.mjs"
@@ -55,30 +55,30 @@
55
55
  },
56
56
  "typesVersions": {
57
57
  "*": {
58
- "type": [
59
- "./build/type/index.d.mts"
60
- ],
61
- "value": [
62
- "./build/value/index.d.mts"
63
- ],
64
- "guard": [
65
- "./build/guard/index.d.mts"
66
- ],
67
58
  "system": [
68
59
  "./build/system/index.d.mts"
69
60
  ],
70
- "format": [
71
- "./build/format/index.d.mts"
72
- ],
73
61
  "compile": [
74
62
  "./build/compile/index.d.mts"
75
63
  ],
64
+ "value": [
65
+ "./build/value/index.d.mts"
66
+ ],
76
67
  "error": [
77
68
  "./build/error/index.d.mts"
78
69
  ],
70
+ "guard": [
71
+ "./build/guard/index.d.mts"
72
+ ],
79
73
  "schema": [
80
74
  "./build/schema/index.d.mts"
81
75
  ],
76
+ "format": [
77
+ "./build/format/index.d.mts"
78
+ ],
79
+ "type": [
80
+ "./build/type/index.d.mts"
81
+ ],
82
82
  ".": [
83
83
  "./build/index.d.mts"
84
84
  ]
package/readme.md CHANGED
@@ -70,7 +70,7 @@ License: MIT
70
70
 
71
71
  ## Type
72
72
 
73
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/type/overview) | [Example](https://tsplay.dev/NaMoBN)
73
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/type/overview)
74
74
 
75
75
  TypeBox provides many functions to create JSON Schema types. Each function returns a small JSON Schema fragment that can be composed into more complex types. TypeBox includes a set of functions that are used to construct JSON Schema compliant schematics as well as a set of extended functions that return schematics for constructs native to JavaScript.
76
76
 
@@ -117,7 +117,7 @@ const S = Type.Number({ // const S = {
117
117
 
118
118
  ## Value
119
119
 
120
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/value/overview) | [Example](https://tsplay.dev/W4YE1w)
120
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/value/overview)
121
121
 
122
122
  The Value submodule provides functions for validation and other typed operations on JavaScript values. It includes functions such as Check, Parse, Clone, Encode, and Decode, as well as advanced functions for performing structural Diff and Patch operations on dynamic JavaScript values.
123
123
 
@@ -145,7 +145,7 @@ const A = Value.Parse(T, { // const A: {
145
145
 
146
146
  ## Script
147
147
 
148
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview) | [Example 1](https://tsplay.dev/N9rQ8m) | [Example 2](https://tsplay.dev/NnrJoN)
148
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview)
149
149
 
150
150
  TypeBox includes a runtime TypeScript DSL engine that can transform TypeScript syntax into JSON Schema. The engine is implemented at runtime and within the TypeScript type system.
151
151
 
@@ -231,8 +231,6 @@ If upgrading from `@sinclair/typebox` 0.34.x refer to the 1.0 migration guide at
231
231
 
232
232
  Most types created with 0.34.x are compatible with V1, and it is possible to run both `typebox` and `@sinclair/typebox` packages side by side.
233
233
 
234
- [Compatibility](https://tsplay.dev/Wzr2rW)
235
-
236
234
  ```typescript
237
235
  import { Type } from '@sinclair/typebox' // TB: 0.34.x
238
236
  import { Static } from 'typebox' // TB: 1.0.0
@@ -1,2 +0,0 @@
1
- /** Checks the value is a Tuple-2 [string, string] result */
2
- export declare function IsResult(value: unknown): value is [string, string];
@@ -1,7 +0,0 @@
1
- // deno-coverage-ignore-start - parsebox tested
2
- import { IsArray, IsEqual } from './guard.mjs';
3
- /** Checks the value is a Tuple-2 [string, string] result */
4
- export function IsResult(value) {
5
- return IsArray(value) && IsEqual(value.length, 2);
6
- }
7
- // deno-coverage-ignore-stop