Comparing version 2.0.0-dev.7 to 2.0.0-dev.8
@@ -17,11 +17,11 @@ import { attest, contextualize } from "@arktype/attest" | ||
attest(t.allows([])).equals(true) | ||
attest(t([]).out).snap([]) | ||
attest(t([])).snap([]) | ||
attest(t.allows(["foo", "bar"])).equals(true) | ||
attest(t(["foo", "bar"]).out).snap(["foo", "bar"]) | ||
attest(t(["foo", "bar"])).snap(["foo", "bar"]) | ||
attest(t.allows(["foo", "bar", 5])).equals(false) | ||
attest(t(["foo", "bar", 5]).errors?.summary).snap( | ||
attest(t(["foo", "bar", 5]).toString()).snap( | ||
"value at [2] must be a string (was number)" | ||
) | ||
attest(t.allows([5, "foo", "bar"])).equals(false) | ||
attest(t([5, "foo", "bar"]).errors?.summary).snap( | ||
attest(t([5, "foo", "bar"]).toString()).snap( | ||
"value at [0] must be a string (was number)" | ||
@@ -35,11 +35,11 @@ ) | ||
attest(t.allows([])).equals(true) | ||
attest(t([]).out).snap([]) | ||
attest(t([])).snap([]) | ||
attest(t.allows([["foo"]])).equals(true) | ||
attest(t([["foo"]]).out).snap([["foo"]]) | ||
attest(t([["foo"]])).snap([["foo"]]) | ||
attest(t.allows(["foo"])).equals(false) | ||
attest(t(["foo"]).errors?.summary).snap( | ||
attest(t(["foo"]).toString()).snap( | ||
"value at [0] must be an array (was string)" | ||
) | ||
attest(t.allows([["foo", 5]])).equals(false) | ||
attest(t([["foo", 5]]).errors?.summary).snap( | ||
attest(t([["foo", 5]]).toString()).snap( | ||
"value at [0][1] must be a string (was number)" | ||
@@ -84,9 +84,9 @@ ) | ||
attest(t.allows(["", 0])).equals(true) | ||
attest(t(["", 0]).out).snap(["", 0]) | ||
attest(t(["", 0])).snap(["", 0]) | ||
attest(t.allows([true, 0])).equals(false) | ||
attest(t([true, 0]).errors?.summary).snap( | ||
attest(t([true, 0]).toString()).snap( | ||
"value at [0] must be a string (was true)" | ||
) | ||
attest(t.allows([0, false])).equals(false) | ||
attest(t([0, false]).errors?.summary) | ||
attest(t([0, false]).toString()) | ||
.snap(`value at [0] must be a string (was number) | ||
@@ -96,8 +96,6 @@ value at [1] must be a number (was false)`) | ||
attest(t.allows([""])).equals(false) | ||
attest(t([""]).errors?.summary).snap( | ||
'must be exactly length 2 (was [""])' | ||
) | ||
attest(t([""]).toString()).snap('must be exactly length 2 (was [""])') | ||
// too long | ||
attest(t.allows(["", 0, 1])).equals(false) | ||
attest(t(["", 0, 1]).errors?.summary).snap( | ||
attest(t(["", 0, 1]).toString()).snap( | ||
'must be exactly length 2 (was ["",0,1])' | ||
@@ -118,3 +116,3 @@ ) | ||
1: 0 | ||
}).errors?.summary | ||
}).toString() | ||
).snap("must be an array (was object)") | ||
@@ -138,6 +136,6 @@ }) | ||
attest(t.allows(valid)).equals(true) | ||
attest(t(valid).out).equals(valid) | ||
attest(t(valid)).equals(valid) | ||
const invalid = [["", 0], [{ a: 0n, b: [undefined] }]] | ||
attest(t.allows(invalid)).equals(false) | ||
attest(t(invalid).errors?.summary).snap( | ||
attest(t(invalid).toString()).snap( | ||
"value at [1][0].b[0] must be null (was undefined)" | ||
@@ -150,8 +148,8 @@ ) | ||
attest<[string?]>(t.infer) | ||
attest(t([]).errors).equals(undefined) | ||
attest(t(["foo"]).errors).equals(undefined) | ||
attest(t([5]).errors?.summary).snap( | ||
attest(t([])).equals([]) | ||
attest(t(["foo"])).equals(["foo"]) | ||
attest(t([5]).toString()).snap( | ||
"value at [0] must be a string (was number)" | ||
) | ||
attest(t(["foo", "bar"]).errors?.summary).snap( | ||
attest(t(["foo", "bar"]).toString()).snap( | ||
"must be at most length 1 (was 2)" | ||
@@ -171,4 +169,4 @@ ) | ||
attest<[string, ...number[]]>(wellRested.infer) | ||
attest(wellRested(["foo"]).out).equals(["foo"]) | ||
attest(wellRested(["foo", 1, 2]).out).equals(["foo", 1, 2]) | ||
attest(wellRested(["foo"])).equals(["foo"]) | ||
attest(wellRested(["foo", 1, 2])).equals(["foo", 1, 2]) | ||
}) | ||
@@ -397,3 +395,3 @@ | ||
// const stringArray = type("string[]") | ||
// attest(stringArray([1, 2]).errors?.summary).snap( | ||
// attest(stringArray([1, 2]).toString()).snap( | ||
// "Item at index 0 must be a string (was number)\nItem at index 1 must be a string (was number)" | ||
@@ -400,0 +398,0 @@ // ) |
@@ -15,7 +15,7 @@ import { attest, contextualize } from "@arktype/attest" | ||
attest(types.a.description).equals(description) | ||
attest(types.a(1).errors?.summary).snap( | ||
attest(types.a(1).toString()).snap( | ||
"must be a series of characters (was number)" | ||
) | ||
attest<{ a: string }>(types.b.infer) | ||
attest(types.b({ a: true }).errors?.summary).snap( | ||
attest(types.b({ a: true }).toString()).snap( | ||
"a must be a series of characters (was true)" | ||
@@ -34,3 +34,3 @@ ) | ||
) | ||
attest(t({ monster: 196882 }).errors?.summary).snap( | ||
attest(t({ monster: 196882 }).toString()).snap( | ||
"monster must be the number of dimensions in the monster group (was 196882)" | ||
@@ -43,3 +43,3 @@ ) | ||
attest<true>(t.infer) | ||
attest(t(false).errors?.summary).snap("must be unfalse (was false)") | ||
attest(t(false).toString()).snap("must be unfalse (was false)") | ||
}) | ||
@@ -50,3 +50,3 @@ | ||
const t = type({ myKey: unfalse }) | ||
attest(t({ myKey: "500" }).errors?.summary).snap( | ||
attest(t({ myKey: "500" }).toString()).snap( | ||
`myKey must be unfalse (was "500")` | ||
@@ -67,3 +67,3 @@ ) | ||
attest<{ myKey: false }>(t.infer) | ||
attest(t({ myKey: true }).errors?.summary).snap( | ||
attest(t({ myKey: true }).toString()).snap( | ||
"myKey must be untrue (was true)" | ||
@@ -84,8 +84,8 @@ ) | ||
age: true | ||
}).errors?.summary | ||
}).toString() | ||
).snap("age must be a number (was true)") | ||
// should give the shallow custom error | ||
attest(user(null).errors?.summary).snap("must be a valid user (was null)") | ||
attest(user(null).toString()).snap("must be a valid user (was null)") | ||
}) | ||
}) |
@@ -80,3 +80,3 @@ // import { attest } from "@arktype/attest" | ||
// const data = getCyclicData() | ||
// attest(types.package(data).out).snap({ | ||
// attest(types.package(data)).snap({ | ||
// name: "arktype", | ||
@@ -92,3 +92,3 @@ // dependencies: [{ name: "typescript" }, "(cycle)" as any as Package], | ||
// data.contributors[0].email = "ssalbdivad" | ||
// attest(types.package(data).errors?.summary).snap( | ||
// attest(types.package(data).toString()).snap( | ||
// "dependencies/1/contributors/0/email must be a valid email (was 'ssalbdivad')\ncontributors/0/email must be a valid email (was 'ssalbdivad')" | ||
@@ -105,3 +105,3 @@ // ) | ||
// ]) | ||
// attest(nonSelfDependent(data).errors?.summary).snap( | ||
// attest(nonSelfDependent(data).toString()).snap( | ||
// 'must be valid (was {"name":"arktype","dependencies":[{"name":"typescript"},"(cycle)"],"contributors":[{"email":"david@arktype.io"}]})' | ||
@@ -108,0 +108,0 @@ // ) |
@@ -9,3 +9,3 @@ // describe("snippets", () => { | ||
// } | ||
// attest(typeSnippet.errors?.summary).snap( | ||
// attest(typeSnippet.toString()).snap( | ||
// "contributors must be more than 1 items long (was 1)" | ||
@@ -23,3 +23,3 @@ // ) | ||
// } | ||
// attest(typeSnippet.errors?.summary).snap( | ||
// attest(typeSnippet.toString()).snap( | ||
// "device/platform must be 'android' or 'ios' (was 'enigma')" | ||
@@ -39,3 +39,3 @@ // ) | ||
// // } | ||
// // attest(scopeSnippet.errors?.summary).snap( | ||
// // attest(scopeSnippet.toString()).snap( | ||
// // "dependencies/0/dependencies/0/contributors/0/email must be a valid email (was 'david@sharktypeio')\ncontributors/0/email must be a valid email (was 'david@sharktypeio')" | ||
@@ -42,0 +42,0 @@ // // ) |
@@ -16,4 +16,4 @@ import { attest, contextualize } from "@arktype/attest" | ||
const e = new Error() | ||
attest(t(e).out).equals(e) | ||
attest(t({}).errors?.summary).snap("must be an Error (was object)") | ||
attest(t(e)).equals(e) | ||
attest(t({}).toString()).snap("must be an Error (was object)") | ||
}) | ||
@@ -26,4 +26,4 @@ it("inherited", () => { | ||
// attest<TypeError>(t.infer) | ||
attest(t(e).out).equals(e) | ||
attest(t(new Error()).errors?.summary).snap( | ||
attest(t(e)).equals(e) | ||
attest(t(new Error()).toString()).snap( | ||
"must be an instance of TypeError (was Error)" | ||
@@ -42,3 +42,3 @@ ) | ||
const sub = new Sub() | ||
attest(t(sub).out).equals(sub) | ||
attest(t(sub)).equals(sub) | ||
}) | ||
@@ -65,4 +65,4 @@ it("multiple branches", () => { | ||
const a = new ArkClass() | ||
attest(ark(a).out).equals(a) | ||
attest(ark({}).errors?.summary).snap( | ||
attest(ark(a)).equals(a) | ||
attest(ark({}).toString()).snap( | ||
"must be an instance of ArkClass (was object)" | ||
@@ -69,0 +69,0 @@ ) |
@@ -45,5 +45,5 @@ import { attest, contextualize } from "@arktype/attest" | ||
it("chained deep intersections", () => { | ||
const b = type({ b: "boolean" }, "=>", (o) => [o.b]) | ||
const b = type({ b: "boolean" }, "=>", o => [o.b]) | ||
const t = type({ | ||
a: ["string", "=>", (s) => s.length] | ||
a: ["string", "=>", s => s.length] | ||
}) | ||
@@ -50,0 +50,0 @@ .and({ |
@@ -9,3 +9,3 @@ // TODO: reenable | ||
// const dataWithExtraneousB = getExtraneousB() | ||
// attest(t(dataWithExtraneousB).out).equals(dataWithExtraneousB) | ||
// attest(t(dataWithExtraneousB)).equals(dataWithExtraneousB) | ||
// }) | ||
@@ -17,3 +17,3 @@ // | ||
// }) | ||
// attest(o({ a: 2 }).errors?.summary).snap( | ||
// attest(o({ a: 2 }).toString()).snap( | ||
// 'a must be a string or removed (was {"a":2})' | ||
@@ -27,4 +27,4 @@ // ) | ||
// }).configure({ keys: "distilled" }) | ||
// attest(t({ a: "ok" }).out).equals({ a: "ok" }) | ||
// attest(t(getExtraneousB()).out).snap({ a: "ok" }) | ||
// attest(t({ a: "ok" })).equals({ a: "ok" }) | ||
// attest(t(getExtraneousB())).snap({ a: "ok" }) | ||
// }) | ||
@@ -36,10 +36,10 @@ // | ||
// }) | ||
// attest(o({ a: ["shawn@arktype.io"] }).out).snap({ | ||
// attest(o({ a: ["shawn@arktype.io"] })).snap({ | ||
// a: ["shawn@arktype.io"] | ||
// }) | ||
// attest(o({ a: ["notAnEmail"] }).errors?.summary).snap( | ||
// attest(o({ a: ["notAnEmail"] }).toString()).snap( | ||
// "a/0 must be a valid email (was 'notAnEmail')" | ||
// ) | ||
// // can handle missing keys | ||
// attest(o({ b: ["shawn"] }).errors?.summary).snap("a must be defined") | ||
// attest(o({ b: ["shawn"] }).toString()).snap("a must be defined") | ||
// }) | ||
@@ -52,7 +52,7 @@ // | ||
// // can distill to first branch | ||
// attest(o({ a: "to", z: "bra" }).out).snap({ a: "to" }) | ||
// attest(o({ a: "to", z: "bra" })).snap({ a: "to" }) | ||
// // can distill to second branch | ||
// attest(o({ b: true, c: false }).out).snap({ b: true }) | ||
// attest(o({ b: true, c: false })).snap({ b: true }) | ||
// // can handle missing keys | ||
// attest(o({ a: 2 }).errors?.summary).snap( | ||
// attest(o({ a: 2 }).toString()).snap( | ||
// 'a must be a string or b must be defined (was {"a":2})' | ||
@@ -66,4 +66,4 @@ // ) | ||
// }).configure({ keys: "strict" }) | ||
// attest(t({ a: "ok" }).out).equals({ a: "ok" }) | ||
// attest(t(getExtraneousB()).errors?.summary).snap("b must be removed") | ||
// attest(t({ a: "ok" })).equals({ a: "ok" }) | ||
// attest(t(getExtraneousB()).toString()).snap("b must be removed") | ||
// }) | ||
@@ -75,7 +75,7 @@ // | ||
// }) | ||
// attest(o({ a: ["shawn"] }).out).snap({ a: ["shawn"] }) | ||
// attest(o({ a: [2] }).errors?.summary).snap( | ||
// attest(o({ a: ["shawn"] })).snap({ a: ["shawn"] }) | ||
// attest(o({ a: [2] }).toString()).snap( | ||
// "a/0 must be a string (was number)" | ||
// ) | ||
// attest(o({ b: ["shawn"] }).errors?.summary).snap( | ||
// attest(o({ b: ["shawn"] }).toString()).snap( | ||
// "b must be removed\na must be defined" | ||
@@ -82,0 +82,0 @@ // ) |
import { attest, contextualize } from "@arktype/attest" | ||
import { rawSchema } from "@arktype/schema" | ||
import { type } from "arktype" | ||
import { ark, type } from "arktype" | ||
@@ -31,3 +31,3 @@ contextualize( | ||
attest<string>(string.infer) | ||
attest(string("string").out).snap("string") | ||
attest(string("string")).snap("string") | ||
}) | ||
@@ -43,2 +43,8 @@ | ||
it("any in expression", () => { | ||
const t = type("string&any") | ||
attest<any>(t.infer) | ||
attest(t.json).equals(ark.string.json) | ||
}) | ||
it("boolean", () => { | ||
@@ -64,2 +70,9 @@ const boolean = type("boolean") | ||
// TODO: ?? | ||
it("never in union", () => { | ||
const t = type("string|never") | ||
attest<string>(t.infer) | ||
attest(t.json).equals(ark.string.json) | ||
}) | ||
it("unknown", () => { | ||
@@ -84,7 +97,7 @@ const expected = rawSchema({}) | ||
// const integer = type("integer") | ||
// attest(integer(123).out).equals(123) | ||
// attest(integer("123").errors?.summary).equals( | ||
// attest(integer(123)).equals(123) | ||
// attest(integer("123").toString()).equals( | ||
// "must be a number (was string)" | ||
// ) | ||
// attest(integer(12.12).errors?.summary).equals( | ||
// attest(integer(12.12).toString()).equals( | ||
// "must be an integer (was 12.12)" | ||
@@ -95,4 +108,4 @@ // ) | ||
// const alpha = type("alpha") | ||
// attest(alpha("user").out).equals("user") | ||
// attest(alpha("user123").errors?.summary).equals( | ||
// attest(alpha("user")).equals("user") | ||
// attest(alpha("user123").toString()).equals( | ||
// "must be only letters (was 'user123')" | ||
@@ -103,6 +116,6 @@ // ) | ||
// const alphanumeric = type("alphanumeric") | ||
// attest(alphanumeric("user123").out).equals("user123") | ||
// attest(alphanumeric("user").out).equals("user") | ||
// attest(alphanumeric("123").out).equals("123") | ||
// attest(alphanumeric("abc@123").errors?.summary).equals( | ||
// attest(alphanumeric("user123")).equals("user123") | ||
// attest(alphanumeric("user")).equals("user") | ||
// attest(alphanumeric("123")).equals("123") | ||
// attest(alphanumeric("abc@123").toString()).equals( | ||
// "must be only letters and digits (was 'abc@123')" | ||
@@ -113,4 +126,4 @@ // ) | ||
// const lowercase = type("lowercase") | ||
// attest(lowercase("var").out).equals("var") | ||
// attest(lowercase("newVar").errors?.summary).equals( | ||
// attest(lowercase("var")).equals("var") | ||
// attest(lowercase("newVar").toString()).equals( | ||
// "must be only lowercase letters (was 'newVar')" | ||
@@ -121,7 +134,7 @@ // ) | ||
// const uppercase = type("uppercase") | ||
// attest(uppercase("VAR").out).equals("VAR") | ||
// attest(uppercase("CONST_VAR").errors?.summary).equals( | ||
// attest(uppercase("VAR")).equals("VAR") | ||
// attest(uppercase("CONST_VAR").toString()).equals( | ||
// "must be only uppercase letters (was 'CONST_VAR')" | ||
// ) | ||
// attest(uppercase("myVar").errors?.summary).equals( | ||
// attest(uppercase("myVar").toString()).equals( | ||
// "must be only uppercase letters (was 'myVar')" | ||
@@ -132,4 +145,4 @@ // ) | ||
// const email = type("email") | ||
// attest(email("shawn@mail.com").out).equals("shawn@mail.com") | ||
// attest(email("shawn@email").errors?.summary).equals( | ||
// attest(email("shawn@mail.com")).equals("shawn@mail.com") | ||
// attest(email("shawn@email").toString()).equals( | ||
// "must be a valid email (was 'shawn@email')" | ||
@@ -140,6 +153,6 @@ // ) | ||
// const uuid = type("uuid") | ||
// attest(uuid("f70b8242-dd57-4e6b-b0b7-649d997140a0").out).equals( | ||
// attest(uuid("f70b8242-dd57-4e6b-b0b7-649d997140a0")).equals( | ||
// "f70b8242-dd57-4e6b-b0b7-649d997140a0" | ||
// ) | ||
// attest(uuid("1234").errors?.summary).equals( | ||
// attest(uuid("1234").toString()).equals( | ||
// "must be a valid UUID (was '1234')" | ||
@@ -150,5 +163,5 @@ // ) | ||
// const parsedNumber = type("parsedNumber") | ||
// attest(parsedNumber("5").out).equals(5) | ||
// attest(parsedNumber("5.5").out).equals(5.5) | ||
// attest(parsedNumber("five").errors?.summary).equals( | ||
// attest(parsedNumber("5")).equals(5) | ||
// attest(parsedNumber("5.5")).equals(5.5) | ||
// attest(parsedNumber("five").toString()).equals( | ||
// "must be a well-formed numeric string (was 'five')" | ||
@@ -159,13 +172,13 @@ // ) | ||
// const parsedInteger = type("parsedInteger") | ||
// attest(parsedInteger("5").out).equals(5) | ||
// attest(parsedInteger("5.5").errors?.summary).equals( | ||
// attest(parsedInteger("5")).equals(5) | ||
// attest(parsedInteger("5.5").toString()).equals( | ||
// "must be a well-formed integer string (was '5.5')" | ||
// ) | ||
// attest(parsedInteger("five").errors?.summary).equals( | ||
// attest(parsedInteger("five").toString()).equals( | ||
// "must be a well-formed integer string (was 'five')" | ||
// ) | ||
// attest(parsedInteger(5).errors?.summary).equals( | ||
// attest(parsedInteger(5).toString()).equals( | ||
// "must be a string (was number)" | ||
// ) | ||
// attest(parsedInteger("9007199254740992").errors?.summary).equals( | ||
// attest(parsedInteger("9007199254740992").toString()).equals( | ||
// "must be an integer in the range Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER (was '9007199254740992')" | ||
@@ -179,6 +192,6 @@ // ) | ||
// ) | ||
// attest(parsedDate("foo").errors?.summary).equals( | ||
// attest(parsedDate("foo").toString()).equals( | ||
// "must be a valid date (was 'foo')" | ||
// ) | ||
// attest(parsedDate(5).errors?.summary).equals( | ||
// attest(parsedDate(5).toString()).equals( | ||
// "must be a string (was number)" | ||
@@ -189,4 +202,4 @@ // ) | ||
// const json = type("json") | ||
// attest(json('{"a": "hello"}').out).equals({ a: "hello" }) | ||
// attest(json(123).errors?.summary).equals( | ||
// attest(json('{"a": "hello"}')).equals({ a: "hello" }) | ||
// attest(json(123).toString()).equals( | ||
// "must be a JSON-parsable string (was number)" | ||
@@ -197,5 +210,5 @@ // ) | ||
// const validCC = "5489582921773376" | ||
// attest(ark.creditCard(validCC).out).equals(validCC) | ||
// attest(ark.creditCard(validCC)).equals(validCC) | ||
// // Regex validation | ||
// attest(ark.creditCard("0".repeat(16)).errors?.summary).equals( | ||
// attest(ark.creditCard("0".repeat(16)).toString()).equals( | ||
// "must be a valid credit card number (was '0000000000000000')" | ||
@@ -205,3 +218,3 @@ // ) | ||
// attest( | ||
// ark.creditCard(validCC.slice(0, -1) + "0").errors?.summary | ||
// ark.creditCard(validCC.slice(0, -1) + "0").toString() | ||
// ).equals( | ||
@@ -212,4 +225,4 @@ // "must be a valid credit card number (was '5489582921773370')" | ||
// it("semver", () => { | ||
// attest(ark.semver("1.0.0").out).equals("1.0.0") | ||
// attest(ark.semver("-1.0.0").errors?.summary).equals( | ||
// attest(ark.semver("1.0.0")).equals("1.0.0") | ||
// attest(ark.semver("-1.0.0").toString()).equals( | ||
// "must be a valid semantic version (see https://semver.org/) (was '-1.0.0')" | ||
@@ -216,0 +229,0 @@ // ) |
@@ -18,4 +18,4 @@ import { attest, contextualize } from "@arktype/attest" | ||
attest<symbol>(t.infer) | ||
attest(t(s).out).equals(s) | ||
attest(t("test").errors?.summary).snap( | ||
attest(t(s)).equals(s) | ||
attest(t("test").toString()).snap( | ||
'must be (symbol anonymous) (was "test")' | ||
@@ -22,0 +22,0 @@ ) |
@@ -6,5 +6,5 @@ import { bench } from "@arktype/attest" | ||
const matcher = match() | ||
.when("string", (s) => s) | ||
.when("number", (n) => n) | ||
.when("boolean", (b) => b) | ||
.when("string", s => s) | ||
.when("number", n => n) | ||
.when("boolean", b => b) | ||
.orThrow() | ||
@@ -22,5 +22,5 @@ | ||
.only<string | number | boolean>() | ||
.when("string", (s) => s) | ||
.when("number", (n) => n) | ||
.when("boolean", (b) => b) | ||
.when("string", s => s) | ||
.when("number", n => n) | ||
.when("boolean", b => b) | ||
.finalize() | ||
@@ -27,0 +27,0 @@ |
import { attest, contextualize } from "@arktype/attest" | ||
import type { Narrowed, Out, of, string } from "@arktype/schema" | ||
import { type equals, reference } from "@arktype/util" | ||
import { type Type, type } from "arktype" | ||
import { reference, type equals } from "@arktype/util" | ||
import { type, type Type } from "arktype" | ||
@@ -13,11 +13,9 @@ contextualize(() => { | ||
attest(odd.json).equals({ domain: "number", predicate: [isOddRef] }) | ||
attest(odd(1).out).equals(1) | ||
attest(odd(2).errors?.summary).snap( | ||
"must be valid according to isOdd (was 2)" | ||
) | ||
attest(odd(1)).equals(1) | ||
attest(odd(2).toString()).snap("must be valid according to isOdd (was 2)") | ||
}) | ||
it("implicit problem anonymous", () => { | ||
const even = type("number", ":", (n) => n % 2 === 0) | ||
attest(even(1).errors?.summary).snap( | ||
const even = type("number", ":", n => n % 2 === 0) | ||
attest(even(1).toString()).snap( | ||
"must be valid according to an anonymous predicate (was 1)" | ||
@@ -31,5 +29,5 @@ ) | ||
":", | ||
(n, ctx) => n % 3 === 0 || ctx.invalid({ expected: "divisible by 3" }) | ||
(n, ctx) => n % 3 === 0 || ctx.invalid("divisible by 3") | ||
]) | ||
attest(even(1).errors?.summary).snap("must be divisible by 3 (was 1)") | ||
attest(even(1).toString()).snap("must be divisible by 3 (was 1)") | ||
}) | ||
@@ -45,5 +43,4 @@ | ||
({ a, b }, ctx) => { | ||
if (a === b) { | ||
return true | ||
} | ||
if (a === b) return true | ||
ctx.error({ expected: "equal to b", path: ["a"] }) | ||
@@ -54,4 +51,4 @@ ctx.error({ expected: "equal to a", path: ["b"] }) | ||
]) | ||
attest(abEqual({ a: 1, b: 1 }).out).equals({ a: 1, b: 1 }) | ||
attest(abEqual({ a: 1, b: 2 }).errors?.summary).snap( | ||
attest(abEqual({ a: 1, b: 1 })).equals({ a: 1, b: 1 }) | ||
attest(abEqual({ a: 1, b: 2 }).toString()).snap( | ||
'a must be equal to b (was {"a":1,"b":2})\nb must be equal to a (was {"a":1,"b":2})' | ||
@@ -72,7 +69,4 @@ ) | ||
attest<number | boolean[]>( | ||
type([ | ||
"number|boolean[]", | ||
":", | ||
(data) => validateNumberOrBooleanList(data) | ||
]).infer | ||
type(["number|boolean[]", ":", data => validateNumberOrBooleanList(data)]) | ||
.infer | ||
) | ||
@@ -93,4 +87,4 @@ attest(() => { | ||
attest<Type<string.narrowed>>(palindrome) | ||
attest(palindrome("dad").out).snap("dad") | ||
attest(palindrome("david").errors?.summary).snap( | ||
attest(palindrome("dad")).snap("dad") | ||
attest(palindrome("david").toString()).snap( | ||
'must be a palindrome (was "david")' | ||
@@ -102,3 +96,3 @@ ) | ||
const t = type("string") | ||
.morph((s) => s.length) | ||
.pipe(s => s.length) | ||
.narrow((n): n is 5 => n === 5) | ||
@@ -105,0 +99,0 @@ |
@@ -95,5 +95,5 @@ import { attest, contextualize } from "@arktype/attest" | ||
// const o = type({ "a?": "string" }).configure({ keys: "strict" }) | ||
// attest(o({ a: "a" }).out).snap({ a: "a" }) | ||
// attest(o({}).out).snap({}) | ||
// attest(o({ a: 1 }).errors?.summary).snap("a must be a string (was number)") | ||
// attest(o({ a: "a" })).snap({ a: "a" }) | ||
// attest(o({})).snap({}) | ||
// attest(o({ a: 1 }).toString()).snap("a must be a string (was number)") | ||
// }) | ||
@@ -105,3 +105,3 @@ | ||
// }) | ||
// attest(t({ a: 1, b: 2 }).errors?.summary).snap( | ||
// attest(t({ a: 1, b: 2 }).toString()).snap( | ||
// "a must be a string (was number)\nb must be boolean (was number)" | ||
@@ -108,0 +108,0 @@ // ) |
@@ -109,3 +109,3 @@ import { bench } from "@arktype/attest" | ||
bench("filter-tuple", () => { | ||
const _ = type(["boolean", ":", (b) => b]) | ||
const _ = type(["boolean", ":", b => b]) | ||
}) | ||
@@ -116,3 +116,3 @@ .median([8.04, "us"]) | ||
bench("filter-chain", () => { | ||
const _ = type("boolean").narrow((b) => b) | ||
const _ = type("boolean").narrow(b => b) | ||
}) | ||
@@ -123,3 +123,3 @@ .median([12.19, "us"]) | ||
bench("morph-tuple", () => { | ||
const _ = type(["boolean", "=>", (b) => b]) | ||
const _ = type(["boolean", "=>", b => b]) | ||
}) | ||
@@ -130,5 +130,5 @@ .median([8.96, "us"]) | ||
bench("morph-chain", () => { | ||
const _ = type("boolean").morph((b) => b) | ||
const _ = type("boolean").pipe(b => b) | ||
}) | ||
.median([2.98, "us"]) | ||
.types([26, "instantiations"]) |
@@ -56,18 +56,8 @@ import { attest, contextualize } from "@arktype/attest" | ||
const $ = scope({ | ||
a: ["string", "=>", (s) => s.length] | ||
a: ["string", "=>", s => s.length] | ||
}) | ||
attest<{ a: number }>($.infer) | ||
// TODO: API? | ||
// attest<{ a: string }>($.in.infer) | ||
attest<{ a: string }>($.inferIn) | ||
}) | ||
// TODO: remove if not preserving | ||
// it("scope.scope", () => { | ||
// const $ = scope({ | ||
// a: "string" | ||
// }) | ||
// const importer = $.scope({ b: "a[]" }) | ||
// attest<{ b: string[] }>(importer.infer) | ||
// const t = importer.type("b") | ||
// attest(t.json).equals(type("string[]").json) | ||
// }) | ||
@@ -155,4 +145,4 @@ it("infers its own helpers", () => { | ||
const { out: data } = X({ pear: { tasty: true } }) | ||
attest(data).snap({ pear: { tasty: true } }) | ||
const out = X({ pear: { tasty: true } }) | ||
attest(out).snap({ pear: { tasty: true } }) | ||
}) | ||
@@ -159,0 +149,0 @@ describe("define", () => { |
@@ -7,4 +7,4 @@ import { attest, contextualize } from "@arktype/attest" | ||
const t = type("number%2") | ||
attest(t(4).out).snap(4) | ||
attest(t(5).errors?.summary).snap("must be a multiple of 2 (was 5)") | ||
attest(t(4)).snap(4) | ||
attest(t(5).toString()).snap("must be a multiple of 2 (was 5)") | ||
}) | ||
@@ -14,4 +14,4 @@ | ||
const t = type("number>2") | ||
attest(t(3).out).snap(3) | ||
attest(t(2).errors?.summary).snap("must be more than 2 (was 2)") | ||
attest(t(3)).snap(3) | ||
attest(t(2).toString()).snap("must be more than 2 (was 2)") | ||
}) | ||
@@ -21,4 +21,4 @@ | ||
const t = type("number") | ||
attest(t(5).out).snap(5) | ||
attest(t("foo").errors?.summary).snap("must be a number (was string)") | ||
attest(t(5)).snap(5) | ||
attest(t("foo").toString()).snap("must be a number (was string)") | ||
}) | ||
@@ -28,4 +28,4 @@ | ||
const t = type("/.*@arktype.io/") | ||
attest(t("shawn@arktype.io").out).snap("shawn@arktype.io") | ||
attest(t("shawn@hotmail.com").errors?.summary).snap( | ||
attest(t("shawn@arktype.io")).snap("shawn@arktype.io") | ||
attest(t("shawn@hotmail.com").toString()).snap( | ||
'must be matched by .*@arktype.io (was "shawn@hotmail.com")' | ||
@@ -41,7 +41,7 @@ ) | ||
}) | ||
attest(t({ name: "Shawn", age: 99 }).out).snap({ | ||
attest(t({ name: "Shawn", age: 99 })).snap({ | ||
name: "Shawn", | ||
age: 99 | ||
}) | ||
attest(t({ name: "Shawn" }).errors?.summary).snap("age must be defined") | ||
attest(t({ name: "Shawn" }).toString()).snap("age must be defined") | ||
}) | ||
@@ -54,8 +54,8 @@ | ||
divisor: { | ||
expected: (ctx) => `% ${ctx.rule} !== 0`, | ||
problem: (ctx) => `${ctx.actual} ${ctx.expected}` | ||
expected: ctx => `% ${ctx.rule} !== 0`, | ||
problem: ctx => `${ctx.actual} ${ctx.expected}` | ||
} | ||
} | ||
).export() | ||
attest(types.isEven(3).errors?.summary).snap("3 % 2 !== 0") | ||
attest(types.isEven(3).toString()).snap("3 % 2 !== 0") | ||
}) | ||
@@ -65,7 +65,5 @@ | ||
const t = type("string|number[]") | ||
attest(t([1]).out).snap([1]) | ||
attest(t("hello").out).snap("hello") | ||
attest(t(2).errors?.summary).snap( | ||
"must be a string or an array (was number)" | ||
) | ||
attest(t([1])).snap([1]) | ||
attest(t("hello")).snap("hello") | ||
attest(t(2).toString()).snap("must be a string or an array (was number)") | ||
}) | ||
@@ -76,4 +74,4 @@ | ||
const data: typeof t.infer = ["foo", 5, "boo", []] | ||
attest(t(data).out).equals(data) | ||
attest(t(["hello"]).errors?.summary).snap( | ||
attest(t(data)).equals(data) | ||
attest(t(["hello"]).toString()).snap( | ||
'must be exactly length 4 (was ["hello"])' | ||
@@ -84,6 +82,9 @@ ) | ||
it("branches", () => { | ||
const t = type([{ a: "string" }, "|", { b: "boolean" }]) | ||
attest(t({ a: "ok" }).out).snap({ a: "ok" }) | ||
attest(t({ b: true }).out).snap({ b: true }) | ||
attest(t({}).errors?.summary).snap("a must be defined or b must be defined") | ||
const t = type({ bar: "boolean" }, "|", { foo: "string" }) | ||
attest(t({ foo: "ok" })).snap({ foo: "ok" }) | ||
attest(t({ bar: true })).snap({ bar: true }) | ||
attest(t({}).toString()).snap("bar must be defined or foo must be defined") | ||
attest(t({ bar: "swapped", foo: true }).toString()).snap( | ||
'bar must be boolean (was "swapped") or foo must be a string (was true)' | ||
) | ||
}) | ||
@@ -93,5 +94,5 @@ | ||
const t = type({ key: [{ a: "string" }, "|", { b: "boolean" }] }) | ||
attest(t({ key: { a: "ok" } }).out).snap({ key: { a: "ok" } }) | ||
attest(t({ key: { b: true } }).out).snap({ key: { b: true } }) | ||
attest(t({ key: {} }).errors?.summary).snap( | ||
attest(t({ key: { a: "ok" } })).snap({ key: { a: "ok" } }) | ||
attest(t({ key: { b: true } })).snap({ key: { b: true } }) | ||
attest(t({ key: {} }).toString()).snap( | ||
"key.a must be defined or key.b must be defined" | ||
@@ -103,8 +104,8 @@ ) | ||
const t = type({ a: "string" }).or({ a: "null" }).or({ a: "number" }) | ||
attest(t({ a: "ok" }).out).snap({ a: "ok" }) | ||
attest(t({ a: 5 }).out).snap({ a: 5 }) | ||
attest(t({ a: "ok" })).snap({ a: "ok" }) | ||
attest(t({ a: 5 })).snap({ a: 5 }) | ||
// value isn't present | ||
attest(t({}).errors?.summary).snap("a must be defined") | ||
attest(t({}).toString()).snap("a must be defined") | ||
// unsatisfying value | ||
attest(t({ a: false }).errors?.summary).snap( | ||
attest(t({ a: false }).toString()).snap( | ||
"a must be a number, a string or null (was false)" | ||
@@ -121,4 +122,4 @@ ) | ||
}).export() | ||
attest(types.d({}).errors?.summary).snap("foo must be defined") | ||
attest(types.d({ foo: null }).errors?.summary).snap( | ||
attest(types.d({}).toString()).snap("foo must be defined") | ||
attest(types.d({ foo: null }).toString()).snap( | ||
"foo must be a function, a number or a string (was null)" | ||
@@ -130,3 +131,3 @@ ) | ||
const naturalNumber = type("integer>0") | ||
attest(naturalNumber(-1.2).errors?.summary).snap( | ||
attest(naturalNumber(-1.2).toString()).snap( | ||
`must be... | ||
@@ -139,3 +140,3 @@ • an integer | ||
}) | ||
attest(naturalAtPath({ natural: -0.1 }).errors?.summary).snap( | ||
attest(naturalAtPath({ natural: -0.1 }).toString()).snap( | ||
`natural must be... | ||
@@ -142,0 +143,0 @@ • an integer |
@@ -8,8 +8,5 @@ import { attest, contextualize } from "@arktype/attest" | ||
const t = type("string") | ||
const { out, errors: errors } = t("") | ||
if (errors) { | ||
errors.throw() | ||
} else { | ||
attest<string>(out) | ||
} | ||
const out = t("") | ||
if (out instanceof type.errors) out.throw() | ||
else attest<string>(out) | ||
}) | ||
@@ -23,12 +20,13 @@ | ||
attest<number>(data) | ||
} else { | ||
throw new Error() | ||
} | ||
} else throw new Error() | ||
attest(t.allows(5)).equals(false) | ||
}) | ||
// TODO: ? | ||
it("errors can be thrown", () => { | ||
const t = type("number") | ||
try { | ||
attest(t("invalid").errors?.throw()) | ||
const result = t("invalid") | ||
attest(result instanceof type.errors && result.throw()) | ||
} catch (e) { | ||
@@ -35,0 +33,0 @@ attest(e instanceof ArkError).equals(true) |
25
ark.ts
@@ -1,2 +0,7 @@ | ||
import { type Ark, type inferred, keywordNodes } from "@arktype/schema" | ||
import { | ||
type Ark, | ||
type ArkErrors, | ||
type inferred, | ||
keywordNodes | ||
} from "@arktype/schema" | ||
import type { Generic } from "./generic.js" | ||
@@ -28,18 +33,16 @@ import type { MatchParser } from "./match.js" | ||
export const type: TypeParser<{}> = ambient.type.bind(ambient) as never | ||
export const type: TypeParser<{}> = ambient.type as never | ||
export namespace type { | ||
export type cast<to> = { | ||
[inferred]?: to | ||
export type cast<t> = { | ||
[inferred]?: t | ||
} | ||
export type errors = ArkErrors | ||
} | ||
export const match: MatchParser<{}> = ambient.match.bind(ambient) as never | ||
export const match: MatchParser<{}> = ambient.match as never | ||
export const define: DefinitionParser<{}> = ambient.define.bind( | ||
ambient | ||
) as never | ||
export const define: DefinitionParser<{}> = ambient.define as never | ||
export const declare: DeclarationParser<{}> = ambient.declare.bind( | ||
ambient | ||
) as never | ||
export const declare: DeclarationParser<{}> = ambient.declare as never |
@@ -7,3 +7,3 @@ import { | ||
} from "@arktype/schema" | ||
import { Callable, type conform, flatMorph } from "@arktype/util" | ||
import { Callable, type conform } from "@arktype/util" | ||
import type { inferDefinition } from "./parser/definition.js" | ||
@@ -61,9 +61,11 @@ import type { | ||
super((...args: unknown[]) => { | ||
const argNodes = flatMorph(params, (i, param: string) => [ | ||
param, | ||
$.parseRoot(args[i]) | ||
]) | ||
return $.parseRoot(def, { args: argNodes }) as never | ||
// const argNodes = flatMorph(params, (i, param: string) => [ | ||
// param, | ||
// $.parseRoot(args[i]) | ||
// ]) | ||
// { args: argNodes } | ||
args | ||
return $.parseRoot(def) as never | ||
}) | ||
} | ||
} |
113
match.ts
@@ -0,9 +1,3 @@ | ||
import type { Narrowed, distillOut, inferIntersection } from "@arktype/schema" | ||
import type { | ||
Morph, | ||
Narrowed, | ||
RawSchema, | ||
distillOut, | ||
inferIntersection | ||
} from "@arktype/schema" | ||
import type { | ||
ErrorMessage, | ||
@@ -166,65 +160,60 @@ isDisjoint, | ||
export const createMatchParser = <$>($: Scope): MatchParser<$> => { | ||
const matchParser = (isRestricted: boolean) => { | ||
const handledCases: { when: RawSchema; then: Morph }[] = [] | ||
let defaultCase: ((x: unknown) => unknown) | null = null | ||
return (() => {}).bind($) as never | ||
// const matchParser = (isRestricted: boolean) => { | ||
// const handledCases: { when: RawSchema; then: Morph }[] = [] | ||
// let defaultCase: ((x: unknown) => unknown) | null = null | ||
const parser = { | ||
when: (when: unknown, then: Morph) => { | ||
handledCases.push({ when: $.parseRoot(when, {}), then }) | ||
// const parser = { | ||
// when: (when: unknown, then: Morph) => { | ||
// handledCases.push({ when: $.parseRoot(when, {}), then }) | ||
return parser | ||
}, | ||
// return parser | ||
// }, | ||
finalize: () => { | ||
// TODO: exhaustiveness checking | ||
// const branches = handledCases.flatMap(({ when, then }) => { | ||
// if (when.root.kind === "union") { | ||
// return when.root.branches.map((branch) => ({ | ||
// in: branch, | ||
// morph: then | ||
// })) | ||
// } | ||
// if (when.root.kind === "morph") { | ||
// return [{ in: when, morph: [when.root.morph, then] }] | ||
// } | ||
// return [{ in: when.root, morph: then }] | ||
// }) | ||
// if (defaultCase) { | ||
// branches.push({ in: new Type("unknown", $), morph: defaultCase }) | ||
// } | ||
// const matchers = schema.union({ | ||
// branches, | ||
// ordered: true | ||
// }) | ||
// return (data: unknown) => { | ||
// const result = matchers.apply(data) | ||
// if (result.errors) { | ||
// throw result.errors | ||
// } | ||
// return result.out | ||
// } | ||
}, | ||
// finalize: () => { | ||
// // TODO: exhaustiveness checking | ||
// const branches = handledCases.flatMap(({ when, then }) => { | ||
// if (when.kind === "union") { | ||
// return when.branches.map((branch) => ({ | ||
// from: branch, | ||
// morph: then | ||
// })) | ||
// } | ||
// if (when.kind === "morph") { | ||
// return [{ from: when, morph: [when.morph, then] }] | ||
// } | ||
// return [{ from: when, morph: then }] | ||
// }) | ||
// if (defaultCase) { | ||
// branches.push({ from: keywordNodes.unknown, morph: defaultCase }) | ||
// } | ||
// const matchers = $.node("union", { | ||
// branches, | ||
// ordered: true | ||
// }) | ||
// return matchers.assert | ||
// }, | ||
orThrow: () => { | ||
// implicitly finalize, we don't need to do anything else because we throw either way | ||
return parser.finalize() | ||
}, | ||
// orThrow: () => { | ||
// // implicitly finalize, we don't need to do anything else because we throw either way | ||
// return parser.finalize() | ||
// }, | ||
default: (x: unknown) => { | ||
if (x instanceof Function) { | ||
defaultCase = x as never | ||
} else { | ||
defaultCase = () => x | ||
} | ||
// default: (x: unknown) => { | ||
// if (x instanceof Function) { | ||
// defaultCase = x as never | ||
// } else { | ||
// defaultCase = () => x | ||
// } | ||
return parser.finalize() | ||
} | ||
} | ||
// return parser.finalize() | ||
// } | ||
// } | ||
return parser | ||
} | ||
// return parser | ||
// } | ||
return Object.assign(() => matchParser(false), { | ||
only: () => matchParser(true) | ||
}) as never | ||
// return Object.assign(() => matchParser(false), { | ||
// only: () => matchParser(true) | ||
// }) as never | ||
} |
@@ -1,2 +0,2 @@ | ||
import { type Ark, type inferred } from "@arktype/schema"; | ||
import { type Ark, type ArkErrors, type inferred } from "@arktype/schema"; | ||
import type { Generic } from "./generic.js"; | ||
@@ -20,5 +20,6 @@ import type { MatchParser } from "./match.js"; | ||
export declare namespace type { | ||
type cast<to> = { | ||
[inferred]?: to; | ||
type cast<t> = { | ||
[inferred]?: t; | ||
}; | ||
type errors = ArkErrors; | ||
} | ||
@@ -25,0 +26,0 @@ export declare const match: MatchParser<{}>; |
@@ -7,6 +7,6 @@ import { keywordNodes } from "@arktype/schema"; | ||
export const ark = ambient.export(); | ||
export const type = ambient.type.bind(ambient); | ||
export const match = ambient.match.bind(ambient); | ||
export const define = ambient.define.bind(ambient); | ||
export const declare = ambient.declare.bind(ambient); | ||
export const type = ambient.type; | ||
export const match = ambient.match; | ||
export const define = ambient.define; | ||
export const declare = ambient.declare; | ||
//# sourceMappingURL=ark.js.map |
import { arkKind } from "@arktype/schema"; | ||
import { Callable, flatMorph } from "@arktype/util"; | ||
import { Callable } from "@arktype/util"; | ||
export class Generic extends Callable { | ||
@@ -12,7 +12,9 @@ params; | ||
super((...args) => { | ||
const argNodes = flatMorph(params, (i, param) => [ | ||
param, | ||
$.parseRoot(args[i]) | ||
]); | ||
return $.parseRoot(def, { args: argNodes }); | ||
// const argNodes = flatMorph(params, (i, param: string) => [ | ||
// param, | ||
// $.parseRoot(args[i]) | ||
// ]) | ||
// { args: argNodes } | ||
args; | ||
return $.parseRoot(def); | ||
}); | ||
@@ -19,0 +21,0 @@ this.params = params; |
106
out/match.js
export const createMatchParser = ($) => { | ||
const matchParser = (isRestricted) => { | ||
const handledCases = []; | ||
let defaultCase = null; | ||
const parser = { | ||
when: (when, then) => { | ||
handledCases.push({ when: $.parseRoot(when, {}), then }); | ||
return parser; | ||
}, | ||
finalize: () => { | ||
// TODO: exhaustiveness checking | ||
// const branches = handledCases.flatMap(({ when, then }) => { | ||
// if (when.root.kind === "union") { | ||
// return when.root.branches.map((branch) => ({ | ||
// in: branch, | ||
// morph: then | ||
// })) | ||
// } | ||
// if (when.root.kind === "morph") { | ||
// return [{ in: when, morph: [when.root.morph, then] }] | ||
// } | ||
// return [{ in: when.root, morph: then }] | ||
// }) | ||
// if (defaultCase) { | ||
// branches.push({ in: new Type("unknown", $), morph: defaultCase }) | ||
// } | ||
// const matchers = schema.union({ | ||
// branches, | ||
// ordered: true | ||
// }) | ||
// return (data: unknown) => { | ||
// const result = matchers.apply(data) | ||
// if (result.errors) { | ||
// throw result.errors | ||
// } | ||
// return result.out | ||
// } | ||
}, | ||
orThrow: () => { | ||
// implicitly finalize, we don't need to do anything else because we throw either way | ||
return parser.finalize(); | ||
}, | ||
default: (x) => { | ||
if (x instanceof Function) { | ||
defaultCase = x; | ||
} | ||
else { | ||
defaultCase = () => x; | ||
} | ||
return parser.finalize(); | ||
} | ||
}; | ||
return parser; | ||
}; | ||
return Object.assign(() => matchParser(false), { | ||
only: () => matchParser(true) | ||
}); | ||
return (() => { }).bind($); | ||
// const matchParser = (isRestricted: boolean) => { | ||
// const handledCases: { when: RawSchema; then: Morph }[] = [] | ||
// let defaultCase: ((x: unknown) => unknown) | null = null | ||
// const parser = { | ||
// when: (when: unknown, then: Morph) => { | ||
// handledCases.push({ when: $.parseRoot(when, {}), then }) | ||
// return parser | ||
// }, | ||
// finalize: () => { | ||
// // TODO: exhaustiveness checking | ||
// const branches = handledCases.flatMap(({ when, then }) => { | ||
// if (when.kind === "union") { | ||
// return when.branches.map((branch) => ({ | ||
// from: branch, | ||
// morph: then | ||
// })) | ||
// } | ||
// if (when.kind === "morph") { | ||
// return [{ from: when, morph: [when.morph, then] }] | ||
// } | ||
// return [{ from: when, morph: then }] | ||
// }) | ||
// if (defaultCase) { | ||
// branches.push({ from: keywordNodes.unknown, morph: defaultCase }) | ||
// } | ||
// const matchers = $.node("union", { | ||
// branches, | ||
// ordered: true | ||
// }) | ||
// return matchers.assert | ||
// }, | ||
// orThrow: () => { | ||
// // implicitly finalize, we don't need to do anything else because we throw either way | ||
// return parser.finalize() | ||
// }, | ||
// default: (x: unknown) => { | ||
// if (x instanceof Function) { | ||
// defaultCase = x as never | ||
// } else { | ||
// defaultCase = () => x | ||
// } | ||
// return parser.finalize() | ||
// } | ||
// } | ||
// return parser | ||
// } | ||
// return Object.assign(() => matchParser(false), { | ||
// only: () => matchParser(true) | ||
// }) as never | ||
}; | ||
//# sourceMappingURL=match.js.map |
@@ -9,10 +9,10 @@ import { type nominal } from "@arktype/util"; | ||
export declare const parseGenericParams: (def: string) => string[]; | ||
export type parseGenericParams<def extends string> = $parseParams<def, "", []> extends infer result extends string[] ? "" extends result[number] ? GenericParamsParseError<emptyGenericParameterMessage> : result : never; | ||
export type parseGenericParams<def extends string> = _parseParams<def, "", []> extends infer result extends string[] ? "" extends result[number] ? GenericParamsParseError<emptyGenericParameterMessage> : result : never; | ||
export declare const emptyGenericParameterMessage = "An empty string is not a valid generic parameter name"; | ||
export type emptyGenericParameterMessage = typeof emptyGenericParameterMessage; | ||
type $parseParams<unscanned extends string, param extends string, result extends string[]> = unscanned extends `${infer lookahead}${infer nextUnscanned}` ? lookahead extends "," ? $parseParams<nextUnscanned, "", [...result, param]> : lookahead extends Scanner.WhiteSpaceToken ? param extends "" ? $parseParams<Scanner.skipWhitespace<nextUnscanned>, "", result> : Scanner.skipWhitespace<nextUnscanned> extends (`${infer nextNonWhitespace}${infer rest}`) ? nextNonWhitespace extends "," ? $parseParams<rest, "", [...result, param]> : GenericParamsParseError<writeUnexpectedCharacterMessage<nextNonWhitespace, ",">> : [ | ||
type _parseParams<unscanned extends string, param extends string, result extends string[]> = unscanned extends `${infer lookahead}${infer nextUnscanned}` ? lookahead extends "," ? _parseParams<nextUnscanned, "", [...result, param]> : lookahead extends Scanner.WhiteSpaceToken ? param extends "" ? _parseParams<Scanner.skipWhitespace<nextUnscanned>, "", result> : Scanner.skipWhitespace<nextUnscanned> extends (`${infer nextNonWhitespace}${infer rest}`) ? nextNonWhitespace extends "," ? _parseParams<rest, "", [...result, param]> : GenericParamsParseError<writeUnexpectedCharacterMessage<nextNonWhitespace, ",">> : [ | ||
...result, | ||
param | ||
] : $parseParams<nextUnscanned, `${param}${lookahead}`, result> : param extends "" ? result : [...result, param]; | ||
] : _parseParams<nextUnscanned, `${param}${lookahead}`, result> : param extends "" ? result : [...result, param]; | ||
export {}; | ||
//# sourceMappingURL=generic.d.ts.map |
import { throwParseError } from "@arktype/util"; | ||
import { writeUnexpectedCharacterMessage } from "./string/shift/operator/operator.js"; | ||
import { Scanner } from "./string/shift/scanner.js"; | ||
export const parseGenericParams = (def) => $parseGenericParams(new Scanner(def)); | ||
export const parseGenericParams = (def) => _parseGenericParams(new Scanner(def)); | ||
export const emptyGenericParameterMessage = "An empty string is not a valid generic parameter name"; | ||
const $parseGenericParams = (scanner) => { | ||
const _parseGenericParams = (scanner) => { | ||
const param = scanner.shiftUntilNextTerminator(); | ||
if (param === "") { | ||
if (param === "") | ||
throwParseError(emptyGenericParameterMessage); | ||
} | ||
scanner.shiftUntilNonWhitespace(); | ||
const nextNonWhitespace = scanner.shift(); | ||
return (nextNonWhitespace === "" ? [param] | ||
: nextNonWhitespace === "," ? [param, ...$parseGenericParams(scanner)] | ||
: nextNonWhitespace === "," ? [param, ..._parseGenericParams(scanner)] | ||
: throwParseError(writeUnexpectedCharacterMessage(nextNonWhitespace, ","))); | ||
}; | ||
//# sourceMappingURL=generic.js.map |
@@ -25,8 +25,7 @@ import { tsKeywords } from "@arktype/schema"; | ||
// because the currently parsed definition will overwrite them. | ||
spreadNode.prop?.forEach((spreadRequired) => !parsedEntries.some(({ inner: innerKey }) => innerKey === spreadRequired.key) && propNodes.push(spreadRequired)); | ||
spreadNode.prop?.forEach(spreadRequired => !parsedEntries.some(({ inner: innerKey }) => innerKey === spreadRequired.key) && propNodes.push(spreadRequired)); | ||
} | ||
for (const entry of parsedEntries) { | ||
if (entry.kind === "spread") { | ||
if (entry.kind === "spread") | ||
return throwParseError(nonLeadingSpreadError); | ||
} | ||
if (entry.kind === "index") { | ||
@@ -33,0 +32,0 @@ // handle key parsing first to match type behavior |
import type { arkKind, GenericProps, PrivateDeclaration, writeMissingSubmoduleAccessMessage } from "@arktype/schema"; | ||
import type { BigintLiteral, charsAfterFirst, Completion, ErrorMessage, writeMalformedNumericLiteralMessage } from "@arktype/util"; | ||
import type { BigintLiteral, charsAfterFirst, Completion, ErrorMessage, isAnyOrNever, writeMalformedNumericLiteralMessage } from "@arktype/util"; | ||
import type { Comparator } from "../string/reduce/shared.js"; | ||
@@ -19,3 +19,3 @@ import type { writeInvalidGenericArgsMessage } from "../string/shift/operand/genericArgs.js"; | ||
export type writePrefixedPrivateReferenceMessage<def extends PrivateDeclaration> = `Private type references should not include '#'. Use '${charsAfterFirst<def>}' instead.`; | ||
type validateStringAst<def extends string, $> = def extends `${infer n extends number}` ? number extends n ? ErrorMessage<writeMalformedNumericLiteralMessage<def, "number">> : undefined : def extends BigintLiteral<infer b> ? bigint extends b ? ErrorMessage<writeMalformedNumericLiteralMessage<def, "bigint">> : undefined : maybeExtractAlias<def, $> extends infer alias extends keyof $ ? $[alias] extends null ? def : def extends PrivateDeclaration ? ErrorMessage<writePrefixedPrivateReferenceMessage<def>> : $[alias] extends GenericProps ? ErrorMessage<writeInvalidGenericArgsMessage<def, $[alias]["params"], []>> : $[alias] extends { | ||
type validateStringAst<def extends string, $> = def extends `${infer n extends number}` ? number extends n ? ErrorMessage<writeMalformedNumericLiteralMessage<def, "number">> : undefined : def extends BigintLiteral<infer b> ? bigint extends b ? ErrorMessage<writeMalformedNumericLiteralMessage<def, "bigint">> : undefined : maybeExtractAlias<def, $> extends infer alias extends keyof $ ? isAnyOrNever<$[alias]> extends true ? def : def extends PrivateDeclaration ? ErrorMessage<writePrefixedPrivateReferenceMessage<def>> : $[alias] extends GenericProps ? ErrorMessage<writeInvalidGenericArgsMessage<def, $[alias]["params"], []>> : $[alias] extends { | ||
[arkKind]: "module"; | ||
@@ -22,0 +22,0 @@ } ? ErrorMessage<writeMissingSubmoduleAccessMessage<def>> : undefined : def extends ErrorMessage ? def : undefined; |
@@ -42,5 +42,4 @@ import { isKeyOf, throwInternalError, throwParseError } from "@arktype/util"; | ||
finalize(finalizer) { | ||
if (this.groups.length) { | ||
if (this.groups.length) | ||
return this.error(writeUnclosedGroupMessage(")")); | ||
} | ||
this.finalizeBranches(); | ||
@@ -51,5 +50,4 @@ this.finalizer = finalizer; | ||
const invertedComparator = invertedComparators[comparator]; | ||
if (!isKeyOf(invertedComparator, minComparators)) { | ||
if (!isKeyOf(invertedComparator, minComparators)) | ||
return this.error(writeUnpairableComparatorMessage(comparator)); | ||
} | ||
if (this.branches.leftBound) { | ||
@@ -73,5 +71,4 @@ return this.error(writeMultipleLeftBoundsMessage(this.branches.leftBound.limit, this.branches.leftBound.comparator, limit, invertedComparator)); | ||
} | ||
else { | ||
else | ||
this.applyPrefixes(); | ||
} | ||
} | ||
@@ -81,5 +78,4 @@ finalizeGroup() { | ||
const topBranchState = this.groups.pop(); | ||
if (!topBranchState) { | ||
if (!topBranchState) | ||
return this.error(writeUnmatchedGroupCloseMessage(this.scanner.unscanned)); | ||
} | ||
this.branches = topBranchState; | ||
@@ -86,0 +82,0 @@ } |
@@ -12,11 +12,9 @@ import { throwParseError, tryParseNumber } from "@arktype/util"; | ||
const stringParsedDate = new Date(source); | ||
if (isValidDate(stringParsedDate)) { | ||
if (isValidDate(stringParsedDate)) | ||
return stringParsedDate; | ||
} | ||
const epochMillis = tryParseNumber(source); | ||
if (epochMillis !== undefined) { | ||
const numberParsedDate = new Date(epochMillis); | ||
if (isValidDate(numberParsedDate)) { | ||
if (isValidDate(numberParsedDate)) | ||
return numberParsedDate; | ||
} | ||
} | ||
@@ -23,0 +21,0 @@ return errorOnFail ? |
@@ -5,7 +5,6 @@ import { isKeyOf } from "@arktype/util"; | ||
const enclosed = s.scanner.shiftUntil(untilLookaheadIsClosing[enclosingTokens[enclosing]]); | ||
if (s.scanner.lookahead === "") { | ||
if (s.scanner.lookahead === "") | ||
return s.error(writeUnterminatedEnclosedMessage(enclosed, enclosing)); | ||
} | ||
// Shift the scanner one additional time for the second enclosing token | ||
const token = `${enclosing}${enclosed}${s.scanner.shift()}`; | ||
s.scanner.shift(); | ||
if (enclosing === "/") { | ||
@@ -19,5 +18,4 @@ // fail parsing if the regex is invalid | ||
} | ||
else if (isKeyOf(enclosing, enclosingQuote)) { | ||
else if (isKeyOf(enclosing, enclosingQuote)) | ||
s.root = s.ctx.$.node("unit", { unit: enclosed }); | ||
} | ||
else { | ||
@@ -44,5 +42,5 @@ const date = tryParseDate(enclosed, writeInvalidDateMessage(enclosed)); | ||
export const untilLookaheadIsClosing = { | ||
"'": (scanner) => scanner.lookahead === `'`, | ||
'"': (scanner) => scanner.lookahead === `"`, | ||
"/": (scanner) => scanner.lookahead === `/` | ||
"'": scanner => scanner.lookahead === `'`, | ||
'"': scanner => scanner.lookahead === `"`, | ||
"/": scanner => scanner.lookahead === `/` | ||
}; | ||
@@ -49,0 +47,0 @@ const enclosingCharDescriptions = { |
@@ -12,5 +12,5 @@ import type { RawSchema } from "@arktype/schema"; | ||
export declare const parseGenericArgs: (name: string, params: string[], s: DynamicState) => ParsedArgs<RawSchema[]>; | ||
export type parseGenericArgs<name extends string, params extends string[], unscanned extends string, $, args> = $parseGenericArgs<name, params, unscanned, $, args, [], []>; | ||
declare const $parseGenericArgs: (name: string, params: string[], s: DynamicState, argDefs: string[], argNodes: RawSchema[]) => ParsedArgs<RawSchema[]>; | ||
type $parseGenericArgs<name extends string, params extends string[], unscanned extends string, $, args, argDefs extends string[], argAsts extends unknown[]> = parseUntilFinalizer<state.initialize<unscanned>, $, args> extends (infer finalArgState extends StaticState) ? { | ||
export type parseGenericArgs<name extends string, params extends string[], unscanned extends string, $, args> = _parseGenericArgs<name, params, unscanned, $, args, [], []>; | ||
declare const _parseGenericArgs: (name: string, params: string[], s: DynamicState, argDefs: string[], argNodes: RawSchema[]) => ParsedArgs<RawSchema[]>; | ||
type _parseGenericArgs<name extends string, params extends string[], unscanned extends string, $, args, argDefs extends string[], argAsts extends unknown[]> = parseUntilFinalizer<state.initialize<unscanned>, $, args> extends (infer finalArgState extends StaticState) ? { | ||
defs: [ | ||
@@ -26,3 +26,3 @@ ...argDefs, | ||
unscanned: infer nextUnscanned extends string; | ||
}) ? finalArgState["finalizer"] extends ">" ? nextAsts["length"] extends params["length"] ? ParsedArgs<nextAsts, nextUnscanned> : state.error<writeInvalidGenericArgsMessage<name, params, nextDefs>> : finalArgState["finalizer"] extends "," ? $parseGenericArgs<name, params, nextUnscanned, $, args, nextDefs, nextAsts> : finalArgState["finalizer"] extends ErrorMessage ? finalArgState : state.error<writeUnclosedGroupMessage<">">> : never : never; | ||
}) ? finalArgState["finalizer"] extends ">" ? nextAsts["length"] extends params["length"] ? ParsedArgs<nextAsts, nextUnscanned> : state.error<writeInvalidGenericArgsMessage<name, params, nextDefs>> : finalArgState["finalizer"] extends "," ? _parseGenericArgs<name, params, nextUnscanned, $, args, nextDefs, nextAsts> : finalArgState["finalizer"] extends ErrorMessage ? finalArgState : state.error<writeUnclosedGroupMessage<">">> : never : never; | ||
export declare const writeInvalidGenericArgsMessage: <name extends string, params extends string[], argDefs extends string[]>(name: name, params: params, argDefs: argDefs) => `${name}<${join<params, ", ", "">}> requires exactly ${params["length"]} args (got ${argDefs["length"]}${argDefs["length"] extends 0 ? "" : `: ${join<argDefs, ",", "">}`})`; | ||
@@ -29,0 +29,0 @@ export type writeInvalidGenericArgsMessage<name extends string, params extends string[], argDefs extends string[]> = `${name}<${join<params, ", ">}> requires exactly ${params["length"]} args (got ${argDefs["length"]}${argDefs["length"] extends (0) ? "" : `: ${join<argDefs, ",">}`})`; |
import { writeUnclosedGroupMessage } from "../../reduce/shared.js"; | ||
export const parseGenericArgs = (name, params, s) => $parseGenericArgs(name, params, s, [], []); | ||
const $parseGenericArgs = (name, params, s, argDefs, argNodes) => { | ||
export const parseGenericArgs = (name, params, s) => _parseGenericArgs(name, params, s, [], []); | ||
const _parseGenericArgs = (name, params, s, argDefs, argNodes) => { | ||
const argState = s.parseUntilFinalizer(); | ||
@@ -17,5 +17,4 @@ // remove the finalizing token from the argDef | ||
} | ||
if (argState.finalizer === ",") { | ||
return $parseGenericArgs(name, params, s, argDefs, argNodes); | ||
} | ||
if (argState.finalizer === ",") | ||
return _parseGenericArgs(name, params, s, argDefs, argNodes); | ||
return argState.error(writeUnclosedGroupMessage(">")); | ||
@@ -22,0 +21,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
import { type GenericProps, RawSchema, type SchemaModule, type writeNonSubmoduleDotMessage, writeUnresolvableMessage } from "@arktype/schema"; | ||
import { type BigintLiteral, type Completion, type ErrorMessage, type join } from "@arktype/util"; | ||
import { type GenericProps, RawSchema, type writeNonSubmoduleDotMessage, writeUnresolvableMessage } from "@arktype/schema"; | ||
import { type BigintLiteral, type Completion, type ErrorMessage, type isAnyOrNever, type join } from "@arktype/util"; | ||
import type { Generic } from "../../../../generic.js"; | ||
@@ -12,6 +12,6 @@ import type { Module } from "../../../../module.js"; | ||
export declare const parseUnenclosed: (s: DynamicState) => void; | ||
export type parseUnenclosed<s extends StaticState, $, args> = Scanner.shiftUntilNextTerminator<s["unscanned"]> extends (Scanner.shiftResult<infer token, infer unscanned>) ? token extends "keyof" ? state.addPrefix<s, "keyof", unscanned> : tryResolve<s, token, $, args> extends infer result ? result extends ErrorMessage<infer message> ? state.error<message> : result extends keyof $ ? $[result] extends GenericProps ? parseGenericInstantiation<token, $[result], state.scanTo<s, unscanned>, $, args> : state.setRoot<s, result, unscanned> : state.setRoot<s, result, unscanned> : never : never; | ||
export type parseUnenclosed<s extends StaticState, $, args> = Scanner.shiftUntilNextTerminator<s["unscanned"]> extends (Scanner.shiftResult<infer token, infer unscanned>) ? token extends "keyof" ? state.addPrefix<s, "keyof", unscanned> : tryResolve<s, token, $, args> extends infer result ? result extends ErrorMessage<infer message> ? state.error<message> : result extends keyof $ ? isAnyOrNever<$[result]> extends true ? state.setRoot<s, result, unscanned> : $[result] extends GenericProps ? parseGenericInstantiation<token, $[result], state.scanTo<s, unscanned>, $, args> : state.setRoot<s, result, unscanned> : state.setRoot<s, result, unscanned> : never : never; | ||
export declare const parseGenericInstantiation: (name: string, g: Generic, s: DynamicState) => RawSchema; | ||
export type parseGenericInstantiation<name extends string, g extends GenericProps, s extends StaticState, $, args> = Scanner.skipWhitespace<s["unscanned"]> extends `<${infer unscanned}` ? parseGenericArgs<name, g["params"], unscanned, $, args> extends (infer result) ? result extends ParsedArgs<infer argAsts, infer nextUnscanned> ? state.setRoot<s, GenericInstantiationAst<g, argAsts>, nextUnscanned> : result : never : state.error<writeInvalidGenericArgsMessage<name, g["params"], []>>; | ||
type tryResolve<s extends StaticState, token extends string, $, args> = token extends keyof $ ? token : `#${token}` extends keyof $ ? token : token extends keyof args ? token : token extends `${number}` ? token : token extends BigintLiteral ? token : token extends (`${infer submodule extends keyof $ & string}.${infer reference}`) ? $[submodule] extends (SchemaModule<infer sub$> | Module<infer sub$>) ? reference extends keyof sub$ ? token : unknown extends sub$ ? ErrorMessage<writeNonSubmoduleDotMessage<submodule>> : unresolvableError<s, reference, $[submodule], args, [submodule]> : ErrorMessage<writeNonSubmoduleDotMessage<submodule>> : unresolvableError<s, token, $, args, []>; | ||
type tryResolve<s extends StaticState, token extends string, $, args> = token extends keyof $ ? token : `#${token}` extends keyof $ ? token : token extends keyof args ? token : token extends `${number}` ? token : token extends BigintLiteral ? token : token extends (`${infer submodule extends keyof $ & string}.${infer reference}`) ? $[submodule] extends Module<infer sub$> ? reference extends keyof sub$ ? token : unresolvableError<s, reference, $[submodule], args, [submodule]> : ErrorMessage<writeNonSubmoduleDotMessage<submodule>> : unresolvableError<s, token, $, args, []>; | ||
/** Provide valid completions for the current token, or fallback to an | ||
@@ -18,0 +18,0 @@ * unresolvable error if there are none */ |
@@ -7,8 +7,6 @@ import { RawSchema, hasArkKind, writeUnresolvableMessage } from "@arktype/schema"; | ||
const token = s.scanner.shiftUntilNextTerminator(); | ||
if (token === "keyof") { | ||
if (token === "keyof") | ||
s.addPrefix("keyof"); | ||
} | ||
else { | ||
else | ||
s.root = unenclosedToNode(s, token); | ||
} | ||
}; | ||
@@ -18,5 +16,4 @@ export const parseGenericInstantiation = (name, g, s) => { | ||
const lookahead = s.scanner.shift(); | ||
if (lookahead !== "<") { | ||
if (lookahead !== "<") | ||
return s.error(writeInvalidGenericArgsMessage(name, g.params, [])); | ||
} | ||
const parsedArgs = parseGenericArgs(name, g.params, s); | ||
@@ -49,9 +46,7 @@ const remainingChars = parsedArgs.unscanned.length; | ||
const maybeNumber = tryParseNumber(token, { strict: true }); | ||
if (maybeNumber !== undefined) { | ||
if (maybeNumber !== undefined) | ||
return s.ctx.$.node("unit", { unit: maybeNumber }); | ||
} | ||
const maybeBigint = tryParseWellFormedBigint(token); | ||
if (maybeBigint !== undefined) { | ||
if (maybeBigint !== undefined) | ||
return s.ctx.$.node("unit", { unit: maybeBigint }); | ||
} | ||
}; | ||
@@ -58,0 +53,0 @@ export const writeMissingOperandMessage = (s) => { |
@@ -78,5 +78,4 @@ import { internalKeywords, jsObjects, tsKeywords, writeUnboundableMessage } from "@arktype/schema"; | ||
if (!limitNode.hasKind("unit") || | ||
(typeof limitNode.unit !== "number" && !(limitNode.unit instanceof Date))) { | ||
(typeof limitNode.unit !== "number" && !(limitNode.unit instanceof Date))) | ||
return s.error(writeInvalidLimitMessage(comparator, limitToken, "right")); | ||
} | ||
const limit = limitNode.unit; | ||
@@ -86,12 +85,9 @@ // apply the newly-parsed right bound | ||
// if the comparator is ==, both the min and max of that pair will be applied | ||
for (const kind of getBoundKinds(comparator, typeof limit === "number" ? limit : limitToken, previousRoot, "right")) { | ||
for (const kind of getBoundKinds(comparator, typeof limit === "number" ? limit : limitToken, previousRoot, "right")) | ||
s.constrainRoot(kind, { rule: limit, exclusive }); | ||
} | ||
if (!s.branches.leftBound) { | ||
if (!s.branches.leftBound) | ||
return; | ||
} | ||
// if there's an open left bound, perform additional validation and apply it | ||
if (!isKeyOf(comparator, maxComparators)) { | ||
if (!isKeyOf(comparator, maxComparators)) | ||
return s.error(writeUnpairableComparatorMessage(comparator)); | ||
} | ||
const lowerBoundKind = getBoundKinds(s.branches.leftBound.comparator, s.branches.leftBound.limit, previousRoot, "left"); | ||
@@ -98,0 +94,0 @@ s.constrainRoot(lowerBoundKind[0], openLeftBoundToSchema(s.branches.leftBound)); |
@@ -7,5 +7,4 @@ import { tryParseInteger } from "@arktype/util"; | ||
}); | ||
if (divisor === 0) { | ||
if (divisor === 0) | ||
s.error(writeInvalidDivisorMessage(0)); | ||
} | ||
s.root = s.root.constrain("divisor", divisor); | ||
@@ -12,0 +11,0 @@ }; |
@@ -23,8 +23,6 @@ import { isKeyOf } from "@arktype/util"; | ||
if (condition(this, shifted)) { | ||
if (shifted[shifted.length - 1] === Scanner.escapeToken) { | ||
if (shifted[shifted.length - 1] === Scanner.escapeToken) | ||
shifted = shifted.slice(0, -1); | ||
} | ||
else { | ||
else | ||
break; | ||
} | ||
} | ||
@@ -31,0 +29,0 @@ shifted += this.shift(); |
@@ -17,5 +17,4 @@ import { throwInternalError, throwParseError } from "@arktype/util"; | ||
export const parseUntilFinalizer = (s) => { | ||
while (s.finalizer === undefined) { | ||
while (s.finalizer === undefined) | ||
next(s); | ||
} | ||
return s; | ||
@@ -22,0 +21,0 @@ }; |
@@ -18,5 +18,4 @@ import { jsObjects, makeRootAndArrayPropertiesMutable, tsKeywords } from "@arktype/schema"; | ||
if (def[i] === "?") { | ||
if (spread) { | ||
if (spread) | ||
return throwParseError(spreadOptionalMessage); | ||
} | ||
optional = true; | ||
@@ -26,17 +25,16 @@ i++; | ||
if (spread) { | ||
if (!element.extends(jsObjects.Array)) { | ||
if (!element.extends(jsObjects.Array)) | ||
return throwParseError(writeNonArraySpreadMessage(element.expression)); | ||
} | ||
// a spread must be distributed over branches e.g.: | ||
// def: [string, ...(number[] | [true, false])] | ||
// nodes: [string, ...number[]] | [string, true, false] | ||
sequences = sequences.flatMap((base) => | ||
sequences = sequences.flatMap(base => | ||
// since appendElement mutates base, we have to shallow-ish clone it for each branch | ||
element.branches.map((branch) => appendSpreadBranch(makeRootAndArrayPropertiesMutable(base), branch))); | ||
element.branches.map(branch => appendSpreadBranch(makeRootAndArrayPropertiesMutable(base), branch))); | ||
} | ||
else { | ||
sequences = sequences.map((base) => appendElement(base, optional ? "optional" : "required", element)); | ||
sequences = sequences.map(base => appendElement(base, optional ? "optional" : "required", element)); | ||
} | ||
} | ||
return ctx.$.raw.schema(sequences.map((sequence) => ({ | ||
return ctx.$.raw.schema(sequences.map(sequence => ({ | ||
proto: Array, | ||
@@ -93,6 +91,6 @@ sequence | ||
} | ||
spread.prefix.forEach((node) => appendElement(base, "required", node)); | ||
spread.optional.forEach((node) => appendElement(base, "optional", node)); | ||
spread.prefix.forEach(node => appendElement(base, "required", node)); | ||
spread.optional.forEach(node => appendElement(base, "optional", node)); | ||
spread.variadic && appendElement(base, "variadic", spread.variadic); | ||
spread.postfix.forEach((node) => appendElement(base, "required", node)); | ||
spread.postfix.forEach(node => appendElement(base, "required", node)); | ||
return base; | ||
@@ -125,5 +123,4 @@ }; | ||
const parseBranchTuple = (def, ctx) => { | ||
if (def[2] === undefined) { | ||
if (def[2] === undefined) | ||
return throwParseError(writeMissingRightOperandMessage(def[1], "")); | ||
} | ||
const l = ctx.$.parse(def[0], ctx); | ||
@@ -140,3 +137,3 @@ const r = ctx.$.parse(def[2], ctx); | ||
// TODO: nested morphs? | ||
return ctx.$.parse(def[0], ctx).morph(def[2]); | ||
return ctx.$.parse(def[0], ctx).pipe(def[2]); | ||
}; | ||
@@ -167,3 +164,3 @@ export const writeMalformedFunctionalExpressionMessage = (operator, value) => `${operator === ":" ? "Narrow" : "Morph"} expression requires a function following '${operator}' (was ${typeof value})`; | ||
.slice(1) | ||
.map((ctor) => typeof ctor === "function" ? | ||
.map(ctor => typeof ctor === "function" ? | ||
ctx.$.node("proto", { proto: ctor }) | ||
@@ -170,0 +167,0 @@ : throwParseError(writeInvalidConstructorMessage(objectKindOrDomainOf(ctor)))); |
@@ -1,3 +0,3 @@ | ||
import { type ArkConfig, type GenericProps, type NodeParseOptions, type PreparsedNodeResolution, type RawSchema, type RawSchemaResolutions, RawSchemaScope, type SchemaScope, type ambient, type arkKind, type destructuredExportContext, type destructuredImportContext, type exportedNameOf } from "@arktype/schema"; | ||
import { type nominal, type show } from "@arktype/util"; | ||
import { type ArkConfig, type GenericProps, type NodeParseContext, type NodeParseOptions, type PreparsedNodeResolution, type RawSchema, type RawSchemaResolutions, RawSchemaScope, type SchemaScope, type ambient, type arkKind, type destructuredExportContext, type destructuredImportContext, type exportedNameOf } from "@arktype/schema"; | ||
import { type isAnyOrNever, type nominal, type show } from "@arktype/util"; | ||
import type { type } from "./ark.js"; | ||
@@ -9,3 +9,3 @@ import { Generic } from "./generic.js"; | ||
import { type GenericDeclaration, type GenericParamsParseError, parseGenericParams } from "./parser/generic.js"; | ||
import type { DeclarationParser, DefinitionParser, Type, TypeParser } from "./type.js"; | ||
import { type DeclarationParser, type DefinitionParser, RawTypeParser, type Type, type TypeParser } from "./type.js"; | ||
export type ScopeParser = <const def>(def: validateScope<def>, config?: ArkConfig) => Scope<inferBootstrapped<bootstrapAliases<def>>>; | ||
@@ -36,3 +36,3 @@ type validateScope<def> = { | ||
type extractGenericParameters<k> = k extends GenericDeclaration<string, infer params> ? params : never; | ||
export type resolve<reference extends keyof $ | keyof args, $, args> = (reference extends keyof args ? args[reference] : $[reference & keyof $]) extends infer resolution ? resolution extends Def<infer def> ? def extends null ? resolution : inferDefinition<def, $, args> : resolution : never; | ||
export type resolve<reference extends keyof $ | keyof args, $, args> = (reference extends keyof args ? args[reference] : $[reference & keyof $]) extends infer resolution ? isAnyOrNever<resolution> extends true ? resolution : resolution extends Def<infer def> ? inferDefinition<def, $, args> : resolution : never; | ||
export type moduleKeyOf<$> = { | ||
@@ -44,3 +44,3 @@ [k in keyof $]: $[k] extends { | ||
export type tryInferSubmoduleReference<$, token> = token extends `${infer submodule extends moduleKeyOf<$>}.${infer subalias}` ? subalias extends keyof $[submodule] ? $[submodule][subalias] extends type.cast<infer t> ? t : never : never : never; | ||
export interface ParseContext extends NodeParseOptions { | ||
export interface ParseContext extends NodeParseContext { | ||
$: RawScope; | ||
@@ -60,8 +60,8 @@ } | ||
constructor(def: Record<string, unknown>, config?: ArkConfig); | ||
type(...args: unknown[]): RawSchema | Generic; | ||
type: RawTypeParser; | ||
match: MatchParser<$>; | ||
declare(): { | ||
type: RawScope["type"]; | ||
declare: () => { | ||
type: RawTypeParser; | ||
}; | ||
define(def: unknown): unknown; | ||
define: (def: unknown) => unknown; | ||
preparseRoot(def: unknown): unknown; | ||
@@ -68,0 +68,0 @@ parseRoot(def: unknown, opts?: NodeParseOptions): RawSchema; |
@@ -9,2 +9,3 @@ import { RawSchemaScope, hasArkKind } from "@arktype/schema"; | ||
import { fullStringParse } from "./parser/string/string.js"; | ||
import { RawTypeParser } from "./type.js"; | ||
export const scope = ((def, config = {}) => new RawScope(def, config)); | ||
@@ -25,40 +26,18 @@ export class RawScope extends RawSchemaScope { | ||
} | ||
type(...args) { | ||
if (args.length === 1) { | ||
// treat as a simple definition | ||
return this.parseRoot(args[0]); | ||
} | ||
if (args.length === 2 && | ||
typeof args[0] === "string" && | ||
args[0][0] === "<" && | ||
args[0].at(-1) === ">") { | ||
// if there are exactly two args, the first of which looks like <${string}>, | ||
// treat as a generic | ||
const params = parseGenericParams(args[0].slice(1, -1)); | ||
const def = args[1]; | ||
// TODO: validateUninstantiatedGeneric, remove this cast | ||
return new Generic(params, def, this); | ||
} | ||
// otherwise, treat as a tuple expression. technically, this also allows | ||
// non-expression tuple definitions to be parsed, but it's not a supported | ||
// part of the API as specified by the associated types | ||
return this.parseRoot(args); | ||
} | ||
type = new RawTypeParser(this); | ||
match = createMatchParser(this); | ||
declare() { | ||
return { type: this.type.bind(this) }; | ||
} | ||
define(def) { | ||
return def; | ||
} | ||
declare = (() => ({ | ||
type: this.type | ||
})).bind(this); | ||
define = ((def) => def).bind(this); | ||
preparseRoot(def) { | ||
if (isThunk(def) && !hasArkKind(def, "generic")) { | ||
if (isThunk(def) && !hasArkKind(def, "generic")) | ||
return def(); | ||
} | ||
return def; | ||
} | ||
parseRoot(def, opts) { | ||
// args: { this: {} as RawSchema }, | ||
return this.parse(def, { | ||
args: { this: {} }, | ||
$: this, | ||
raw: def, | ||
...opts | ||
@@ -69,3 +48,3 @@ }).bindScope(this); | ||
if (typeof def === "string") { | ||
if (ctx.args && Object.keys(ctx.args).every((k) => !def.includes(k))) { | ||
if (ctx.args && Object.keys(ctx.args).every(k => !def.includes(k))) { | ||
// we can only rely on the cache if there are no contextual | ||
@@ -75,5 +54,4 @@ // resolutions like "this" or generic args | ||
} | ||
if (!this.parseCache[def]) { | ||
if (!this.parseCache[def]) | ||
this.parseCache[def] = this.parseString(def, ctx); | ||
} | ||
return this.parseCache[def]; | ||
@@ -80,0 +58,0 @@ } |
@@ -1,9 +0,12 @@ | ||
import { type BaseMeta, type Morph, type NodeDef, type Out, type Predicate, type PrimitiveConstraintKind, type Schema, type ambient, type constrain, type constraintKindOf, type distillConstrainableIn, type distillConstrainableOut, type distillIn, type distillOut, type includesMorphs, type inferIntersection, type inferMorphOut, type inferNarrow } from "@arktype/schema"; | ||
import type { Constructor, array, conform } from "@arktype/util"; | ||
import type { Generic, validateParameterString } from "./generic.js"; | ||
import { ArkErrors, type BaseMeta, type BaseRoot, type Disjoint, type Morph, type NodeDef, type Out, type Predicate, type PrimitiveConstraintKind, RawSchema, type Schema, type ambient, type constrain, type constraintKindOf, type distillConstrainableOut, type distillIn, type distillOut, type includesMorphs, type inferIntersection, type inferMorphOut, type inferNarrow, type inferPipes, type internalImplementationOf } from "@arktype/schema"; | ||
import { Callable, type Constructor, type array, type conform } from "@arktype/util"; | ||
import { Generic, type validateParameterString } from "./generic.js"; | ||
import type { inferDefinition, validateDeclared, validateDefinition } from "./parser/definition.js"; | ||
import type { parseGenericParams } from "./parser/generic.js"; | ||
import { parseGenericParams } from "./parser/generic.js"; | ||
import type { IndexOneOperator, IndexZeroOperator, TupleInfixOperator } from "./parser/tuple.js"; | ||
import type { Scope, bindThis } from "./scope.js"; | ||
export type TypeParser<$> = { | ||
import type { RawScope, Scope, bindThis } from "./scope.js"; | ||
export interface TypeParserAttachments { | ||
errors: typeof ArkErrors; | ||
} | ||
export interface TypeParser<$> extends TypeParserAttachments { | ||
<const def>(def: validateTypeRoot<def, $>): Type<inferTypeRoot<def, $>, $>; | ||
@@ -14,19 +17,35 @@ <const zero, const one, const rest extends array>(_0: zero extends IndexZeroOperator ? zero : validateTypeRoot<zero, $>, _1: zero extends "keyof" ? validateTypeRoot<one, $> : zero extends "instanceof" ? conform<one, Constructor> : zero extends "===" ? conform<one, unknown> : conform<one, IndexOneOperator>, ..._2: zero extends "===" ? rest : zero extends "instanceof" ? conform<rest, readonly Constructor[]> : one extends TupleInfixOperator ? one extends ":" ? [Predicate<distillIn<inferTypeRoot<zero, $>>>] : one extends "=>" ? [Morph<distillOut<inferTypeRoot<zero, $>>, unknown>] : one extends "@" ? [string | BaseMeta] : [validateTypeRoot<rest[0], $>] : []): Type<inferTypeRoot<[zero, one, ...rest], $>, $>; | ||
}>): Generic<parseGenericParams<params>, def, $>; | ||
}; | ||
} | ||
export declare class RawTypeParser extends Callable<(...args: unknown[]) => RawSchema | Generic, TypeParserAttachments> { | ||
constructor($: RawScope); | ||
} | ||
export type DeclarationParser<$> = <preinferred>() => { | ||
type: <def>(def: validateDeclared<preinferred, def, $ & ambient, bindThis<def>>) => Type<preinferred, $>; | ||
}; | ||
declare class _Type<t = unknown, $ = any> extends BaseRoot<t, $> implements internalImplementationOf<Schema> { | ||
$: Scope<$>; | ||
get in(): Type<this["tIn"], $>; | ||
get out(): Type<this["tOut"], $>; | ||
intersect<def>(def: validateTypeRoot<def, $>): Type<inferIntersection<t, inferTypeRoot<def, $>>> | Disjoint; | ||
and<def>(def: validateTypeRoot<def, $>): Type<inferIntersection<t, inferTypeRoot<def, $>>, $>; | ||
or<def>(def: validateTypeRoot<def, $>): Type<t | inferTypeRoot<def, $>, $>; | ||
array(): Type<t[], $>; | ||
keyof(): Type<keyof this["inferIn"], $>; | ||
pipe<a extends Morph<this["infer"]>>(a: a): Type<inferPipes<t, [a]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>>(a: a, b: b): Type<inferPipes<t, [a, b]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>, c extends Morph<inferMorphOut<b>>>(a: a, b: b, c: c): Type<inferPipes<t, [a, b, c]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>, c extends Morph<inferMorphOut<b>>, d extends Morph<inferMorphOut<c>>>(a: a, b: b, c: c, d: d): Type<inferPipes<t, [a, b, c, d]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>, c extends Morph<inferMorphOut<b>>, d extends Morph<inferMorphOut<c>>, e extends Morph<inferMorphOut<d>>>(a: a, b: b, c: c, d: d, e: e): Type<inferPipes<t, [a, b, c, d, e]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>, c extends Morph<inferMorphOut<b>>, d extends Morph<inferMorphOut<c>>, e extends Morph<inferMorphOut<d>>, f extends Morph<inferMorphOut<e>>>(a: a, b: b, c: c, d: d, e: e, f: f): Type<inferPipes<t, [a, b, c, d, e, f]>, $>; | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>, c extends Morph<inferMorphOut<b>>, d extends Morph<inferMorphOut<c>>, e extends Morph<inferMorphOut<d>>, f extends Morph<inferMorphOut<e>>, g extends Morph<inferMorphOut<f>>>(a: a, b: b, c: c, d: d, e: e, f: f, g: g): Type<inferPipes<t, [a, b, c, d, e, f, g]>, $>; | ||
narrow<def extends Predicate<distillConstrainableOut<t>>>(def: def): Type<includesMorphs<t> extends true ? (In: this["tIn"]) => Out<inferNarrow<this["infer"], def>> : inferNarrow<this["infer"], def>, $>; | ||
equals<def>(def: validateTypeRoot<def, $>): this is Type<inferTypeRoot<def>, $>; | ||
extract<def>(r: validateTypeRoot<def, $>): Type<t, $>; | ||
exclude<def>(r: validateTypeRoot<def, $>): Type<t, $>; | ||
extends<def>(other: validateTypeRoot<def, $>): this is Type<inferTypeRoot<def>, $>; | ||
constrain<kind extends PrimitiveConstraintKind, const def extends NodeDef<kind>>(kind: conform<kind, constraintKindOf<this["inferIn"]>>, def: def): Type<constrain<t, kind, def>, $>; | ||
} | ||
export interface Type< | ||
/** @ts-expect-error allow instantiation assignment to the base type */ | ||
out t = unknown, $ = any> extends Schema<t, $> { | ||
and: (<def>(def: validateTypeRoot<def, $>) => Type<inferIntersection<t, inferTypeRoot<def, $>>, $>) & Schema<t, $>["and"]; | ||
or: (<def>(def: validateTypeRoot<def, $>) => Type<t | inferTypeRoot<def, $>, $>) & Schema<t, $>["or"]; | ||
get in(): Type<distillConstrainableIn<t>, $>; | ||
get out(): Type<distillConstrainableOut<t>, $>; | ||
array(): Type<t[], $>; | ||
morph: (<morph extends Morph<this["infer"]>, outValidatorDef = never>(morph: morph, outValidator?: validateTypeRoot<outValidatorDef, $>) => Type<(In: distillConstrainableIn<t>) => Out<[ | ||
outValidatorDef | ||
] extends [never] ? inferMorphOut<morph> : distillConstrainableOut<inferTypeRoot<outValidatorDef, $>>>, $>) & Schema<t, $>["morph"]; | ||
narrow<def extends Predicate<distillConstrainableOut<t>>>(def: def): Type<includesMorphs<t> extends true ? (In: distillIn<t>) => Out<inferNarrow<this["infer"], def>> : inferNarrow<this["infer"], def>, $>; | ||
constrain<kind extends PrimitiveConstraintKind, const def extends NodeDef<kind>>(kind: conform<kind, constraintKindOf<this["in"]["infer"]>>, def: def): Type<constrain<t, kind, def>, $>; | ||
out t = unknown, $ = any> extends _Type<t, $> { | ||
} | ||
@@ -38,2 +57,3 @@ export type TypeConstructor<t = unknown, $ = any> = new (def: unknown, $: Scope<$>) => Type<t, $>; | ||
export type inferTypeRoot<def, $ = {}> = inferDefinition<def, $ & ambient, bindThis<def>>; | ||
export {}; | ||
//# sourceMappingURL=type.d.ts.map |
@@ -1,3 +0,34 @@ | ||
import { RawSchema } from "@arktype/schema"; | ||
import { ArkErrors, RawSchema } from "@arktype/schema"; | ||
import { Callable } from "@arktype/util"; | ||
import { Generic } from "./generic.js"; | ||
import { parseGenericParams } from "./parser/generic.js"; | ||
const typeParserAttachments = Object.freeze({ | ||
errors: ArkErrors | ||
}); | ||
export class RawTypeParser extends Callable { | ||
constructor($) { | ||
super((...args) => { | ||
if (args.length === 1) { | ||
// treat as a simple definition | ||
return $.parseRoot(args[0]); | ||
} | ||
if (args.length === 2 && | ||
typeof args[0] === "string" && | ||
args[0][0] === "<" && | ||
args[0].at(-1) === ">") { | ||
// if there are exactly two args, the first of which looks like <${string}>, | ||
// treat as a generic | ||
const params = parseGenericParams(args[0].slice(1, -1)); | ||
const def = args[1]; | ||
// TODO: validateUninstantiatedGeneric, remove this cast | ||
return new Generic(params, def, $); | ||
} | ||
// otherwise, treat as a tuple expression. technically, this also allows | ||
// non-expression tuple definitions to be parsed, but it's not a supported | ||
// part of the API as specified by the associated types | ||
return $.parseRoot(args); | ||
}, { bind: $, attach: typeParserAttachments }); | ||
} | ||
} | ||
export const Type = RawSchema; | ||
//# sourceMappingURL=type.js.map |
{ | ||
"name": "arktype", | ||
"description": "TypeScript's 1:1 validator, optimized from editor to runtime", | ||
"version": "2.0.0-dev.7", | ||
"version": "2.0.0-dev.8", | ||
"license": "MIT", | ||
@@ -41,5 +41,5 @@ "author": { | ||
"dependencies": { | ||
"@arktype/util": "0.0.33", | ||
"@arktype/schema": "0.0.7" | ||
"@arktype/util": "0.0.34", | ||
"@arktype/schema": "0.0.8" | ||
} | ||
} |
@@ -16,6 +16,6 @@ import { type nominal, throwParseError } from "@arktype/util" | ||
export const parseGenericParams = (def: string): string[] => | ||
$parseGenericParams(new Scanner(def)) | ||
_parseGenericParams(new Scanner(def)) | ||
export type parseGenericParams<def extends string> = | ||
$parseParams<def, "", []> extends infer result extends string[] ? | ||
_parseParams<def, "", []> extends infer result extends string[] ? | ||
"" extends result[number] ? | ||
@@ -31,7 +31,6 @@ GenericParamsParseError<emptyGenericParameterMessage> | ||
const $parseGenericParams = (scanner: Scanner): string[] => { | ||
const _parseGenericParams = (scanner: Scanner): string[] => { | ||
const param = scanner.shiftUntilNextTerminator() | ||
if (param === "") { | ||
throwParseError(emptyGenericParameterMessage) | ||
} | ||
if (param === "") throwParseError(emptyGenericParameterMessage) | ||
scanner.shiftUntilNonWhitespace() | ||
@@ -41,3 +40,3 @@ const nextNonWhitespace = scanner.shift() | ||
nextNonWhitespace === "" ? [param] | ||
: nextNonWhitespace === "," ? [param, ...$parseGenericParams(scanner)] | ||
: nextNonWhitespace === "," ? [param, ..._parseGenericParams(scanner)] | ||
: throwParseError(writeUnexpectedCharacterMessage(nextNonWhitespace, ",")) | ||
@@ -47,3 +46,3 @@ ) | ||
type $parseParams< | ||
type _parseParams< | ||
unscanned extends string, | ||
@@ -54,7 +53,7 @@ param extends string, | ||
unscanned extends `${infer lookahead}${infer nextUnscanned}` ? | ||
lookahead extends "," ? $parseParams<nextUnscanned, "", [...result, param]> | ||
lookahead extends "," ? _parseParams<nextUnscanned, "", [...result, param]> | ||
: lookahead extends Scanner.WhiteSpaceToken ? | ||
param extends "" ? | ||
// if the next char is whitespace and we aren't in the middle of a param, skip to the next one | ||
$parseParams<Scanner.skipWhitespace<nextUnscanned>, "", result> | ||
_parseParams<Scanner.skipWhitespace<nextUnscanned>, "", result> | ||
: Scanner.skipWhitespace<nextUnscanned> extends ( | ||
@@ -64,3 +63,3 @@ `${infer nextNonWhitespace}${infer rest}` | ||
nextNonWhitespace extends "," ? | ||
$parseParams<rest, "", [...result, param]> | ||
_parseParams<rest, "", [...result, param]> | ||
: GenericParamsParseError< | ||
@@ -71,4 +70,4 @@ writeUnexpectedCharacterMessage<nextNonWhitespace, ","> | ||
[...result, param] | ||
: $parseParams<nextUnscanned, `${param}${lookahead}`, result> | ||
: _parseParams<nextUnscanned, `${param}${lookahead}`, result> | ||
: param extends "" ? result | ||
: [...result, param] |
@@ -49,3 +49,3 @@ import { | ||
spreadNode.prop?.forEach( | ||
(spreadRequired) => | ||
spreadRequired => | ||
!parsedEntries.some( | ||
@@ -57,5 +57,3 @@ ({ inner: innerKey }) => innerKey === spreadRequired.key | ||
for (const entry of parsedEntries) { | ||
if (entry.kind === "spread") { | ||
return throwParseError(nonLeadingSpreadError) | ||
} | ||
if (entry.kind === "spread") return throwParseError(nonLeadingSpreadError) | ||
@@ -62,0 +60,0 @@ if (entry.kind === "index") { |
@@ -12,2 +12,3 @@ import type { | ||
ErrorMessage, | ||
isAnyOrNever, | ||
writeMalformedNumericLiteralMessage | ||
@@ -85,5 +86,3 @@ } from "@arktype/util" | ||
: maybeExtractAlias<def, $> extends infer alias extends keyof $ ? | ||
$[alias] extends null ? | ||
// handle any/never | ||
def | ||
isAnyOrNever<$[alias]> extends true ? def | ||
: def extends PrivateDeclaration ? | ||
@@ -90,0 +89,0 @@ ErrorMessage<writePrefixedPrivateReferenceMessage<def>> |
@@ -80,5 +80,4 @@ import type { LimitLiteral, RawSchema } from "@arktype/schema" | ||
finalize(finalizer: Scanner.FinalizingLookahead): void { | ||
if (this.groups.length) { | ||
return this.error(writeUnclosedGroupMessage(")")) | ||
} | ||
if (this.groups.length) return this.error(writeUnclosedGroupMessage(")")) | ||
this.finalizeBranches() | ||
@@ -90,5 +89,5 @@ this.finalizer = finalizer | ||
const invertedComparator = invertedComparators[comparator] | ||
if (!isKeyOf(invertedComparator, minComparators)) { | ||
if (!isKeyOf(invertedComparator, minComparators)) | ||
return this.error(writeUnpairableComparatorMessage(comparator)) | ||
} | ||
if (this.branches.leftBound) { | ||
@@ -118,5 +117,3 @@ return this.error( | ||
this.root = this.branches.intersection | ||
} else { | ||
this.applyPrefixes() | ||
} | ||
} else this.applyPrefixes() | ||
} | ||
@@ -127,5 +124,5 @@ | ||
const topBranchState = this.groups.pop() | ||
if (!topBranchState) { | ||
if (!topBranchState) | ||
return this.error(writeUnmatchedGroupCloseMessage(this.scanner.unscanned)) | ||
} | ||
this.branches = topBranchState | ||
@@ -132,0 +129,0 @@ } |
@@ -43,11 +43,8 @@ import type { DateLiteral } from "@arktype/schema" | ||
const stringParsedDate = new Date(source) | ||
if (isValidDate(stringParsedDate)) { | ||
return stringParsedDate | ||
} | ||
if (isValidDate(stringParsedDate)) return stringParsedDate | ||
const epochMillis = tryParseNumber(source) | ||
if (epochMillis !== undefined) { | ||
const numberParsedDate = new Date(epochMillis) | ||
if (isValidDate(numberParsedDate)) { | ||
return numberParsedDate | ||
} | ||
if (isValidDate(numberParsedDate)) return numberParsedDate | ||
} | ||
@@ -54,0 +51,0 @@ return errorOnFail ? |
@@ -24,7 +24,7 @@ import { isKeyOf } from "@arktype/util" | ||
) | ||
if (s.scanner.lookahead === "") { | ||
if (s.scanner.lookahead === "") | ||
return s.error(writeUnterminatedEnclosedMessage(enclosed, enclosing)) | ||
} | ||
// Shift the scanner one additional time for the second enclosing token | ||
const token = `${enclosing}${enclosed}${s.scanner.shift()}` | ||
s.scanner.shift() | ||
if (enclosing === "/") { | ||
@@ -41,5 +41,5 @@ // fail parsing if the regex is invalid | ||
) | ||
} else if (isKeyOf(enclosing, enclosingQuote)) { | ||
} else if (isKeyOf(enclosing, enclosingQuote)) | ||
s.root = s.ctx.$.node("unit", { unit: enclosed }) | ||
} else { | ||
else { | ||
const date = tryParseDate(enclosed, writeInvalidDateMessage(enclosed)) | ||
@@ -98,5 +98,5 @@ s.root = s.ctx.$.node("unit", { unit: date, description: enclosed }) | ||
> = { | ||
"'": (scanner) => scanner.lookahead === `'`, | ||
'"': (scanner) => scanner.lookahead === `"`, | ||
"/": (scanner) => scanner.lookahead === `/` | ||
"'": scanner => scanner.lookahead === `'`, | ||
'"': scanner => scanner.lookahead === `"`, | ||
"/": scanner => scanner.lookahead === `/` | ||
} | ||
@@ -103,0 +103,0 @@ |
@@ -20,3 +20,3 @@ import type { RawSchema } from "@arktype/schema" | ||
s: DynamicState | ||
): ParsedArgs<RawSchema[]> => $parseGenericArgs(name, params, s, [], []) | ||
): ParsedArgs<RawSchema[]> => _parseGenericArgs(name, params, s, [], []) | ||
@@ -29,5 +29,5 @@ export type parseGenericArgs< | ||
args | ||
> = $parseGenericArgs<name, params, unscanned, $, args, [], []> | ||
> = _parseGenericArgs<name, params, unscanned, $, args, [], []> | ||
const $parseGenericArgs = ( | ||
const _parseGenericArgs = ( | ||
name: string, | ||
@@ -52,9 +52,9 @@ params: string[], | ||
} | ||
if (argState.finalizer === ",") { | ||
return $parseGenericArgs(name, params, s, argDefs, argNodes) | ||
} | ||
if (argState.finalizer === ",") | ||
return _parseGenericArgs(name, params, s, argDefs, argNodes) | ||
return argState.error(writeUnclosedGroupMessage(">")) | ||
} | ||
type $parseGenericArgs< | ||
type _parseGenericArgs< | ||
name extends string, | ||
@@ -91,3 +91,3 @@ params extends string[], | ||
: finalArgState["finalizer"] extends "," ? | ||
$parseGenericArgs< | ||
_parseGenericArgs< | ||
name, | ||
@@ -94,0 +94,0 @@ params, |
@@ -5,3 +5,2 @@ import { | ||
RawSchema, | ||
type SchemaModule, | ||
hasArkKind, | ||
@@ -15,2 +14,3 @@ type writeNonSubmoduleDotMessage, | ||
type ErrorMessage, | ||
type isAnyOrNever, | ||
type join, | ||
@@ -38,7 +38,4 @@ printable, | ||
const token = s.scanner.shiftUntilNextTerminator() | ||
if (token === "keyof") { | ||
s.addPrefix("keyof") | ||
} else { | ||
s.root = unenclosedToNode(s, token) | ||
} | ||
if (token === "keyof") s.addPrefix("keyof") | ||
else s.root = unenclosedToNode(s, token) | ||
} | ||
@@ -54,3 +51,5 @@ | ||
: result extends keyof $ ? | ||
$[result] extends GenericProps ? | ||
isAnyOrNever<$[result]> extends true ? | ||
state.setRoot<s, result, unscanned> | ||
: $[result] extends GenericProps ? | ||
parseGenericInstantiation< | ||
@@ -75,5 +74,5 @@ token, | ||
const lookahead = s.scanner.shift() | ||
if (lookahead !== "<") { | ||
if (lookahead !== "<") | ||
return s.error(writeInvalidGenericArgsMessage(name, g.params, [])) | ||
} | ||
const parsedArgs = parseGenericArgs(name, g.params, s) | ||
@@ -136,9 +135,8 @@ const remainingChars = parsedArgs.unscanned.length | ||
const maybeNumber = tryParseNumber(token, { strict: true }) | ||
if (maybeNumber !== undefined) { | ||
if (maybeNumber !== undefined) | ||
return s.ctx.$.node("unit", { unit: maybeNumber }) | ||
} | ||
const maybeBigint = tryParseWellFormedBigint(token) | ||
if (maybeBigint !== undefined) { | ||
if (maybeBigint !== undefined) | ||
return s.ctx.$.node("unit", { unit: maybeBigint }) | ||
} | ||
} | ||
@@ -155,12 +153,5 @@ | ||
) ? | ||
$[submodule] extends ( | ||
SchemaModule<infer sub$> | Module<infer sub$> // TODO: shouldn't need both checks? | ||
) ? | ||
reference extends keyof sub$ ? token | ||
: unknown extends sub$ ? | ||
// not sure why we need the additional check here, but for now TS seems to | ||
// hit this branch for a non-scope dot access rather than failing | ||
// initially when we try to infer r. if this can be removed without breaking | ||
// any submodule test cases, do it! | ||
ErrorMessage<writeNonSubmoduleDotMessage<submodule>> | ||
$[submodule] extends Module<infer sub$> ? | ||
reference extends keyof sub$ ? | ||
token | ||
: unresolvableError<s, reference, $[submodule], args, [submodule]> | ||
@@ -167,0 +158,0 @@ : ErrorMessage<writeNonSubmoduleDotMessage<submodule>> |
@@ -184,5 +184,4 @@ import { | ||
(typeof limitNode.unit !== "number" && !(limitNode.unit instanceof Date)) | ||
) { | ||
) | ||
return s.error(writeInvalidLimitMessage(comparator, limitToken, "right")) | ||
} | ||
@@ -198,12 +197,11 @@ const limit = limitNode.unit | ||
"right" | ||
)) { | ||
)) | ||
s.constrainRoot(kind, { rule: limit, exclusive }) | ||
} | ||
if (!s.branches.leftBound) { | ||
return | ||
} | ||
if (!s.branches.leftBound) return | ||
// if there's an open left bound, perform additional validation and apply it | ||
if (!isKeyOf(comparator, maxComparators)) { | ||
if (!isKeyOf(comparator, maxComparators)) | ||
return s.error(writeUnpairableComparatorMessage(comparator)) | ||
} | ||
const lowerBoundKind = getBoundKinds( | ||
@@ -210,0 +208,0 @@ s.branches.leftBound.comparator, |
@@ -11,5 +11,4 @@ import { tryParseInteger } from "@arktype/util" | ||
}) | ||
if (divisor === 0) { | ||
s.error(writeInvalidDivisorMessage(0)) | ||
} | ||
if (divisor === 0) s.error(writeInvalidDivisorMessage(0)) | ||
s.root = s.root.constrain("divisor", divisor) | ||
@@ -16,0 +15,0 @@ } |
@@ -30,7 +30,5 @@ import { type Dict, isKeyOf } from "@arktype/util" | ||
if (condition(this, shifted)) { | ||
if (shifted[shifted.length - 1] === Scanner.escapeToken) { | ||
if (shifted[shifted.length - 1] === Scanner.escapeToken) | ||
shifted = shifted.slice(0, -1) | ||
} else { | ||
break | ||
} | ||
else break | ||
} | ||
@@ -37,0 +35,0 @@ shifted += this.shift() |
@@ -65,5 +65,4 @@ import type { RawSchema } from "@arktype/schema" | ||
export const parseUntilFinalizer = (s: DynamicState): DynamicStateWithRoot => { | ||
while (s.finalizer === undefined) { | ||
next(s) | ||
} | ||
while (s.finalizer === undefined) next(s) | ||
return s as DynamicStateWithRoot | ||
@@ -70,0 +69,0 @@ } |
@@ -56,5 +56,4 @@ import { | ||
if (def[i] === "?") { | ||
if (spread) { | ||
return throwParseError(spreadOptionalMessage) | ||
} | ||
if (spread) return throwParseError(spreadOptionalMessage) | ||
optional = true | ||
@@ -64,11 +63,11 @@ i++ | ||
if (spread) { | ||
if (!element.extends(jsObjects.Array)) { | ||
if (!element.extends(jsObjects.Array)) | ||
return throwParseError(writeNonArraySpreadMessage(element.expression)) | ||
} | ||
// a spread must be distributed over branches e.g.: | ||
// def: [string, ...(number[] | [true, false])] | ||
// nodes: [string, ...number[]] | [string, true, false] | ||
sequences = sequences.flatMap((base) => | ||
sequences = sequences.flatMap(base => | ||
// since appendElement mutates base, we have to shallow-ish clone it for each branch | ||
element.branches.map((branch) => | ||
element.branches.map(branch => | ||
appendSpreadBranch(makeRootAndArrayPropertiesMutable(base), branch) | ||
@@ -78,3 +77,3 @@ ) | ||
} else { | ||
sequences = sequences.map((base) => | ||
sequences = sequences.map(base => | ||
appendElement(base, optional ? "optional" : "required", element) | ||
@@ -86,3 +85,3 @@ ) | ||
sequences.map( | ||
(sequence) => | ||
sequence => | ||
({ | ||
@@ -150,6 +149,6 @@ proto: Array, | ||
} | ||
spread.prefix.forEach((node) => appendElement(base, "required", node)) | ||
spread.optional.forEach((node) => appendElement(base, "optional", node)) | ||
spread.prefix.forEach(node => appendElement(base, "required", node)) | ||
spread.optional.forEach(node => appendElement(base, "optional", node)) | ||
spread.variadic && appendElement(base, "variadic", spread.variadic) | ||
spread.postfix.forEach((node) => appendElement(base, "required", node)) | ||
spread.postfix.forEach(node => appendElement(base, "required", node)) | ||
return base | ||
@@ -422,5 +421,5 @@ } | ||
const parseBranchTuple: PostfixParser<"|" | "&"> = (def, ctx) => { | ||
if (def[2] === undefined) { | ||
if (def[2] === undefined) | ||
return throwParseError(writeMissingRightOperandMessage(def[1], "")) | ||
} | ||
const l = ctx.$.parse(def[0], ctx) | ||
@@ -468,3 +467,3 @@ const r = ctx.$.parse(def[2], ctx) | ||
// TODO: nested morphs? | ||
return ctx.$.parse(def[0], ctx).morph(def[2] as Morph) | ||
return ctx.$.parse(def[0], ctx).pipe(def[2] as Morph) | ||
} | ||
@@ -528,3 +527,3 @@ | ||
.slice(1) | ||
.map((ctor) => | ||
.map(ctor => | ||
typeof ctor === "function" ? | ||
@@ -531,0 +530,0 @@ ctx.$.node("proto", { proto: ctor as Constructor }) |
72
scope.ts
import { | ||
type ArkConfig, | ||
type GenericProps, | ||
type NodeParseContext, | ||
type NodeParseOptions, | ||
@@ -21,2 +22,3 @@ type PreparsedNodeResolution, | ||
hasDomain, | ||
type isAnyOrNever, | ||
isThunk, | ||
@@ -44,7 +46,8 @@ type nominal, | ||
import { fullStringParse } from "./parser/string/string.js" | ||
import type { | ||
DeclarationParser, | ||
DefinitionParser, | ||
Type, | ||
TypeParser | ||
import { | ||
type DeclarationParser, | ||
type DefinitionParser, | ||
RawTypeParser, | ||
type Type, | ||
type TypeParser | ||
} from "./type.js" | ||
@@ -131,8 +134,5 @@ | ||
) extends infer resolution ? | ||
resolution extends Def<infer def> ? | ||
def extends null ? | ||
// handle resolution of any and never | ||
resolution | ||
: inferDefinition<def, $, args> | ||
: resolution | ||
isAnyOrNever<resolution> extends true ? resolution | ||
: resolution extends Def<infer def> ? inferDefinition<def, $, args> | ||
: resolution | ||
: never | ||
@@ -154,3 +154,3 @@ | ||
export interface ParseContext extends NodeParseOptions { | ||
export interface ParseContext extends NodeParseContext { | ||
$: RawScope | ||
@@ -198,40 +198,15 @@ } | ||
type(...args: unknown[]): RawSchema | Generic { | ||
if (args.length === 1) { | ||
// treat as a simple definition | ||
return this.parseRoot(args[0]) | ||
} | ||
if ( | ||
args.length === 2 && | ||
typeof args[0] === "string" && | ||
args[0][0] === "<" && | ||
args[0].at(-1) === ">" | ||
) { | ||
// if there are exactly two args, the first of which looks like <${string}>, | ||
// treat as a generic | ||
const params = parseGenericParams(args[0].slice(1, -1)) | ||
const def = args[1] | ||
// TODO: validateUninstantiatedGeneric, remove this cast | ||
return new Generic(params, def, this as never) as never | ||
} | ||
// otherwise, treat as a tuple expression. technically, this also allows | ||
// non-expression tuple definitions to be parsed, but it's not a supported | ||
// part of the API as specified by the associated types | ||
return this.parseRoot(args) | ||
} | ||
type = new RawTypeParser(this as never) | ||
match: MatchParser<$> = createMatchParser(this as never) as never | ||
declare(): { type: RawScope["type"] } { | ||
return { type: this.type.bind(this) } | ||
} | ||
declare = (() => ({ | ||
type: this.type | ||
})).bind(this) | ||
define(def: unknown): unknown { | ||
return def | ||
} | ||
define = ((def: unknown) => def).bind(this) | ||
override preparseRoot(def: unknown): unknown { | ||
if (isThunk(def) && !hasArkKind(def, "generic")) { | ||
return def() | ||
} | ||
if (isThunk(def) && !hasArkKind(def, "generic")) return def() | ||
return def | ||
@@ -241,5 +216,6 @@ } | ||
override parseRoot(def: unknown, opts?: NodeParseOptions): RawSchema { | ||
// args: { this: {} as RawSchema }, | ||
return this.parse(def, { | ||
args: { this: {} as RawSchema }, | ||
$: this as never, | ||
raw: def, | ||
...opts | ||
@@ -251,3 +227,3 @@ }).bindScope(this) | ||
if (typeof def === "string") { | ||
if (ctx.args && Object.keys(ctx.args).every((k) => !def.includes(k))) { | ||
if (ctx.args && Object.keys(ctx.args).every(k => !def.includes(k))) { | ||
// we can only rely on the cache if there are no contextual | ||
@@ -257,5 +233,5 @@ // resolutions like "this" or generic args | ||
} | ||
if (!this.parseCache[def]) { | ||
if (!this.parseCache[def]) | ||
this.parseCache[def] = this.parseString(def, ctx) | ||
} | ||
return this.parseCache[def] | ||
@@ -262,0 +238,0 @@ } |
185
type.ts
import { | ||
ArkErrors, | ||
type BaseMeta, | ||
type BaseRoot, | ||
type Disjoint, | ||
type Morph, | ||
@@ -13,3 +16,2 @@ type NodeDef, | ||
type constraintKindOf, | ||
type distillConstrainableIn, | ||
type distillConstrainableOut, | ||
@@ -21,6 +23,13 @@ type distillIn, | ||
type inferMorphOut, | ||
type inferNarrow | ||
type inferNarrow, | ||
type inferPipes, | ||
type internalImplementationOf | ||
} from "@arktype/schema" | ||
import type { Constructor, array, conform } from "@arktype/util" | ||
import type { Generic, validateParameterString } from "./generic.js" | ||
import { | ||
Callable, | ||
type Constructor, | ||
type array, | ||
type conform | ||
} from "@arktype/util" | ||
import { Generic, type validateParameterString } from "./generic.js" | ||
import type { | ||
@@ -31,3 +40,3 @@ inferDefinition, | ||
} from "./parser/definition.js" | ||
import type { parseGenericParams } from "./parser/generic.js" | ||
import { parseGenericParams } from "./parser/generic.js" | ||
import type { | ||
@@ -38,5 +47,8 @@ IndexOneOperator, | ||
} from "./parser/tuple.js" | ||
import type { Scope, bindThis } from "./scope.js" | ||
import type { RawScope, Scope, bindThis } from "./scope.js" | ||
export interface TypeParserAttachments { | ||
errors: typeof ArkErrors | ||
} | ||
export type TypeParser<$> = { | ||
export interface TypeParser<$> extends TypeParserAttachments { | ||
// Parse and check the definition, returning either the original input for a | ||
@@ -75,2 +87,40 @@ // valid definition or a string representing an error message. | ||
const typeParserAttachments = Object.freeze({ | ||
errors: ArkErrors | ||
} satisfies TypeParserAttachments) | ||
export class RawTypeParser extends Callable< | ||
(...args: unknown[]) => RawSchema | Generic, | ||
TypeParserAttachments | ||
> { | ||
constructor($: RawScope) { | ||
super( | ||
(...args) => { | ||
if (args.length === 1) { | ||
// treat as a simple definition | ||
return $.parseRoot(args[0]) | ||
} | ||
if ( | ||
args.length === 2 && | ||
typeof args[0] === "string" && | ||
args[0][0] === "<" && | ||
args[0].at(-1) === ">" | ||
) { | ||
// if there are exactly two args, the first of which looks like <${string}>, | ||
// treat as a generic | ||
const params = parseGenericParams(args[0].slice(1, -1)) | ||
const def = args[1] | ||
// TODO: validateUninstantiatedGeneric, remove this cast | ||
return new Generic(params, def, $ as never) as never | ||
} | ||
// otherwise, treat as a tuple expression. technically, this also allows | ||
// non-expression tuple definitions to be parsed, but it's not a supported | ||
// part of the API as specified by the associated types | ||
return $.parseRoot(args) | ||
}, | ||
{ bind: $, attach: typeParserAttachments } | ||
) | ||
} | ||
} | ||
export type DeclarationParser<$> = <preinferred>() => { | ||
@@ -83,36 +133,84 @@ // for some reason, making this a const parameter breaks preinferred validation | ||
export interface Type< | ||
/** @ts-expect-error allow instantiation assignment to the base type */ | ||
out t = unknown, | ||
$ = any | ||
> extends Schema<t, $> { | ||
and: (<def>( | ||
// this is declared as a class internally so we can ensure all "abstract" | ||
// methods of BaseRoot are overridden, but we end up exporting it as an interface | ||
// to ensure it is not accessed as a runtime value | ||
declare class _Type<t = unknown, $ = any> | ||
extends BaseRoot<t, $> | ||
implements internalImplementationOf<Schema> | ||
{ | ||
$: Scope<$>; | ||
get in(): Type<this["tIn"], $> | ||
get out(): Type<this["tOut"], $> | ||
intersect<def>( | ||
def: validateTypeRoot<def, $> | ||
) => Type<inferIntersection<t, inferTypeRoot<def, $>>, $>) & | ||
Schema<t, $>["and"] | ||
): Type<inferIntersection<t, inferTypeRoot<def, $>>> | Disjoint | ||
or: (<def>( | ||
and<def>( | ||
def: validateTypeRoot<def, $> | ||
) => Type<t | inferTypeRoot<def, $>, $>) & | ||
Schema<t, $>["or"] | ||
): Type<inferIntersection<t, inferTypeRoot<def, $>>, $> | ||
get in(): Type<distillConstrainableIn<t>, $> | ||
get out(): Type<distillConstrainableOut<t>, $> | ||
or<def>(def: validateTypeRoot<def, $>): Type<t | inferTypeRoot<def, $>, $> | ||
array(): Type<t[], $> | ||
morph: (<morph extends Morph<this["infer"]>, outValidatorDef = never>( | ||
morph: morph, | ||
outValidator?: validateTypeRoot<outValidatorDef, $> | ||
) => Type< | ||
( | ||
In: distillConstrainableIn<t> | ||
) => Out< | ||
[outValidatorDef] extends [never] ? inferMorphOut<morph> | ||
: distillConstrainableOut<inferTypeRoot<outValidatorDef, $>> | ||
>, | ||
$ | ||
>) & | ||
Schema<t, $>["morph"] | ||
keyof(): Type<keyof this["inferIn"], $> | ||
pipe<a extends Morph<this["infer"]>>(a: a): Type<inferPipes<t, [a]>, $> | ||
pipe<a extends Morph<this["infer"]>, b extends Morph<inferMorphOut<a>>>( | ||
a: a, | ||
b: b | ||
): Type<inferPipes<t, [a, b]>, $> | ||
pipe< | ||
a extends Morph<this["infer"]>, | ||
b extends Morph<inferMorphOut<a>>, | ||
c extends Morph<inferMorphOut<b>> | ||
>(a: a, b: b, c: c): Type<inferPipes<t, [a, b, c]>, $> | ||
pipe< | ||
a extends Morph<this["infer"]>, | ||
b extends Morph<inferMorphOut<a>>, | ||
c extends Morph<inferMorphOut<b>>, | ||
d extends Morph<inferMorphOut<c>> | ||
>(a: a, b: b, c: c, d: d): Type<inferPipes<t, [a, b, c, d]>, $> | ||
pipe< | ||
a extends Morph<this["infer"]>, | ||
b extends Morph<inferMorphOut<a>>, | ||
c extends Morph<inferMorphOut<b>>, | ||
d extends Morph<inferMorphOut<c>>, | ||
e extends Morph<inferMorphOut<d>> | ||
>(a: a, b: b, c: c, d: d, e: e): Type<inferPipes<t, [a, b, c, d, e]>, $> | ||
pipe< | ||
a extends Morph<this["infer"]>, | ||
b extends Morph<inferMorphOut<a>>, | ||
c extends Morph<inferMorphOut<b>>, | ||
d extends Morph<inferMorphOut<c>>, | ||
e extends Morph<inferMorphOut<d>>, | ||
f extends Morph<inferMorphOut<e>> | ||
>( | ||
a: a, | ||
b: b, | ||
c: c, | ||
d: d, | ||
e: e, | ||
f: f | ||
): Type<inferPipes<t, [a, b, c, d, e, f]>, $> | ||
pipe< | ||
a extends Morph<this["infer"]>, | ||
b extends Morph<inferMorphOut<a>>, | ||
c extends Morph<inferMorphOut<b>>, | ||
d extends Morph<inferMorphOut<c>>, | ||
e extends Morph<inferMorphOut<d>>, | ||
f extends Morph<inferMorphOut<e>>, | ||
g extends Morph<inferMorphOut<f>> | ||
>( | ||
a: a, | ||
b: b, | ||
c: c, | ||
d: d, | ||
e: e, | ||
f: f, | ||
g: g | ||
): Type<inferPipes<t, [a, b, c, d, e, f, g]>, $> | ||
// TODO: based on below, should maybe narrow morph output if used after | ||
@@ -123,3 +221,3 @@ narrow<def extends Predicate<distillConstrainableOut<t>>>( | ||
includesMorphs<t> extends true ? | ||
(In: distillIn<t>) => Out<inferNarrow<this["infer"], def>> | ||
(In: this["tIn"]) => Out<inferNarrow<this["infer"], def>> | ||
: inferNarrow<this["infer"], def>, | ||
@@ -129,2 +227,13 @@ $ | ||
equals<def>( | ||
def: validateTypeRoot<def, $> | ||
): this is Type<inferTypeRoot<def>, $> | ||
// TODO: i/o | ||
extract<def>(r: validateTypeRoot<def, $>): Type<t, $> | ||
exclude<def>(r: validateTypeRoot<def, $>): Type<t, $> | ||
extends<def>( | ||
other: validateTypeRoot<def, $> | ||
): this is Type<inferTypeRoot<def>, $> | ||
constrain< | ||
@@ -134,3 +243,3 @@ kind extends PrimitiveConstraintKind, | ||
>( | ||
kind: conform<kind, constraintKindOf<this["in"]["infer"]>>, | ||
kind: conform<kind, constraintKindOf<this["inferIn"]>>, | ||
def: def | ||
@@ -140,2 +249,8 @@ ): Type<constrain<t, kind, def>, $> | ||
export interface Type< | ||
/** @ts-expect-error allow instantiation assignment to the base type */ | ||
out t = unknown, | ||
$ = any | ||
> extends _Type<t, $> {} | ||
export type TypeConstructor<t = unknown, $ = any> = new ( | ||
@@ -142,0 +257,0 @@ def: unknown, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1144804
23222
+ Added@arktype/schema@0.0.8(transitive)
+ Added@arktype/util@0.0.34(transitive)
- Removed@arktype/schema@0.0.7(transitive)
- Removed@arktype/util@0.0.33(transitive)
Updated@arktype/schema@0.0.8
Updated@arktype/util@0.0.34