@unique-nft/api
Version:
Definitely typed JS API for the Unique Network blockchain
98 lines (82 loc) • 4.06 kB
text/typescript
import {
AttributeSchema,
COLLECTION_SCHEMA_NAME,
UniqueCollectionSchemaDecoded,
UniqueCollectionSchemaToCreate
} from "../../types";
import {getKeys} from "../../../tsUtils";
import {ValidationError} from "../../../utils/errors";
import {validateValueVsAttributeType} from "./collection-validators";
import {
validateAndParseSemverString,
validateLocalizedStringWithDefault,
validateUrlWithHashObject,
validateNumber,
isPlainObject,
validateAttributeKey,
} from "./common-validators";
const validateAttributeEnumKey = (schema: AttributeSchema, num: number, varName: string) => {
validateNumber(num, true, varName)
const enumKeys = getKeys(schema.enumValues || {}).map(n => parseInt(n as any as string))
if (!enumKeys.includes(num)) {
throw new ValidationError(`${varName} value (${num}) not found in the attribute schema enum keys: [${enumKeys.join()}]`)
}
}
export const validateUniqueToken = <T, C extends UniqueCollectionSchemaToCreate | UniqueCollectionSchemaDecoded>(token: any, collectionSchema: C): token is T => {
if (collectionSchema.schemaName !== COLLECTION_SCHEMA_NAME.unique) {
throw new ValidationError(`schemaName is not "unique" (passed ${collectionSchema.schemaName})`)
}
if (token.hasOwnProperty('name')) {
validateLocalizedStringWithDefault(token.name, true, 'token.name')
}
if (token.hasOwnProperty('description')) {
validateLocalizedStringWithDefault(token.description, true, 'token.description')
}
validateUrlWithHashObject(token.image, 'token.image')
if (token.hasOwnProperty('imagePreview')) {
validateUrlWithHashObject(token.imagePreview, 'token.imagePreview')
}
const schemaVersion = validateAndParseSemverString(collectionSchema.schemaVersion, 'collectionSchema.schemaVersion')
if (token.encodedAttributes && collectionSchema.attributesSchema) {
isPlainObject(token.encodedAttributes, 'token.encodedAttributes')
for (let key in collectionSchema.attributesSchema) {
const schema = collectionSchema.attributesSchema[key]
validateAttributeKey(key, 'token.encodedAttributes')
const varName = `token.encodedAttributes.${key}`
const attr = token.encodedAttributes[key]
if (!token.encodedAttributes.hasOwnProperty(key)) {
if (schema.optional) {
continue
} else {
throw new ValidationError(`${varName} should be provided, it's not optional attribute`)
}
}
if (schema.isArray && !Array.isArray(attr)) {
throw new ValidationError(`${varName} is not array, while schema requires an array`)
}
if (!schema.isArray && Array.isArray(attr)) {
throw new ValidationError(`${varName} is an array, while schema requires to be not an array`)
}
const attrs = schema.isArray ? attr : [attr]
if (schema.enumValues) {
attrs.forEach((num: any, index: number) => {
validateAttributeEnumKey(schema, num, `${varName}[${index}]`)
})
} else {
attrs.forEach((attrElem: any, index: number) => {
validateValueVsAttributeType(attrElem, schema.type, `${varName}[${index}]`)
})
}
}
}
if (collectionSchema.hasOwnProperty('video') && token.hasOwnProperty('video')) {
validateUrlWithHashObject(token.video, 'token.video')
}
if (collectionSchema.hasOwnProperty('audio') && token.hasOwnProperty('audio')) {
validateUrlWithHashObject(token.audio, 'token.audio')
}
if (collectionSchema.hasOwnProperty('spatialObject') && token.hasOwnProperty('spatialObject')) {
validateUrlWithHashObject(token.spatialObject, 'token.spatialObject')
}
return true
}