tst-defaults
Advanced tools
Comparing version 1.0.4 to 1.1.0
@@ -17,3 +17,5 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: | ||
// Add the IDs of extensions you want installed when the container is created. | ||
"extensions": [], | ||
"extensions": [ | ||
"firsttris.vscode-jest-runner" | ||
], | ||
@@ -20,0 +22,0 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. |
import { Type } from "tst-reflect"; | ||
/** | ||
* Saves default value for specified type | ||
* If this type already saved, it will be rewritten with new value | ||
* @param defaultValue Default value for the type <T> | ||
* @param type Type which need to save | ||
*/ | ||
export declare function useDefault<T>(defaultValue: T, type?: Type): void; | ||
/** | ||
* Mergin default values into object or array with already reflected type value | ||
* @param t Type of tst-reflect | ||
* Merges default values into object or array with already reflected type value | ||
* @param value Current value | ||
* @param type Type of tst-reflect | ||
* @returns New rewritten value with default value (or null if not found expected type) | ||
*/ | ||
export declare function mergeDefaults<T>(value: T, type?: Type): T; | ||
export declare function mergeDefaults<T>(value: T, type: Type): T; | ||
/** | ||
@@ -17,5 +23,6 @@ * Returns default value for specified type <T> | ||
* boolean - false | ||
* object - {} | ||
* Object - {} | ||
* if type not expected - null | ||
* @param type Typeof tst-reflect library | ||
*/ | ||
export declare function getDefaultValue<T>(t?: Type): any; | ||
export declare function getDefaultValue<T>(type?: Type): any; |
@@ -7,6 +7,7 @@ "use strict"; | ||
const usingTypes = new Map(); | ||
/* | ||
/** | ||
* Saves default value for specified type | ||
* If this type already saved, it will rewrite with new value | ||
* If this type already saved, it will be rewritten with new value | ||
* @param defaultValue Default value for the type <T> | ||
* @param type Type which need to save | ||
*/ | ||
@@ -16,3 +17,4 @@ function useDefault(defaultValue, type) { | ||
delete arguments[arguments.length]; | ||
const t = type ? type : (__genericParams__ && __genericParams__.T); | ||
let t = type ? type : (__genericParams__ && __genericParams__.T); | ||
t = resolveType(t); | ||
let d = defaultValue; | ||
@@ -29,11 +31,9 @@ if (Array.isArray(d)) { | ||
/** | ||
* Mergin default values into object or array with already reflected type value | ||
* @param t Type of tst-reflect | ||
* Merges default values into object or array with already reflected type value | ||
* @param value Current value | ||
* @param type Type of tst-reflect | ||
* @returns New rewritten value with default value (or null if not found expected type) | ||
*/ | ||
function mergeDefaults(value, type) { | ||
var __genericParams__ = arguments[--arguments.length]; | ||
delete arguments[arguments.length]; | ||
const t = type instanceof tst_reflect_1.Type ? type : (__genericParams__ && __genericParams__.T); | ||
let t = resolveType(type); | ||
let v = value; | ||
@@ -43,10 +43,22 @@ if (v === undefined) { | ||
} | ||
const props = t.getProperties(); | ||
for (const prop of props) { | ||
if (!prop.optional) { | ||
if (v[prop.name] === undefined || prop.type.isObjectLike()) { | ||
v[prop.name] = mergeDefaults(v[prop.name], prop.type, { T: _ßr.Type.store.wrap({ n: "any", k: 2 }) }); | ||
// Resolving arrays too | ||
if (t.isArray() && Array.isArray(value) && value.length) { | ||
let typeArg = t.getTypeArguments()[0]; | ||
if (typeArg) { | ||
for (let i = 0; i < value.length; i++) { | ||
value[i] = mergeDefaults(value[i], typeArg); | ||
} | ||
} | ||
} | ||
else { | ||
const props = t.getProperties(); | ||
for (const prop of props) { | ||
if (!prop.optional) { | ||
let propType = resolveType(prop.type); | ||
if (v[prop.name] === undefined || propType.isObjectLike() || propType.isArray()) { | ||
v[prop.name] = mergeDefaults(v[prop.name], propType); | ||
} | ||
} | ||
} | ||
} | ||
return v; | ||
@@ -56,2 +68,20 @@ } | ||
/** | ||
* Check if type if bug-like type of ts-reflect | ||
* And if it is, gets real type | ||
* @param type | ||
* @returns | ||
*/ | ||
const resolveType = (type) => { | ||
if (type instanceof Function) { | ||
let t = type(); | ||
if (!(t instanceof tst_reflect_1.Type)) { | ||
throw new Error("Type is not a reflected Type"); | ||
} | ||
return t; | ||
} | ||
else { | ||
return type; | ||
} | ||
}; | ||
/** | ||
* Returns default value for specified type <T> | ||
@@ -63,25 +93,27 @@ * Predefined values: | ||
* boolean - false | ||
* object - {} | ||
* Object - {} | ||
* if type not expected - null | ||
* @param type Typeof tst-reflect library | ||
*/ | ||
function getDefaultValue(t) { | ||
function getDefaultValue(type) { | ||
var __genericParams__ = arguments[--arguments.length]; | ||
delete arguments[arguments.length]; | ||
const type = t ? t : (__genericParams__ && __genericParams__.T); | ||
let t = type ? type : (__genericParams__ && __genericParams__.T); | ||
t = resolveType(t); | ||
if (usingTypes.has(type)) { | ||
return usingTypes.get(type); | ||
} | ||
else if (type.isArray() || type.isTuple()) { | ||
else if (t.isArray() || t.isTuple()) { | ||
return []; | ||
} | ||
else if (type.isBoolean()) { | ||
else if (t.isBoolean()) { | ||
return false; | ||
} | ||
else if (type.isEnum() || type.isNumber()) { | ||
else if (t.isEnum() || t.isNumber()) { | ||
return 0; | ||
} | ||
else if (type.isObjectLike()) { | ||
else if (t.isObjectLike()) { | ||
return {}; | ||
} | ||
else if (type.isString()) { | ||
else if (t.isString()) { | ||
return ""; | ||
@@ -88,0 +120,0 @@ } |
{ | ||
"name": "tst-defaults", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "Get default values by Typescript type reflection", | ||
@@ -27,4 +27,4 @@ "main": "dist/index.js", | ||
"build": "ttsc", | ||
"test": "ttsc -p tests/tsconfig.json && jest tests/dist" | ||
"test": "yarn build && ttsc -p tests/tsconfig.json && jest tests/dist" | ||
} | ||
} |
@@ -5,9 +5,12 @@ import { getType, Type } from "tst-reflect" | ||
/* | ||
/** | ||
* Saves default value for specified type | ||
* If this type already saved, it will rewrite with new value | ||
* If this type already saved, it will be rewritten with new value | ||
* @param defaultValue Default value for the type <T> | ||
* @param type Type which need to save | ||
*/ | ||
export function useDefault<T>(defaultValue: T, type?: Type): void { | ||
const t = type ? type : getType<T>(); | ||
let t = type ? type : getType<T>(); | ||
t = resolveType(t); | ||
let d = defaultValue as any; | ||
@@ -19,2 +22,3 @@ if (Array.isArray(d)) { | ||
} | ||
usingTypes.set(t, d); | ||
@@ -24,11 +28,11 @@ } | ||
/** | ||
* Mergin default values into object or array with already reflected type value | ||
* @param t Type of tst-reflect | ||
* Merges default values into object or array with already reflected type value | ||
* @param value Current value | ||
* @param type Type of tst-reflect | ||
* @returns New rewritten value with default value (or null if not found expected type) | ||
*/ | ||
export function mergeDefaults<T>(value: T, type?: Type): T { | ||
export function mergeDefaults<T>(value: T, type: Type): T { | ||
const t = type instanceof Type ? type : getType<T>(); | ||
let t = resolveType(type); | ||
let v = value as any; | ||
@@ -39,7 +43,21 @@ if (v === undefined) { | ||
const props = t.getProperties() | ||
for (const prop of props) { | ||
if (!prop.optional) { | ||
if (v[prop.name] === undefined || prop.type.isObjectLike()) { | ||
v[prop.name] = mergeDefaults(v[prop.name], prop.type); | ||
// Resolving arrays too | ||
if (t.isArray() && Array.isArray(value) && value.length) { | ||
let typeArg = t.getTypeArguments()[0]; | ||
if (typeArg) { | ||
for (let i = 0; i < value.length; i++) { | ||
value[i] = mergeDefaults(value[i], typeArg); | ||
} | ||
} | ||
} else { | ||
const props = t.getProperties(); | ||
for (const prop of props) { | ||
if (!prop.optional) { | ||
let propType = resolveType(prop.type); | ||
if (v[prop.name] === undefined || propType.isObjectLike() || propType.isArray()) { | ||
v[prop.name] = mergeDefaults(v[prop.name], propType); | ||
} | ||
} | ||
@@ -53,2 +71,20 @@ } | ||
/** | ||
* Check if type if bug-like type of ts-reflect | ||
* And if it is, gets real type | ||
* @param type | ||
* @returns | ||
*/ | ||
const resolveType = (type: Type):Type => { | ||
if (type instanceof Function) { | ||
let t = type() as Type; | ||
if (!(t instanceof Type)) { | ||
throw new Error("Type is not a reflected Type") | ||
} | ||
return t; | ||
} else { | ||
return type; | ||
} | ||
} | ||
/** | ||
* Returns default value for specified type <T> | ||
@@ -60,19 +96,21 @@ * Predefined values: | ||
* boolean - false | ||
* object - {} | ||
* Object - {} | ||
* if type not expected - null | ||
* @param type Typeof tst-reflect library | ||
*/ | ||
export function getDefaultValue<T>(t?: Type): any { | ||
const type = t ? t : getType<T>(); | ||
export function getDefaultValue<T>(type?: Type): any { | ||
let t = type ? type : getType<T>(); | ||
t = resolveType(t); | ||
if (usingTypes.has(type)) { | ||
return usingTypes.get(type); | ||
} else if (type.isArray() || type.isTuple()) { | ||
} else if (t.isArray() || t.isTuple()) { | ||
return []; | ||
} else if (type.isBoolean()) { | ||
} else if (t.isBoolean()) { | ||
return false; | ||
} else if (type.isEnum() || type.isNumber()) { | ||
} else if (t.isEnum() || t.isNumber()) { | ||
return 0; | ||
} else if (type.isObjectLike()) { | ||
} else if (t.isObjectLike()) { | ||
return {} | ||
} else if (type.isString()) { | ||
} else if (t.isString()) { | ||
return ""; | ||
@@ -79,0 +117,0 @@ } |
@@ -28,7 +28,17 @@ import { getDefaultValue, mergeDefaults, useDefault } from "../../dist/"; | ||
work_type: WorkType | ||
users: User[] | ||
} | ||
type User = { | ||
first_name?: string | ||
last_name: string | ||
friends: User[] | ||
rate_expires?: Duration | ||
} | ||
const returnIgnoredJsonError = ():any => {} | ||
test('json schema defaults', () => { | ||
useDefault({ | ||
@@ -42,3 +52,12 @@ seconds: -1, | ||
"use_snippets": true | ||
} | ||
}, | ||
"users": [{ | ||
"friends": [{ | ||
"first_name": "Oleg", | ||
"last_name": "Prokofyev", | ||
"rate_expires": { | ||
"seconds": 1000 | ||
} | ||
}] | ||
}] | ||
}`; | ||
@@ -58,2 +77,14 @@ | ||
work_type: 0, | ||
users: [{ | ||
first_name: undefined, | ||
last_name: "", | ||
friends: [{ | ||
first_name: "Oleg", | ||
last_name: "Prokofyev", | ||
friends: [], | ||
rate_expires: { | ||
seconds: 1000 | ||
} | ||
}] | ||
}] | ||
} as Settings); | ||
@@ -63,2 +94,3 @@ }) | ||
test("default object and array is not referrence", () => { | ||
const d1 = { | ||
@@ -76,9 +108,2 @@ seconds: -1, | ||
test("create if undefined value", () => { | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<number>())).toBe(0) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<Object>())).toEqual({}) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<Array<number>>())).toEqual([]) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<[number, boolean]>())).toEqual({"0": 0, "1": false}) | ||
}) | ||
test("default values", () => { | ||
@@ -93,2 +118,10 @@ expect(getDefaultValue(getType<Array<number>>())).toEqual([]); | ||
expect(getDefaultValue(getType<[boolean, number, Object]>())).toEqual({}); | ||
expect(getDefaultValue(getType<[boolean, number, Object]>())).toEqual({}); | ||
}) | ||
test("create if undefined value", () => { | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<number>())).toBe(0) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<Object>())).toEqual({}) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<Array<number>>())).toEqual([]) | ||
expect(mergeDefaults(returnIgnoredJsonError(), getType<[number, boolean]>())).toEqual({"0": 0, "1": false}) | ||
}) |
Sorry, the diff of this file is not supported yet
23824
442