Skip to content

Commit

Permalink
more docs cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ssalbdivad committed Jun 12, 2024
1 parent 38f6b12 commit 6e88967
Show file tree
Hide file tree
Showing 15 changed files with 109 additions and 77 deletions.
24 changes: 12 additions & 12 deletions ark/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
"astro": "astro"
},
"dependencies": {
"arktype": "workspace:*",
"@arktype/fs": "workspace:*",
"@arktype/util": "workspace:*",
"@astrojs/react": "3.5.0",
"@astrojs/starlight": "0.24.2",
"@shikijs/twoslash": "1.6.4",
"arkdark": "workspace:*",
"@arktype/fs": "workspace:*",
"@astrojs/starlight": "0.23.1",
"@astrojs/react": "3.4.0",
"@shikijs/twoslash": "1.6.0",
"twoslash": "0.2.6",
"astro": "4.9.1",
"sharp": "0.33.4",
"shiki": "1.6.0",
"arktype": "workspace:*",
"astro": "4.10.2",
"astro-og-canvas": "0.5.0",
"canvaskit-wasm": "0.39.1",
"framer-motion": "11.2.10",
"react": "18.3.1",
"react-dom": "18.3.1",
"framer-motion": "11.2.6",
"astro-og-canvas": "0.5.0",
"canvaskit-wasm": "0.39.1"
"sharp": "0.33.4",
"shiki": "1.6.4",
"twoslash": "0.2.8"
},
"devDependencies": {
"@types/react": "18.3.3",
Expand Down
7 changes: 7 additions & 0 deletions ark/docs/src/assets/errorSquiggle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
51 changes: 23 additions & 28 deletions ark/docs/src/content/docs/intro/adding-constraints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ sidebar:
order: 3
---

:::caution[Under Construction]
We're still working on our new docs, as evidenced by the fact that they are not done.

Check back soon for more!
:::

TypeScript is extremely versatile for representing types like `string` or `number`, but what about `email` or `integer less than 100`?

In ArkType, conditions that narrow a type beyond its **basis** are called **constraints**.
Expand Down Expand Up @@ -82,28 +76,29 @@ type _Contact = typeof _contact.t
interface Contact extends _Contact {}

export const contact: Type<Contact> = _contact

const contacts = contact.array().atLeastLength(1)

const extractDuplicates = (arr: typeof contacts.infer) =>
Object.values(Object.groupBy(arr, contact => contact.email)).flatMap(
contactsWithEmail =>
contactsWithEmail && contactsWithEmail.length > 1 ?
contactsWithEmail[0].email
: []
)
// ---cut---
const uniqueContacts = contacts.narrow((arr, ctx) => {
// get a list of the duplicate emails
const duplicates = extractDuplicates(arr)

// return true if there are no duplicates
if (duplicates.length === 0) return true

// or false with a custom error message listing the duplicates
return ctx.invalid({
expected: "an array of unique contacts",
actual: `duplicated by ${duplicates}`
})
const goodContact = contact.narrow((data, ctx) => {
if (data.score > 75 || data.email.endsWith("@arktype.io")) {
return true
}
// add a customizable error and return false
return ctx.mustBe("a better contact")
})

const out = goodContact({
email: "[email protected]",
score: 60
})

if (out instanceof type.errors) {
console.error(out.summary)
} else {
console.log(out.email)
}
```

You now know how to refine your types to enforce additional constraints at runtime (see the full list [here](/reference/constraints)).

Once your input is fully validated, you still need to make some adjustments before it's ready to use in your code?

The final section of intro will cover **morphs**, an extremely powerful tool for composing and transforming Types.
11 changes: 11 additions & 0 deletions ark/docs/src/content/docs/intro/morphs-and-more.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Morphs & More
sidebar:
order: 4
---

:::caution[Under Construction]
We're still working on our new docs, as evidenced by the fact that they are not done.

Check back soon for more!
:::
2 changes: 1 addition & 1 deletion ark/docs/src/content/docs/intro/your-first-type.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ if (out instanceof type.errors) {

And that's it! You now know how to to define a `Type` use it to check your data at runtime.

Next, we'll take a look at how ArkType extends TypeScript's type system to handle common runtime constraints like `minLength` and `pattern`.
Next, we'll take a look at how ArkType extends TypeScript's type system to handle runtime constraints like `maxLength` and `pattern`.
3 changes: 3 additions & 0 deletions ark/docs/src/content/docs/reference/constraints.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
title: Constraints
---
4 changes: 3 additions & 1 deletion ark/docs/src/pages/og/[...slug].ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export const { getStaticPaths, GET } = OGImageRoute({
title: page.data.title === "ArkType" ? "ArkType" : "ArkType Docs",
description:
page.data.title === "ArkType" ? defaultDescription : page.data.title,
bgImage: { path: fromPackageRoot("src", "assets", "ogBg.png") },
bgImage: {
path: fromPackageRoot("src", "assets", "openGraphBackground.png")
},
font: {
title: {
families: ["Raleway"],
Expand Down
17 changes: 16 additions & 1 deletion ark/docs/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ starlight-theme-select,
white-space: pre !important;
}

.twoslash .twoslash-error {
/* Override the builtin error squiggle to match our theme */
background: url("/src/assets/errorSquiggle.svg") repeat-x bottom left;
}

.twoslash .twoslash-popup-code,
.twoslash .twoslash-popup-error,
.twoslash .twoslash-popup-docs {
padding: 0px !important;
}

.twoslash .twoslash-popup-code pre {
padding: 0.5rem;
}

.twoslash .twoslash-hover:hover .twoslash-popup-container,
.twoslash .twoslash-completion-cursor .twoslash-completion-list {
border-radius: 1rem;
Expand All @@ -108,7 +123,7 @@ starlight-theme-select,
box-shadow: var(--hover-glow);
}

/** used to display runtime errors on hover */
/** display runtime errors on hover */
.twoslash .twoslash-popup-docs {
color: #f85858;
font-size: small;
Expand Down
38 changes: 16 additions & 22 deletions ark/repo/scratch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,22 @@ type _Contact = typeof _contact.t
interface Contact extends _Contact {}

export const contact: Type<Contact> = _contact

const contacts = contact.array().atLeastLength(1)

const extractDuplicates = (arr: typeof contacts.infer) =>
Object.values(Object.groupBy(arr, contact => contact.email)).flatMap(
contactsWithEmail =>
contactsWithEmail && contactsWithEmail.length > 1 ?
contactsWithEmail[0].email
: []
)
// ---cut---
const goodContact = contact.narrow((data, ctx) => {
if (data.score > 75 || data.email.endsWith("@arktype.io")) {
return true
}
// add a customizable error and return false
return ctx.mustBe("a better contact")
})

const uniqueContacts = contacts.narrow((arr, ctx) => {
// get a list of the duplicate emails
const duplicates = extractDuplicates(arr)

// return true if there are no duplicates
if (duplicates.length === 0) return true

// or false with a custom error message listing the duplicates
return ctx.invalid({
expected: "an array of unique contacts",
actual: `duplicated by ${duplicates}`
})
const out = goodContact({
email: "[email protected]",
score: 60
})

if (out instanceof type.errors) {
console.error(out.summary)
} else {
console.log(`${out.email}: ${out.score}`)
}
8 changes: 4 additions & 4 deletions ark/schema/__tests__/morphs.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { attest, contextualize } from "@arktype/attest"
import { schema } from "@arktype/schema"
import { schema, tsKeywords } from "@arktype/schema"
import { wellFormedNumberMatcher } from "@arktype/util"

contextualize(() => {
Expand All @@ -24,11 +24,11 @@ contextualize(() => {
const n = schema([
{
in: "string",
morphs: (s: string) => Number.parseFloat(s)
morphs: [(s: string) => Number.parseFloat(s), tsKeywords.number]
},
"number"
])
attest(n.in.json).snap(["number", "string"])
attest(n.out.json).snap({})
attest(n.in.expression).snap("number | string")
attest(n.out.expression).snap("number")
})
})
7 changes: 6 additions & 1 deletion ark/schema/shared/traversal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,16 @@ export class TraversalContext {
return result
}

invalid(input: ArkErrorInput): false {
reject(input: ArkErrorInput): false {
this.error(input)
return false
}

mustBe(expected: string): false {
this.error(expected)
return false
}

pushBranch(): void {
this.branches.push({
error: undefined,
Expand Down
10 changes: 5 additions & 5 deletions ark/type/__tests__/narrow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ contextualize(() => {
const divisibleBy3 = type([
"number",
":",
(n, ctx) => n % 3 === 0 || ctx.invalid("divisible by 3")
(n, ctx) => n % 3 === 0 || ctx.reject("divisible by 3")
])
attest(divisibleBy3(1).toString()).snap("must be divisible by 3 (was 1)")
})

it("chained narrows", () => {
const divisibleBy30 = type("number")
.narrow((n, ctx) => n % 2 === 0 || ctx.invalid("divisible by 2"))
.narrow((n, ctx) => n % 3 === 0 || ctx.invalid("divisible by 3"))
.narrow((n, ctx) => n % 5 === 0 || ctx.invalid("divisible by 5"))
.narrow((n, ctx) => n % 2 === 0 || ctx.reject("divisible by 2"))
.narrow((n, ctx) => n % 3 === 0 || ctx.reject("divisible by 3"))
.narrow((n, ctx) => n % 5 === 0 || ctx.reject("divisible by 5"))

attest<number.narrowed>(divisibleBy30.t)

Expand Down Expand Up @@ -90,7 +90,7 @@ contextualize(() => {
"string",
":",
(s, ctx) =>
s === [...s].reverse().join("") ? true : ctx.invalid("a palindrome")
s === [...s].reverse().join("") ? true : ctx.reject("a palindrome")
])
attest<Type<string.narrowed>>(palindrome)
attest(palindrome("dad")).snap("dad")
Expand Down
2 changes: 1 addition & 1 deletion ark/type/__tests__/realWorld.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ nospace must be matched by ^\\S*$ (was "One space")`)
const Amount = type(
"string",
":",
(s, ctx) => Number.isInteger(Number(s)) || ctx.invalid("number")
(s, ctx) => Number.isInteger(Number(s)) || ctx.reject("number")
)
.pipe((s, ctx) => {
try {
Expand Down
2 changes: 1 addition & 1 deletion ark/type/__tests__/traverse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ isAdmin must be false, null or true (was 1)`)
}).narrow(
(d, ctx) =>
d.password === d.repeatPassword ||
ctx.invalid({
ctx.reject({
expected: "identical to password",
actual: null,
relativePath: ["repeatPassword"]
Expand Down

0 comments on commit 6e88967

Please sign in to comment.