Comparing version 0.1.8 to 0.1.9
@@ -29,9 +29,10 @@ "use strict"; | ||
test('serialize', () => { | ||
const type = __1.Type.solve(data); | ||
const type = __1.Type.type(data); | ||
const result = __1.Type.serialize(type); | ||
const expected = '{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"region","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"phoneCode","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"timezones","type":{"primitive":"list","list":{"items":{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"offset","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"pos","type":{"primitive":"obj","obj":{"properties":[{"name":"lat","type":{"primitive":"decimal","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"log","type":{"primitive":"decimal","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}}]},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}}]},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}}]},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}'; | ||
console.log(result); | ||
const expected = '{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string"}},{"name":"region","type":{"primitive":"string"}},{"name":"phoneCode","type":{"primitive":"string"}},{"name":"timezones","type":{"primitive":"list","list":{"items":{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string"}},{"name":"offset","type":{"primitive":"integer"}},{"name":"pos","type":{"primitive":"obj","obj":{"properties":[{"name":"lat","type":{"primitive":"decimal"}},{"name":"log","type":{"primitive":"decimal"}}]}}}]}}}}}]}}'; | ||
expect(expected).toStrictEqual(result); | ||
}); | ||
test('stringify', () => { | ||
const type = __1.Type.solve(data); | ||
const type = __1.Type.type(data); | ||
const result = __1.Type.stringify(type); | ||
@@ -38,0 +39,0 @@ const expected = '{name:string,region:string,phoneCode:string,timezones:[{name:string,offset:integer,pos:{lat:decimal,log:decimal}}]}'; |
@@ -51,9 +51,9 @@ "use strict"; | ||
test('serialize', () => { | ||
const type = __1.Type.solve(data); | ||
const type = __1.Type.type(data); | ||
const result = __1.Type.serialize(type); | ||
const expected = '{"primitive":"obj","obj":{"properties":[{"name":"id","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"customerId","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"employeeId","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"orderDate","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"requiredDate","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"shippedDate","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"shipViaId","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"freight","type":{"primitive":"decimal","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"name","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"address","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"city","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"region","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"postalCode","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"country","type":{"primitive":"string","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"details","type":{"primitive":"list","list":{"items":{"primitive":"obj","obj":{"properties":[{"name":"orderId","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"productId","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"unitPrice","type":{"primitive":"decimal","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"quantity","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},{"name":"discount","type":{"primitive":"integer","nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}}]},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}}]},"nullable":false,"undefinable":false,"async":false,"unique":false,"repeated":0,"repeatRate":0,"count":0,"indefinite":0,"nullables":0}'; | ||
const expected = '{"primitive":"obj","obj":{"properties":[{"name":"id","type":{"primitive":"integer"}},{"name":"customerId","type":{"primitive":"string"}},{"name":"employeeId","type":{"primitive":"integer"}},{"name":"orderDate","type":{"primitive":"string"}},{"name":"requiredDate","type":{"primitive":"string"}},{"name":"shippedDate","type":{"primitive":"string"}},{"name":"shipViaId","type":{"primitive":"integer"}},{"name":"freight","type":{"primitive":"decimal"}},{"name":"name","type":{"primitive":"string"}},{"name":"address","type":{"primitive":"string"}},{"name":"city","type":{"primitive":"string"}},{"name":"region","type":{"primitive":"string"}},{"name":"postalCode","type":{"primitive":"string"}},{"name":"country","type":{"primitive":"string"}},{"name":"details","type":{"primitive":"list","list":{"items":{"primitive":"obj","obj":{"properties":[{"name":"orderId","type":{"primitive":"integer"}},{"name":"productId","type":{"primitive":"integer"}},{"name":"unitPrice","type":{"primitive":"decimal"}},{"name":"quantity","type":{"primitive":"integer"}},{"name":"discount","type":{"primitive":"integer"}}]}}}}}]}}'; | ||
expect(expected).toStrictEqual(result); | ||
}); | ||
test('stringify', () => { | ||
const type = __1.Type.solve(data); | ||
const type = __1.Type.type(data); | ||
const result = __1.Type.stringify(type); | ||
@@ -60,0 +60,0 @@ const expected = '{id:integer,customerId:string,employeeId:integer,orderDate:string,requiredDate:string,shippedDate:string,shipViaId:integer,freight:decimal,name:string,address:string,city:string,region:string,postalCode:string,country:string,details:[{orderId:integer,productId:integer,unitPrice:decimal,quantity:integer,discount:integer}]}'; |
@@ -25,11 +25,15 @@ import { Primitive } from './primitive'; | ||
func?: FuncType | undefined; | ||
nullable: boolean; | ||
undefinable: boolean; | ||
async: boolean; | ||
unique: boolean; | ||
repeated: number; | ||
repeatRate: number; | ||
indefinite: number; | ||
nullables: number; | ||
count: number; | ||
nullable?: boolean; | ||
undefinable?: boolean; | ||
async?: boolean; | ||
unique?: boolean; | ||
repeated?: number; | ||
repeatRate?: number; | ||
indefinite?: number; | ||
nullables?: number; | ||
count?: number; | ||
distinctCount?: number; | ||
onParentDistinctRepeated?: number; | ||
onParentDistinctRepeatedRate?: number; | ||
onParentDistinctUnique?: boolean; | ||
constructor(primitive: Primitive, obj?: ObjType | undefined, list?: ListType | undefined, func?: FuncType | undefined); | ||
@@ -55,12 +59,15 @@ static get any(): Type; | ||
static isFunc(type: Type | string): boolean; | ||
private static modifier; | ||
static stringify(type?: Type): string; | ||
static parse(schema: string): Type; | ||
static serialize(type?: Type): string | undefined; | ||
static serialize(type?: Type, indentation?: number): string | undefined; | ||
static deserialize(type?: string): Type | undefined; | ||
static solve(value: any): Type; | ||
private static _solve; | ||
static solveCardinality(value: any, type: Type): void; | ||
static type(value: any): Type; | ||
private static _type; | ||
static cardinality(value: any, type: Type): void; | ||
private static solvePropertyCardinality; | ||
private static solveOnObjectProperties; | ||
private static completeCardinalityProperties; | ||
private static iterations; | ||
static key(value: any, type: Type): string; | ||
} |
@@ -7,2 +7,3 @@ "use strict"; | ||
class Type { | ||
// eslint-disable-next-line no-useless-constructor | ||
constructor(primitive, obj, list, func) { | ||
@@ -13,11 +14,2 @@ this.primitive = primitive; | ||
this.func = func; | ||
this.nullable = false; | ||
this.undefinable = false; | ||
this.async = false; | ||
this.unique = false; | ||
this.repeated = 0; | ||
this.repeatRate = 0; | ||
this.count = 0; | ||
this.indefinite = 0; | ||
this.nullables = 0; | ||
} | ||
@@ -140,2 +132,5 @@ static get any() { | ||
} | ||
static modifier(type) { | ||
return (type.undefinable ? '?' : type.nullable ? '!' : ''); | ||
} | ||
static stringify(type) { | ||
@@ -146,3 +141,3 @@ if (type === undefined) { | ||
if (this.isPrimitive(type)) { | ||
return type.primitive.toString(); | ||
return this.modifier(type) + type.primitive.toString(); | ||
} | ||
@@ -155,7 +150,7 @@ if (this.isObj(type)) { | ||
} | ||
return `{${properties.join(',')}}`; | ||
return `${this.modifier(type)}{${properties.join(',')}}`; | ||
} | ||
if (this.isList(type)) { | ||
const arrayType = type.list; | ||
return `[${this.stringify(arrayType.items)}]`; | ||
return `${this.modifier(type)}[${this.stringify(arrayType.items)}]`; | ||
} | ||
@@ -168,3 +163,3 @@ if (this.isFunc(type)) { | ||
} | ||
return `(${params.join(',')}=>${this.stringify(funcType.ret)})`; | ||
return `(${params.join(',')}>${type.async ? '~' : ''} ${this.stringify(funcType.ret)})`; | ||
} | ||
@@ -176,6 +171,9 @@ return 'any'; | ||
} | ||
static serialize(type) { | ||
static serialize(type, indentation) { | ||
if (type === undefined || type === null) { | ||
return undefined; | ||
} | ||
if (indentation) { | ||
return JSON.stringify(type, null, indentation); | ||
} | ||
return JSON.stringify(type); | ||
@@ -189,8 +187,8 @@ } | ||
} | ||
static solve(value) { | ||
static type(value) { | ||
const type = new Type(primitive_1.Primitive.undefined); | ||
this._solve(value, type); | ||
this._type(value, type); | ||
return type; | ||
} | ||
static _solve(value, type) { | ||
static _type(value, type) { | ||
if (value === undefined || value === null) { | ||
@@ -211,3 +209,3 @@ return; | ||
for (const item of value) { | ||
this._solve(item, type.list.items); | ||
this._type(item, type.list.items); | ||
} | ||
@@ -242,3 +240,3 @@ } | ||
} | ||
this._solve(entry[1], property.type); | ||
this._type(entry[1], property.type); | ||
} | ||
@@ -279,4 +277,39 @@ } | ||
} | ||
static solveCardinality(value, type) { | ||
static cardinality(value, type) { | ||
if (Type.isList(type) && type.list && Type.isObj(type.list.items) && type.list.items.obj) { | ||
// List of objects | ||
const typeObj = type.list.items; | ||
if (!typeObj.repeated && !typeObj.nullables && !typeObj.indefinite) { | ||
typeObj.repeated = 0; | ||
typeObj.nullables = 0; | ||
typeObj.indefinite = 0; | ||
const listObjects = []; | ||
for (const obj of value) { | ||
if (obj === undefined) { | ||
typeObj.indefinite++; | ||
} | ||
else if (obj === null) { | ||
typeObj.nullables++; | ||
} | ||
else { | ||
const key = this.key(obj, typeObj); | ||
listObjects.push({ key, obj }); | ||
} | ||
} | ||
const distinctObjects = []; | ||
for (let i = 0; i < listObjects.length; i++) { | ||
const item = listObjects[i]; | ||
if (distinctObjects.find(o => o.key === item.key) === undefined) { | ||
distinctObjects.push(item); | ||
} | ||
for (let j = i + 1; j < listObjects.length; j++) { | ||
const item2 = listObjects[j]; | ||
if (item.key === item2.key) { | ||
typeObj.repeated++; | ||
} | ||
} | ||
} | ||
this.solveOnObjectProperties(distinctObjects.map(p => p.obj), typeObj); | ||
this.completeCardinalityProperties(typeObj, value.length); | ||
} | ||
for (const property of type.list.items.obj.properties) { | ||
@@ -287,2 +320,3 @@ this.solvePropertyCardinality(value, property); | ||
else if (Type.isObj(type) && type.obj) { | ||
// Object | ||
for (const property of type.obj.properties) { | ||
@@ -293,4 +327,12 @@ this.solvePropertyCardinality(value, property); | ||
else if (Type.isList(type) && type.list && Type.isPrimitive(type.list.items) && type.list.items.primitive) { | ||
// List of primitives | ||
type.list.items.indefinite = 0; | ||
type.list.items.nullables = 0; | ||
type.list.items.repeated = 0; | ||
const distinct = []; | ||
for (let i = 0; i < value.length; i++) { | ||
const item = value[i]; | ||
if (distinct.find(o => o === item) === undefined) { | ||
distinct.push(item); | ||
} | ||
if (item === undefined) { | ||
@@ -311,19 +353,28 @@ type.list.items.indefinite++; | ||
} | ||
type.distinctCount = distinct.length; | ||
type.list.items.distinctCount = distinct.length; | ||
this.completeCardinalityProperties(type.list.items, value.length); | ||
} | ||
} | ||
static solvePropertyCardinality(value, property) { | ||
static solvePropertyCardinality(list, property) { | ||
if (!property.type) { | ||
return; | ||
} | ||
property.type.indefinite = 0; | ||
property.type.nullables = 0; | ||
property.type.repeated = 0; | ||
if (property.type && Type.isPrimitive(property.type)) { | ||
for (let i = 0; i < value.length; i++) { | ||
const item = value[i]; | ||
if (item[property.name] === undefined) { | ||
// Property is a primitive in List of objects | ||
for (let i = 0; i < list.length; i++) { | ||
const item = list[i][property.name]; | ||
if (item === undefined) { | ||
property.type.indefinite++; | ||
} | ||
else if (item[property.name] === null) { | ||
else if (item === null) { | ||
property.type.nullables++; | ||
} | ||
else { | ||
for (let j = i + 1; j < value.length; j++) { | ||
const item2 = value[j]; | ||
if (item[property.name] === item2[property.name]) { | ||
for (let j = i + 1; j < list.length; j++) { | ||
const item2 = list[j][property.name]; | ||
if (item === item2) { | ||
property.type.repeated++; | ||
@@ -334,22 +385,28 @@ } | ||
} | ||
this.completeCardinalityProperties(property.type, value.length); | ||
this.completeCardinalityProperties(property.type, list.length); | ||
} | ||
else if (property.type && Type.isObj(property.type)) { | ||
const values = []; | ||
for (const item of value) { | ||
if (item[property.name] === undefined) { | ||
else if (property.type && Type.isObj(property.type) && property.type.obj) { | ||
// Property is an object in List of objects | ||
const listObjects = []; | ||
for (const objs of list) { | ||
const obj = objs[property.name]; | ||
if (obj === undefined) { | ||
property.type.indefinite++; | ||
} | ||
else if (item[property.name] === null) { | ||
else if (obj === null) { | ||
property.type.nullables++; | ||
} | ||
else { | ||
values.push(item[property.name]); | ||
listObjects.push({ key: JSON.stringify(obj), obj }); | ||
} | ||
} | ||
for (let i = 0; i < values.length; i++) { | ||
const item = values[i]; | ||
for (let j = i + 1; j < values.length; j++) { | ||
const item2 = values[j]; | ||
if (JSON.stringify(item) === JSON.stringify(item2)) { | ||
const distinctObjects = []; | ||
for (let i = 0; i < listObjects.length; i++) { | ||
const item = listObjects[i]; | ||
if (distinctObjects.find(o => o.key === item.key) === undefined) { | ||
distinctObjects.push(item); | ||
} | ||
for (let j = i + 1; j < listObjects.length; j++) { | ||
const item2 = listObjects[j]; | ||
if (item.key === item2.key) { | ||
property.type.repeated++; | ||
@@ -359,23 +416,29 @@ } | ||
} | ||
this.completeCardinalityProperties(property.type, value.length); | ||
this.solveCardinality(values, property.type); | ||
this.solveOnObjectProperties(distinctObjects.map(p => p.obj), property.type); | ||
this.completeCardinalityProperties(property.type, list.length); | ||
this.cardinality(listObjects.map(o => o.obj), property.type); | ||
} | ||
else if (property.type && Type.isList(property.type)) { | ||
const values = []; | ||
for (const item of value) { | ||
if (item[property.name] === undefined) { | ||
else if (property.type && Type.isList(property.type) && property.type.list && property.type.list.items) { | ||
// Property is a list in List of objects | ||
const dictionary = []; | ||
for (const item of list) { | ||
const children = item[property.name]; | ||
if (children === undefined) { | ||
property.type.indefinite++; | ||
} | ||
else if (item[property.name] === null) { | ||
else if (children === null) { | ||
property.type.nullables++; | ||
} | ||
else { | ||
values.push(...item[property.name]); | ||
for (const child of children) { | ||
const key = this.key(child, property.type.list.items); | ||
dictionary.push({ key, obj: child }); | ||
} | ||
} | ||
} | ||
for (let i = 0; i < values.length; i++) { | ||
const item = values[i]; | ||
for (let j = i + 1; j < values.length; j++) { | ||
const item2 = values[j]; | ||
if (JSON.stringify(item) === JSON.stringify(item2)) { | ||
for (let i = 0; i < dictionary.length; i++) { | ||
const item = dictionary[i]; | ||
for (let j = i + 1; j < dictionary.length; j++) { | ||
const item2 = dictionary[j]; | ||
if (item.key === item2.key) { | ||
property.type.repeated++; | ||
@@ -385,12 +448,42 @@ } | ||
} | ||
this.completeCardinalityProperties(property.type, values.length); | ||
this.solveCardinality(values, property.type); | ||
this.completeCardinalityProperties(property.type, dictionary.length); | ||
this.cardinality(dictionary.map(p => p.obj), property.type); | ||
} | ||
} | ||
static solveOnObjectProperties(list, type) { | ||
if (!type.obj) { | ||
return; | ||
} | ||
type.distinctCount = list.length; | ||
for (const property of type.obj.properties) { | ||
if (property.type && Type.isPrimitive(property.type)) { | ||
property.type.onParentDistinctRepeated = 0; | ||
property.type.distinctCount = list.length; | ||
for (let i = 0; i < list.length; i++) { | ||
const field = list[i][property.name]; | ||
if (field === undefined || field === null) { | ||
continue; | ||
} | ||
else { | ||
for (let j = i + 1; j < list.length; j++) { | ||
const field2 = list[j][property.name]; | ||
if (field === field2) { | ||
property.type.onParentDistinctRepeated++; | ||
} | ||
} | ||
} | ||
} | ||
property.type.onParentDistinctRepeatedRate = property.type.onParentDistinctRepeated / this.iterations(list.length - 1); | ||
property.type.onParentDistinctUnique = property.type.onParentDistinctRepeated === 0 && list.length > 0; | ||
} | ||
} | ||
} | ||
static completeCardinalityProperties(type, count) { | ||
type.repeatRate = type.repeated / this.iterations(count - 1); | ||
type.count = count; | ||
type.nullable = type.nullables > 0; | ||
type.undefinable = type.indefinite > 0; | ||
type.unique = type.repeated === 0 && type.count > 0; | ||
if (type.repeated !== undefined && type.nullables !== undefined && type.indefinite !== undefined) { | ||
type.repeatRate = type.repeated / this.iterations(count - 1); | ||
type.nullable = type.nullables > 0; | ||
type.undefinable = type.indefinite > 0; | ||
type.unique = type.repeated === 0 && type.count > 0; | ||
} | ||
} | ||
@@ -403,2 +496,29 @@ static iterations(n) { | ||
} | ||
static key(value, type) { | ||
if (Type.isList(type) && type.list) { | ||
const keys = []; | ||
for (const item of value) { | ||
keys.push(this.key(item, type.list.items)); | ||
} | ||
return '[' + keys.sort().join(',') + ']'; | ||
} | ||
else if (Type.isObj(type) && type.obj) { | ||
const keys = []; | ||
for (const property of type.obj.properties.sort((a, b) => a.name.localeCompare(b.name))) { | ||
if (property.type) { | ||
const propertyValue = value[property.name]; | ||
if (propertyValue !== undefined && propertyValue !== null) { | ||
keys.push(property.name + ':' + this.key(propertyValue, property.type)); | ||
} | ||
} | ||
} | ||
return '{' + keys.join(',') + '}'; | ||
} | ||
else if (Type.isPrimitive(type)) { | ||
return value.toString(); | ||
} | ||
else { | ||
return value.toString(); | ||
} | ||
} | ||
} | ||
@@ -419,2 +539,12 @@ exports.Type = Type; | ||
} | ||
chars(count = 1, offset = 0) { | ||
const chars = []; | ||
for (let i = this.index + offset; i < count; i++) { | ||
if (i >= this.length) { | ||
return chars.join(''); | ||
} | ||
chars.push(this.buffer[i]); | ||
} | ||
return chars.join(''); | ||
} | ||
parse() { | ||
@@ -530,3 +660,3 @@ return this.getType(); | ||
} | ||
if (this.current === '>') { | ||
if (this.chars(2) === '>') { | ||
this.index += 2; | ||
@@ -533,0 +663,0 @@ ret = this.getType(); |
{ | ||
"name": "typ3s", | ||
"version": "0.1.8", | ||
"version": "0.1.9", | ||
"description": "Allow define type on json", | ||
@@ -5,0 +5,0 @@ "scripts": { |
359
README.md
@@ -40,23 +40,344 @@ # typ3s | ||
|type |description | | ||
|:------------------------------|:----------------------------------------------------------| | ||
| [string] | array of string | | ||
| [string, integer] | tuple with string and integer properties | | ||
| {name:string, nro:integer} | object with string and integer properties | | ||
| [{name:string, today:date}] | array of object | | ||
| (>any) | function without params and return value | | ||
| (list:[integer]>integer) | function with array integer as params and return integer | | ||
| (today:date,nro:?integer>date)| function with undefinable integer param | | ||
| {name:string,nro:?integer} | object of properties string and undefinable integer | | ||
| {name:string,nro:!integer} | object of properties string and nullable integer | | ||
| ([integer]>~integer) | function with return async of integer | | ||
|type |description | | ||
|:--------------------------------|:----------------------------------------------------------| | ||
| [string] | array of string | | ||
| [string, integer] | tuple with string and integer properties | | ||
| {name:string, nro:integer} | object with string and integer properties | | ||
| [{name:string, today:date}] | array of object | | ||
| (>any) | function without params and return value | | ||
| (list:[integer]>integer) | function with array integer as params and return integer | | ||
| (today:date,nro:?integer>date) | function with undefinable integer param | | ||
| {name:string,nro:?integer} | object of properties string and undefinable integer | | ||
| {name:string,nro:!integer} | object of properties string and nullable integer | | ||
| ([integer]>~integer) | function with return async of integer | | ||
## Methods | ||
| method |description | | ||
|:--------------|:--------------------------------------------------------------------------| | ||
| solve | | | ||
| stringify | | | ||
| parse | | | ||
| serialize | | | ||
| deserialized | | | ||
| method |description | | ||
|:--------------|:----------------------------------------------| | ||
| type | get the type | | ||
| stringify | converts the type to a string | | ||
| parse | converts the string to type | | ||
| serialize | serialize type | | ||
| deserialized | deserialize type | | ||
| cardinality | complete cardinality information in the type | | ||
## Example | ||
This example shows how you can obtain the type of an array of objects, convert it to a string, parse it, serialize it, and deserialize it. | ||
```ts | ||
import { Type } from 'typ3s' | ||
const data = [ | ||
{ | ||
name: 'Spain', | ||
region: { name: 'Europe', code: 'EU', description: 'European Union' }, | ||
languages: ['Spanish', 'Catalan', 'Galician', 'Basque'], | ||
phoneCode: 34 | ||
}, | ||
{ | ||
name: 'France', | ||
region: { name: 'Europe', code: 'EU', description: 'European Union' }, | ||
languages: ['French'], | ||
phoneCode: 33 | ||
}, | ||
{ | ||
name: 'Canada', | ||
region: { name: 'North America', code: 'NA', description: null }, | ||
languages: ['English', 'French'] | ||
} | ||
] | ||
const type = Type.type(data) | ||
const stringified = Type.stringify(type) | ||
const type2 = Type.parse(stringified) | ||
const serialized = Type.serialize(type2, 2) | ||
const deserialized = Type.deserialize(serialized) | ||
const serialize2 = Type.serialize(deserialized) | ||
console.log(stringified) | ||
console.log(serialized) | ||
console.log(serialize2) | ||
``` | ||
**stringified:** | ||
```javascript | ||
[{name:string,region:{name:string,code:string,description:string},languages:[string],phoneCode:integer}] | ||
``` | ||
**serialized:** | ||
```json | ||
{ | ||
"primitive": "list", | ||
"list": { | ||
"items": { | ||
"primitive": "obj", | ||
"obj": { | ||
"properties": [ | ||
{ | ||
"name": "name", | ||
"type": { | ||
"primitive": "string" | ||
} | ||
}, | ||
{ | ||
"name": "region", | ||
"type": { | ||
"primitive": "obj", | ||
"obj": { | ||
"properties": [ | ||
{ | ||
"name": "name", | ||
"type": { | ||
"primitive": "string" | ||
} | ||
}, | ||
{ | ||
"name": "code", | ||
"type": { | ||
"primitive": "string" | ||
} | ||
}, | ||
{ | ||
"name": "description", | ||
"type": { | ||
"primitive": "string" | ||
} | ||
} | ||
] | ||
} | ||
} | ||
}, | ||
{ | ||
"name": "languages", | ||
"type": { | ||
"primitive": "list", | ||
"list": { | ||
"items": { | ||
"primitive": "string" | ||
} | ||
} | ||
} | ||
}, | ||
{ | ||
"name": "phoneCode", | ||
"type": { | ||
"primitive": "integer" | ||
} | ||
} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
**serialized2:** | ||
```json | ||
{"primitive":"list","list":{"items":{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string"}},{"name":"region","type":{"primitive":"obj","obj":{"properties":[{"name":"name","type":{"primitive":"string"}},{"name":"code","type":{"primitive":"string"}},{"name":"description","type":{"primitive":"string"}}]}}},{"name":"languages","type":{"primitive":"list","list":{"items":{"primitive":"string"}}}},{"name":"phoneCode","type":{"primitive":"integer"}}]}}}} | ||
``` | ||
## Cardinality example | ||
This example shows how you can obtain the cardinality of an array of objects. | ||
By using the cardinality method, you get information about the cardinality that is added to the type. | ||
```ts | ||
import { Type } from '../../lib' | ||
const data = [ | ||
{ | ||
name: 'Spain', | ||
region: { name: 'Europe', code: 'EU', description: 'European Union' }, | ||
languages: ['Spanish', 'Catalan', 'Galician', 'Basque'], | ||
phoneCode: 34 | ||
}, | ||
{ | ||
name: 'France', | ||
region: { name: 'Europe', code: 'EU', description: 'European Union' }, | ||
languages: ['French'], | ||
phoneCode: 33 | ||
}, | ||
{ | ||
name: 'Canada', | ||
region: { name: 'North America', code: 'NA', description: null }, | ||
languages: ['English', 'French'] | ||
} | ||
] | ||
const type = Type.type(data) | ||
Type.cardinality(data, type) | ||
const stringified = Type.stringify(type) | ||
const serialized = Type.serialize(type, 1) | ||
console.log(stringified) | ||
console.log(serialized) | ||
``` | ||
**stringified:** | ||
```javascript | ||
[{languages:[string],name:string,phoneCode:?integer,region:{code:string,description:!string,name:string}}] | ||
``` | ||
**serialized:** | ||
```json | ||
{ | ||
"primitive": "list", | ||
"list": { | ||
"items": { | ||
"primitive": "obj", | ||
"obj": { | ||
"properties": [ | ||
{ | ||
"name": "languages", | ||
"type": { | ||
"primitive": "list", | ||
"list": { | ||
"items": { | ||
"primitive": "string", | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 1, | ||
"distinctCount": 6, | ||
"count": 7, | ||
"repeatRate": 0.047619047619047616, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": false | ||
} | ||
}, | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 1, | ||
"count": 7, | ||
"repeatRate": 0.047619047619047616, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": false, | ||
"distinctCount": 6 | ||
} | ||
}, | ||
{ | ||
"name": "name", | ||
"type": { | ||
"primitive": "string", | ||
"onParentDistinctRepeated": 0, | ||
"distinctCount": 3, | ||
"onParentDistinctRepeatedRate": 0, | ||
"onParentDistinctUnique": true, | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 0, | ||
"count": 3, | ||
"repeatRate": 0, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": true | ||
} | ||
}, | ||
{ | ||
"name": "phoneCode", | ||
"type": { | ||
"primitive": "integer", | ||
"onParentDistinctRepeated": 0, | ||
"distinctCount": 3, | ||
"onParentDistinctRepeatedRate": 0, | ||
"onParentDistinctUnique": true, | ||
"indefinite": 1, | ||
"nullables": 0, | ||
"repeated": 0, | ||
"count": 3, | ||
"repeatRate": 0, | ||
"nullable": false, | ||
"undefinable": true, | ||
"unique": true | ||
} | ||
}, | ||
{ | ||
"name": "region", | ||
"type": { | ||
"primitive": "obj", | ||
"obj": { | ||
"properties": [ | ||
{ | ||
"name": "code", | ||
"type": { | ||
"primitive": "string", | ||
"onParentDistinctRepeated": 0, | ||
"distinctCount": 2, | ||
"onParentDistinctRepeatedRate": 0, | ||
"onParentDistinctUnique": true, | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 1, | ||
"count": 3, | ||
"repeatRate": 0.3333333333333333, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": false | ||
} | ||
}, | ||
{ | ||
"name": "description", | ||
"type": { | ||
"primitive": "string", | ||
"onParentDistinctRepeated": 0, | ||
"distinctCount": 2, | ||
"onParentDistinctRepeatedRate": 0, | ||
"onParentDistinctUnique": true, | ||
"indefinite": 0, | ||
"nullables": 1, | ||
"repeated": 1, | ||
"count": 3, | ||
"repeatRate": 0.3333333333333333, | ||
"nullable": true, | ||
"undefinable": false, | ||
"unique": false | ||
} | ||
}, | ||
{ | ||
"name": "name", | ||
"type": { | ||
"primitive": "string", | ||
"onParentDistinctRepeated": 0, | ||
"distinctCount": 2, | ||
"onParentDistinctRepeatedRate": 0, | ||
"onParentDistinctUnique": true, | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 1, | ||
"count": 3, | ||
"repeatRate": 0.3333333333333333, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": false | ||
} | ||
} | ||
] | ||
}, | ||
"indefinite": 0, | ||
"nullables": 0, | ||
"repeated": 1, | ||
"distinctCount": 2, | ||
"count": 3, | ||
"repeatRate": 0.3333333333333333, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": false | ||
} | ||
} | ||
] | ||
}, | ||
"repeated": 0, | ||
"nullables": 0, | ||
"indefinite": 0, | ||
"distinctCount": 3, | ||
"count": 3, | ||
"repeatRate": 0, | ||
"nullable": false, | ||
"undefinable": false, | ||
"unique": true | ||
} | ||
} | ||
} | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
86806
930
383
1