Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
flasd committed Mar 19, 2020
0 parents commit 8514d59
Show file tree
Hide file tree
Showing 6 changed files with 3,292 additions and 0 deletions.
63 changes: 63 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

dist
64 changes: 64 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Dependency directories
node_modules/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
.rts2_cache_modern/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# Source files
src/

# Tslint file
tslint.json
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@flasd/express-yup-middleware",
"version": "0.3.0",
"private": false,
"source": "src/index.ts",
"main": "dist/index.umd.js",
"module": "dist/index.js",
"license": "MIT",
"dependencies": {
"@types/express": "^4.17.2",
"@types/yup": "^0.26.30",
"deepmerge": "^4.2.2",
"lodash.get": "^4.4.2",
"yup": "^0.28.1"
},
"scripts": {
"build": "microbundle -f esm,umd --target node --strict --name expressYupMiddleware",
"dev": "microbundle watch"
},
"devDependencies": {
"microbundle": "0.12.0-next.7"
}
}
89 changes: 89 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { isSchema, object } from 'yup';
import { Schema, ValidateOptions, ValidationError } from 'yup';
import { Request, Response, NextFunction } from 'express';
import deepmerge from 'deepmerge';
import get from 'lodash.get';

type ResponseOptions = {
errorCode?: number;
returnErrors?: boolean;
transformErrors?: (errors: Array<string>) => Array<string>
}

type ExpressYupMiddlewareConfig = {
validateOptions?: ValidateOptions,
responseOptions?: ResponseOptions,
entityFrom: 'query' | 'body' | 'other',
entityPath?: string,
transformEntity?: (entity: any) => any
}

const defaults: ExpressYupMiddlewareConfig = {
validateOptions: {
strict: true,
stripUnknown: true,
abortEarly: false,
},
responseOptions: {
errorCode: 422,
returnErrors: true,
transformErrors: (e) => e,
},
entityFrom: 'body',
}

function getSchema(schema: Schema<any> | object, validateOptions: ValidateOptions) {
if (isSchema(schema)) {
return schema;
}

return object(schema).strict(validateOptions.strict);
}

export default function validate(schema: Schema<any> | Object, options?: ExpressYupMiddlewareConfig) {
const configs: ExpressYupMiddlewareConfig = deepmerge(
defaults,
options || {}
);

const finalSchema = getSchema(schema, configs.validateOptions);

return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
try {
let entity: any;

if (configs.entityFrom === 'body') {
entity = configs.entityPath ? get(req.body, configs.entityPath, {}) : req.body;
} else if (configs.entityFrom === 'query') {
entity = configs.entityPath ? get(req.query, configs.entityPath, {}) : req.query;
} else {
entity = configs.entityPath ? get(req, configs.entityPath, {}) : null;
}

if (typeof configs.transformEntity === 'function') {
entity = configs.transformEntity(entity);
}

await finalSchema.validate(entity, configs.validateOptions);
next();
} catch (error) {
if (!(error instanceof ValidationError)) {
throw error;
}

const { errors } = error;
let payload = [];

if (
Array.isArray(errors)
&& typeof configs.responseOptions.transformErrors === 'function'
) {
payload = configs.responseOptions.transformErrors(errors);
}

res
.status(configs.responseOptions.errorCode)
.send(configs.responseOptions.returnErrors ? { errors: payload } : {});
}
}
}
5 changes: 5 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true
}
}
Loading

0 comments on commit 8514d59

Please sign in to comment.