UNPKG

@platform/cell.schema

Version:

URI and database schemas for the `cell.os`.

174 lines (173 loc) 7.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var common_1 = require("../common"); var ALLOW = { NS: [] }; exports.DEFAULT = { ALLOW: ALLOW }; var Uri = (function () { function Uri() { } Uri.parse = function (input) { var text = (input || '').trim().split('?')[0]; var data = { type: 'UNKNOWN' }; var error; var toString = function () { return text; }; var setError = function (isError, message) { if (!error && isError) { error = { type: 'URI', message: message, uri: text }; } }; setError(!text, 'URI not specified'); var index = text.indexOf(':'); setError(index < 0, 'Not a valid multi-part URI'); if (!error) { var left = text.substring(0, index); var right = text.substring(index + 1).trim(); if (left === 'ns') { var id = right; setError(!id, 'Namespace URI identifier not found'); setError(!Uri.is.valid.ns(id), "URI contains an invalid \"ns\" identifier (\"" + id + "\")"); var uri = { type: 'NS', id: id, toString: toString }; data = uri; } else if (left === 'file') { var id = right; setError(!id, 'File URI identifier not found'); var parts = id.split(':'); var ns = (parts[0] || '').trim(); var file = (parts[1] || '').trim(); setError(!file, "File identifier within namespace \"" + ns + "\" not found"); var uri = { type: 'FILE', id: id, ns: ns, file: file, toString: toString }; data = uri; } else if (left === 'cell') { var id = right || ''; setError(!id, "ID of 'cell' not found"); var type = 'CELL'; var key = ''; var ns = ''; if (!id.includes(':')) { setError(true, "The 'cell' URI does not have a coordinate address, eg. \":A1\" in \"cell:foo:A1\""); } else { var bang = id.replace(/\:/g, '!'); var parts = common_1.coord.cell.toCell(bang); type = common_1.coord.cell.toType(bang); key = parts.key; ns = parts.ns; setError(!key, "Coordinate key of '" + (type || '<empty>') + "' not found"); setError(!ns, "Coordinate namespace of '" + (type || '<empty>') + "' not found"); if (!error) { text = toUri('cell', type, ns, key); } } data = { type: type, id: id, ns: ns, key: key, toString: toString }; } } var ok = !Boolean(error) && data.type !== 'UNKNOWN'; var res = { ok: ok, uri: text, type: data.type, parts: data, toString: toString, }; return error ? tslib_1.__assign(tslib_1.__assign({}, res), { error: error }) : res; }; Uri.cuid = common_1.cuid; Uri.slug = common_1.slug; Uri.ALLOW = tslib_1.__assign({}, exports.DEFAULT.ALLOW); Uri.create = { ns: function (id) { return toUri('ns', 'NS', id); }, cell: function (ns, key) { return toUri('cell', 'CELL', ns, key); }, row: function (ns, key) { return toUri('cell', 'ROW', ns, key); }, column: function (ns, key) { return toUri('cell', 'COLUMN', ns, key); }, file: function (ns, fileid) { return toUri('file', 'FILE', ns, fileid); }, }; Uri.is = { uri: function (input) { return Uri.parse(input).ok; }, type: function (type, input) { var uri = Uri.parse(input); return uri.parts.type === type && (type === 'UNKNOWN' ? true : uri.ok); }, ns: function (input) { return Uri.is.type('NS', input); }, file: function (input) { return Uri.is.type('FILE', input); }, cell: function (input) { return Uri.is.type('CELL', input); }, row: function (input) { return Uri.is.type('ROW', input); }, column: function (input) { return Uri.is.type('COLUMN', input); }, valid: { ns: function (input) { var value = (input || '').replace(/^ns\:/, ''); if (!value) { return false; } if (isCuid(value)) { return true; } var matchLegal = value.match(/^[A-Za-z0-9\.]*$/); if (!matchLegal || (matchLegal && matchLegal[0] !== value)) { return false; } return Uri.ALLOW.NS.some(function (pattern) { return typeof pattern === 'string' ? pattern.includes('*') ? common_1.wildcard.isMatch(value, pattern) : pattern === value : pattern(value); }); }, }, }; return Uri; }()); exports.Uri = Uri; var alphaNumeric = new RegExp(/^[a-z0-9]+$/i); function trimPrefix(prefix, input) { var regex = new RegExp("^" + prefix + ":+"); return input.trim().replace(regex, ''); } function toUri(prefix, type, id, suffix) { id = (id || '').trim(); id = id === ':' ? '' : id; if (id) { ['ns', 'cell', 'file'].forEach(function (prefix) { return (id = trimPrefix(prefix, id)); }); } if (!id) { throw new Error("The \"" + prefix + "\" URI was not supplied with a namespace identifier. (\"" + id + "\")"); } if (!Uri.is.valid.ns(id)) { var err = "URI contains an invalid \"" + prefix + "\" identifier, must be an alpha-numeric cuid. (\"" + id + "\")"; throw new Error(err); } if (typeof suffix === 'string') { suffix = (suffix || '').trim().replace(/^\:*/, ''); if (!suffix) { throw new Error("The \"" + prefix + "\" URI was not supplied with a suffix key."); } if (prefix === 'file') { if (!alphaNumeric.test(suffix)) { var err = "The \"file\" URI contains an invalid file-identifier, must be alpha-numeric (\"" + suffix + "\")."; throw new Error(err); } suffix = ":" + suffix; } else { if (suffix === 'undefined') { var err = "The suffix \"undefined\" (string) was given - this it likely an upstream error where an [undefined] value has been converted into a string."; throw new Error(err); } suffix = suffix || ''; var suffixType = common_1.coord.cell.toType(suffix) || ''; if (suffixType !== type) { var key = suffix || ''; var err = "The \"" + prefix + ":\" URI was not supplied with a valid " + type + " key (given key \"" + key + "\")."; throw new Error(err); } suffix = ":" + suffix; } } return prefix + ":" + id + (suffix || ''); } function isCuid(input) { return input.length === 25 && input[0] === 'c' && alphaNumeric.test(input); }