@backland/schema
Version:
TypeScript schema declaration and validation library with static type inference
158 lines (157 loc) • 4.81 kB
JavaScript
;
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