mirror of
https://github.com/foomo/fender-ts.git
synced 2026-08-11 20:40:16 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/typescript",
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": { "browsers": "defaults, not ie 11", "node": true },
|
||||
"modules": false,
|
||||
"useBuiltIns": false,
|
||||
"loose": true
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": ["@babel/plugin-transform-modules-commonjs"]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yaml,yml}]
|
||||
indent_style = space
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"prettier",
|
||||
"prettier/@typescript-eslint"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2020,
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"browser": true
|
||||
},
|
||||
"settings": {
|
||||
"import/extensions": [
|
||||
".js",
|
||||
".ts"
|
||||
]
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: '/'
|
||||
open-pull-requests-limit: 20
|
||||
schedule:
|
||||
interval: weekly
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Pull Requests
|
||||
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the main branch
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
CI: true
|
||||
|
||||
jobs:
|
||||
pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x, 18.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm install
|
||||
- run: npm run lint
|
||||
- run: npm test
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
*.
|
||||
.*
|
||||
!.github/
|
||||
!.babelrc
|
||||
!.eslintrc
|
||||
!.gitignore
|
||||
!.editorconfig
|
||||
!.prettierignore
|
||||
!.prettierrc
|
||||
dist/
|
||||
node_modules/
|
||||
tmp/
|
||||
@@ -0,0 +1,2 @@
|
||||
dist/
|
||||
node_modules/
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 bestbytes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Generated
+17895
File diff suppressed because it is too large
Load Diff
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"name": "superstruct-fender",
|
||||
"description": "Superstruct extension with fender rules",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/foomo/superstruct-fender.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf ./{dist} && rollup --config ./rollup.config.js",
|
||||
"clean": "rm -rf ./{dist,node_modules}",
|
||||
"fix": "npm run fix:eslint && npm run fix:prettier",
|
||||
"fix:eslint": "npm run lint:eslint --fix",
|
||||
"fix:prettier": "npm run lint:prettier --write",
|
||||
"lint": "npm run lint:eslint && npm run lint:prettier",
|
||||
"lint:eslint": "eslint '{src,test}/*.{js,ts}'",
|
||||
"lint:prettier": "prettier --list-different '**/*.{js,json,ts}'",
|
||||
"release": "npm run build && npm run lint && np",
|
||||
"test": "npm run build && npm run test:types && npm run test:mocha",
|
||||
"test:mocha": "mocha --require ./test/register.cjs --require source-map-support/register ./test/index.ts",
|
||||
"test:types": "tsc --noEmit && tsc --project ./test/tsconfig.json --noEmit",
|
||||
"watch": "npm run build -- --watch"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"superstruct": "1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.21.0",
|
||||
"@babel/core": "7.21.0",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.21.2",
|
||||
"@babel/preset-env": "7.20.2",
|
||||
"@babel/preset-typescript": "7.21.0",
|
||||
"@babel/register": "7.21.0",
|
||||
"@rollup/plugin-typescript": "11.0.0",
|
||||
"@types/expect": "24.3.0",
|
||||
"@types/lodash": "4.14.191",
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/node": "18.15.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.54.1",
|
||||
"@typescript-eslint/parser": "5.54.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "8.36.0",
|
||||
"eslint-config-prettier": "8.7.0",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"is-email": "1.0.2",
|
||||
"is-url": "1.2.4",
|
||||
"is-uuid": "1.0.2",
|
||||
"lodash": "4.17.21",
|
||||
"mocha": "10.2.0",
|
||||
"np": "7.6.3",
|
||||
"prettier": "2.8.4",
|
||||
"rollup": "3.19.1",
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"keywords": [
|
||||
"api",
|
||||
"array",
|
||||
"assert",
|
||||
"cast",
|
||||
"check",
|
||||
"checker",
|
||||
"collection",
|
||||
"data",
|
||||
"error",
|
||||
"express",
|
||||
"hapi",
|
||||
"interface",
|
||||
"invalid",
|
||||
"joi",
|
||||
"json",
|
||||
"list",
|
||||
"model",
|
||||
"object",
|
||||
"orm",
|
||||
"scalar",
|
||||
"schema",
|
||||
"struct",
|
||||
"throw",
|
||||
"type",
|
||||
"types",
|
||||
"valid",
|
||||
"validate",
|
||||
"validation",
|
||||
"validator"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'rollup'
|
||||
import typescript from '@rollup/plugin-typescript'
|
||||
|
||||
export default defineConfig({
|
||||
input: './src/index.ts',
|
||||
plugins: [typescript()],
|
||||
output: [
|
||||
{
|
||||
file: './dist/index.mjs',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
},
|
||||
{
|
||||
file: './dist/index.cjs',
|
||||
format: 'umd',
|
||||
name: 'Superstruct Fender',
|
||||
sourcemap: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
export * from './structs/string'
|
||||
@@ -0,0 +1,49 @@
|
||||
import {Struct, refine} from "superstruct";
|
||||
|
||||
export function prefix<T extends string, S extends any>(
|
||||
struct: Struct<T, S>,
|
||||
expected: string
|
||||
): Struct<T, S> {
|
||||
return refine(struct, 'prefix', (value) => {
|
||||
return (
|
||||
value.startsWith(expected) ||
|
||||
`Expected a ${struct.type} prefix \`${expected}\` but received "${value}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export function noPrefix<T extends string, S extends any>(
|
||||
struct: Struct<T, S>,
|
||||
expected: string
|
||||
): Struct<T, S> {
|
||||
return refine(struct, 'prefix', (value) => {
|
||||
return (
|
||||
!value.startsWith(expected) ||
|
||||
`Expected a ${struct.type} no prefix \`${expected}\` but received "${value}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export function suffix<T extends string, S extends any>(
|
||||
struct: Struct<T, S>,
|
||||
expected: string
|
||||
): Struct<T, S> {
|
||||
return refine(struct, 'suffix', (value) => {
|
||||
return (
|
||||
value.endsWith(expected) ||
|
||||
`Expected a ${struct.type} suffix \`${expected}\` but received "${value}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export function noSuffix<T extends string, S extends any>(
|
||||
struct: Struct<T, S>,
|
||||
expected: string
|
||||
): Struct<T, S> {
|
||||
return refine(struct, 'suffix', (value) => {
|
||||
return (
|
||||
!value.endsWith(expected) ||
|
||||
`Expected a ${struct.type} no suffix \`${expected}\` but received "${value}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import assert, { CallTracker } from 'assert'
|
||||
import fs from 'fs'
|
||||
import { pick } from 'lodash'
|
||||
import { basename, extname, resolve } from 'path'
|
||||
import {
|
||||
any,
|
||||
assert as assertValue,
|
||||
// eslint-disable-next-line import/named
|
||||
Context,
|
||||
create as createValue,
|
||||
deprecated,
|
||||
StructError,
|
||||
} from 'superstruct'
|
||||
|
||||
describe('superstruct-fender', () => {
|
||||
describe('validation', () => {
|
||||
const kindsDir = resolve(__dirname, 'validation')
|
||||
const kinds = fs
|
||||
.readdirSync(kindsDir)
|
||||
.filter((t) => t[0] !== '.')
|
||||
.map((t) => basename(t, extname(t)))
|
||||
|
||||
for (const kind of kinds) {
|
||||
describe(kind, () => {
|
||||
const testsDir = resolve(kindsDir, kind)
|
||||
const tests = fs
|
||||
.readdirSync(testsDir)
|
||||
.filter((t) => t[0] !== '.')
|
||||
.map((t) => basename(t, extname(t)))
|
||||
|
||||
for (const name of tests) {
|
||||
const module = require(resolve(testsDir, name))
|
||||
const { Struct, data, create, only, skip, output, failures } = module
|
||||
const run = only ? it.only : skip ? it.skip : it
|
||||
run(name, () => {
|
||||
let actual
|
||||
let err
|
||||
|
||||
try {
|
||||
if (create) {
|
||||
actual = createValue(data, Struct)
|
||||
} else {
|
||||
assertValue(data, Struct)
|
||||
actual = data
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof StructError)) {
|
||||
throw e
|
||||
}
|
||||
|
||||
err = e
|
||||
}
|
||||
|
||||
if ('output' in module) {
|
||||
if (err) {
|
||||
throw new Error(
|
||||
`Expected "${name}" fixture not to throw an error but it did:\n\n${err}`
|
||||
)
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(actual, output)
|
||||
} else if ('failures' in module) {
|
||||
if (!err) {
|
||||
throw new Error(
|
||||
`Expected "${name}" fixture to throw an error but it did not.`
|
||||
)
|
||||
}
|
||||
|
||||
const props = ['type', 'path', 'refinement', 'value', 'branch']
|
||||
const actualFailures = err
|
||||
.failures()
|
||||
.map((failure) => pick(failure, ...props))
|
||||
|
||||
assert.deepStrictEqual(actualFailures, failures)
|
||||
assert.deepStrictEqual(pick(err, ...props), failures[0])
|
||||
} else {
|
||||
throw new Error(
|
||||
`The "${name}" fixture did not define an \`output\` or \`failures\` export.`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* A helper for testing type signatures.
|
||||
*/
|
||||
|
||||
export function test<T>(fn: (x: unknown) => T) {}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
require('@babel/register')({
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import {string} from 'superstruct'
|
||||
import {prefix} from "../../../src/structs/string";
|
||||
|
||||
export const Struct = prefix(string(), "faa")
|
||||
|
||||
export const data = "foobar"
|
||||
|
||||
export const failures = [
|
||||
{
|
||||
value: 'foobar',
|
||||
type: 'string',
|
||||
refinement: 'prefix',
|
||||
path: [],
|
||||
branch: [data],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
import {string} from 'superstruct'
|
||||
import {suffix} from "../../../src/structs/string";
|
||||
|
||||
export const Struct = suffix(string(), "bar")
|
||||
|
||||
export const data = "foobar"
|
||||
|
||||
export const output = "foobar"
|
||||
@@ -0,0 +1,16 @@
|
||||
import {string} from 'superstruct'
|
||||
import {suffix} from "../../../src/structs/string";
|
||||
|
||||
export const Struct = suffix(string(), "baz")
|
||||
|
||||
export const data = "foobar"
|
||||
|
||||
export const failures = [
|
||||
{
|
||||
value: 'foobar',
|
||||
type: 'string',
|
||||
refinement: 'suffix',
|
||||
path: [],
|
||||
branch: [data],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
import {string} from 'superstruct'
|
||||
import {prefix} from "../../../src/structs/string";
|
||||
|
||||
export const Struct = prefix(string(), "foo")
|
||||
|
||||
export const data = "foobar"
|
||||
|
||||
export const output = "foobar"
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"include": ["./src/**/*.ts"],
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext"],
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"target": "es2020"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user