Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/takitotech/schemez
This library allows users to create JSON schemas and respective TypeScript types in a manner consistent with TypeScript coding. Not only does this reduce code duplication, it makes it simpler for TypeScript developers to learn it.
https://github.com/takitotech/schemez
jsonschema typescript typescript-library validate
Last synced: 3 months ago
JSON representation
This library allows users to create JSON schemas and respective TypeScript types in a manner consistent with TypeScript coding. Not only does this reduce code duplication, it makes it simpler for TypeScript developers to learn it.
- Host: GitHub
- URL: https://github.com/takitotech/schemez
- Owner: TakitoTech
- License: mit
- Created: 2022-06-25T14:01:34.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-07T19:34:11.000Z (3 months ago)
- Last Synced: 2024-10-14T03:22:49.952Z (3 months ago)
- Topics: jsonschema, typescript, typescript-library, validate
- Language: TypeScript
- Homepage:
- Size: 625 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# schemez
This library allows users to create JSON schemas and respective TypeScript types in a manner consistent with TypeScript coding. Not only does this reduce code duplication, it makes it simpler for TypeScript developers to learn it.
Heavily based on seemingly abandoned project [jsonschema-definer](https://github.com/Sujimoshi/jsonschema-definer).
Added features like "pick", "omit", and etc, improved code and typescript support, and removed validator to avoid dependency.
## ๐ฅ Install
```sh
npm i -D schemez
yarn add -D schemez
pnpm i -D schemez
```## ๐ Usage
Basic example```ts
import s from "schemez";// Lets define a simple object schema
const UserSchema = s.shape({
name: s.string(),
email: s.string().format('email').optional(),
password: s.string().minLength(8),
role: s.enum('client', 'supplier'),
birthday: s.instanceOf(Date)
});// Now lets get interface from schema
type User = typeof UserSchema.type
/*
type User = {
name: string,
email?: string | undefined,
password: string,
role: 'client' | 'supplier',
birthday: Date
}
*/// Get plain JSON Schema using .valueOf()
console.log(UserSchema.valueOf())const AdminUserSchema = UserSchema.andShape({
company: s.string().minLength(3),
});// Now lets get interface from schema
type AdminUser = typeof AdminUserSchema.type
/*
type AdminUser = {
name: string,
email?: string | undefined,
password: string,
role: 'client' | 'supplier',
birthday: Date,
}
*/// Get plain JSON Schema using .valueOf()
console.log(AdminUserSchema.valueOf())const BotUserSchema = UserSchema.pick("name", "role");
// Now lets get interface from schema
type BotUser = typeof BotUserSchema.type
/*
type BotUser = {
name: string,
role: 'client' | 'supplier',
}
*/// Get plain JSON Schema using .valueOf()
console.log(BotUserSchema.valueOf())```
## ๐ Reasons for using schemez
- Sensible defaults (ie properties are required by default)
- Built in TypeScript and TypeScript Support
- Reduced code duplication with TypeScript-like utilities (ie pick, omit, etc)
- Less code overall
- Can be easily extended to include UI via JSON Schema prop "description"## ๐ Reasons against using schemez
- New
- Existing libraries with similar features (find more below)## ๐ Comparison against similar libraries (fluent-json-schema vs schemez vs typebox)
[Comparison](https://stackblitz.com/edit/typescript-5bksyx?file=index.ts)
## โญ๏ธ Show your support
Give a โญ๏ธ if this project helped you!
## ๐ DocumentationFull documentation available [here](https://takitotech.github.io/schemez/)
### Main exported variable s: SchemaFactory extends BaseSchema. Examples found in test files.
Method
Description
TypeScript
JSON Schema
s.any(): BaseSchema
Correspond to any type
any
{ }
s.string(): StringSchema
For strings validation
string
{ "type": "string" }
s.number(): NumericSchema
For float/integer validation
number
{ "type": "number" }
s.integer(): NumericSchema
For integer values validation
number
{ "type": "integer" }
s.boolean(): BaseSchema
For boolean values
boolean
{ "type": "boolean" }
s.null(): BaseSchema
For null value validation
null
{ "type": "null" }
s.array(): ArraySchema
Array validation (more likely you are looking for s.list)
[]
{ "type": "array" }
s.list(itemType: T): ArraySchema
Validation of lists. Example: s.list(s.string()): ArraySchema
T[]
{ "type": "array", "items": { ... } }
s.object(): ObjectSchema
Object creation (more likely you are looking for s.shape)
{}
{ "type": "object" }
s.shape({ key: Schema }: T): ObjectSchema
Object creation
{ ... }
{ "type": "object", properties: T, additionalProperties: false } }
s.pick(...fields: string[]: T): ObjectSchema
Create a new object with chosen fields
{ ... }
{ "type": "object", properties: T, additionalProperties: false } }
s.omit(...fields: string[]: T): ObjectSchema
Create a new object with not-chosen fields
{ ... }
{ "type": "object", properties: T, additionalProperties: false } }
s.and(mergeWith: ObjectSchema): ObjectSchema
Create a new object that merges with both ObjectSchemas. Similar to typescript's intersection operator (&)
& (aka. intersection)
{ "type": "object", properties: T, additionalProperties: false } }
s.andShape({ key: Schema }: T): ObjectSchema
Create a new object that merges with ObjectSchema and new ObjectSchema. Similar to and + shape.
& (aka. intersection)
{ "type": "object", properties: T, additionalProperties: false } }
s.enum(...constants: T[]): BaseSchema
Enumerable schema
A | B | C
{ enum: [ T[0], T[1] ] }
s.const(constant: T): BaseSchema
Constant value
const
{ const: T }
s.anyOf(...schemas: BaseSchema[]): BaseSchema
Any (one or more) of given types
any
{ anyOf: [ T[0], T[1], ... ] }
s.oneOf(...schemas: BaseSchema[]): BaseSchema
Value shoud correspond to ONE of given types
any
{ oneOf: [ T[0], T[1], ... ] }
s.allOf(...schemas: BaseSchema[]): BaseSchema
Value should correspond to ALL of given type
any
{ allOf: [ T[0], T[1], ... ] }
s.raw(values: any): BaseSchema
Set custom schema values (For Swagger definitions for example)
any
{ ...values }
s.title(value: string): BaseSchema
Add title to schema
N/A
{ "title": "string" }
s.description(value: string): BaseSchema
Add description (either string or object that is stringified) to schema
N/A
{ "description": "string" }
s.optional(): BaseSchema
Optional (similar to optional (?) typescript type and NOT partial type)
T | undefined
{ "required": [ ... ] }
s.partial(): ObjectSchema
Sets object's fields as optional; Does NOT set object itself as optional
{ ...? } (aka. optional fields)
{ "type": "object", properties: T, additionalProperties: false, "required": [] } }
s.partialDeep(): ObjectSchema
Sets object's fields and fields' fields recursively as optional; Does NOT set object itself as optional
{ ...? } (aka. optional fields)
{ "type": "object", properties: T, additionalProperties: false, "required": [] } }
## ๐ญ Release setup
Uses semantic-release to manage releases.### ๐ Commit message format
**semantic-release** uses the commit messages to determine the consumer impact of changes in the codebase.
Following formalized conventions for commit messages, **semantic-release** automatically determines the next [semantic version](https://semver.org) number, generates a changelog and publishes the release.By default, **semantic-release** uses [Angular Commit Message Conventions](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format).
The commit message format can be changed with the [`preset` or `config` options](docs/usage/configuration.md#options) of the [@semantic-release/commit-analyzer](https://github.com/semantic-release/commit-analyzer#options) and [@semantic-release/release-notes-generator](https://github.com/semantic-release/release-notes-generator#options) plugins.Tools such as [commitizen](https://github.com/commitizen/cz-cli) or [commitlint](https://github.com/conventional-changelog/commitlint) can be used to help contributors and enforce valid commit messages.
The table below shows which commit message gets you which release type when `semantic-release` runs (using the default configuration):
| Commit message | Release type |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |
| `fix(pencil): stop graphite breaking when too much pressure applied` | ~~Patch~~ Fix Release |
| `feat(pencil): add 'graphiteWidth' option` | ~~Minor~~ Feature Release |
| `perf(pencil): remove graphiteWidth option`
`BREAKING CHANGE: The graphiteWidth option has been removed.`
`The default graphite width of 10mm is always used for performance reasons.` | ~~Major~~ Breaking Release
(Note that the `BREAKING CHANGE: ` token must be in the footer of the commit) |Ref: https://github.com/semantic-release/semantic-release#commit-message-format
## ๐ค Contributing
Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/TakitoTech/schemez/issues).### ๐งช Run tests
```sh
pnpm test
```## โ๏ธ Author
๐ค TriStarGod
* Github: [@TriStarGod](https://github.com/TriStarGod)