Skip to content

Commit

Permalink
feat: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewBastin committed Oct 14, 2023
0 parents commit 40990d9
Show file tree
Hide file tree
Showing 8 changed files with 2,160 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist
node_modules
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<div align="center">

# verzod

</div>

A simple versioning and migration library based on Zod schemas.

## Concept
*Verzod* allows you to define an 'entity' that can have multiple versions. Each version is defined by a Zod schema. You can then use the library to check if a given data matches the schema of the entity, and if not, migrate it to the latest version and use it.

## Installation
- Install the NPM package
```bash
$ npm install verzod
```

## Usage
- Create a versioned *entity* that you want to use
```ts
import { createVersionedEntity, InferredEntity } from "verzod"
import { z } from "zod"

const Environment_V1 = z.object({
name: z.string(),
v: z.literal(1),
variables: z.array(
z.object({
key: z.string(),
value: z.string(),
masked: z.boolean()
})
)
})

const Environment_V2 = z.object({
name: z.string(),
v: z.literal(2),
variables: z.array(
z.union([
z.object({
name: z.string(),
value: z.string(),
masked: z.literal(false)
}),
z.object({
name: z.string(),
masked: z.literal(true)
})
])
)
})

const Environment = createVersionedEntity({
latestVersion: 2,
versionMap: {
1: defineVersion({
initial: true,
schema: Environment_V1
}),
2: defineVersion({
initial: false,
schema: Environment_V2,
up(old: z.infer<typeof Environment_V1>) {
return <z.infer<typeof Environment_V2>>{
...old,
v: 2,
variables: old.variables.map(v => ({
...v,
masked: false
}))
}
}
})
},
getVersion(data: unknown) {
return typeof data === "object"
&& data !== null
&& "v" in data
&& typeof data["v"] === "number"
? data["v"]
: null
}
})
```

- You can use the various library functionality demoed below.
```ts
import { InferredEntity } from "verzod"

// Get the type of the entity (will resolve to the type of the latest version schema)
type Environment = InferredEntity<typeof Environment>


// You can use `is` method to check if the data given matches the schema
const v2_data = {
name: "test",
v: 2,
variables: [{ key: "hello", masked: true }]
}

Environment.is(v2_data) // Returns true

const v1_data = { name: "test", v: 1, variables: [{ key: "hello", value: "there" }]}
Environment.is(v1_data) // Returns true (it returns true for old versions)

const invalid_ver_data = { name: "test", v: 3, variables: [] }
Environment.is(invalid_ver_data) // false (invalid version)

const invalid_schema_data = { name: "test", v: 2, vars: [] }
Environment.is(invalid_schema_data) // false (invalid schema)

// NOTE: There is also `isLatest` to check only for the latest version
// This also narrows the type to only the latest version unlike `is` which
// narrows to all given versions
Environment.isLatest(v2_data) // true

Environment.isLatest(v1_data) // false

// You can use `safeParse` method to parse (and if needed, migrate) the data
Environment.safeParse(v2_data) // { type: "ok", value: v2_data }
Environment.safeParse(v1_data) // { type: "ok", value: { name: "test", v: 2, variables: [{ name: "hello", value: "there", masked: false }]}} <- Migrated old schema

Environment.safeParse(invalid_ver_data) // { type: "err", error: { type: "INVALID_VER", version: 3 } <- invalid version

Environment.safeParse(invalid_schema_data) // { type: "err", error: { type: "GIVEN_VER_VALIDATION_FAIL", version: 2, versionDef: <relevant version map entry> } } <- correct version, but invalid data

```

<br />
<br />
<p align="center"><b>made with ❤️ by <a href="https://github.com/AndrewBastin">andrew bastin</a></b></p>
39 changes: 39 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "verzod",
"version": "0.1.0",
"license": "MIT",
"private": "false",
"description": "A simple versioning and migration library based on Zod schemas",
"author": "Andrew Bastin ([email protected])",
"homepage": "https://github.com/AndrewBastin/verzod",
"bugs": {
"url": "https://github.com/AndrewBastin/verzod/issues"
},
"keywords": [
"versioning",
"migration",
"zod"
],
"engines": {
"node": ">=16"
},
"type": "module",
"files": [
"dist"
],
"exports": "./dist/index.js",
"scripts": {
"test": "vitest --run",
"build": "tsup",
"prepublish": "tsup"
},
"dependencies": {
"zod": "^3.22.2"
},
"devDependencies": {
"jiti": "^1.20.0",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"vitest": "^0.34.6"
}
}
Loading

0 comments on commit 40990d9

Please sign in to comment.