From 4fe96236055daa82632bbfd48945b5ea0ab88491 Mon Sep 17 00:00:00 2001 From: David Blass Date: Thu, 16 Jan 2025 19:57:45 -0500 Subject: [PATCH] feat: 2.0 (#1256) --- .gitignore | 1 + ark/attest/package.json | 2 +- ark/dark/README.md | 14 + ark/dark/arktype.scratch.ts | 3 + ark/dark/injected.tmLanguage.json | 2 +- ark/dark/package.json | 2 +- ark/dark/tsWithArkType.tmLanguage.json | 5 +- ark/docs/app/(home)/layout.tsx | 8 +- ark/docs/app/docs/[[...slug]]/page.tsx | 17 +- ark/docs/app/global.css | 15 +- ark/docs/app/layout.tsx | 2 + ark/docs/components/ApiTable.tsx | 59 +- ark/docs/components/Banner.tsx | 145 ++ ark/docs/components/FloatYourBoat.tsx | 84 +- ark/docs/components/LocalFriendlyUrl.tsx | 6 +- ark/docs/components/ReleaseBanner.tsx | 12 + ark/docs/components/apiData.ts | 1267 +++++++++++++---- ark/docs/components/snippets/contentsById.ts | 19 +- ark/docs/content/docs/blog/2.0.mdx | 52 + ark/docs/content/docs/blog/index.mdx | 11 + ark/docs/content/docs/blog/meta.json | 5 + ark/docs/content/docs/configuration/index.mdx | 260 +++- ark/docs/content/docs/configuration/meta.json | 2 +- ark/docs/content/docs/expressions/index.mdx | 41 + ark/docs/content/docs/meta.json | 4 +- ark/docs/content/docs/traversal-api.mdx | 7 + ark/docs/content/docs/type-api.mdx | 8 - ark/docs/lib/shiki.ts | 34 +- ark/docs/lib/writeSnippetsEntrypoint.ts | 11 +- ark/docs/package.json | 28 +- ark/fast-check/arbitraries/date.ts | 4 +- ark/fast-check/arbitraries/number.ts | 27 +- ark/fast-check/arktypeFastCheck.ts | 8 +- ark/fs/package.json | 2 +- ark/repo/build.ts | 2 +- ark/repo/{jsdocGen.ts => jsDocGen.ts} | 167 ++- ark/repo/package.json | 2 +- ark/repo/scratch.ts | 77 +- ark/repo/testV8.js | 4 +- ark/schema/config.ts | 94 +- ark/schema/kinds.ts | 31 +- ark/schema/node.ts | 20 +- ark/schema/package.json | 2 +- ark/schema/parse.ts | 25 +- ark/schema/predicate.ts | 9 +- ark/schema/roots/domain.ts | 67 +- ark/schema/roots/intersection.ts | 58 +- ark/schema/roots/morph.ts | 4 +- ark/schema/roots/proto.ts | 75 +- ark/schema/roots/root.ts | 10 +- ark/schema/roots/union.ts | 4 +- ark/schema/scope.ts | 118 +- ark/schema/shared/declare.ts | 7 +- ark/schema/shared/disjoint.ts | 4 + ark/schema/shared/errors.ts | 16 +- ark/schema/shared/implement.ts | 18 +- ark/schema/shared/traversal.ts | 260 ++-- ark/schema/structure/structure.ts | 56 +- ark/type/__tests__/clone.test.ts | 3 + ark/type/__tests__/config.test.ts | 82 ++ ark/type/__tests__/filter.test.ts | 52 + ark/type/__tests__/get.test.ts | 2 +- ark/type/__tests__/keywords/number.test.ts | 9 +- ark/type/__tests__/realWorld.test.ts | 39 + ark/type/__tests__/submodule.test.ts | 4 +- ark/type/__tests__/traverse.test.ts | 25 + ark/type/__tests__/type.test.ts | 10 + ark/type/keywords/keywords.ts | 2 + ark/type/keywords/number.ts | 11 +- ark/type/keywords/string.ts | 10 +- ark/type/methods/base.ts | 337 +++-- ark/type/package.json | 12 +- ark/type/parser/definition.ts | 29 +- ark/type/scope.ts | 14 +- ark/util/package.json | 2 +- ark/util/records.ts | 10 + ark/util/registry.ts | 2 +- ark/util/strings.ts | 9 + package.json | 34 +- 79 files changed, 3085 insertions(+), 910 deletions(-) create mode 100644 ark/docs/components/Banner.tsx create mode 100644 ark/docs/components/ReleaseBanner.tsx create mode 100644 ark/docs/content/docs/blog/2.0.mdx create mode 100644 ark/docs/content/docs/blog/index.mdx create mode 100644 ark/docs/content/docs/blog/meta.json create mode 100644 ark/docs/content/docs/traversal-api.mdx rename ark/repo/{jsdocGen.ts => jsDocGen.ts} (59%) create mode 100644 ark/type/__tests__/filter.test.ts diff --git a/.gitignore b/.gitignore index cd854c3aeb..116d714293 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ dist out +*.vsix node_modules temp tmp diff --git a/ark/attest/package.json b/ark/attest/package.json index 41c2898994..a9e31098d2 100644 --- a/ark/attest/package.json +++ b/ark/attest/package.json @@ -1,6 +1,6 @@ { "name": "@ark/attest", - "version": "0.37.0", + "version": "0.38.0", "license": "MIT", "author": { "name": "David Blass", diff --git a/ark/dark/README.md b/ark/dark/README.md index 5f4a3d1778..61ac55a992 100644 --- a/ark/dark/README.md +++ b/ark/dark/README.md @@ -45,6 +45,20 @@ To determine which scopes need to be changed, you can view scopes applied to any Changes to `injected.tmLanguage.json` should be mirrored to [tsWithArkType.tmLanguage.json](./tsWithArkType.tmLanguage.json). +#### Testing tsWithArkType.tmLanguage.json + +To test the standalone rules for TS w/ ArkType highlighting, replace `grammars` in `package.json` with the following: + +```json + "grammars": { + "scopeName": "source.ts", + "language": "typescript", + "path": "tsWithArkType.tmLanguage.json" + } +``` + +Be sure to switch back before publishing! + > [!IMPORTANT] > You must reload the extension host window to see scope changes reflected diff --git a/ark/dark/arktype.scratch.ts b/ark/dark/arktype.scratch.ts index 5c74c08e01..eed8c03f8d 100644 --- a/ark/dark/arktype.scratch.ts +++ b/ark/dark/arktype.scratch.ts @@ -164,3 +164,6 @@ const highlighted = type({ pattern: "/^(?:4[0-9]{12}(?:[0-9]{3,6}))$/", bar: "(string | number)[]" }) + +// chained calls should be highlighted +highlighted.or("string[]").or({ object: "string[]" }) diff --git a/ark/dark/injected.tmLanguage.json b/ark/dark/injected.tmLanguage.json index b7174cdcbf..bc1cf52c3d 100644 --- a/ark/dark/injected.tmLanguage.json +++ b/ark/dark/injected.tmLanguage.json @@ -40,7 +40,7 @@ }, "arkChained": { "contentName": "meta.embedded.arktype.definition", - "begin": "([^\\)\\(\\s]+)?(\\.)\\b(and|or|when|extends|ifExtends|intersect|merge|exclude|extract|overlaps|subsumes|to)(\\()", + "begin": "([^\\)\\(\\s]+)?(\\.)\\b(and|or|when|extends|ifExtends|intersect|merge|exclude|extract|overlaps|subsumes|to|satisfies)(\\()", "beginCaptures": { "2": { "name": "punctuation.accessor.ts" diff --git a/ark/dark/package.json b/ark/dark/package.json index 39df47823c..45e37e911c 100644 --- a/ark/dark/package.json +++ b/ark/dark/package.json @@ -2,7 +2,7 @@ "name": "arkdark", "displayName": "ArkDark", "description": "Syntax highlighting, inline errors and theme for ArkTypeβ›΅", - "version": "5.13.0", + "version": "5.14.0", "publisher": "arktypeio", "type": "module", "license": "MIT", diff --git a/ark/dark/tsWithArkType.tmLanguage.json b/ark/dark/tsWithArkType.tmLanguage.json index bc561f821c..45d53e97cf 100644 --- a/ark/dark/tsWithArkType.tmLanguage.json +++ b/ark/dark/tsWithArkType.tmLanguage.json @@ -48,7 +48,7 @@ }, "arkChained": { "contentName": "meta.embedded.arktype.definition", - "begin": "([^\\)\\(\\s]+)?(\\.)\\b(and|or|when|extends|ifExtends|intersect|merge|exclude|extract|overlaps|subsumes|to)(\\()", + "begin": "([^\\)\\(\\s]+)?(\\.)\\b(and|or|when|extends|ifExtends|intersect|merge|exclude|extract|overlaps|subsumes|to|satisfies)(\\()", "beginCaptures": { "2": { "name": "punctuation.accessor.ts" @@ -498,6 +498,9 @@ { "include": "#arkDefinition" }, + { + "include": "#arkChained" + }, { "include": "#string" }, diff --git a/ark/docs/app/(home)/layout.tsx b/ark/docs/app/(home)/layout.tsx index 673b9b57d2..350be2d177 100644 --- a/ark/docs/app/(home)/layout.tsx +++ b/ark/docs/app/(home)/layout.tsx @@ -9,8 +9,14 @@ export type LayoutProps = { export default ({ children }: LayoutProps): React.ReactElement => ( }} + nav={{ + ...baseOptions.nav, + children: + }} > {children} diff --git a/ark/docs/app/docs/[[...slug]]/page.tsx b/ark/docs/app/docs/[[...slug]]/page.tsx index 13165cf6cd..4e5a404349 100644 --- a/ark/docs/app/docs/[[...slug]]/page.tsx +++ b/ark/docs/app/docs/[[...slug]]/page.tsx @@ -25,10 +25,21 @@ export default async (props: { params: Promise<{ slug?: string[] }> }) => { const MDX = page.data.body + const isApiPage = + page.data.title.endsWith("API") || page.data.title.endsWith("Configuration") + return ( - - {page.data.title} - {page.data.description} + + + {page.data.title} + + {page.data.description} + + + span { + color: var(--twoslash-error-color) !important; +} + +.error.highlighted.runtime-error { + background-color: #f8585822; + border-left: 3px solid var(--ark-runtime-error); +} + +.error.highlighted.runtime-error > span { color: var(--ark-runtime-error) !important; } @@ -135,7 +144,7 @@ div.twoslash-popup-container { } .completions-block code { - padding-bottom: 3rem; + padding-bottom: 2rem; } /** avoid a janky white outline on hovers: diff --git a/ark/docs/app/layout.tsx b/ark/docs/app/layout.tsx index 35f2cfa927..8d899187b3 100644 --- a/ark/docs/app/layout.tsx +++ b/ark/docs/app/layout.tsx @@ -3,6 +3,7 @@ import "fumadocs-twoslash/twoslash.css" import { RootProvider } from "fumadocs-ui/provider" import { Raleway } from "next/font/google" import type { ReactNode } from "react" +import { ReleaseBanner } from "../components/ReleaseBanner.tsx" const raleway = Raleway({ subsets: ["latin"] @@ -23,6 +24,7 @@ export default ({ children }: { children: ReactNode }) => ( defaultTheme: "dark" }} > + {children} diff --git a/ark/docs/components/ApiTable.tsx b/ark/docs/components/ApiTable.tsx index 7616eb3930..148c59a6ac 100644 --- a/ark/docs/components/ApiTable.tsx +++ b/ark/docs/components/ApiTable.tsx @@ -1,33 +1,28 @@ -import type { JSX } from "react" -import type { ApiGroup, ParsedJsDocPart } from "../../repo/jsdocGen.ts" +import type { ApiGroup, ParsedJsDocPart } from "../../repo/jsDocGen.ts" import { apiDocsByGroup } from "./apiData.ts" import { CodeBlock } from "./CodeBlock.tsx" import { LocalFriendlyUrl } from "./LocalFriendlyUrl.tsx" export type ApiTableProps = { group: ApiGroup - rows: JSX.Element[] } export const ApiTable = ({ group }: ApiTableProps) => ( - <> -

{group}

-
- - - - - - - - - {apiDocsByGroup[group].map(props => ( - - ))} - -
-
- +
+ + + + + + + + + {apiDocsByGroup[group].map(props => ( + + ))} + +
+
) const ApiTableHeader = () => ( @@ -37,7 +32,7 @@ const ApiTableHeader = () => ( Name Summary - Example + Notes & Examples ) @@ -51,7 +46,17 @@ interface ApiTableRowProps { const ApiTableRow = ({ name, summary, example, notes }: ApiTableRowProps) => ( - {name} + + {name} + {JsDocParts(summary)} {notes.map((note, i) => ( @@ -70,13 +75,9 @@ const JsDocParts = (parts: readonly ParsedJsDocPart[]) => {part.value} : part.kind === "reference" ? - + {part.value} - : part.kind === "tag" ? -

- {part.name} {JsDocParts(part.value)} -

:

__html: part.value .replace(/(\*\*|__)([^*_]+)\1/g, "$2") .replace(/(\*|_)([^*_]+)\1/g, "$2") + .replace(/`([^`]+)`/g, "$1") + .replace(/^-(.*)/g, "β€’ $1") }} /> } diff --git a/ark/docs/components/Banner.tsx b/ark/docs/components/Banner.tsx new file mode 100644 index 0000000000..3e7379a11d --- /dev/null +++ b/ark/docs/components/Banner.tsx @@ -0,0 +1,145 @@ +"use client" + +import { buttonVariants, cn } from "fumadocs-ui/components/api" +import { X } from "lucide-react" +import { type HTMLAttributes, useCallback, useEffect, useState } from "react" +import { FloatYourBoat } from "./FloatYourBoat.tsx" + +// Based on: +// https://github.com/fuma-nama/fumadocs/blob/1e6ece043987c8bf607249b66a8945632b229982/packages/ui/src/components/banner.tsx#L65 + +export const Banner = ({ + id = "banner", + changeLayout = true, + boat, + children, + ...props +}: HTMLAttributes & { + boat?: boolean + /** + * Change Fumadocs layout styles + * + * @defaultValue true + */ + changeLayout?: boolean +}): React.ReactElement => { + const [open, setOpen] = useState(true) + const globalKey = id ? `nd-banner-${id}` : undefined + + useEffect(() => { + if (globalKey) setOpen(localStorage.getItem(globalKey) !== "true") + }, [globalKey]) + + const onClick = useCallback(() => { + setOpen(false) + if (globalKey) localStorage.setItem(globalKey, "true") + }, [globalKey]) + + return ( +

+
+ {changeLayout && open ? + + : null} + {globalKey ? + + : null} + {id ? +