@atomiqlabs/sdk-lib
Version:
Basic SDK functionality library for atomiq
152 lines (133 loc) • 5.7 kB
text/typescript
export function parseBigInt(str: string | number): bigint | null {
if(str==null) return null;
if(typeof(str)!=="string" && typeof(str)!=="number") return null;
try {
return BigInt(str);
} catch (e) {
return null;
}
}
export enum FieldTypeEnum {
String=0,
Boolean=1,
Number=2,
BigInt=3,
Any=4,
StringOptional=100,
BooleanOptional=101,
NumberOptional=102,
BigIntOptional=103,
AnyOptional=104,
}
export type FieldType<T extends FieldTypeEnum | RequestSchema | ((val: any) => (string | boolean | number | bigint | any))> =
T extends FieldTypeEnum.String ? string :
T extends FieldTypeEnum.Boolean ? boolean :
T extends FieldTypeEnum.Number ? number :
T extends FieldTypeEnum.BigInt ? bigint :
T extends FieldTypeEnum.Any ? any :
T extends FieldTypeEnum.StringOptional ? string :
T extends FieldTypeEnum.BooleanOptional ? boolean :
T extends FieldTypeEnum.NumberOptional ? number :
T extends FieldTypeEnum.BigIntOptional ? bigint :
T extends FieldTypeEnum.AnyOptional ? any :
T extends RequestSchema ? RequestSchemaResult<T> :
T extends ((val: any) => string) ? string :
T extends ((val: any) => boolean) ? boolean :
T extends ((val: any) => number) ? number :
T extends ((val: any) => bigint) ? bigint :
T extends ((val: any) => any) ? any :
never;
export type RequestSchemaResult<T extends RequestSchema> = {
[key in keyof T]: FieldType<T[key]>
}
export type RequestSchemaResultPromise<T extends RequestSchema> = {
[key in keyof T]: Promise<FieldType<T[key]>>
}
export type RequestSchema = {
[fieldName: string]: FieldTypeEnum | RequestSchema | ((val: any) => any)
}
function isAllOptional(schema: RequestSchema) {
for(let key in schema) {
if(!isOptionalField(schema[key])) return false;
}
return true;
}
export function isOptionalField(type: FieldTypeEnum | RequestSchema | ((val: any) => (string | boolean | number | bigint | any))) {
if(typeof(type)==="function") return type(undefined)!=null;
if(typeof(type)==="object") return isAllOptional(type);
return type>=100;
}
export function verifyField<T extends FieldTypeEnum | RequestSchema | ((val: any) => (string | boolean | number | bigint | any))>(fieldType: T, val: any): FieldType<T> {
const type: FieldTypeEnum | RequestSchema | ((val: any) => (string | boolean | number | bigint | any)) = fieldType;
if(typeof(type)==="function") {
const result = type(val);
if(result==null) return;
return result;
}
if(val==null && isOptionalField(type as FieldTypeEnum)) {
return null;
}
if(type===FieldTypeEnum.Any || type===FieldTypeEnum.AnyOptional) {
return val;
} else if(type===FieldTypeEnum.Boolean || type===FieldTypeEnum.BooleanOptional) {
if(typeof(val)!=="boolean") return;
return val as any;
} else if(type===FieldTypeEnum.Number || type===FieldTypeEnum.NumberOptional) {
if(typeof(val)!=="number") return;
if(isNaN(val as number)) return;
return val as any;
} else if(type===FieldTypeEnum.BigInt || type===FieldTypeEnum.BigIntOptional) {
const result = parseBigInt(val);
if(result==null) return;
return result as any;
} else if(type===FieldTypeEnum.String || type===FieldTypeEnum.StringOptional) {
if(typeof(val)!=="string") return;
return val as any;
} else {
//Probably another request schema
const result = verifySchema(val, type as RequestSchema);
if(result==null) return;
return result as any;
}
}
export function verifySchema<T extends RequestSchema>(req: any, schema: T): RequestSchemaResult<T> {
if(req==null) return null;
const resultSchema: any = {};
for(let fieldName in schema) {
const val: any = req[fieldName];
const type: FieldTypeEnum | RequestSchema | ((val: any) => boolean) = schema[fieldName];
if(typeof(type)==="function") {
const result = type(val);
if(result==null) return null;
resultSchema[fieldName] = result;
continue;
}
if(val==null && isOptionalField(type as FieldTypeEnum)) {
resultSchema[fieldName] = null;
continue;
}
if(type===FieldTypeEnum.Any || type===FieldTypeEnum.AnyOptional) {
resultSchema[fieldName] = val;
} else if(type===FieldTypeEnum.Boolean || type===FieldTypeEnum.BooleanOptional) {
if(typeof(val)!=="boolean") return null;
resultSchema[fieldName] = val;
} else if(type===FieldTypeEnum.Number || type===FieldTypeEnum.NumberOptional) {
if(typeof(val)!=="number") return null;
if(isNaN(val as number)) return null;
resultSchema[fieldName] = val;
} else if(type===FieldTypeEnum.BigInt || type===FieldTypeEnum.BigIntOptional) {
const result = parseBigInt(val);
if(result==null) return null;
resultSchema[fieldName] = result;
} else if(type===FieldTypeEnum.String || type===FieldTypeEnum.StringOptional) {
if(typeof(val)!=="string") return null;
resultSchema[fieldName] = val;
} else {
//Probably another request schema
const result = verifySchema(val, type as RequestSchema);
if(result==null) return null;
resultSchema[fieldName] = result;
}
}
return resultSchema;
}