UNPKG

@backland/schema

Version:

TypeScript schema declaration and validation library with static type inference

158 lines (157 loc) 4.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.backlandValueTypeCheckEntries = exports.JSONToSchemaOptions = exports.JSONFieldCase = void 0; exports.isCursorString = isCursorString; exports.jsonToSchemaDefinition = jsonToSchemaDefinition; exports.jsonToType = jsonToType; exports.valueToTypeDef = valueToTypeDef; exports.valuesToBacklandTypeRecord = void 0; var _utils = require("@backland/utils"); var _CircularDeps = require("./CircularDeps"); var _GraphType = require("./GraphType/GraphType"); var _ObjectType = require("./ObjectType"); var _UlidField = require("./fields/UlidField"); const record = _CircularDeps.CircularDeps.record({ keyType: 'string', type: 'any' }); const JSONFieldCase = Object.keys(_utils.stringCase).concat('camelCase'); exports.JSONFieldCase = JSONFieldCase; const JSONToSchemaOptions = (0, _ObjectType.createObjectType)({ fieldCase: { enum: JSONFieldCase, optional: true }, examples: 'boolean?', name: 'string?', json: { record: { type: 'any', keyType: 'string' } } }); exports.JSONToSchemaOptions = JSONToSchemaOptions; function jsonToType(init) { const { name } = init; const definition = valueToTypeDef({ ...init, value: init.json }); const type = (0, _GraphType.createType)(definition); if (name) { type.identify(name); } return type; } function jsonToSchemaDefinition(options) { record.parse(options.json, 'jsonToSchema: Invalid input.'); const res = valueToTypeDef({ ...options, value: options.json }); if ('object' in res && typeof res.object === 'object') { return res.object; } throw (0, _utils.customError)({ message: 'Invalid field', details: res, stackFrom: jsonToSchemaDefinition }); } function isCursorString(value) { if (!value || typeof value !== 'string') return false; try { _utils.IndexCursor.parse(value, { destination: 'document' }); return true; } catch (e) { return false; } } const phoneType = _CircularDeps.CircularDeps.phone({}); const valuesToBacklandTypeRecord = { null: value => value === null, undefined: value => value === undefined, string: value => typeof value === 'string', boolean: value => typeof value === 'boolean', float: value => (0, _utils.getTypeName)(value) === 'Number' && !!`${value}`.match(/^\d*\.\d*$/), int: value => (0, _utils.getTypeName)(value) === 'Number' && !!`${value}`.match(/^\d*$/), array: Array.isArray, object: value => (0, _utils.isPlainObject)(value), cursor: isCursorString, date: value => (0, _utils.getTypeName)(value) === 'Date', email: value => Boolean(value && typeof value === 'string' && _utils.EmailRegex.test(value)), ID: value => !!value && typeof value === 'string' && _UlidField.ULID_REGEX.test(value), phone: phoneType.is, record: value => !!value && typeof value === 'object' && !(0, _utils.isPlainObject)(value), ulid: value => typeof value === 'string' && _UlidField.ULID_REGEX.test(value), union: () => false, unknown: () => false, alias: () => false, any: () => false, literal: () => false, meta: () => false, enum: () => false }; exports.valuesToBacklandTypeRecord = valuesToBacklandTypeRecord; const backlandValueTypeCheckEntries = (0, _utils.entries)(valuesToBacklandTypeRecord); exports.backlandValueTypeCheckEntries = backlandValueTypeCheckEntries; function valueToTypeDef(options) { const { fieldCase = 'keep', examples, value } = options; const typename = function iifeTypename() { var _backlandValueTypeChe; return ((_backlandValueTypeChe = backlandValueTypeCheckEntries.find(([, check]) => { return check(value); })) === null || _backlandValueTypeChe === void 0 ? void 0 : _backlandValueTypeChe[0]) || 'unknown'; }(); const field = { [typename]: {} }; if (examples && typename !== 'object') { field.description = `Eg: ${(0, _utils.inspectObject)(value).trim()}`; } if ('array' in field) { const child = value.map(el => { return valueToTypeDef({ ...options, value: el }); }); field.array.of = function iife() { if (!child.length) return 'unknown'; return child.length === 1 ? child[0] : { union: child }; }(); } if (typename === 'object') { field[typename] = (0, _utils.entries)(value).reduce((acc, [key, subValue]) => { if (fieldCase) { if (fieldCase === 'camelCase') { key = (0, _utils.joinPathsCamelCase)(key); } else { key = _utils.stringCase[fieldCase](key); } } return { ...acc, [key]: valueToTypeDef({ ...options, value: subValue }) }; }, {}); } return field; } //# sourceMappingURL=jsonToType.js.map