Setup eslint and enforce rules
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
82e7a1f299
commit
1d5056b753
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
lib
|
||||||
|
dist
|
@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 12,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
"error",
|
||||||
|
"single",
|
||||||
|
{
|
||||||
|
"allowTemplateLiterals": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"no-console": "error",
|
||||||
|
"curly": "error",
|
||||||
|
"eqeqeq": "error",
|
||||||
|
"guard-for-in": "error",
|
||||||
|
"no-alert": "error",
|
||||||
|
"no-caller": "error",
|
||||||
|
"no-constructor-return": "error",
|
||||||
|
"no-eval": "error",
|
||||||
|
"no-implicit-coercion": "error",
|
||||||
|
"no-implied-eval": "error",
|
||||||
|
"no-invalid-this": "error",
|
||||||
|
"no-return-await": "error",
|
||||||
|
"no-throw-literal": "error",
|
||||||
|
"no-useless-call": "error",
|
||||||
|
"radix": "error",
|
||||||
|
"yoda": "error",
|
||||||
|
"@typescript-eslint/no-shadow": "error",
|
||||||
|
"brace-style": "error",
|
||||||
|
"camelcase": "error",
|
||||||
|
"comma-dangle": [
|
||||||
|
"error",
|
||||||
|
"always-multiline"
|
||||||
|
],
|
||||||
|
"comma-spacing": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"before": false,
|
||||||
|
"after": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"comma-style": [
|
||||||
|
"error",
|
||||||
|
"last"
|
||||||
|
],
|
||||||
|
"computed-property-spacing": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"eol-last": "error",
|
||||||
|
"func-call-spacing": [
|
||||||
|
"error",
|
||||||
|
"never"
|
||||||
|
],
|
||||||
|
"keyword-spacing": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"before": true,
|
||||||
|
"after": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lines-between-class-members": "error",
|
||||||
|
"max-params": [
|
||||||
|
"error",
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"new-parens": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"newline-per-chained-call": "error",
|
||||||
|
"no-trailing-spaces": "error",
|
||||||
|
"no-underscore-dangle": "error",
|
||||||
|
"no-unneeded-ternary": "error",
|
||||||
|
"no-whitespace-before-property": "error",
|
||||||
|
"object-property-newline": "error",
|
||||||
|
"prefer-exponentiation-operator": "error",
|
||||||
|
"prefer-object-spread": "error",
|
||||||
|
"spaced-comment": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,21 @@
|
|||||||
import {Template} from "../Template"
|
import {Template} from '../Template'
|
||||||
import {UniversalPath} from "../../util"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A template that generates a new configuration file in the app/configs directory.
|
* A template that generates a new configuration file in the app/configs directory.
|
||||||
*/
|
*/
|
||||||
const config_template: Template = {
|
const templateConfig: Template = {
|
||||||
name: 'config',
|
name: 'config',
|
||||||
fileSuffix: '.config.ts',
|
fileSuffix: '.config.ts',
|
||||||
description: 'Create a new config file.',
|
description: 'Create a new config file.',
|
||||||
baseAppPath: ['configs'],
|
baseAppPath: ['configs'],
|
||||||
render(name: string, fullCanonicalName: string, targetFilePath: UniversalPath) {
|
render() {
|
||||||
return `import { env } from '@extollo/lib'
|
return `import { env } from '@extollo/lib'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
key: env('VALUE_ENV_VAR', 'default value'),
|
key: env('VALUE_ENV_VAR', 'default value'),
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export { config_template }
|
export { templateConfig }
|
||||||
|
@ -1,130 +1,150 @@
|
|||||||
import {ValidationResult, ValidatorFunction} from "./types";
|
import {ValidationResult, ValidatorFunction} from './types'
|
||||||
|
|
||||||
export namespace Arr {
|
/** Requires the input value to be an array. */
|
||||||
/** Requires the input value to be an array. */
|
function is(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
export function is(fieldName: string, inputValue: any): ValidationResult {
|
|
||||||
if ( Array.isArray(inputValue) ) {
|
if ( Array.isArray(inputValue) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'must be an array'
|
message: 'must be an array',
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Requires the values in the input value array to be distinct. */
|
/** Requires the values in the input value array to be distinct. */
|
||||||
export function distinct(fieldName: string, inputValue: any): ValidationResult {
|
function distinct(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( (new Set(inputValue)).size === inputValue.length ) {
|
if ( Array.isArray(inputValue) && (new Set(inputValue)).size === inputValue.length ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'must not contain duplicate values'
|
message: 'must not contain duplicate values',
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input array to contain the given value.
|
* Builds a validator function that requires the input array to contain the given value.
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
export function includes(value: any): ValidatorFunction {
|
function includes(value: unknown): ValidatorFunction {
|
||||||
return function includes(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( inputValue.includes(value) ) {
|
if ( Array.isArray(inputValue) && inputValue.includes(value) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must include ${value}`
|
message: `must include ${value}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input array NOT to contain the given value.
|
* Builds a validator function that requires the input array NOT to contain the given value.
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
export function excludes(value: any): ValidatorFunction {
|
function excludes(value: unknown): ValidatorFunction {
|
||||||
return function excludes(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( !inputValue.includes(value) ) {
|
if ( Array.isArray(inputValue) && !inputValue.includes(value) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must not include ${value}`
|
message: `must not include ${value}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input array to have exactly `len` many entries.
|
* Builds a validator function that requires the input array to have exactly `len` many entries.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function length(len: number): ValidatorFunction {
|
function length(len: number): ValidatorFunction {
|
||||||
return function length(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( inputValue.length === len ) {
|
if ( Array.isArray(inputValue) && inputValue.length === len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be exactly of length ${len}`
|
message: `must be exactly of length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input array to have at least `len` many entries.
|
* Builds a validator function that requires the input array to have at least `len` many entries.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function lengthMin(len: number): ValidatorFunction {
|
function lengthMin(len: number): ValidatorFunction {
|
||||||
return function lengthMin(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( inputValue.length >= len ) {
|
if ( Array.isArray(inputValue) && inputValue.length >= len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be at least length ${len}`
|
message: `must be at least length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input array to have at most `len` many entries.
|
* Builds a validator function that requires the input array to have at most `len` many entries.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function lengthMax(len: number): ValidatorFunction {
|
function lengthMax(len: number): ValidatorFunction {
|
||||||
return function lengthMax(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
const arr = is(fieldName, inputValue)
|
const arr = is(fieldName, inputValue)
|
||||||
if ( !arr.valid ) return arr
|
if ( !arr.valid ) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
if ( inputValue.length <= len ) {
|
if ( Array.isArray(inputValue) && inputValue.length <= len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be at most length ${len}`
|
message: `must be at most length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Arr = {
|
||||||
|
is,
|
||||||
|
distinct,
|
||||||
|
includes,
|
||||||
|
excludes,
|
||||||
|
length,
|
||||||
|
lengthMin,
|
||||||
|
lengthMax,
|
||||||
|
}
|
||||||
|
@ -1,224 +1,245 @@
|
|||||||
import {ValidationResult, ValidatorFunction} from "./types";
|
import {ValidationResult, ValidatorFunction} from './types'
|
||||||
import {isJSON} from '../../util'
|
import {isJSON} from '../../util'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String-related validation rules.
|
* String-related validation rules.
|
||||||
*/
|
*/
|
||||||
export namespace Str {
|
const regexes: {[key: string]: RegExp} = {
|
||||||
const regexes: {[key: string]: RegExp} = {
|
|
||||||
'string.is.alpha': /[a-zA-Z]*/,
|
'string.is.alpha': /[a-zA-Z]*/,
|
||||||
'string.is.alpha_num': /[a-zA-Z0-9]*/,
|
'string.is.alpha_num': /[a-zA-Z0-9]*/,
|
||||||
'string.is.alpha_dash': /[a-zA-Z\-]*/,
|
'string.is.alpha_dash': /[a-zA-Z-]*/,
|
||||||
'string.is.alpha_score': /[a-zA-Z_]*/,
|
'string.is.alpha_score': /[a-zA-Z_]*/,
|
||||||
'string.is.alpha_num_dash_score': /[a-zA-Z\-_0-9]*/,
|
'string.is.alpha_num_dash_score': /[a-zA-Z\-_0-9]*/,
|
||||||
'string.is.email': /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)])/,
|
'string.is.email': /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)])/, // eslint-disable-line no-control-regex
|
||||||
'string.is.ip': /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/,
|
'string.is.ip': /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/,
|
||||||
'string.is.ip.v4': /(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/,
|
'string.is.ip.v4': /(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/,
|
||||||
'string.is.ip.v6': /(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))/,
|
'string.is.ip.v6': /(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))/,
|
||||||
'string.is.mime': /^(?=[-a-z]{1,127}\/[-.a-z0-9]{1,127}$)[a-z]+(-[a-z]+)*\/[a-z0-9]+([-.][a-z0-9]+)*$/,
|
'string.is.mime': /^(?=[-a-z]{1,127}\/[-.a-z0-9]{1,127}$)[a-z]+(-[a-z]+)*\/[a-z0-9]+([-.][a-z0-9]+)*$/,
|
||||||
'string.is.url': /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=+$,\w]+@)?[A-Za-z0-9.\-]+|(?:www\.|[\-;:&=+$,\w]+@)[A-Za-z0-9.\-]+)((?:\/[+~%\/.\w\-_]*)?\??(?:[\-+=&;%@.\w_]*)#?(?:[.!\/\\\w]*))?)/,
|
'string.is.url': /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w\-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\\w]*))?)/,
|
||||||
'string.is.uuid': /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,
|
'string.is.uuid': /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/,
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateRex(key: string, inputValue: any, message: string): ValidationResult {
|
function validateRex(key: string, inputValue: unknown, message: string): ValidationResult {
|
||||||
if ( regexes[key].test(inputValue) ) {
|
if ( regexes[key].test(String(inputValue)) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message
|
message,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Requires the input value to be alphabetical characters only. */
|
/** Requires the input value to be alphabetical characters only. */
|
||||||
export function alpha(fieldName: string, inputValue: any): ValidationResult {
|
function alpha(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.alpha', inputValue, 'must be alphabetical only')
|
return validateRex('string.is.alpha', inputValue, 'must be alphabetical only')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be alphanumeric characters only. */
|
/** Requires the input value to be alphanumeric characters only. */
|
||||||
export function alphaNum(fieldName: string, inputValue: any): ValidationResult {
|
function alphaNum(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.alpha_num', inputValue, 'must be alphanumeric only')
|
return validateRex('string.is.alpha_num', inputValue, 'must be alphanumeric only')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be alphabetical characters or the "-" character only. */
|
/** Requires the input value to be alphabetical characters or the "-" character only. */
|
||||||
export function alphaDash(fieldName: string, inputValue: any): ValidationResult {
|
function alphaDash(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.alpha_dash', inputValue, 'must be alphabetical and dashes only')
|
return validateRex('string.is.alpha_dash', inputValue, 'must be alphabetical and dashes only')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be alphabetical characters or the "_" character only. */
|
/** Requires the input value to be alphabetical characters or the "_" character only. */
|
||||||
export function alphaScore(fieldName: string, inputValue: any): ValidationResult {
|
function alphaScore(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.alpha_score', inputValue, 'must be alphabetical and underscores only')
|
return validateRex('string.is.alpha_score', inputValue, 'must be alphabetical and underscores only')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be alphabetical characters, numeric characters, "-", or "_" only. */
|
/** Requires the input value to be alphabetical characters, numeric characters, "-", or "_" only. */
|
||||||
export function alphaNumDashScore(fieldName: string, inputValue: any): ValidationResult {
|
function alphaNumDashScore(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.alpha_num_dash_score', inputValue, 'must be alphanumeric, dashes, and underscores only')
|
return validateRex('string.is.alpha_num_dash_score', inputValue, 'must be alphanumeric, dashes, and underscores only')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid RFC email address format. */
|
/** Requires the input value to be a valid RFC email address format. */
|
||||||
export function email(fieldName: string, inputValue: any): ValidationResult {
|
function email(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.email', inputValue, 'must be an email address')
|
return validateRex('string.is.email', inputValue, 'must be an email address')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid IPv4 or IPv6 address. */
|
/** Requires the input value to be a valid IPv4 or IPv6 address. */
|
||||||
export function ip(fieldName: string, inputValue: any): ValidationResult {
|
function ip(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.ip', inputValue, 'must be a valid IP address')
|
return validateRex('string.is.ip', inputValue, 'must be a valid IP address')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid IPv4 address. */
|
/** Requires the input value to be a valid IPv4 address. */
|
||||||
export function ipv4(fieldName: string, inputValue: any): ValidationResult {
|
function ipv4(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.ip.v4', inputValue, 'must be a valid IP version 4 address')
|
return validateRex('string.is.ip.v4', inputValue, 'must be a valid IP version 4 address')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid IPv6 address. */
|
/** Requires the input value to be a valid IPv6 address. */
|
||||||
export function ipv6(fieldName: string, inputValue: any): ValidationResult {
|
function ipv6(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.ip.v6', inputValue, 'must be a valid IP version 6 address')
|
return validateRex('string.is.ip.v6', inputValue, 'must be a valid IP version 6 address')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid file MIME type. */
|
/** Requires the input value to be a valid file MIME type. */
|
||||||
export function mime(fieldName: string, inputValue: any): ValidationResult {
|
function mime(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.mime', inputValue, 'must be a valid MIME-type')
|
return validateRex('string.is.mime', inputValue, 'must be a valid MIME-type')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid RFC URL format. */
|
/** Requires the input value to be a valid RFC URL format. */
|
||||||
export function url(fieldName: string, inputValue: any): ValidationResult {
|
function url(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.url', inputValue, 'must be a valid URL')
|
return validateRex('string.is.url', inputValue, 'must be a valid URL')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid RFC UUID format. */
|
/** Requires the input value to be a valid RFC UUID format. */
|
||||||
export function uuid(fieldName: string, inputValue: any): ValidationResult {
|
function uuid(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
return validateRex('string.is.uuid', inputValue, 'must be a valid UUID')
|
return validateRex('string.is.uuid', inputValue, 'must be a valid UUID')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validation function that requires the input value to match the given regex.
|
* Builds a validation function that requires the input value to match the given regex.
|
||||||
* @param rex
|
* @param rex
|
||||||
*/
|
*/
|
||||||
export function regex(rex: RegExp): ValidatorFunction {
|
function regex(rex: RegExp): ValidatorFunction {
|
||||||
return function regex(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( rex.test(inputValue) ) {
|
if ( rex.test(String(inputValue)) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'is not valid'
|
message: 'is not valid',
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validation function that requires the input to NOT match the given regex.
|
* Builds a validation function that requires the input to NOT match the given regex.
|
||||||
* @param rex
|
* @param rex
|
||||||
*/
|
*/
|
||||||
export function notRegex(rex: RegExp): ValidatorFunction {
|
function notRegex(rex: RegExp): ValidatorFunction {
|
||||||
return function notRegex(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( !rex.test(inputValue) ) {
|
if ( !rex.test(String(inputValue)) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'is not valid'
|
message: 'is not valid',
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validation function that requires the given input to end with the substring.
|
* Builds a validation function that requires the given input to end with the substring.
|
||||||
* @param substr
|
* @param substr
|
||||||
*/
|
*/
|
||||||
export function ends(substr: string): ValidatorFunction {
|
function ends(substr: string): ValidatorFunction {
|
||||||
return function ends(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( String(inputValue).endsWith(substr) ) {
|
if ( String(inputValue).endsWith(substr) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must end with "${substr}"`
|
message: `must end with "${substr}"`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validation function that requires the given input to begin with the substring.
|
* Builds a validation function that requires the given input to begin with the substring.
|
||||||
* @param substr
|
* @param substr
|
||||||
*/
|
*/
|
||||||
export function begins(substr: string): ValidatorFunction {
|
function begins(substr: string): ValidatorFunction {
|
||||||
return function begins(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( String(inputValue).startsWith(substr) ) {
|
if ( String(inputValue).startsWith(substr) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must begin with "${substr}"`
|
message: `must begin with "${substr}"`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Requires the input value to be a valid JSON string. */
|
/** Requires the input value to be a valid JSON string. */
|
||||||
export function json(fieldName: string, inputValue: any): ValidationResult {
|
function json(fieldName: string, inputValue: unknown): ValidationResult {
|
||||||
if ( isJSON(inputValue) ) {
|
if ( isJSON(String(inputValue)) ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: 'must be valid JSON'
|
message: 'must be valid JSON',
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input value to have exactly len many characters.
|
* Builds a validator function that requires the input value to have exactly len many characters.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function length(len: number): ValidatorFunction {
|
function length(len: number): ValidatorFunction {
|
||||||
return function length(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( inputValue.length === len ) {
|
if ( String(inputValue).length === len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be exactly of length ${len}`
|
message: `must be exactly of length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input value to have at least len many characters.
|
* Builds a validator function that requires the input value to have at least len many characters.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function lengthMin(len: number): ValidatorFunction {
|
function lengthMin(len: number): ValidatorFunction {
|
||||||
return function lengthMin(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( inputValue.length >= len ) {
|
if ( String(inputValue).length >= len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be at least length ${len}`
|
message: `must be at least length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a validator function that requires the input value to have at most len many characters.
|
* Builds a validator function that requires the input value to have at most len many characters.
|
||||||
* @param len
|
* @param len
|
||||||
*/
|
*/
|
||||||
export function lengthMax(len: number): ValidatorFunction {
|
function lengthMax(len: number): ValidatorFunction {
|
||||||
return function lengthMax(fieldName: string, inputValue: any): ValidationResult {
|
return (fieldName: string, inputValue: unknown): ValidationResult => {
|
||||||
if ( inputValue.length <= len ) {
|
if ( String(inputValue).length <= len ) {
|
||||||
return { valid: true }
|
return { valid: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
valid: false,
|
valid: false,
|
||||||
message: `must be at most length ${len}`
|
message: `must be at most length ${len}`,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const Str = {
|
||||||
|
alpha,
|
||||||
|
alphaNum,
|
||||||
|
alphaDash,
|
||||||
|
alphaScore,
|
||||||
|
alphaNumDashScore,
|
||||||
|
email,
|
||||||
|
ip,
|
||||||
|
ipv4,
|
||||||
|
ipv6,
|
||||||
|
mime,
|
||||||
|
url,
|
||||||
|
uuid,
|
||||||
|
regex,
|
||||||
|
notRegex,
|
||||||
|
ends,
|
||||||
|
begins,
|
||||||
|
json,
|
||||||
|
length,
|
||||||
|
lengthMin,
|
||||||
|
lengthMax,
|
||||||
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import {ErrorWithContext} from "../../util";
|
import {ErrorWithContext} from '../../util'
|
||||||
import {Container} from "../../di";
|
import {Container} from '../../di'
|
||||||
import {ResultIterable} from "./result/ResultIterable";
|
import {ResultIterable} from './result/ResultIterable'
|
||||||
import {QueryRow} from "../types";
|
import {QueryRow} from '../types'
|
||||||
import {AbstractBuilder} from "./AbstractBuilder";
|
import {AbstractBuilder} from './AbstractBuilder'
|
||||||
import {AbstractResultIterable} from "./result/AbstractResultIterable";
|
import {AbstractResultIterable} from './result/AbstractResultIterable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the abstract builder class that returns simple QueryRow objects.
|
* Implementation of the abstract builder class that returns simple QueryRow objects.
|
||||||
*/
|
*/
|
||||||
export class Builder extends AbstractBuilder<QueryRow> {
|
export class Builder extends AbstractBuilder<QueryRow> {
|
||||||
public getNewInstance(): AbstractBuilder<QueryRow> {
|
public getNewInstance(): AbstractBuilder<QueryRow> {
|
||||||
return Container.getContainer().make<Builder>(Builder);
|
return Container.getContainer().make<Builder>(Builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
public getResultIterable(): AbstractResultIterable<QueryRow> {
|
public getResultIterable(): AbstractResultIterable<QueryRow> {
|
||||||
if ( !this._connection ) {
|
if ( !this.registeredConnection ) {
|
||||||
throw new ErrorWithContext(`No connection specified to fetch iterator for query.`)
|
throw new ErrorWithContext(`No connection specified to fetch iterator for query.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Container.getContainer().make<ResultIterable>(ResultIterable, this, this._connection)
|
return Container.getContainer().make<ResultIterable>(ResultIterable, this, this.registeredConnection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue