UNPKG

stackpress

Version:

Incept is a content management framework.

556 lines (555 loc) 19.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const cuid2_1 = require("@paralleldrive/cuid2"); const nanoid_1 = require("nanoid"); const typemap = __importStar(require("../config/typemaps.js")); const assert_js_1 = __importDefault(require("../assert.js")); const helpers_js_1 = require("../helpers.js"); const Attributes_js_1 = __importDefault(require("./Attributes.js")); class Column { get active() { return this.attributes.active; } get assertions() { if (this.attributes.generated || this.relation || this.related) { return []; } const assertions = this.attributes.assertions; for (const type in typemap) { if (this.type === type) { if (this.multiple) { if (!assertions.find(v => v.method === 'array')) { assertions.unshift({ method: 'array', args: [typemap.method[type]], message: 'Invalid format' }); } } else if (!assertions.find(v => v.method === typemap.method[type])) { assertions.unshift({ method: typemap.method[type], args: [], message: 'Invalid format' }); } } } if (this.enum && !assertions.find(v => v.method === 'option')) { assertions.unshift({ method: 'option', args: Object.values(this.enum), message: 'Invalid option' }); } if (this.attributes.unique) { if (!assertions.find(v => v.method === 'unique')) { assertions.unshift({ method: 'unique', args: [], message: 'Already exists' }); } } if (!this.multiple && this.required && typeof this.attributes.default === 'undefined') { if (!assertions.find(v => v.method === 'required')) { assertions.unshift({ method: 'required', args: [], message: `${this.name} is required` }); } } return assertions; } get clen() { return this.attributes.clen; } get dash() { return (0, helpers_js_1.dasherize)(this.name); } get default() { const defaults = this.attributes.default; if (typeof defaults === 'string') { if (defaults.toLowerCase() === 'cuid()') { return (0, cuid2_1.createId)(); } else if (defaults.toLowerCase() === 'nanoid()') { return (0, nanoid_1.nanoid)(); } else if (defaults.toLowerCase() === 'now()') { return new Date(); } else if (/^cuid\(([0-9]+)\)$/.test(defaults)) { return (0, cuid2_1.createId)(); } const forCuid = defaults.match(/^cuid\(([0-9]+)\)$/); if (forCuid) { const uuid = (0, cuid2_1.init)({ length: parseInt(forCuid[1]) || 10 }); return uuid(); } const forNano = defaults.match(/^nanoid\(([0-9]+)\)$/); if (forNano) { return (0, nanoid_1.nanoid)(parseInt(forNano[1]) || 10); } } return defaults; } get description() { return this.attributes.description; } get enum() { return this._fieldset.registry.enum.get(this.type) || null; } get encrypted() { return this.attributes.encrypted; } get example() { return this.attributes.example; } get field() { return this.attributes.field; } get fieldset() { return this._fieldset.registry.fieldset.get(this.type) || null; } get filter() { return this.attributes.filter; } get generated() { return this.attributes.generated; } get hash() { return this.attributes.hash; } get id() { return this.attributes.id; } get indexable() { return this.attributes.indexable; } get label() { return this.attributes.label || this.name; } get list() { if (this.model) { return { component: false, method: 'hide', args: [], attributes: {} }; } return this.attributes.list; } get max() { return this.attributes.max; } get min() { return this.attributes.min; } get model() { return this._fieldset.registry.model.get(this.type) || null; } get related() { const model = this._fieldset.registry.model.get(this.type); if (!model) { return null; } const column = Array.from(model.columns.values()) .filter(column => !!column.relation) .find(column => column.type === this._fieldset.name); if (!(column === null || column === void 0 ? void 0 : column.relation)) { return null; } return column.relation; } get relation() { const relation = this.attributes.relation; if (!relation || !this.model) { return null; } const models = { parent: this.model, child: this._fieldset }; let foreignColumns = Array.from(models.parent.columns.values()).filter(column => column.type === this._fieldset.name).filter(column => !relation.name || relation.name === column.name); if (foreignColumns.length === 0) { return null; } const columns = { parent: foreignColumns[0], child: this }; const keys = { parent: models.parent.column(relation.foreign), child: models.child.column(relation.local) }; if (!keys.parent || !keys.child) { return null; } const types = { parent: columns.parent.multiple ? 2 : columns.parent.required ? 1 : 0, child: columns.child.multiple ? 2 : columns.child.required ? 1 : 0 }; return { parent: { model: models.parent, column: columns.parent, key: keys.parent, type: types.parent }, child: { model: models.child, column: columns.child, key: keys.child, type: types.child } }; } get searchable() { return this.attributes.searchable; } get schema() { const type = (() => { if (Boolean(this.fieldset || this.multiple || this.type === 'Json' || this.type === 'Object' || this.type === 'Hash')) { return 'json'; } else if ([ 'Char', 'Text', 'Integer', 'Float', 'Boolean', 'Date', 'Time', 'Datetime', 'Binary', 'Timestamp' ].includes(this.type)) { return this.type.toLowerCase(); } else if (this.type === 'Number') { return String(this.step).split('.')[1].length > 0 ? 'float' : 'integer'; } else if (this.enum) { return 'enum'; } return 'varchar'; })(); const length = (() => { if (type === 'enum' && this.enum) { return [Math.max(...Object.values(this.enum).map(value => String(value).length)), 0]; } else if (type === 'char' || type === 'varchar') { return [Math.min(this.clen || 255, 255), 0]; } else if (type === 'integer') { return [String(this.max).split('.')[0].length, 0]; } else if (type === 'float') { return [ String(this.max).split('.')[0].length, String(this.step).split('.')[1].length ]; } return [0, 0]; })(); const defaults = this.default ? this.default : this.required ? null : undefined; const unsigned = this.min >= 0; const increment = Boolean(this.attributes.get('increment')); const index = this.id ? 'primary' : this.unique ? 'unique' : this.indexable ? 'index' : undefined; return { type, length, defaults, unsigned, increment, index }; } get sortable() { return this.attributes.sortable; } get snake() { return (0, helpers_js_1.snakerize)(this.name); } get span() { return this.attributes.span; } get step() { const step = this.attributes.step; if (step === 1 && this.type === 'Float') { return 0.01; } return step || 1; } get title() { return (0, helpers_js_1.capitalize)((0, helpers_js_1.camelize)(this.name)); } get typemap() { return { type: typemap.type[this.type], model: typemap.model[this.type], format: typemap.format[this.type], method: typemap.method[this.type], literal: typemap.literal[this.type], mysql: typemap.mysql[this.type], pgsql: typemap.pgsql[this.type], sqlite: typemap.sqlite[this.type], helper: typemap.helper[this.type] }; } get unique() { return this.attributes.unique; } get view() { if (this.model) { return { component: false, method: 'hide', args: [], attributes: {} }; } return this.attributes.view; } get zindex() { return this.attributes.zindex; } constructor(fieldset, info) { this._fieldset = fieldset; this.type = info.type; this.name = info.name; this.multiple = info.multiple; this.required = info.required; this.attributes = new Attributes_js_1.default(Object.entries(info.attributes)); } assert(value, strict = true) { for (const assertion of this.assertions) { const { method, args, message } = assertion; const hasDefault = typeof this.default !== 'undefined'; const hasNoValue = value === null || typeof value === 'undefined' || value === ''; if (typeof assert_js_1.default[method] !== 'function' || (!strict && method === 'required') || (!strict && hasNoValue) || (strict && hasNoValue && (!this.required || hasDefault))) { continue; } if (!assert_js_1.default[method](value, ...args)) { return message || ''; } } if (this.fieldset && value) { const fieldset = this.fieldset; if (this.multiple) { if (!Array.isArray(value)) { return 'Invalid format'; } const errors = []; value.forEach(value => errors.push(fieldset.assert(value, strict))); if (errors.some(error => error)) { return errors; } } else { const message = fieldset.assert(value, strict); if (message) return message; } } return null; } attribute(name) { return this.attributes.get(name); } serialize(value, options = {}, seed) { const { bool = true, date = true, object = false } = options; if (!this.required && (value === null || typeof value === 'undefined')) { return value; } else if (typeof value === 'undefined') { return value; } if (typeof value === 'string' && this.hash) { return (0, helpers_js_1.hash)(value); } else if (typeof value === 'string' && this.encrypted && seed) { return (0, helpers_js_1.encrypt)(value, seed); } if (this.fieldset || this.multiple) { return object ? value : JSON.stringify(value); } if (this.typemap.method) { const type = this.typemap.method; if (['number', 'integer', 'float'].includes(type)) { const serialized = Number(value); return !isNaN(serialized) ? serialized : 0; } else if (type === 'boolean') { if (value === 'false') { return bool ? false : 0; } else if (value === 'true') { return bool ? true : 1; } return bool ? Boolean(value) : Number(Boolean(value)); } else if (type === 'date') { if (value instanceof Date) { return date ? value : [ value.toISOString().split('T')[0], value.toTimeString().split(' ')[0] ].join(' '); } else if (typeof value === 'number') { const stamp = new Date(value); return date ? stamp : [ stamp.toISOString().split('T')[0], stamp.toTimeString().split(' ')[0] ].join(' '); } let stamp = new Date(value); if (isNaN(stamp.getTime())) { stamp = new Date(0); } return date ? stamp : [ stamp.toISOString().split('T')[0], stamp.toTimeString().split(' ')[0] ].join(' '); } else if (type === 'object') { if (typeof value === 'string') { try { if (object) { return JSON.parse(value); } JSON.parse(value); return value; } catch (e) { } } return object ? value : JSON.stringify(value); } return (value === null || value === void 0 ? void 0 : value.toString()) || value; } if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'undefined') { return value; } else if (typeof value === 'boolean') { return bool ? value : Number(value); } else if (value instanceof Date) { return date ? value : [ value.toISOString().split('T')[0], value.toTimeString().split(' ')[0] ].join(' '); } return object ? value : ((value === null || value === void 0 ? void 0 : value.toString()) || value); } unserialize(value, options = {}, seed) { const { bool = true, date = true } = options; if (value === null || typeof value === 'undefined') { return value; } else if (this.fieldset || this.multiple) { if (typeof value === 'string') { try { return JSON.parse(value); } catch (e) { return this.multiple ? [] : {}; } } } if (this.fieldset) { const fieldset = this.fieldset; return !this.multiple ? this.fieldset.unserialize(value, options, seed) : Array.isArray(value) ? value.map(value => fieldset.unserialize(value, options, seed)) : []; } if (typeof value === 'string' && this.encrypted && seed) { return (0, helpers_js_1.decrypt)(value, seed); } if (this.typemap.method) { const type = this.typemap.method; if (['number', 'integer', 'float'].includes(type)) { const serialized = Number(value); return !isNaN(serialized) ? serialized : 0; } else if (type === 'boolean') { return bool ? Boolean(value) : Number(Boolean(value)); } else if (type === 'date') { if (value instanceof Date) { return date ? value : [ value.toISOString().split('T')[0], value.toTimeString().split(' ')[0] ].join(' '); } else if (typeof value === 'number') { const stamp = new Date(value); return date ? stamp : [ stamp.toISOString().split('T')[0], stamp.toTimeString().split(' ')[0] ].join(' '); } let stamp = new Date(value); if (isNaN(stamp.getTime())) { stamp = new Date(0); } return date ? stamp : [ stamp.toISOString().split('T')[0], stamp.toTimeString().split(' ')[0] ].join(' '); } else if (type === 'object') { if (typeof value === 'string') { try { return JSON.parse(value); } catch (e) { } } return value; } } return value; } } exports.default = Column;