1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.Uri = exports.DEFAULT = void 0;
|
4 | var tslib_1 = require("tslib");
|
5 | var common_1 = require("../common");
|
6 | var ALLOW = { NS: [] };
|
7 | exports.DEFAULT = { ALLOW: ALLOW };
|
8 | var stripQuotes = function (text) {
|
9 | return text.trim().replace(/^"/, '').replace(/"$/, '').replace(/^'/, '').replace(/'$/, '').trim();
|
10 | };
|
11 | var Uri = (function () {
|
12 | function Uri() {
|
13 | }
|
14 | Uri.clean = function (input) {
|
15 | var text = stripQuotes(input || '');
|
16 | text = text.replace(/^=/, '').trim();
|
17 | text = stripQuotes(text);
|
18 | text = text.split('?')[0].trim();
|
19 | return text;
|
20 | };
|
21 | Uri.parse = function (input) {
|
22 | var text = Uri.clean(input);
|
23 | var data = { type: 'UNKNOWN' };
|
24 | var error;
|
25 | var toString = function () { return text; };
|
26 | var setError = function (isError, message) {
|
27 | if (!error && isError) {
|
28 | error = { type: 'URI', message: message, uri: text };
|
29 | }
|
30 | };
|
31 | setError(!text, 'URI not specified');
|
32 | var index = text.indexOf(':');
|
33 | setError(index < 0, 'Not a valid multi-part URI');
|
34 | if (!error) {
|
35 | var left = text.substring(0, index);
|
36 | var right = text.substring(index + 1).trim();
|
37 | if (left === 'ns') {
|
38 | var id = right;
|
39 | setError(!id, 'Namespace URI identifier not found');
|
40 | setError(!Uri.is.valid.ns(id), "URI contains an invalid \"ns\" identifier (\"" + id + "\")");
|
41 | var uri = { type: 'NS', id: id, toString: toString };
|
42 | data = uri;
|
43 | }
|
44 | else if (left === 'file') {
|
45 | var id = right;
|
46 | setError(!id, 'File URI identifier not found');
|
47 | var parts = id.split(':');
|
48 | var ns = (parts[0] || '').trim();
|
49 | var file = (parts[1] || '').trim();
|
50 | setError(!file, "File identifier within namespace \"" + ns + "\" not found");
|
51 | var uri = { type: 'FILE', id: id, ns: ns, file: file, toString: toString };
|
52 | data = uri;
|
53 | }
|
54 | else if (left === 'cell') {
|
55 | var id = right || '';
|
56 | setError(!id, "ID of 'cell' not found");
|
57 | var type = 'CELL';
|
58 | var key = '';
|
59 | var ns = '';
|
60 | if (!id.includes(':')) {
|
61 | setError(true, "The 'cell' URI does not have a coordinate address, eg. \":A1\" in \"cell:foo:A1\"");
|
62 | }
|
63 | else {
|
64 | var bang = id.replace(/\:/g, '!');
|
65 | var parts = common_1.coord.cell.toCell(bang);
|
66 | type = common_1.coord.cell.toType(bang);
|
67 | key = parts.key;
|
68 | ns = parts.ns;
|
69 | setError(!key, "Coordinate key of '" + (type || '<empty>') + "' not found");
|
70 | setError(!ns, "Coordinate namespace of '" + (type || '<empty>') + "' not found");
|
71 | if (!error) {
|
72 | text = toUri('cell', type, ns, key);
|
73 | }
|
74 | }
|
75 | data = { type: type, id: id, ns: ns, key: key, toString: toString };
|
76 | }
|
77 | }
|
78 | var ok = !Boolean(error) && data.type !== 'UNKNOWN';
|
79 | var res = {
|
80 | ok: ok,
|
81 | uri: text,
|
82 | type: data.type,
|
83 | parts: data,
|
84 | toString: toString,
|
85 | };
|
86 | return error ? tslib_1.__assign(tslib_1.__assign({}, res), { error: error }) : res;
|
87 | };
|
88 | Uri.ns = function (input, throwError) {
|
89 | input = typeof input === 'string' && !input.includes(':') ? "ns:" + input.trim() : input;
|
90 | return parseOrThrow(input, 'NS', throwError);
|
91 | };
|
92 | Uri.cell = function (input, throwError) {
|
93 | return parseOrThrow(input, 'CELL', throwError);
|
94 | };
|
95 | Uri.row = function (input, throwError) {
|
96 | return parseOrThrow(input, 'ROW', throwError);
|
97 | };
|
98 | Uri.column = function (input, throwError) {
|
99 | return parseOrThrow(input, 'COLUMN', throwError);
|
100 | };
|
101 | Uri.file = function (input, throwError) {
|
102 | return parseOrThrow(input, 'FILE', throwError);
|
103 | };
|
104 | Uri.eq = function (a, b) {
|
105 | var toString = function (input) {
|
106 | input = input === undefined || input === null ? '' : input;
|
107 | var text = input.toString().trim();
|
108 | return !text.includes(':') ? "ns:" + text : text;
|
109 | };
|
110 | return toString(a) === toString(b);
|
111 | };
|
112 | Uri.toNs = function (input) {
|
113 | if (input === undefined) {
|
114 | return Uri.ns(common_1.cuid());
|
115 | }
|
116 | if (typeof input === 'string') {
|
117 | input = Uri.clean(input);
|
118 | }
|
119 | if (typeof input === 'string' && !input.includes(':')) {
|
120 | return Uri.ns(input);
|
121 | }
|
122 | var obj = typeof input === 'string' ? Uri.parse(input).parts : input;
|
123 | if (obj.type === 'NS') {
|
124 | return obj;
|
125 | }
|
126 | if (obj.type === 'CELL' || obj.type === 'COLUMN' || obj.type === 'ROW') {
|
127 | return Uri.ns(obj.ns);
|
128 | }
|
129 | if (obj.type === 'FILE') {
|
130 | return Uri.ns(obj.ns);
|
131 | }
|
132 | throw new Error("A namespace cannot be derived from the uri (" + input.toString() + ")");
|
133 | };
|
134 | Uri.toRowIndex = function (input) {
|
135 | var uri = typeof input === 'object' ? input : Uri.parse(input).parts;
|
136 | if (uri.type === 'CELL' || uri.type === 'COLUMN' || uri.type === 'ROW') {
|
137 | return common_1.coord.cell.toRowIndex(uri.key);
|
138 | }
|
139 | else {
|
140 | return -1;
|
141 | }
|
142 | };
|
143 | Uri.toColumnIndex = function (input) {
|
144 | var uri = typeof input === 'object' ? input : Uri.parse(input).parts;
|
145 | if (uri.type === 'CELL' || uri.type === 'COLUMN' || uri.type === 'ROW') {
|
146 | return common_1.coord.cell.toColumnIndex(uri.key);
|
147 | }
|
148 | else {
|
149 | return -1;
|
150 | }
|
151 | };
|
152 | Uri.cuid = common_1.cuid;
|
153 | Uri.slug = common_1.slug;
|
154 | Uri.ALLOW = tslib_1.__assign({}, exports.DEFAULT.ALLOW);
|
155 | Uri.create = {
|
156 | ns: function (id) { return toUri('ns', 'NS', id); },
|
157 | cell: function (ns, key) { return toUri('cell', 'CELL', ns, key); },
|
158 | row: function (ns, key) { return toUri('cell', 'ROW', ns, key); },
|
159 | column: function (ns, key) { return toUri('cell', 'COLUMN', ns, key); },
|
160 | file: function (ns, fileid) { return toUri('file', 'FILE', ns, fileid); },
|
161 | };
|
162 | Uri.is = {
|
163 | uri: function (input) { return Uri.parse(input).ok; },
|
164 | type: function (type, input) {
|
165 | var uri = Uri.parse(input);
|
166 | var types = Array.isArray(type) ? type : [type];
|
167 | return types.some(function (type) {
|
168 | return uri.parts.type === type && (type === 'UNKNOWN' ? true : uri.ok);
|
169 | });
|
170 | },
|
171 | ns: function (input) { return Uri.is.type('NS', input); },
|
172 | file: function (input) { return Uri.is.type('FILE', input); },
|
173 | cell: function (input) { return Uri.is.type('CELL', input); },
|
174 | row: function (input) { return Uri.is.type('ROW', input); },
|
175 | column: function (input) { return Uri.is.type('COLUMN', input); },
|
176 | valid: {
|
177 | ns: function (input) {
|
178 | var value = (input || '').replace(/^ns\:/, '');
|
179 | if (!value) {
|
180 | return false;
|
181 | }
|
182 | if (isCuid(value)) {
|
183 | return true;
|
184 | }
|
185 | var matchLegal = value.match(/^[A-Za-z0-9\.]*$/);
|
186 | if (!matchLegal || (matchLegal && matchLegal[0] !== value)) {
|
187 | return false;
|
188 | }
|
189 | return Uri.ALLOW.NS.some(function (pattern) {
|
190 | return typeof pattern === 'string'
|
191 | ? pattern.includes('*')
|
192 | ? common_1.wildcard.isMatch(value, pattern)
|
193 | : pattern === value
|
194 | : pattern(value);
|
195 | });
|
196 | },
|
197 | },
|
198 | };
|
199 | Uri.strip = {
|
200 | ns: function (input) { return stripPrefix(input, 'ns'); },
|
201 | cell: function (input) { return stripPrefix(input, 'cell'); },
|
202 | file: function (input) { return stripPrefix(input, 'file'); },
|
203 | };
|
204 | return Uri;
|
205 | }());
|
206 | exports.Uri = Uri;
|
207 | var alphaNumeric = new RegExp(/^[a-z0-9]+$/i);
|
208 | function trimPrefix(prefix, input) {
|
209 | var regex = new RegExp("^" + prefix + ":+");
|
210 | return input.trim().replace(regex, '');
|
211 | }
|
212 | function toUri(prefix, type, id, suffix) {
|
213 | id = (id || '').trim();
|
214 | id = id === ':' ? '' : id;
|
215 | if (id) {
|
216 | ['ns', 'cell', 'file'].forEach(function (prefix) { return (id = trimPrefix(prefix, id)); });
|
217 | }
|
218 | if (!id) {
|
219 | throw new Error("The \"" + prefix + "\" URI was not supplied with a namespace identifier. (\"" + id + "\")");
|
220 | }
|
221 | if (!Uri.is.valid.ns(id)) {
|
222 | var err = "URI contains an invalid \"" + prefix + "\" identifier, must be an alpha-numeric cuid. (\"" + id + "\")";
|
223 | throw new Error(err);
|
224 | }
|
225 | if (typeof suffix === 'string') {
|
226 | suffix = (suffix || '').trim().replace(/^\:*/, '');
|
227 | if (!suffix) {
|
228 | throw new Error("The \"" + prefix + "\" URI was not supplied with a suffix key.");
|
229 | }
|
230 | if (prefix === 'file') {
|
231 | if (!alphaNumeric.test(suffix)) {
|
232 | var err = "The \"file\" URI contains an invalid file-identifier, must be alpha-numeric (\"" + suffix + "\").";
|
233 | throw new Error(err);
|
234 | }
|
235 | suffix = ":" + suffix;
|
236 | }
|
237 | else {
|
238 | if (suffix === 'undefined') {
|
239 | var err = "The suffix \"undefined\" (string) was given - this it likely an upstream error where an [undefined] value has been converted into a string.";
|
240 | throw new Error(err);
|
241 | }
|
242 | suffix = suffix || '';
|
243 | var suffixType = common_1.coord.cell.toType(suffix) || '';
|
244 | if (suffixType !== type) {
|
245 | var key = suffix || '';
|
246 | var err = "The \"" + prefix + ":\" URI was not supplied with a valid " + type + " key (given key \"" + key + "\").";
|
247 | throw new Error(err);
|
248 | }
|
249 | suffix = ":" + suffix;
|
250 | }
|
251 | }
|
252 | return prefix + ":" + id + (suffix || '');
|
253 | }
|
254 | function isCuid(input) {
|
255 | return input.length === 25 && input[0] === 'c' && alphaNumeric.test(input);
|
256 | }
|
257 | function parseOrThrow(input, type, throwError) {
|
258 | if (typeof input === 'object') {
|
259 | return input;
|
260 | }
|
261 | else {
|
262 | var parsed = Uri.parse(input);
|
263 | var isTypeMismatch = type && parsed.type !== type;
|
264 | var hasError = Boolean(parsed.error) || isTypeMismatch;
|
265 | throwError = throwError === undefined ? true : throwError;
|
266 | if (hasError) {
|
267 | var text = (input === null || input === void 0 ? void 0 : input.toString()) || '';
|
268 | if (!parsed.error && isTypeMismatch) {
|
269 | parsed.ok = false;
|
270 | parsed.error = {
|
271 | uri: text,
|
272 | message: "The uri (" + text + ") is not of type " + type,
|
273 | type: 'URI',
|
274 | };
|
275 | }
|
276 | if (typeof throwError === 'function') {
|
277 | throwError(parsed);
|
278 | }
|
279 | if (throwError === true) {
|
280 | if (parsed.error) {
|
281 | throw new Error(parsed.error.message);
|
282 | }
|
283 | }
|
284 | }
|
285 | return parsed.parts;
|
286 | }
|
287 | }
|
288 | function stripPrefix(input, prefix) {
|
289 | var left = prefix + ":";
|
290 | input = (input || '').trim();
|
291 | input = input.startsWith(left) ? input.substring(left.length) : input;
|
292 | return input;
|
293 | }
|