@sleekcms/json-zen 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +29 -0
- package/README.md +292 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +326 -0
- package/lib/index.js.map +1 -0
- package/lib/lib.d.ts +9 -0
- package/lib/lib.d.ts.map +1 -0
- package/lib/lib.js +35 -0
- package/lib/lib.js.map +1 -0
- package/lib/types.d.ts +24 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +111 -0
- package/lib/types.js.map +1 -0
- package/lib/zen-error.d.ts +7 -0
- package/lib/zen-error.d.ts.map +1 -0
- package/lib/zen-error.js +17 -0
- package/lib/zen-error.js.map +1 -0
- package/package.json +55 -0
- package/src/index.ts +334 -0
- package/src/lib.ts +31 -0
- package/src/types.ts +115 -0
- package/src/zen-error.ts +16 -0
package/src/lib.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function isArray(value: unknown): value is unknown[] {
|
|
2
|
+
return Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function isObject(value: unknown): value is Record<string, unknown> {
|
|
6
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function isString(value: unknown): value is string {
|
|
10
|
+
return typeof value === 'string' || value instanceof String;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function isNumber(value: unknown): value is number {
|
|
14
|
+
return typeof value === 'number' || value instanceof Number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isBoolean(value: unknown): value is boolean {
|
|
18
|
+
return typeof value === 'boolean' || value instanceof Boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isInteger(value: unknown): value is number {
|
|
22
|
+
return Number.isInteger(value);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isFunction(value: unknown): value is Function {
|
|
26
|
+
return typeof value === 'function';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isRegExp(value: unknown): value is RegExp {
|
|
30
|
+
return value instanceof RegExp;
|
|
31
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { isArray, isObject, isString, isNumber, isBoolean, isRegExp } from "./lib";
|
|
2
|
+
|
|
3
|
+
export interface CheckOptions {
|
|
4
|
+
path?: string;
|
|
5
|
+
json?: unknown;
|
|
6
|
+
parent?: unknown;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type TypeValidatorFunction = (value?: unknown, opts?: CheckOptions) => boolean | unknown;
|
|
10
|
+
|
|
11
|
+
export interface TypesMap {
|
|
12
|
+
[key: string]: TypeValidatorFunction;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class ZenTypes {
|
|
16
|
+
types: TypesMap;
|
|
17
|
+
|
|
18
|
+
static ALIASES: Record<string, string> = {
|
|
19
|
+
"s": "string",
|
|
20
|
+
"n": "number",
|
|
21
|
+
"b": "boolean",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
static TYPES: TypesMap = {
|
|
25
|
+
"string": (v?: unknown) => v !== undefined ? isString(v) : "",
|
|
26
|
+
"number": (v?: unknown) => v !== undefined ? isNumber(v) : 0,
|
|
27
|
+
"boolean": (v?: unknown) => v !== undefined ? isBoolean(v) : true,
|
|
28
|
+
"null": (v?: unknown) => v !== undefined ? v === null : null,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
constructor(types?: Record<string, unknown>) {
|
|
32
|
+
this.types = Object.assign({}, ZenTypes.TYPES);
|
|
33
|
+
if (types) {
|
|
34
|
+
for (const k in types) {
|
|
35
|
+
if (k.match(/^_/)) continue;
|
|
36
|
+
const fn = types[k];
|
|
37
|
+
this.types[k] = ZenTypes._toType(fn);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static _toType(fn: unknown): TypeValidatorFunction {
|
|
43
|
+
if (isArray(fn)) {
|
|
44
|
+
const lookup = fn as string[];
|
|
45
|
+
return (v?: unknown): boolean | string => {
|
|
46
|
+
if (v !== undefined) return !isString(v) || lookup.indexOf(v as string) >= 0;
|
|
47
|
+
else return lookup[(Math.random() * lookup.length) | 0];
|
|
48
|
+
};
|
|
49
|
+
} else if (isRegExp(fn)) {
|
|
50
|
+
const regex = fn as RegExp;
|
|
51
|
+
return (v?: unknown): boolean | string => {
|
|
52
|
+
if (v !== undefined) return !isString(v) || regex.test(v as string);
|
|
53
|
+
else return regex.source.replace(/\\(.)/g, "$1");
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return fn as TypeValidatorFunction;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static extend(obj: Record<string, unknown>): void {
|
|
60
|
+
for (const k in obj) {
|
|
61
|
+
this.TYPES[k] = this._toType(obj[k]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static toSchema(obj: unknown): string {
|
|
66
|
+
if (obj === null) return "?";
|
|
67
|
+
if (obj === undefined) return "?";
|
|
68
|
+
if (isArray(obj)) return "array";
|
|
69
|
+
if (isObject(obj)) return "object";
|
|
70
|
+
if (isString(obj)) return "string";
|
|
71
|
+
if (isBoolean(obj)) return "boolean";
|
|
72
|
+
if (isNumber(obj)) return "number";
|
|
73
|
+
return "?";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
resolve(k: string): string {
|
|
77
|
+
return ZenTypes.ALIASES[k] ?? k;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
sample(k: string): unknown {
|
|
81
|
+
if (!this.has(k)) return null;
|
|
82
|
+
return this.types[this.resolve(k)]();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
has(k: string): boolean {
|
|
86
|
+
return !!this.types[this.resolve(k)];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
cast(k: string, value: unknown): unknown {
|
|
90
|
+
const resolved = this.resolve(k);
|
|
91
|
+
if (!this.has(k)) return null;
|
|
92
|
+
if (resolved === "boolean") {
|
|
93
|
+
if (["true", "1", "yes", true].indexOf(value as string | boolean) >= 0) return true;
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (resolved === "number") return parseFloat(value as string);
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
check(k: string, obj: unknown, opts?: CheckOptions): boolean {
|
|
101
|
+
const resolved = this.resolve(k);
|
|
102
|
+
if (!this.has(k)) return false;
|
|
103
|
+
return this.types[resolved](obj, opts) as boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
show(): Record<string, unknown> {
|
|
107
|
+
const obj: Record<string, unknown> = {};
|
|
108
|
+
for (const k in this.types) {
|
|
109
|
+
obj[k] = this.types[k]();
|
|
110
|
+
}
|
|
111
|
+
return obj;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default ZenTypes;
|
package/src/zen-error.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ValidationError = [string, string];
|
|
2
|
+
|
|
3
|
+
export class ZenError extends Error {
|
|
4
|
+
errors: ValidationError[];
|
|
5
|
+
|
|
6
|
+
constructor(errors: ValidationError[]) {
|
|
7
|
+
if (errors.length === 1) {
|
|
8
|
+
super(errors[0].join(": "));
|
|
9
|
+
} else {
|
|
10
|
+
super(`Validation failed: ${errors.length} errors found`);
|
|
11
|
+
}
|
|
12
|
+
this.errors = errors;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default ZenError;
|