Giter Site home page Giter Site logo

arktypeio / arktype Goto Github PK

View Code? Open in Web Editor NEW
3.7K 13.0 52.0 9.38 MB

TypeScript's 1:1 validator, optimized from editor to runtime

Home Page: https://arktype.io

License: MIT License

JavaScript 1.67% TypeScript 96.24% CSS 0.46% MDX 1.52% Astro 0.11%
typescript runtime-typechecking static-typing parsing javascript

arktype's Introduction

ArkType TypeScript's 1:1 validator

What is it?

ArkType is a runtime validation library that can infer TypeScript definitions 1:1 and reuse them as highly-optimized validators for your data.

With each character you type, you'll get immediate feedback from your editor in the form of either a fully-inferred Type or a specific and helpful ParseError.

This result exactly mirrors what you can expect to happen at runtime down to the punctuation of the error message- no plugins required.

Check out how it works or scroll slightly to read about installation.

Npm Icon npm install arktype (or whatever package manager you prefer)

Our types are tested in strict-mode with TypeScript version 5.4+, although you will likely have success with other versions after 5.0.

If your types work but you notice errors in node_modules, this could be due to tsconfig incompatibilities- please enable compilerOptions/skipLibCheck (docs).

Your first type

Defining basic types in ArkType is just like TypeScript, so if you already know how to do that, congratulations! You already know most of ArkType's syntax ๐ŸŽ‰

For an ever better in-editor developer experience, try the ArkDark VSCode extension for syntax highlighting.

import { type } from "arktype"

// Definitions are statically parsed and inferred as TS
export const user = type({
	name: "string",
	device: {
		platform: "'android'|'ios'",
		"version?": "number"
	}
})

// Validators return typed data or clear, customizable errors.
export const out = user({
	name: "Alan Turing",
	device: {
		// errors.summary: "device/platform must be 'android' or 'ios' (was 'enigma')"
		platform: "enigma"
	}
})

if (out instanceof type.errors) {
	// a clear, user-ready error message, even for complex unions and intersections
	console.log(out.summary)
} else {
	// your valid data!
	console.log(out)
}

Example syntax

Lots more docs are on the way, but I want to highlight some of the most useful syntax patterns/features that are carried over from alpha as well as those new to the 2.0 release.

// Syntax carried over from 1.0 + TS
export const currentTsSyntax = type({
	keyword: "null",
	stringLiteral: "'TS'",
	numberLiteral: "5",
	bigintLiteral: "5n",
	union: "string|number",
	intersection: "boolean&true",
	array: "Date[]",
	grouping: "(0|1)[]",
	objectLiteral: {
		nested: "string",
		"optional?": "number"
	},
	tuple: ["number", "number"]
})

// available syntax new to 2.0

export const upcomingTsSyntax = type({
	keyof: "keyof object",
	variadicTuples: ["true", "...", "false[]"]
})

// runtime-specific syntax and builtin keywords with great error messages

export const validationSyntax = type({
	keywords: "email|uuid|creditCard|integer", // and many more
	builtinParsers: "parse.date", // parses a Date from a string
	nativeRegexLiteral: /@arktype\.io/,
	embeddedRegexLiteral: "email&/@arktype\\.io/",
	divisibility: "number%10", // a multiple of 10
	bound: "alpha>10", // an alpha-only string with more than 10 characters
	range: "1<=email[]<100", // a list of 1 to 99 emails
	narrows: ["number", ":", n => n % 2 === 1], // an odd integer
	morphs: ["string", "=>", parseFloat] // validates a string input then parses it to a number
})

// root-level expressions

const intersected = type({ value: "string" }, "&", { format: "'bigint'" })

// chained expressions via .or, .and, .narrow, .pipe and much more
//  (these replace previous helper methods like union and intersection)

const user = type({
	name: "string",
	age: "number"
})

const parseUser = type("string").pipe(s => JSON.parse(s), user)

// type is fully introspectable and traversable, displayed as:
type ParseUser = Type<
	(In: string) => Out<{
		name: string
		age: number
	}>
>

const maybeMe = parseUser('{ "name": "David" }')

if (maybeMe instanceof type.errors) {
	// "age must be a number (was missing)"
	console.log(maybeMe.summary)
}

There's so much more I want to share but I want to get at least an initial version of the 2.0 branch merged tonight so look forward to that next week!

API

ArkType supports many of TypeScript's built-in types and operators, as well as some new ones dedicated exclusively to runtime validation. In fact, we got a little ahead of ourselves and built a ton of cool features, but we're still working on getting caught up syntax and API docs. Keep an eye out for more in the next couple weeks โ›ต

In the meantime, check out the examples here and use the type hints you get to learn how you can customize your types and scopes. If you want to explore some of the more advanced features, take a look at our unit tests or ask us on Discord if your functionality is supported. If not, create a GitHub issue so we can prioritize it!

Integrations

tRPC

ArkType can easily be used with tRPC via the assert prop:

...
t.procedure
  .input(
    type({
      name: "string",
      "age?": "number"
    }).assert
  )
...

How?

ArkType's isomorphic parser has parallel static and dynamic implementations. This means as soon as you type a definition in your editor, you'll know the eventual result at runtime.

If you're curious, below is an example of what that looks like under the hood. If not, close that hood back up, npm install arktype and enjoy top-notch developer experience ๐Ÿง‘โ€๐Ÿ’ป

export const parseOperator = (s: DynamicState): void => {
	const lookahead = s.scanner.shift()
	return (
		lookahead === "" ? s.finalize()
		: lookahead === "[" ?
			s.scanner.shift() === "]" ?
				s.rootToArray()
			:	s.error(incompleteArrayTokenMessage)
		: isKeyOf(lookahead, Scanner.branchTokens) ? s.pushRootToBranch(lookahead)
		: lookahead === ")" ? s.finalizeGroup()
		: isKeyOf(lookahead, Scanner.comparatorStartChars) ?
			parseBound(s, lookahead)
		: lookahead === "%" ? parseDivisor(s)
		: lookahead === " " ? parseOperator(s)
		: throwInternalError(writeUnexpectedCharacterMessage(lookahead))
	)
}

export type parseOperator<s extends StaticState> =
	s["unscanned"] extends Scanner.shift<infer lookahead, infer unscanned> ?
		lookahead extends "[" ?
			unscanned extends Scanner.shift<"]", infer nextUnscanned> ?
				state.setRoot<s, [s["root"], "[]"], nextUnscanned>
			:	error<incompleteArrayTokenMessage>
		: lookahead extends Scanner.BranchToken ?
			state.reduceBranch<s, lookahead, unscanned>
		: lookahead extends ")" ? state.finalizeGroup<s, unscanned>
		: lookahead extends Scanner.ComparatorStartChar ?
			parseBound<s, lookahead, unscanned>
		: lookahead extends "%" ? parseDivisor<s, unscanned>
		: lookahead extends " " ? parseOperator<state.scanTo<s, unscanned>>
		: error<writeUnexpectedCharacterMessage<lookahead>>
	:	state.finalize<s>

Contributions

We accept and encourage pull requests from outside ArkType.

Depending on your level of familiarity with type systems and TS generics, some parts of the codebase may be hard to jump into. That said, there's plenty of opportunities for more straightforward contributions.

If you're planning on submitting a non-trivial fix or a new feature, please create an issue first so everyone's on the same page. The last thing we want is for you to spend time on a submission we're unable to merge.

When you're ready, check out our guide to get started!

License

This project is licensed under the terms of the MIT license.

Collaboration

I'd love to hear about what you're working on and how ArkType can help. Please reach out to [email protected].

Code of Conduct

We will not tolerate any form of disrespect toward members of our community. Please refer to our Code of Conduct and reach out to [email protected] immediately if you've seen or experienced an interaction that may violate these standards.

Sponsorship

We've been working full-time on this project for over a year and it means a lot to have the community behind us.

If the project has been useful to you and you are in a financial position to do so, please chip in via GitHub Sponsors.

Otherwise, consider sending me an email ([email protected]) or message me on Discord to let me know you're a fan of ArkType. Either would make my day!

ArkSponsors โ›ต

fubhy sam-goodwin

Sponsors ๐Ÿฅฐ

tmm jacksteamdev neodon mewhhaha codeandcats
Timeraa marcagba Phalangers

arktype's People

Contributors

ahrjarrett avatar andarist avatar bas950 avatar bavannah avatar becca718 avatar dearlordylord avatar dependabot[bot] avatar dimava avatar ghoullier avatar github-actions[bot] avatar gustavoguichard avatar hsiwe avatar malezjaa avatar nickserv avatar rhofvendahl avatar roottool avatar sarthakagrawal avatar shawnmorreau avatar ssalbdivad avatar thetayloredman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arktype's Issues

UI and database objects for all user-specific data

  1. SuggestionsCard should get real data as part of this task.
  2. Users can view recorded test cases and other saved data like groups of elements/actions, test suites etc. in both search and hierarchical formats

security review

security review

  • Investigate how analytics API works for storing keys security
    -- remove app secret from redo-server\

Tag input create tag on space

First steps:

  1. Take ChipInput out of app (currently in learner page) and move it to components

  2. Make a new ChipInput component that looks like our Button component in that it:

  • imports the material-ui ChipInput component and props

  • wraps them up and can add custom props if needed

  1. Rely on the @re-do/components chip input from app and delete material-ui-chip-input dependency from app

make sure electron package builds for linux/mac/windows, look into npm install

Need to get cross-platform build output for Redo. Should be able to do so using this tool:

https://www.electron.build

The documentation looks very detailed although you might find it hard to understand most of what's going on. Would recommend just trying to glean as much as you can and try to get one small thing running at a time. If you are making lots of changes to different files, something is probably going wrong :)

To start, let's shoot for:

  1. Being able to run "npm run pack" and get the following build output variants (see documentation):
    .dmg, .deb, .nsis, .tar.gz

Once we can do this, we'll want to be able to run "npm run publish" and get those files into AWS (Sarthak is working on getting AWS set up today, so you'll need to coordinate with him). Looks like there's info about that process here:

https://www.electron.build/configuration/publish

Any progress you can make would be super helpful, may involve some head banging though ๐Ÿ€

Change name of any imports from Mui to include prefix Mui

Throughout our app it's a common pattern to import components from material-ui and then wrap them in our own customized versions of those components with some defaults assumed. To make it clear at which layers we're looking at MUI components and when it's our own custom components (often by the same name), I'd like to standardize on importing material-ui components with a prefix of Mui. E.g.:

import {Button as MuiButton} from "@material-ui/core"

This should make it easier to debug code in the future and to help us tell at a glance which components are ours.

fix usestate console error

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in Unknown (created by SignIn)
in FormContext
in Unknown (created by SignIn)
in div (created by ForwardRef(Paper))
in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
in WithStyles(ForwardRef(Card))
in Unknown
in Unknown (created by SignIn)
in div (created by ForwardRef(Grid))
in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
in WithStyles(ForwardRef(Grid))
in Unknown
in Unknown (created by SignIn)
in SignIn

Final review before launch

  1. 1/2 day Github continuous integration process set up

  2. figure out versioning scheme for packages

  3. add analytics to app with segment

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.