+)
diff --git a/ark/fuma/components/AutoplayDemo.tsx b/ark/docs/components/AutoplayDemo.tsx
similarity index 95%
rename from ark/fuma/components/AutoplayDemo.tsx
rename to ark/docs/components/AutoplayDemo.tsx
index b6f09ae322..63408785a5 100644
--- a/ark/fuma/components/AutoplayDemo.tsx
+++ b/ark/docs/components/AutoplayDemo.tsx
@@ -1,5 +1,3 @@
-import React from "react"
-
export type AutoplayDemoProps = React.DetailedHTMLProps<
React.VideoHTMLAttributes,
HTMLVideoElement
diff --git a/ark/docs/components/Badge.tsx b/ark/docs/components/Badge.tsx
new file mode 100644
index 0000000000..cde16b24de
--- /dev/null
+++ b/ark/docs/components/Badge.tsx
@@ -0,0 +1,31 @@
+import { cva, type VariantProps } from "class-variance-authority"
+import { cn } from "fumadocs-ui/components/api"
+import * as React from "react"
+
+export const badgeVariants = cva(
+ "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
+ outline: "text-foreground"
+ }
+ },
+ defaultVariants: {
+ variant: "default"
+ }
+ }
+)
+
+export interface BadgeProps
+ extends React.HTMLAttributes,
+ VariantProps {}
+
+export const Badge = ({ className, variant, ...props }: BadgeProps) => (
+
+)
diff --git a/ark/docs/components/CodeBlock.tsx b/ark/docs/components/CodeBlock.tsx
new file mode 100644
index 0000000000..9c99ada6ca
--- /dev/null
+++ b/ark/docs/components/CodeBlock.tsx
@@ -0,0 +1,91 @@
+import type { propwiseXor } from "@ark/util"
+import type { HighlightOptions } from "fumadocs-core/server"
+import { Popup, PopupContent, PopupTrigger } from "fumadocs-twoslash/ui"
+import { cn } from "fumadocs-ui/components/api"
+import {
+ CodeBlock as FumaCodeBlock,
+ Pre
+} from "fumadocs-ui/components/codeblock"
+import { toJsxRuntime } from "hast-util-to-jsx-runtime"
+import { Fragment, jsx, jsxs } from "react/jsx-runtime"
+import { getSingletonHighlighter } from "shiki"
+import { shikiConfig, type BuiltinLang } from "../lib/shiki.ts"
+import type { SnippetId } from "../lib/writeSnippetsEntrypoint.ts"
+import snippetContentsById from "./snippets/contentsById.ts"
+
+export type CodeBlockProps = {
+ /** @default "ts" */
+ lang?: BuiltinLang
+ style?: React.CSSProperties
+ className?: string
+ includesCompletions?: boolean
+} & propwiseXor<{ children: string }, { fromFile: SnippetId }>
+
+// preload languages for shiki
+// https://github.com/fuma-nama/fumadocs/issues/1095
+const highlighter = await getSingletonHighlighter({
+ langs: shikiConfig.langs,
+ themes: [shikiConfig.themes.dark]
+})
+
+const components: HighlightOptions["components"] = {
+ // rounded none is for syntax tabs
+ pre: ({ className, children, ...props }) => (
+
+ {children}
+
+ )
+}
+
+// overriding these custom components allows hovers to render
+// correctly in code blocks outside markdown (e.g. on the home page)
+Object.assign(components, {
+ Popup,
+ PopupContent,
+ PopupTrigger
+})
+
+export const CodeBlock: React.FC = ({
+ lang = "ts",
+ children,
+ fromFile,
+ style,
+ className,
+ includesCompletions
+}) => {
+ children ??= snippetContentsById[fromFile!]
+
+ const highlighted = highlight(lang, children)
+
+ return (
+
+ {highlighted}
+
+ )
+}
+
+const highlight = (lang: BuiltinLang, contents: string) => {
+ try {
+ const hast = highlighter.codeToHast(contents, {
+ ...shikiConfig,
+ lang
+ })
+
+ return toJsxRuntime(hast, {
+ Fragment,
+ jsx,
+ jsxs,
+ components
+ })
+ } catch (e) {
+ console.error(`Failed to transform the following code:\n${contents}`)
+ throw e
+ }
+}
diff --git a/ark/fuma/components/FloatYourBoat.tsx b/ark/docs/components/FloatYourBoat.tsx
similarity index 83%
rename from ark/fuma/components/FloatYourBoat.tsx
rename to ark/docs/components/FloatYourBoat.tsx
index 28729d4abf..9e5b5ad1b9 100644
--- a/ark/fuma/components/FloatYourBoat.tsx
+++ b/ark/docs/components/FloatYourBoat.tsx
@@ -1,16 +1,16 @@
"use client"
import { motion } from "framer-motion"
-import React from "react"
+import { useLayoutEffect, useMemo, useState } from "react"
import { BoatIcon } from "./icons/boat.tsx"
const BOB_HEIGHT_PX = 2
const BOB_WIDTH_PX = 16
export const FloatYourBoat = () => {
- const [loopDuration, setLoopDuration] = React.useState(null)
+ const [loopDuration, setLoopDuration] = useState(null)
- const bobFrames = React.useMemo(() => {
+ const bobFrames = useMemo(() => {
if (!loopDuration) return []
const frames: number[] = []
for (let i = 0; i < loopDuration; i++)
@@ -18,7 +18,7 @@ export const FloatYourBoat = () => {
return frames
}, [loopDuration])
- React.useLayoutEffect(() => {
+ useLayoutEffect(() => {
const width = window.innerWidth
setLoopDuration(width / BOB_WIDTH_PX)
}, [])
diff --git a/ark/fuma/components/Hero.tsx b/ark/docs/components/Hero.tsx
similarity index 100%
rename from ark/fuma/components/Hero.tsx
rename to ark/docs/components/Hero.tsx
diff --git a/ark/docs/components/InstallationTabs.tsx b/ark/docs/components/InstallationTabs.tsx
new file mode 100644
index 0000000000..fed0b31f3c
--- /dev/null
+++ b/ark/docs/components/InstallationTabs.tsx
@@ -0,0 +1,25 @@
+import { Tab, Tabs } from "fumadocs-ui/components/tabs"
+import { CodeBlock } from "./CodeBlock.tsx"
+
+const installers = ["pnpm", "npm", "yarn", "bun"] as const satisfies string[]
+
+export type Installer = (typeof installers)[number]
+
+type InstallationTabProps = {
+ name: Installer
+}
+
+const InstallerTab = ({ name }: InstallationTabProps) => (
+
+ {`${name} install arktype`}
+
+)
+
+export const InstallationTabs = () => (
+
+
+
+
+
+
+)
diff --git a/ark/fuma/components/LinkCard.tsx b/ark/docs/components/LinkCard.tsx
similarity index 100%
rename from ark/fuma/components/LinkCard.tsx
rename to ark/docs/components/LinkCard.tsx
diff --git a/ark/fuma/components/PlatformCloud.tsx b/ark/docs/components/PlatformCloud.tsx
similarity index 100%
rename from ark/fuma/components/PlatformCloud.tsx
rename to ark/docs/components/PlatformCloud.tsx
diff --git a/ark/fuma/components/RuntimeBenchmarksGraph.tsx b/ark/docs/components/RuntimeBenchmarksGraph.tsx
similarity index 98%
rename from ark/fuma/components/RuntimeBenchmarksGraph.tsx
rename to ark/docs/components/RuntimeBenchmarksGraph.tsx
index 9d0e7e2c3d..09e82fb9f2 100644
--- a/ark/fuma/components/RuntimeBenchmarksGraph.tsx
+++ b/ark/docs/components/RuntimeBenchmarksGraph.tsx
@@ -1,5 +1,4 @@
import { cn } from "fumadocs-ui/components/api"
-import React from "react"
const barStyles: React.CSSProperties = {
height: "30px",
diff --git a/ark/fuma/components/SyntaxTabs.tsx b/ark/docs/components/SyntaxTabs.tsx
similarity index 67%
rename from ark/fuma/components/SyntaxTabs.tsx
rename to ark/docs/components/SyntaxTabs.tsx
index 1954f2083e..4abcf27091 100644
--- a/ark/fuma/components/SyntaxTabs.tsx
+++ b/ark/docs/components/SyntaxTabs.tsx
@@ -1,6 +1,6 @@
import type { omit, unionToPropwiseXor } from "@ark/util"
import { Tab, Tabs, type TabsProps } from "fumadocs-ui/components/tabs"
-import type React from "react"
+import { Children, isValidElement, type FC } from "react"
export const syntaxKinds = [
"string",
@@ -16,7 +16,17 @@ export const SyntaxTabs: React.FC> = ({
children,
...rest
}) => (
-
+
+ Children.toArray(children).some(
+ child =>
+ isValidElement(child) &&
+ (child.props as SyntaxTabProps | undefined)?.[kind]
+ )
+ )}
+ >
{children}
)
@@ -31,6 +41,6 @@ type SyntaxTabProps = DiscriminatedSyntaxKindProps & {
children: React.ReactNode
}
-export const SyntaxTab: React.FC = props => (
+export const SyntaxTab: FC = props => (
props[k])!}>{props.children}
)
diff --git a/ark/fuma/components/icons/arktype-logo.tsx b/ark/docs/components/icons/arktype-logo.tsx
similarity index 100%
rename from ark/fuma/components/icons/arktype-logo.tsx
rename to ark/docs/components/icons/arktype-logo.tsx
diff --git a/ark/fuma/components/icons/boat.tsx b/ark/docs/components/icons/boat.tsx
similarity index 100%
rename from ark/fuma/components/icons/boat.tsx
rename to ark/docs/components/icons/boat.tsx
diff --git a/ark/fuma/components/icons/bun.tsx b/ark/docs/components/icons/bun.tsx
similarity index 100%
rename from ark/fuma/components/icons/bun.tsx
rename to ark/docs/components/icons/bun.tsx
diff --git a/ark/fuma/components/icons/chromium.tsx b/ark/docs/components/icons/chromium.tsx
similarity index 100%
rename from ark/fuma/components/icons/chromium.tsx
rename to ark/docs/components/icons/chromium.tsx
diff --git a/ark/fuma/components/icons/deno.tsx b/ark/docs/components/icons/deno.tsx
similarity index 100%
rename from ark/fuma/components/icons/deno.tsx
rename to ark/docs/components/icons/deno.tsx
diff --git a/ark/fuma/components/icons/intellij.tsx b/ark/docs/components/icons/intellij.tsx
similarity index 100%
rename from ark/fuma/components/icons/intellij.tsx
rename to ark/docs/components/icons/intellij.tsx
diff --git a/ark/fuma/components/icons/js.tsx b/ark/docs/components/icons/js.tsx
similarity index 100%
rename from ark/fuma/components/icons/js.tsx
rename to ark/docs/components/icons/js.tsx
diff --git a/ark/fuma/components/icons/neovim.tsx b/ark/docs/components/icons/neovim.tsx
similarity index 100%
rename from ark/fuma/components/icons/neovim.tsx
rename to ark/docs/components/icons/neovim.tsx
diff --git a/ark/fuma/components/icons/node.tsx b/ark/docs/components/icons/node.tsx
similarity index 100%
rename from ark/fuma/components/icons/node.tsx
rename to ark/docs/components/icons/node.tsx
diff --git a/ark/fuma/components/icons/npm.tsx b/ark/docs/components/icons/npm.tsx
similarity index 100%
rename from ark/fuma/components/icons/npm.tsx
rename to ark/docs/components/icons/npm.tsx
diff --git a/ark/fuma/components/icons/ts.tsx b/ark/docs/components/icons/ts.tsx
similarity index 100%
rename from ark/fuma/components/icons/ts.tsx
rename to ark/docs/components/icons/ts.tsx
diff --git a/ark/fuma/components/icons/vscode.tsx b/ark/docs/components/icons/vscode.tsx
similarity index 100%
rename from ark/fuma/components/icons/vscode.tsx
rename to ark/docs/components/icons/vscode.tsx
diff --git a/ark/docs/src/content/docs/snippets/betterErrors.twoslash.ts b/ark/docs/components/snippets/betterErrors.twoslash.ts
similarity index 100%
rename from ark/docs/src/content/docs/snippets/betterErrors.twoslash.ts
rename to ark/docs/components/snippets/betterErrors.twoslash.ts
diff --git a/ark/docs/src/content/docs/snippets/clarityAndConcision.twoslash.js b/ark/docs/components/snippets/clarityAndConcision.twoslash.js
similarity index 100%
rename from ark/docs/src/content/docs/snippets/clarityAndConcision.twoslash.js
rename to ark/docs/components/snippets/clarityAndConcision.twoslash.js
diff --git a/ark/docs/components/snippets/contentsById.ts b/ark/docs/components/snippets/contentsById.ts
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ark/docs/src/content/docs/snippets/deepIntrospectability.twoslash.js b/ark/docs/components/snippets/deepIntrospectability.twoslash.js
similarity index 100%
rename from ark/docs/src/content/docs/snippets/deepIntrospectability.twoslash.js
rename to ark/docs/components/snippets/deepIntrospectability.twoslash.js
diff --git a/ark/docs/src/content/docs/snippets/intrinsicOptimization.twoslash.js b/ark/docs/components/snippets/intrinsicOptimization.twoslash.js
similarity index 100%
rename from ark/docs/src/content/docs/snippets/intrinsicOptimization.twoslash.js
rename to ark/docs/components/snippets/intrinsicOptimization.twoslash.js
diff --git a/ark/docs/src/content/docs/snippets/unparalleledDx.twoslash.js b/ark/docs/components/snippets/unparalleledDx.twoslash.js
similarity index 100%
rename from ark/docs/src/content/docs/snippets/unparalleledDx.twoslash.js
rename to ark/docs/components/snippets/unparalleledDx.twoslash.js
diff --git a/ark/docs/src/content/docs/about.mdx b/ark/docs/content/docs/about.mdx
similarity index 100%
rename from ark/docs/src/content/docs/about.mdx
rename to ark/docs/content/docs/about.mdx
diff --git a/ark/docs/content/docs/auto.mdx b/ark/docs/content/docs/auto.mdx
new file mode 100644
index 0000000000..373ce1fcfe
--- /dev/null
+++ b/ark/docs/content/docs/auto.mdx
@@ -0,0 +1,7 @@
+---
+title: AutoDocs
+---
+
+import { AutoDocs } from "../../components/AutoDocs.tsx"
+
+
diff --git a/ark/docs/src/content/docs/configuration.mdx b/ark/docs/content/docs/configuration/index.mdx
similarity index 100%
rename from ark/docs/src/content/docs/configuration.mdx
rename to ark/docs/content/docs/configuration/index.mdx
diff --git a/ark/fuma/content/docs/configuration/meta.json b/ark/docs/content/docs/configuration/meta.json
similarity index 100%
rename from ark/fuma/content/docs/configuration/meta.json
rename to ark/docs/content/docs/configuration/meta.json
diff --git a/ark/fuma/content/docs/definitions.mdx b/ark/docs/content/docs/definitions.mdx
similarity index 98%
rename from ark/fuma/content/docs/definitions.mdx
rename to ark/docs/content/docs/definitions.mdx
index 6584ad3550..1248c114d0 100644
--- a/ark/fuma/content/docs/definitions.mdx
+++ b/ark/docs/content/docs/definitions.mdx
@@ -8,7 +8,7 @@ import { SyntaxTab, SyntaxTabs } from "../../components/SyntaxTabs.tsx"
### Kitchen Sink
-```ts twoslash
+```ts
export const currentTsSyntax = type({
keyword: "null",
stringLiteral: "'TS'",
@@ -37,7 +37,7 @@ export const currentTsSyntax = type({
## Constraints
-```ts twoslash
+```ts
// runtime-specific syntax and builtin keywords with great error messages
export const validationSyntax = type({
diff --git a/ark/fuma/content/docs/expressions/index.mdx b/ark/docs/content/docs/expressions/index.mdx
similarity index 100%
rename from ark/fuma/content/docs/expressions/index.mdx
rename to ark/docs/content/docs/expressions/index.mdx
diff --git a/ark/fuma/content/docs/expressions/meta.json b/ark/docs/content/docs/expressions/meta.json
similarity index 100%
rename from ark/fuma/content/docs/expressions/meta.json
rename to ark/docs/content/docs/expressions/meta.json
diff --git a/ark/docs/src/content/docs/faq.mdx b/ark/docs/content/docs/faq.mdx
similarity index 100%
rename from ark/docs/src/content/docs/faq.mdx
rename to ark/docs/content/docs/faq.mdx
diff --git a/ark/docs/src/content/docs/generics.mdx b/ark/docs/content/docs/generics/index.mdx
similarity index 99%
rename from ark/docs/src/content/docs/generics.mdx
rename to ark/docs/content/docs/generics/index.mdx
index a355d869fa..9c69a2835d 100644
--- a/ark/docs/src/content/docs/generics.mdx
+++ b/ark/docs/content/docs/generics/index.mdx
@@ -1,7 +1,5 @@
---
title: Generics
-sidebar:
- order: 3
---
### Keywords
@@ -32,6 +30,7 @@ const createBox = (of: type.Any) =>
})
const boxType = createBox(type("string"))
+// ^?
// @ts-expect-error
const badBox = createBox(type("number"))
diff --git a/ark/fuma/content/docs/generics/meta.json b/ark/docs/content/docs/generics/meta.json
similarity index 87%
rename from ark/fuma/content/docs/generics/meta.json
rename to ark/docs/content/docs/generics/meta.json
index 01e6a02103..4fbbc987d2 100644
--- a/ark/fuma/content/docs/generics/meta.json
+++ b/ark/docs/content/docs/generics/meta.json
@@ -1,5 +1,6 @@
{
"title": "Generics",
+ "icon": "Advanced",
"pages": [
"[keywords](/docs/generics#keywords)",
"[syntax](/docs/generics#syntax)",
diff --git a/ark/docs/src/content/docs/integrations.mdx b/ark/docs/content/docs/integrations/index.mdx
similarity index 100%
rename from ark/docs/src/content/docs/integrations.mdx
rename to ark/docs/content/docs/integrations/index.mdx
diff --git a/ark/fuma/content/docs/integrations/meta.json b/ark/docs/content/docs/integrations/meta.json
similarity index 100%
rename from ark/fuma/content/docs/integrations/meta.json
rename to ark/docs/content/docs/integrations/meta.json
diff --git a/ark/docs/src/content/docs/intro/adding-constraints.mdx b/ark/docs/content/docs/intro/adding-constraints.mdx
similarity index 97%
rename from ark/docs/src/content/docs/intro/adding-constraints.mdx
rename to ark/docs/content/docs/intro/adding-constraints.mdx
index 3ff357a7df..7046b1ed0d 100644
--- a/ark/docs/src/content/docs/intro/adding-constraints.mdx
+++ b/ark/docs/content/docs/intro/adding-constraints.mdx
@@ -10,8 +10,6 @@ In ArkType, conditions that narrow a type beyond its **basis** are called **cons
Constraints are a first-class citizen of ArkType. They are fully composable with TypeScript's built-in operators and governed by the same underlying principles of set-theory.
-In other words, **they just work**.
-
## Define
Let's create a new `contact` Type that enforces our example constraints.
@@ -45,8 +43,9 @@ type _Contact = typeof _contact.t
interface Contact extends _Contact {}
export const contact: type = _contact
-// ---cut---
+// ---cut-start---
// a non-empty list of Contact
+// ---cut-end---
const contacts = contact.array().atLeastLength(1)
```
@@ -96,11 +95,12 @@ score (133.7) must be...
}
const narrowMessage = (e: type.errors): e is RuntimeErrors => true
-// ---cut---
+// ---cut-start---
const out = palindromicContact({
email: "david@arktype.io",
score: 133.7
})
+// ---cut-end---
if (out instanceof type.errors) {
// ---cut-start---
diff --git a/ark/docs/content/docs/intro/meta.json b/ark/docs/content/docs/intro/meta.json
new file mode 100644
index 0000000000..a0ace20283
--- /dev/null
+++ b/ark/docs/content/docs/intro/meta.json
@@ -0,0 +1,5 @@
+{
+ "title": "Intro",
+ "defaultOpen": true,
+ "pages": ["setup", "your-first-type", "adding-constraints", "morphs-and-more"]
+}
diff --git a/ark/docs/src/content/docs/intro/morphs-and-more.mdx b/ark/docs/content/docs/intro/morphs-and-more.mdx
similarity index 100%
rename from ark/docs/src/content/docs/intro/morphs-and-more.mdx
rename to ark/docs/content/docs/intro/morphs-and-more.mdx
diff --git a/ark/fuma/content/docs/intro/setup.mdx b/ark/docs/content/docs/intro/setup.mdx
similarity index 79%
rename from ark/fuma/content/docs/intro/setup.mdx
rename to ark/docs/content/docs/intro/setup.mdx
index 929906ee6e..605fae4cd9 100644
--- a/ark/fuma/content/docs/intro/setup.mdx
+++ b/ark/docs/content/docs/intro/setup.mdx
@@ -5,24 +5,11 @@ sidebar:
---
import { Tab, Tabs } from "fumadocs-ui/components/tabs"
-import { CodeBlock } from "../../../components/CodeBlock.tsx"
+import { InstallationTabs } from "../../../components/InstallationTabs.tsx"
## Installation
-
-
- pnpm install arktype
-
-
- npm install arktype
-
-
- yarn install arktype
-
-
- bun install arktype
-
-
+
You'll also need...
diff --git a/ark/fuma/content/docs/intro/your-first-type.mdx b/ark/docs/content/docs/intro/your-first-type.mdx
similarity index 97%
rename from ark/fuma/content/docs/intro/your-first-type.mdx
rename to ark/docs/content/docs/intro/your-first-type.mdx
index 931b4aabd9..69723b2317 100644
--- a/ark/fuma/content/docs/intro/your-first-type.mdx
+++ b/ark/docs/content/docs/intro/your-first-type.mdx
@@ -8,7 +8,7 @@ If you already know TypeScript, congratulations- you just learned most of ArkTyp
## Define
-```ts twoslash
+```ts
import { type } from "arktype"
const user = type({
@@ -32,7 +32,7 @@ If you make a mistake, don't worry- every definition gets the autocomplete and v
Suppose we want to move `platform` and `version` from our original type to a new `device` property.
-```ts twoslash
+```ts
const user = type({
name: "string",
// nested definitions don't need to be wrapped
@@ -45,7 +45,7 @@ const user = type({
To decouple `device` from `user`, just move it to its own type and reference it.
-```ts twoslash
+```ts
const device = type({
platform: "'android' | 'ios'",
"versions?": "(number | string)[]"
@@ -61,7 +61,7 @@ const user = type({
At runtime, we can pass `unknown` data to our type and get back either a validated `User` or an array of clear, customizable errors with a root `summary`.
-```ts twoslash
+```ts
const user = type({
name: "string",
device: {
diff --git a/ark/fuma/content/docs/keywords.mdx b/ark/docs/content/docs/keywords.mdx
similarity index 80%
rename from ark/fuma/content/docs/keywords.mdx
rename to ark/docs/content/docs/keywords.mdx
index ef5221ad64..86bb95405a 100644
--- a/ark/fuma/content/docs/keywords.mdx
+++ b/ark/docs/content/docs/keywords.mdx
@@ -2,15 +2,19 @@
title: Keywords
---
+import { Asterisk } from "../../components/Asterisk.tsx"
import { SyntaxTab, SyntaxTabs } from "../../components/SyntaxTabs.tsx"
### TypeScript
-All\* builtin TypeScript keywords are directly available.
+
+ All
+ builtin TypeScript keywords are directly available.
+
-```ts twoslash
+```ts
const keywords = type({
string: "string",
date: "Date"
@@ -20,7 +24,7 @@ const keywords = type({
-```ts twoslash
+```ts
const keywords = type({
string: type.string,
date: type.Date
@@ -33,13 +37,18 @@ Common keywords are exposed directly on `type`.
+
+ `any` and `void` are misleading and unnecessary for runtime
+ validation and so are not included as keywords by default.
+
+
### Subtype
Subtype keywords refine or transform their root type.
-```ts twoslash
+```ts
const keywords = type({
dateFormattedString: "string.date",
transformStringToDate: "string.date.parse",
@@ -54,7 +63,7 @@ You can easily explore available subtypes via autocomplete by with a partial def
-```ts twoslash
+```ts
const keywords = type({
dateFormattedString: type.keywords.string.date.root,
isoFormattedString: type.keywords.string.date.iso.root,
diff --git a/ark/docs/content/docs/meta.json b/ark/docs/content/docs/meta.json
new file mode 100644
index 0000000000..bafe11247e
--- /dev/null
+++ b/ark/docs/content/docs/meta.json
@@ -0,0 +1,16 @@
+{
+ "pages": [
+ "intro",
+ "primitives",
+ "objects",
+ "keywords",
+ "expressions",
+ "type-api",
+ "configuration",
+ "integrations",
+ "scopes",
+ "generics",
+ "faq",
+ "about"
+ ]
+}
diff --git a/ark/docs/content/docs/objects/arrays/meta.json b/ark/docs/content/docs/objects/arrays/meta.json
new file mode 100644
index 0000000000..36ff60b1bb
--- /dev/null
+++ b/ark/docs/content/docs/objects/arrays/meta.json
@@ -0,0 +1,11 @@
+{
+ "title": "arrays and tuples",
+ "pages": [
+ "lengths",
+ "[prefix](/docs/objects#arrays/prefix)",
+ "[optional](/docs/objects#arrays/optional)",
+ "[defaultable](/docs/objects#arrays/defaultable)",
+ "[variadic](/docs/objects#arrays/variadic)",
+ "[postfix](/docs/objects#arrays/postfix)"
+ ]
+}
diff --git a/ark/fuma/content/docs/objects/index.mdx b/ark/docs/content/docs/objects/index.mdx
similarity index 77%
rename from ark/fuma/content/docs/objects/index.mdx
rename to ark/docs/content/docs/objects/index.mdx
index 2fc6425fa7..822d17fb85 100644
--- a/ark/fuma/content/docs/objects/index.mdx
+++ b/ark/docs/content/docs/objects/index.mdx
@@ -8,10 +8,9 @@ import { SyntaxTab, SyntaxTabs } from "../../../components/SyntaxTabs.tsx"
Objects definitions can include any combination of required, optional, defaultable named properties and index signatures.
-
-##### required
+### required [#properties-required]
-
+
```ts
@@ -44,12 +43,11 @@ const myObject = type({
-
+
-
-##### optional
+### optional [#properties-optional]
-
+
```ts
@@ -102,36 +100,36 @@ const myObject = type({
-
+
+
+
-:::caution[Optional properties cannot be present with the value undefined]
+ In TypeScript, there is a setting called [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes) that can be set to `true` to enforce the distinction between properties that are missing and properties that are present with the value `undefined`.
-In TypeScript, there is a setting called `exactOptionalPropertyTypes` that can be set to `true` to enforce the distinction between properties that are missing and properties that are present with the value `undefined`.
+ ArkType mirrors this behavior by default, so if you want to allow `undefined`, you'll need to add it to your value's definition. If you're interested in a builtin configuration option for this setting, we'd love feedback or contributions on [this issue](https://github.com/arktypeio/arktype/issues/1191).
-ArkType mirrors this behavior by default, so if you want to allow `undefined`, you'll need to add it to your value's definition. If you're interested in a builtin configuration option for this setting, we'd love feedback or contributions on [this issue](https://github.com/arktypeio/arktype/issues/1191).
+
+ See an example
-
- See an example
+ ```ts
+ const myObj = type({
+ "key?": "number"
+ })
-```ts
-const myObj = type({
- "key?": "number"
-})
+ // valid data
+ const validResult = myObj({})
-// valid data
-const validResult = myObj({})
+ // Error: key must be a number (was undefined)
+ const errorResult = myObj({ key: undefined })
+ ```
-// Error: key must be a number (was undefined)
-const errorResult = myObj({ key: undefined })
-```
+
-
-:::
+
-
-##### defaultable
+### defaultable [#properties-defaultable]
-
+
```ts
@@ -162,23 +160,24 @@ const myObject = type({
-
+
-:::caution[Optional and default only work within objects and tuples!]
-Unlike e.g. `number.array()`, `number.optional()` and `number.default(0)` don't return a new `Type`, but rather a tuple definition like `[Type, "?"]` or `[Type, "=", 0]`.
+
+ Unlike e.g. `number.array()`, `number.optional()` and `number.default(0)` don't return a new `Type`, but rather a tuple definition like `[Type, "?"]` or `[Type, "=", 0]`.
-This reflects the fact that in ArkType's type system, optionality and defaultability are only meaningful in reference to a property. Attempting to create an optional or defaultable value outside an object like `type("string?")` will result in a `ParseError`.
+ This reflects the fact that in ArkType's type system, optionality and defaultability are only meaningful in reference to a property. Attempting to create an optional or defaultable value outside an object like `type("string?")` will result in a `ParseError`.
-To create a `Type` accepting `string` or `undefined`, use a union like `type("string | undefined")`.
+ To create a `Type` accepting `string` or `undefined`, use a union like `type("string | undefined")`.
-To have it transform `undefined` to an empty string, use an explicit morph like:
+ To have it transform `undefined` to an empty string, use an explicit morph like:
-```ts
-const fallbackString = type("string | undefined").pipe(v => v ?? "")
-```
+ ```ts
+ const fallbackString = type("string | undefined").pipe(v => v ?? "")
+ ```
-
-##### index
+
+
+### index [#properties-index]
@@ -196,23 +195,19 @@ const myObject = type({
-
-##### undeclared
+### undeclared [#properties-undeclared]
🚧 Coming soon ™️🚧
-
-##### merge
+### merge [#properties-merge]
🚧 Coming soon ™️🚧
-
-##### keyof
+### keyof [#properties-keyof]
🚧 Coming soon ™️🚧
-
-##### get
+### get [#properties-get]
🚧 Coming soon ™️🚧
@@ -261,8 +256,7 @@ const arrays = type({
-
-##### lengths
+### lengths [#arrays-lengths]
Constrain an array with an inclusive or exclusive min or max length.
@@ -332,8 +326,7 @@ const range = type({
Like objects, tuples are structures whose values are nested definitions. Like TypeScript, ArkType supports prefix, optional, variadic, and postfix elements, with the same restrictions about combining them.
-
-##### prefix
+### prefix [#tuples-prefix]
@@ -366,8 +359,11 @@ const myTuple = type([
-
-##### optional
+### defaultable [#tuples-defaultable]
+
+🚧 Coming soon ™️🚧
+
+### optional [#tuples-optional]
Tuples can include any number of optional elements following its prefix elements.
@@ -428,8 +424,7 @@ const myTuple = type([
-
-##### variadic
+### variadic [#tuples-variadic]
Like in TypeScript, variadic elements allow zero or more consecutive values of a given type and may occur at most once in a tuple.
@@ -456,8 +451,7 @@ const myTuple = type([type.string, "...", type.number.array()])
-
-##### postfix
+### postfix [#tuples-postfix]
Postfix elements are required elements following a variadic element.
@@ -486,8 +480,7 @@ const myTuple = type(["...", type.number.array(), type.boolean, type.string])
## dates
-
-##### literals
+### literals [#dates-literals]
Date literals represent a Date instance with an exact value.
@@ -500,8 +493,7 @@ const literals = type({
})
```
-
-##### ranges
+### ranges [#dates-ranges]
Constrain a Date with an inclusive or exclusive min or max.
@@ -608,7 +600,6 @@ const instances = type({
-
-##### keywords
+### keywords [#instanceof-keywords]
🚧 Coming soon ™️🚧
diff --git a/ark/fuma/content/docs/objects/meta.json b/ark/docs/content/docs/objects/meta.json
similarity index 50%
rename from ark/fuma/content/docs/objects/meta.json
rename to ark/docs/content/docs/objects/meta.json
index ab5e6366aa..e820fe437e 100644
--- a/ark/fuma/content/docs/objects/meta.json
+++ b/ark/docs/content/docs/objects/meta.json
@@ -1,9 +1,9 @@
{
"title": "Objects",
+ "defaultOpen": true,
"pages": [
- "[properties](/docs/objects#properties)",
- "[arrays](/docs/objects#arrays)",
- "[tuples](/docs/objects#tuples)",
+ "properties",
+ "arrays",
"[dates](/docs/objects#dates)",
"[instanceof](/docs/objects#instanceof)"
]
diff --git a/ark/docs/content/docs/objects/properties/meta.json b/ark/docs/content/docs/objects/properties/meta.json
new file mode 100644
index 0000000000..aa27b3ae6b
--- /dev/null
+++ b/ark/docs/content/docs/objects/properties/meta.json
@@ -0,0 +1,13 @@
+{
+ "title": "properties",
+ "pages": [
+ "[required](/docs/objects#properties/required)",
+ "[optional](/docs/objects#properties/optional)",
+ "[defaultable](/docs/objects#properties/defaultable)",
+ "[index](/docs/objects#properties/index)",
+ "[undeclared](/docs/objects#properties/undeclared)",
+ "[merge](/docs/objects#properties/merge)",
+ "[keyof](/docs/objects#properties/keyof)",
+ "[get](/docs/objects#properties/get)"
+ ]
+}
diff --git a/ark/docs/src/content/docs/primitives.mdx b/ark/docs/content/docs/primitives/index.mdx
similarity index 81%
rename from ark/docs/src/content/docs/primitives.mdx
rename to ark/docs/content/docs/primitives/index.mdx
index 20558e9f94..01cc1b2213 100644
--- a/ark/docs/src/content/docs/primitives.mdx
+++ b/ark/docs/content/docs/primitives/index.mdx
@@ -2,18 +2,15 @@
title: Primitives
---
-import { Tabs } from "@astrojs/starlight/components"
-import SyntaxTab from "../../components/SyntaxTab.astro"
+import { SyntaxTab, SyntaxTabs } from "../../../components/SyntaxTabs.tsx"
## string
-
-##### keywords
+### keywords [#string-keywords]
🚧 Coming soon ™️🚧
-
-##### literals
+### literals [#string-literals]
```ts
const literals = type({
@@ -22,8 +19,7 @@ const literals = type({
})
```
-
-##### patterns
+### patterns [#string-patterns]
Regex literals specify an unanchored regular expression that an input string must match.
@@ -37,11 +33,11 @@ const literals = type({
```
-##### lengths
+### lengths [#string-lengths]
Constrain a string with an inclusive or exclusive min or max length.
-
+
```ts
@@ -68,11 +64,11 @@ const bounded = type({
-
+
Range expressions allow you to specify both a min and max length and use the same syntax for exclusivity.
-
+
```ts
@@ -97,17 +93,15 @@ const range = type({
-
+
## number
-
-##### keywords
+### keywords [#number-keywords]
🚧 Coming soon ™️🚧
-
-##### literals
+### literals [#number-literals]
```ts
const literals = type({
@@ -115,12 +109,11 @@ const literals = type({
})
```
-
-##### ranges
+### ranges [#number-ranges]
Constrain a number with an inclusive or exclusive min or max.
-
+
```ts
@@ -147,11 +140,11 @@ const bounded = type({
-
+
Range expressions allow you to specify both a min and max and use the same syntax for exclusivity.
-
+
```ts
@@ -177,14 +170,13 @@ const range = type({
-
+
-
-##### divisors
+### divisors [#number-divisors]
Constrain a `number` to a multiple of the specified integer.
-
+
```ts
@@ -205,13 +197,13 @@ const evens = type({
-
+
## bigint
To allow any `bigint` value, use the `"bigint"` keyword.
-
+
```ts
@@ -232,10 +224,9 @@ const symbols = type({
-
+
-
-##### literals
+### literals [#bigint-literals]
To require an exact `bigint` value in your type, you can use add the suffix `n` to a string-embedded [number literal](/primitives#number/literals) to make it a `bigint`.
@@ -251,7 +242,7 @@ You may also use a [unit expression](/expressions#unit) to define `bigint` liter
To allow any `symbol` value, use the `"symbol"` keyword.
-
+
```ts
@@ -272,7 +263,7 @@ const symbols = type({
-
+
To reference a specific symbol in your definition, use a [unit expression](/expressions#unit).
@@ -282,7 +273,7 @@ No special syntax is required to define symbolic properties like `{ [mySymbol]:
To allow `true` or `false`, use the `"boolean"` keyword.
-
+
```ts
@@ -303,14 +294,13 @@ const booleans = type({
-
+
-
-##### literals
+### literals [#boolean-literals]
To require a specific boolean value, use the corresponding literal.
-
+
```ts
@@ -337,13 +327,13 @@ const booleans = type({
-
+
## null
The `"null"` keyword can be used to allow the exact value `null`, generally as part of a [union](/expressions#union).
-
+
```ts
@@ -364,13 +354,13 @@ const nullable = type({
-
+
## undefined
The `"undefined"` keyword can be used to allow the exact value `undefined`, generally as part of a [union](/expressions#union).
-
+
```ts
@@ -391,27 +381,29 @@ const myObj = type({
-
+
-:::caution[Allowing `undefined` as a value does not make the key optional!]
+
-In TypeScript, a required property that allows `undefined` must still be present for the type to be satisfied.
+ In TypeScript, a required property that allows `undefined` must still be present for the type to be satisfied.
-The same is true in ArkType.
+ The same is true in ArkType.
-
- See an example
+
+ See an example
-```ts
-const myObj = type({
- key: "number | undefined"
-})
+ ```ts
+ const myObj = type({
+ key: "number | undefined"
+ })
-// valid data
-const validResult = myObj({ key: undefined })
+ // valid data
+ const validResult = myObj({ key: undefined })
-// Error: name must be a number or undefined (was missing)
-const errorResult = myObj({})
-```
+ // Error: name must be a number or undefined (was missing)
+ const errorResult = myObj({})
+ ```
+
+
-
+
diff --git a/ark/docs/content/docs/primitives/meta.json b/ark/docs/content/docs/primitives/meta.json
new file mode 100644
index 0000000000..08c15d9b88
--- /dev/null
+++ b/ark/docs/content/docs/primitives/meta.json
@@ -0,0 +1,13 @@
+{
+ "title": "Primitives",
+ "defaultOpen": true,
+ "pages": [
+ "string",
+ "number",
+ "[bigint](/docs/primitives#bigint)",
+ "[symbol](/docs/primitives#symbol)",
+ "[boolean](/docs/primitives#boolean)",
+ "[null](/docs/primitives#null)",
+ "[undefined](/docs/primitives#undefined)"
+ ]
+}
diff --git a/ark/docs/content/docs/primitives/number/meta.json b/ark/docs/content/docs/primitives/number/meta.json
new file mode 100644
index 0000000000..60c2f6bbd6
--- /dev/null
+++ b/ark/docs/content/docs/primitives/number/meta.json
@@ -0,0 +1,9 @@
+{
+ "title": "number",
+ "pages": [
+ "[keywords](/docs/primitives#number/keywords)",
+ "[literals](/docs/primitives#number/literals)",
+ "[ranges](/docs/primitives#number/ranges)",
+ "[divisors](/docs/primitives#number/divisors)"
+ ]
+}
diff --git a/ark/docs/content/docs/primitives/string/meta.json b/ark/docs/content/docs/primitives/string/meta.json
new file mode 100644
index 0000000000..f6754bd550
--- /dev/null
+++ b/ark/docs/content/docs/primitives/string/meta.json
@@ -0,0 +1,9 @@
+{
+ "title": "string",
+ "pages": [
+ "[keywords](/docs/primitives#string/keywords)",
+ "[literals](/docs/primitives#string/literals)",
+ "[patterns](/docs/primitives#string/patterns)",
+ "[lengths](/docs/primitives#string/lengths)"
+ ]
+}
diff --git a/ark/docs/src/content/docs/scopes.mdx b/ark/docs/content/docs/scopes/index.mdx
similarity index 98%
rename from ark/docs/src/content/docs/scopes.mdx
rename to ark/docs/content/docs/scopes/index.mdx
index 2b977bf315..4a97bcc520 100644
--- a/ark/docs/src/content/docs/scopes.mdx
+++ b/ark/docs/content/docs/scopes/index.mdx
@@ -1,7 +1,5 @@
---
title: Scopes
-sidebar:
- order: 2
---
Scopes are the foundation of ArkType, and one of the most powerful features for users wanting full control over configuration and to make their own keywords available fluidly within string definition syntax.
@@ -38,6 +36,7 @@ const packageData: Package = {
dependencies: [{ name: "typescript" }],
contributors: [{ email: "david@sharktypeio" }]
}
+
packageData.dependencies![0].dependencies = [packageData]
export const out = types.package(packageData)
diff --git a/ark/fuma/content/docs/scopes/meta.json b/ark/docs/content/docs/scopes/meta.json
similarity index 90%
rename from ark/fuma/content/docs/scopes/meta.json
rename to ark/docs/content/docs/scopes/meta.json
index 8691b7cdc2..710f78e1c8 100644
--- a/ark/fuma/content/docs/scopes/meta.json
+++ b/ark/docs/content/docs/scopes/meta.json
@@ -1,5 +1,6 @@
{
"title": "Scopes",
+ "icon": "Advanced",
"pages": [
"[modules](/docs/scopes#modules)",
"[visibility](/docs/scopes#visibility)",
diff --git a/ark/docs/src/content/docs/types.mdx b/ark/docs/content/docs/type-api.mdx
similarity index 88%
rename from ark/docs/src/content/docs/types.mdx
rename to ark/docs/content/docs/type-api.mdx
index 897561404e..cdf119bb19 100644
--- a/ark/docs/src/content/docs/types.mdx
+++ b/ark/docs/content/docs/type-api.mdx
@@ -1,5 +1,5 @@
---
-title: Types
+title: Type API
---
🚧 Coming soon ™️🚧
diff --git a/ark/fuma/lib/ambient.d.ts b/ark/docs/lib/ambient.d.ts
similarity index 100%
rename from ark/fuma/lib/ambient.d.ts
rename to ark/docs/lib/ambient.d.ts
diff --git a/ark/fuma/lib/metadata.ts b/ark/docs/lib/metadata.ts
similarity index 79%
rename from ark/fuma/lib/metadata.ts
rename to ark/docs/lib/metadata.ts
index 8661f672ac..475c488cc0 100644
--- a/ark/fuma/lib/metadata.ts
+++ b/ark/docs/lib/metadata.ts
@@ -1,5 +1,5 @@
import { createMetadataImage } from "fumadocs-core/server"
-import { source } from "./source.ts"
+import { source } from "./source.tsx"
export const metadataImage = createMetadataImage({
imageRoute: "/docs-og",
diff --git a/ark/fuma/lib/shiki.ts b/ark/docs/lib/shiki.ts
similarity index 75%
rename from ark/fuma/lib/shiki.ts
rename to ark/docs/lib/shiki.ts
index a31572d2e4..9cf03769a7 100644
--- a/ark/fuma/lib/shiki.ts
+++ b/ark/docs/lib/shiki.ts
@@ -1,26 +1,28 @@
import { transformerNotationErrorLevel } from "@shikijs/transformers"
import type { RehypeCodeOptions } from "fumadocs-core/mdx-plugins"
import { transformerTwoslash } from "fumadocs-twoslash"
-import { defaultCompilerOptions } from "twoslash"
+import { createRequire } from "node:module"
-const { default: arkTypePackageJson } = await import("arkdark/package.json", {
- with: { type: "json" }
-})
+/** for some reason a standard import with an attribute like:
+
+ import arkDarkTheme from "arkdark/arkdark.json" with { type: "json" }
+
+results in an error like:
-const { default: arkTypeTmJson } = await import(
- "arkdark/tsWithArkType.tmLanguage.json",
- {
- with: { type: "json" }
- }
-)
+ Module "file:///home/ssalb/arktype/ark/dark/arkdark.json" needs an import attribute of "type: json"
-const { default: arkDarkTheme } = await import("arkdark/arkdark.json", {
- with: { type: "json" }
-})
+despite it having the attribute. Using require as a workaround- convert to an import
+like the one above if possible in the future without breaking the build.*/
-// Theme adjustments
+const require = createRequire(import.meta.url)
-arkDarkTheme.colors["editor.background"] = "#00000027"
+const arkDarkTheme = require("arkdark/arkdark.json")
+const arkTypePackageJson = require("arkdark/package.json")
+const arkTypeTmJson = require("arkdark/tsWithArkType.tmLanguage.json")
+
+// Theme adjustments
+/** should match the css rule for .bg-fd-secondary\/50 */
+arkDarkTheme.colors["editor.background"] = "#0006"
arkDarkTheme.tokenColors.push({
// this is covered by editorBracketHighlight.foreground1 etc. in VSCode,
@@ -37,8 +39,7 @@ const twoslash = transformerTwoslash({
langs: ["ts", "js"],
twoslashOptions: {
compilerOptions: {
- ...defaultCompilerOptions,
- exactOptionalPropertyTypes: true,
+ // avoid ... in certain longer types on hover
noErrorTruncation: true
},
extraFiles: {
@@ -130,11 +131,19 @@ declare global {
}
})
-export const shikiConfig: RehypeCodeOptions = {
+export const shikiConfig = {
themes: {
dark: arkDarkTheme,
light: arkDarkTheme
},
langs: ["json", "bash", { ...arkTypeTmJson, name: "ts" }],
transformers: [twoslash, transformerNotationErrorLevel()]
-}
+} as const satisfies RehypeCodeOptions
+
+export type shikiConfig = typeof shikiConfig
+
+export type BuiltinLang = {
+ [i in keyof shikiConfig["langs"]]: extractName
+}[number]
+
+type extractName = lang extends { name: infer name } ? name : lang
diff --git a/ark/docs/lib/source.tsx b/ark/docs/lib/source.tsx
new file mode 100644
index 0000000000..1e14932f5a
--- /dev/null
+++ b/ark/docs/lib/source.tsx
@@ -0,0 +1,35 @@
+import type { autocomplete } from "@ark/util"
+import { loader } from "fumadocs-core/source"
+import { createMDXSource } from "fumadocs-mdx"
+import { icons } from "lucide-react"
+import { createElement } from "react"
+import { docs, meta } from "../.source"
+import { Badge } from "../components/Badge.tsx"
+
+export type IconName = keyof typeof icons | "Advanced"
+
+export const source = loader({
+ baseUrl: "/docs",
+ source: createMDXSource(docs, meta),
+ icon: (name?: autocomplete) => {
+ if (!name) return
+ if (name in icons) return createElement(icons[name as never])
+
+ if (name === "Advanced") {
+ return (
+
+ advanced
+
+ )
+ }
+
+ throw new Error(`${name} is not a valid icon`)
+ }
+})
diff --git a/ark/docs/lib/writeSnippetsEntrypoint.ts b/ark/docs/lib/writeSnippetsEntrypoint.ts
new file mode 100644
index 0000000000..d84c7e3819
--- /dev/null
+++ b/ark/docs/lib/writeSnippetsEntrypoint.ts
@@ -0,0 +1,54 @@
+import { fromHere, readFile, shell, writeFile } from "@ark/fs"
+import { flatMorph, throwInternalError } from "@ark/util"
+import { existsSync } from "fs"
+
+/**
+ * Previously, we used raw-loader imports like:
+ *
+ * import unparalleledDx from "./snippets/unparalleledDx.twoslash.js?raw"
+ *
+ * so that we could write longer code blocks for use in .tsx
+ * without losing syntax highlighting, type checking etc.
+ * However, I was unable to get this working with Next's --turbo
+ * flag, which seems very impactful in terms of performance.
+ *
+ * As a workaround, when this config is loaded, we regenerate
+ * the contents.ts file and just import that directly. It is
+ * then committed to git as normal.
+ */
+export const writeSnippetsEntrypoint = () => {
+ const snippetContentsById = flatMorph(snippetIds, (i, id) => {
+ const tsPath = snippetPath(`${id}.twoslash.ts`)
+ const jsPath = snippetPath(`${id}.twoslash.js`)
+
+ const path =
+ existsSync(tsPath) ? tsPath
+ : existsSync(jsPath) ? jsPath
+ : throwInternalError(
+ `Expected a snippet file at ${tsPath} or ${jsPath} (neither existed).`
+ )
+ return [id, readFile(path)]
+ })
+
+ const toPath = snippetPath("contentsById.ts")
+
+ writeFile(
+ toPath,
+ `export default ${JSON.stringify(snippetContentsById, null, 4)}`
+ )
+
+ shell(`pnpm prettier --write ${toPath}`)
+}
+
+const snippetIds = [
+ "betterErrors",
+ "clarityAndConcision",
+ "deepIntrospectability",
+ "intrinsicOptimization",
+ "unparalleledDx"
+] as const
+
+export type SnippetId = (typeof snippetIds)[number]
+
+const snippetPath = (fileName: string) =>
+ fromHere("..", "components", "snippets", fileName)
diff --git a/ark/fuma/next-env.d.ts b/ark/docs/next-env.d.ts
similarity index 53%
rename from ark/fuma/next-env.d.ts
rename to ark/docs/next-env.d.ts
index 40c3d68096..1b3be0840f 100644
--- a/ark/fuma/next-env.d.ts
+++ b/ark/docs/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/ark/fuma/next.config.ts b/ark/docs/next.config.ts
similarity index 61%
rename from ark/fuma/next.config.ts
rename to ark/docs/next.config.ts
index d9fd2dbd60..6fe5293677 100644
--- a/ark/fuma/next.config.ts
+++ b/ark/docs/next.config.ts
@@ -1,28 +1,27 @@
+/* eslint-disable @typescript-eslint/no-require-imports */
import type { NextConfig } from "next"
+import { writeSnippetsEntrypoint } from "./lib/writeSnippetsEntrypoint.ts"
// Next can only treat next.config.ts as CJS, but fumadocs-mdx only supports ESM
// This allows us to import it using Node 22+ with --experimental-require-module
// Should convert to a standard import in the future when this is resolved
// https://github.com/fuma-nama/fumadocs/issues/1054
const { createMDX } =
- // eslint-disable-next-line @typescript-eslint/no-require-imports
require("./node_modules/fumadocs-mdx/dist/next/index.js") as typeof import("fumadocs-mdx/next")
+writeSnippetsEntrypoint()
+
const config = {
- output: "export",
reactStrictMode: true,
+ cleanDistDir: true,
serverExternalPackages: ["twoslash", "typescript"],
- webpack: config => {
- // this must be added to the beginning of the array
- // so that imports like the following don't have types stripped:
-
- // import betterErrors from "!./snippets/betterErrors.twoslash.ts?raw"
- config.module.rules.push({
- resourceQuery: /raw/,
- type: "asset/source"
- })
-
- return config
+ // the following properties are required by nextjs-github-pages:
+ // https://github.com/gregrickaby/nextjs-github-pages
+ output: "export",
+ basePath:
+ process.env.NODE_ENV === "development" ? (undefined as never) : "/arktype",
+ images: {
+ unoptimized: true
}
} as const satisfies NextConfig
diff --git a/ark/docs/package.json b/ark/docs/package.json
index 74960d4cd3..21ab94399d 100644
--- a/ark/docs/package.json
+++ b/ark/docs/package.json
@@ -1,40 +1,44 @@
{
"name": "@ark/docs",
+ "version": "0.0.1",
"private": true,
"type": "module",
- "version": "0.0.1",
- "license": "MIT",
"scripts": {
- "dev": "astro dev",
- "start": "astro dev",
- "build": "pnpm check && astro build",
- "check": "astro check --minimumSeverity warning --minimumFailingSeverity warning",
- "preview": "astro preview"
+ "build": "NODE_OPTIONS=--no-warnings next build",
+ "dev": "NODE_OPTIONS=--no-warnings next dev --turbo",
+ "start": "next start",
+ "clean": "rm -rf .next .source out",
+ "postinstall": "fumadocs-mdx",
+ "upDeps": "pnpm up --latest"
},
"dependencies": {
"@ark/fs": "workspace:*",
"@ark/util": "workspace:*",
- "@astrojs/check": "0.9.4",
- "@astrojs/react": "3.6.2",
- "@astrojs/starlight": "0.29.0",
- "@astrojs/ts-plugin": "1.10.4",
- "@shikijs/transformers": "1.22.2",
- "@shikijs/twoslash": "1.22.2",
+ "@fumadocs/cli": "0.0.4",
+ "@icons-pack/react-simple-icons": "10.2.0",
+ "@shikijs/transformers": "1.24.4",
+ "@types/mdx": "2.0.13",
+ "@types/react": "19.0.2",
+ "@types/react-dom": "19.0.2",
"arkdark": "workspace:*",
"arktype": "workspace:*",
- "astro": "4.16.18",
- "astro-og-canvas": "0.5.4",
- "canvaskit-wasm": "0.39.1",
- "framer-motion": "11.11.17",
- "react": "18.3.1",
- "react-dom": "18.3.1",
- "sharp": "0.33.5",
- "shiki": "1.22.2",
- "twoslash": "0.2.12"
- },
- "devDependencies": {
- "@types/react": "18.3.12",
- "@types/react-dom": "18.3.1",
+ "autoprefixer": "10.4.20",
+ "class-variance-authority": "0.7.1",
+ "framer-motion": "11.15.0",
+ "fumadocs-core": "14.6.2",
+ "fumadocs-mdx": "11.1.2",
+ "fumadocs-twoslash": "2.0.2",
+ "fumadocs-ui": "14.6.2",
+ "hast-util-to-jsx-runtime": "2.3.2",
+ "lucide-react": "0.469.0",
+ "next": "15.1.2",
+ "postcss": "8.4.49",
+ "prettier-plugin-tailwindcss": "0.6.9",
+ "react": "19.0.0",
+ "react-dom": "19.0.0",
+ "shiki": "1.24.4",
+ "tailwindcss": "3.4.17",
+ "twoslash": "0.2.12",
"typescript": "catalog:"
}
}
diff --git a/ark/fuma/postcss.config.cjs b/ark/docs/postcss.config.cjs
similarity index 100%
rename from ark/fuma/postcss.config.cjs
rename to ark/docs/postcss.config.cjs
diff --git a/ark/docs/public/check.svg b/ark/docs/public/image/check.svg
similarity index 100%
rename from ark/docs/public/check.svg
rename to ark/docs/public/image/check.svg
diff --git a/ark/docs/public/copy.svg b/ark/docs/public/image/copy.svg
similarity index 100%
rename from ark/docs/public/copy.svg
rename to ark/docs/public/image/copy.svg
diff --git a/ark/docs/src/assets/errorSquiggle.svg b/ark/docs/public/image/errorSquiggle.svg
similarity index 100%
rename from ark/docs/src/assets/errorSquiggle.svg
rename to ark/docs/public/image/errorSquiggle.svg
diff --git a/ark/docs/public/favicon.svg b/ark/docs/public/image/favicon.svg
similarity index 100%
rename from ark/docs/public/favicon.svg
rename to ark/docs/public/image/favicon.svg
diff --git a/ark/docs/src/assets/logo.png b/ark/docs/public/image/logo.png
similarity index 100%
rename from ark/docs/src/assets/logo.png
rename to ark/docs/public/image/logo.png
diff --git a/ark/docs/src/assets/logoTransparent.png b/ark/docs/public/image/logoTransparent.png
similarity index 100%
rename from ark/docs/src/assets/logoTransparent.png
rename to ark/docs/public/image/logoTransparent.png
diff --git a/ark/docs/src/assets/openGraphBackground.png b/ark/docs/public/image/openGraphBackground.png
similarity index 100%
rename from ark/docs/src/assets/openGraphBackground.png
rename to ark/docs/public/image/openGraphBackground.png
diff --git a/ark/docs/src/assets/splash.png b/ark/docs/public/image/splash.png
similarity index 100%
rename from ark/docs/src/assets/splash.png
rename to ark/docs/public/image/splash.png
diff --git a/ark/fuma/source.config.ts b/ark/docs/source.config.ts
similarity index 100%
rename from ark/fuma/source.config.ts
rename to ark/docs/source.config.ts
diff --git a/ark/docs/src/assets/Raleway.ttf b/ark/docs/src/assets/Raleway.ttf
deleted file mode 100644
index 33969e8558..0000000000
Binary files a/ark/docs/src/assets/Raleway.ttf and /dev/null differ
diff --git a/ark/docs/src/assets/boat.svg b/ark/docs/src/assets/boat.svg
deleted file mode 100644
index d6c5070ea7..0000000000
--- a/ark/docs/src/assets/boat.svg
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/bun.svg b/ark/docs/src/assets/bun.svg
deleted file mode 100644
index a26d889406..0000000000
--- a/ark/docs/src/assets/bun.svg
+++ /dev/null
@@ -1,49 +0,0 @@
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/chromium.svg b/ark/docs/src/assets/chromium.svg
deleted file mode 100644
index 6bd293bb9f..0000000000
--- a/ark/docs/src/assets/chromium.svg
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/deno.svg b/ark/docs/src/assets/deno.svg
deleted file mode 100644
index 7c9e4b9e19..0000000000
--- a/ark/docs/src/assets/deno.svg
+++ /dev/null
@@ -1,84 +0,0 @@
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/github.svg b/ark/docs/src/assets/github.svg
deleted file mode 100644
index be5067ae7c..0000000000
--- a/ark/docs/src/assets/github.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/githubDark.svg b/ark/docs/src/assets/githubDark.svg
deleted file mode 100644
index 45f939727c..0000000000
--- a/ark/docs/src/assets/githubDark.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/intellij.svg b/ark/docs/src/assets/intellij.svg
deleted file mode 100644
index 0e6a001690..0000000000
--- a/ark/docs/src/assets/intellij.svg
+++ /dev/null
@@ -1,44 +0,0 @@
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/js.svg b/ark/docs/src/assets/js.svg
deleted file mode 100644
index 54f714f71e..0000000000
--- a/ark/docs/src/assets/js.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/logo.svg b/ark/docs/src/assets/logo.svg
deleted file mode 100644
index e96c892243..0000000000
--- a/ark/docs/src/assets/logo.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/logoTransparent.svg b/ark/docs/src/assets/logoTransparent.svg
deleted file mode 100644
index 447dcec589..0000000000
--- a/ark/docs/src/assets/logoTransparent.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
diff --git a/ark/docs/src/assets/neovim.svg b/ark/docs/src/assets/neovim.svg
deleted file mode 100644
index 82606c5ea3..0000000000
--- a/ark/docs/src/assets/neovim.svg
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/node.svg b/ark/docs/src/assets/node.svg
deleted file mode 100644
index 5a3396c0ec..0000000000
--- a/ark/docs/src/assets/node.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/npm.svg b/ark/docs/src/assets/npm.svg
deleted file mode 100644
index f328a78329..0000000000
--- a/ark/docs/src/assets/npm.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/ts.svg b/ark/docs/src/assets/ts.svg
deleted file mode 100644
index 6d2b10f98c..0000000000
--- a/ark/docs/src/assets/ts.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
\ No newline at end of file
diff --git a/ark/docs/src/assets/vscode.svg b/ark/docs/src/assets/vscode.svg
deleted file mode 100644
index 42949c4ef4..0000000000
--- a/ark/docs/src/assets/vscode.svg
+++ /dev/null
@@ -1,54 +0,0 @@
-
\ No newline at end of file
diff --git a/ark/docs/src/components/AutoplayDemo.tsx b/ark/docs/src/components/AutoplayDemo.tsx
deleted file mode 100644
index b01d904b4b..0000000000
--- a/ark/docs/src/components/AutoplayDemo.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from "react"
-
-export type AutoplayDemoProps = React.DetailedHTMLProps<
- React.VideoHTMLAttributes,
- HTMLVideoElement
-> & { src: string }
-
-export const AutoplayDemo = (props: AutoplayDemoProps) => (
-
-)
diff --git a/ark/docs/src/components/BenchmarksGraph.tsx b/ark/docs/src/components/BenchmarksGraph.tsx
deleted file mode 100644
index b86ccfd106..0000000000
--- a/ark/docs/src/components/BenchmarksGraph.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import React from "react"
-
-const barStyles: React.CSSProperties = {
- height: "30px",
- borderRadius: "5px",
- display: "flex",
- alignItems: "baseline",
- marginRight: "1rem",
- color: "black"
-}
-
-const arkBarStyles = {
- ...barStyles,
- background:
- "repeating-linear-gradient(135deg, #40decc, #40decc 10px, #34c8b9 10px, #34c8b9 20px)"
-}
-
-const zodBarStyles = {
- ...barStyles,
- background:
- "repeating-linear-gradient(135deg, #b084f6, #b084f6 10px, #9a6fe3 10px, #9a6fe3 20px)"
-}
-
-export const RuntimeBenchmarksGraph = () => (
-