@rebasepro/common 0.0.1-canary.2 → 0.0.1-canary.4d4fb3e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/collections/CollectionRegistry.d.ts +2 -2
- package/dist/data/buildRebaseData.d.ts +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +398 -815
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +418 -835
- package/dist/index.umd.js.map +1 -1
- package/dist/util/builders.d.ts +6 -13
- package/dist/util/collections.d.ts +2 -2
- package/dist/util/entities.d.ts +16 -8
- package/dist/util/index.d.ts +1 -11
- package/dist/util/navigation_from_path.d.ts +10 -5
- package/dist/util/navigation_utils.d.ts +1 -12
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/references.d.ts +1 -1
- package/dist/util/relations.d.ts +4 -4
- package/dist/util/resolutions.d.ts +10 -12
- package/dist/util/storage.d.ts +4 -4
- package/package.json +11 -16
- package/src/collections/CollectionRegistry.ts +96 -33
- package/src/data/buildRebaseData.ts +221 -0
- package/src/index.ts +1 -0
- package/src/types/json-logic-js.d.ts +8 -0
- package/src/util/builders.ts +8 -18
- package/src/util/callbacks.ts +3 -4
- package/src/util/collections.ts +4 -4
- package/src/util/conditions.ts +4 -4
- package/src/util/entities.ts +37 -12
- package/src/util/index.ts +1 -11
- package/src/util/navigation_from_path.ts +8 -7
- package/src/util/navigation_utils.ts +4 -56
- package/src/util/parent_references_from_path.ts +1 -1
- package/src/util/permissions.test.ts +24 -28
- package/src/util/permissions.ts +14 -14
- package/src/util/references.ts +16 -2
- package/src/util/relations.ts +23 -19
- package/src/util/resolutions.ts +31 -62
- package/src/util/storage.ts +5 -5
- package/dist/util/arrays.d.ts +0 -1
- package/dist/util/dates.d.ts +0 -1
- package/dist/util/entity_actions.d.ts +0 -2
- package/dist/util/fields.d.ts +0 -2
- package/dist/util/flatten_object.d.ts +0 -5
- package/dist/util/hash.d.ts +0 -1
- package/dist/util/names.d.ts +0 -22
- package/dist/util/objects.d.ts +0 -26
- package/dist/util/os.d.ts +0 -2
- package/dist/util/plurals.d.ts +0 -16
- package/dist/util/regexp.d.ts +0 -7
- package/dist/util/strings.d.ts +0 -7
- package/src/util/arrays.ts +0 -3
- package/src/util/dates.ts +0 -1
- package/src/util/entity_actions.ts +0 -28
- package/src/util/fields.ts +0 -28
- package/src/util/flatten_object.ts +0 -45
- package/src/util/hash.ts +0 -11
- package/src/util/names.ts +0 -30
- package/src/util/objects.ts +0 -376
- package/src/util/os.ts +0 -13
- package/src/util/plurals.ts +0 -188
- package/src/util/regexp.ts +0 -32
- package/src/util/strings.ts +0 -84
package/dist/index.umd.js
CHANGED
|
@@ -1,298 +1,16 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@rebasepro/types"), require("
|
|
3
|
-
})(this, function(exports2, types,
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@rebasepro/types"), require("@rebasepro/utils"), require("json-logic-js"), require("fast-equals"), require("lodash/cloneDeep.js")) : typeof define === "function" && define.amd ? define(["exports", "@rebasepro/types", "@rebasepro/utils", "json-logic-js", "fast-equals", "lodash/cloneDeep.js"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["Rebase Util"] = {}, global.types, global.utils, global.jsonLogic, global.fastEquals, global.cloneDeep));
|
|
3
|
+
})(this, function(exports2, types, utils, jsonLogic, fastEquals, cloneDeep) {
|
|
4
4
|
"use strict";
|
|
5
5
|
const DEFAULT_ONE_OF_TYPE = "type";
|
|
6
6
|
const DEFAULT_ONE_OF_VALUE = "value";
|
|
7
|
-
const isEmptyArray = (value) => Array.isArray(value) && value.length === 0;
|
|
8
|
-
const isFunction = (obj) => typeof obj === "function";
|
|
9
|
-
const isInteger = (obj) => String(Math.floor(Number(obj))) === String(obj);
|
|
10
|
-
const isNaN$1 = (obj) => obj !== obj;
|
|
11
|
-
function getIn$1(obj, key, def, p = 0) {
|
|
12
|
-
const path = toPath(key);
|
|
13
|
-
while (obj && p < path.length) {
|
|
14
|
-
obj = obj[path[p++]];
|
|
15
|
-
}
|
|
16
|
-
if (p !== path.length && !obj) {
|
|
17
|
-
return def;
|
|
18
|
-
}
|
|
19
|
-
return obj === void 0 ? def : obj;
|
|
20
|
-
}
|
|
21
|
-
function setIn(obj, path, value) {
|
|
22
|
-
const res = clone(obj);
|
|
23
|
-
let resVal = res;
|
|
24
|
-
let i = 0;
|
|
25
|
-
const pathArray = toPath(path);
|
|
26
|
-
for (; i < pathArray.length - 1; i++) {
|
|
27
|
-
const currentPath = pathArray[i];
|
|
28
|
-
const currentObj = getIn$1(obj, pathArray.slice(0, i + 1));
|
|
29
|
-
if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {
|
|
30
|
-
resVal = resVal[currentPath] = clone(currentObj);
|
|
31
|
-
} else {
|
|
32
|
-
const nextPath = pathArray[i + 1];
|
|
33
|
-
resVal = resVal[currentPath] = isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {
|
|
37
|
-
return obj;
|
|
38
|
-
}
|
|
39
|
-
if (value === void 0) {
|
|
40
|
-
delete resVal[pathArray[i]];
|
|
41
|
-
} else {
|
|
42
|
-
resVal[pathArray[i]] = value;
|
|
43
|
-
}
|
|
44
|
-
if (i === 0 && value === void 0) {
|
|
45
|
-
delete res[pathArray[i]];
|
|
46
|
-
}
|
|
47
|
-
return res;
|
|
48
|
-
}
|
|
49
|
-
function clone(value) {
|
|
50
|
-
if (Array.isArray(value)) {
|
|
51
|
-
return [...value];
|
|
52
|
-
} else if (typeof value === "object" && value !== null) {
|
|
53
|
-
return {
|
|
54
|
-
...value
|
|
55
|
-
};
|
|
56
|
-
} else {
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function toPath(value) {
|
|
61
|
-
if (Array.isArray(value)) return value;
|
|
62
|
-
return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
|
|
63
|
-
}
|
|
64
|
-
const pick = (obj, ...args) => ({
|
|
65
|
-
...args.reduce((res, key) => ({
|
|
66
|
-
...res,
|
|
67
|
-
[key]: obj[key]
|
|
68
|
-
}), {})
|
|
69
|
-
});
|
|
70
|
-
function isObject(item) {
|
|
71
|
-
return !!item && typeof item === "object" && !Array.isArray(item);
|
|
72
|
-
}
|
|
73
|
-
function isPlainObject(obj) {
|
|
74
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
const proto = Object.getPrototypeOf(obj);
|
|
78
|
-
return proto === Object.prototype;
|
|
79
|
-
}
|
|
80
|
-
function mergeDeep(target, source, ignoreUndefined = false) {
|
|
81
|
-
if (!isObject(target)) {
|
|
82
|
-
return target;
|
|
83
|
-
}
|
|
84
|
-
const output = {
|
|
85
|
-
...target
|
|
86
|
-
};
|
|
87
|
-
if (!isObject(source)) {
|
|
88
|
-
return output;
|
|
89
|
-
}
|
|
90
|
-
for (const key in source) {
|
|
91
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
92
|
-
const sourceValue = source[key];
|
|
93
|
-
const outputValue = output[key];
|
|
94
|
-
if (ignoreUndefined && sourceValue === void 0) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
if (sourceValue instanceof Date) {
|
|
98
|
-
output[key] = new Date(sourceValue.getTime());
|
|
99
|
-
} else if (Array.isArray(sourceValue)) {
|
|
100
|
-
if (Array.isArray(outputValue)) {
|
|
101
|
-
const newArray = [];
|
|
102
|
-
const maxLength = Math.max(outputValue.length, sourceValue.length);
|
|
103
|
-
for (let i = 0; i < maxLength; i++) {
|
|
104
|
-
const sourceItem = sourceValue[i];
|
|
105
|
-
const targetItem = outputValue[i];
|
|
106
|
-
if (i >= sourceValue.length) {
|
|
107
|
-
newArray[i] = targetItem;
|
|
108
|
-
} else if (i >= outputValue.length) {
|
|
109
|
-
newArray[i] = sourceItem;
|
|
110
|
-
} else if (sourceItem === null) {
|
|
111
|
-
newArray[i] = targetItem;
|
|
112
|
-
} else if (isPlainObject(sourceItem) && isPlainObject(targetItem)) {
|
|
113
|
-
newArray[i] = mergeDeep(targetItem, sourceItem, ignoreUndefined);
|
|
114
|
-
} else {
|
|
115
|
-
newArray[i] = sourceItem;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
output[key] = newArray;
|
|
119
|
-
} else {
|
|
120
|
-
output[key] = [...sourceValue];
|
|
121
|
-
}
|
|
122
|
-
} else if (isPlainObject(sourceValue)) {
|
|
123
|
-
if (isPlainObject(outputValue)) {
|
|
124
|
-
output[key] = mergeDeep(outputValue, sourceValue, ignoreUndefined);
|
|
125
|
-
} else {
|
|
126
|
-
output[key] = sourceValue;
|
|
127
|
-
}
|
|
128
|
-
} else if (isObject(sourceValue)) {
|
|
129
|
-
output[key] = sourceValue;
|
|
130
|
-
} else {
|
|
131
|
-
output[key] = sourceValue;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return output;
|
|
136
|
-
}
|
|
137
|
-
function getValueInPath(o, path) {
|
|
138
|
-
if (!o) return void 0;
|
|
139
|
-
if (typeof o === "object") {
|
|
140
|
-
if (path in o) {
|
|
141
|
-
return o[path];
|
|
142
|
-
}
|
|
143
|
-
if (path.includes(".") || path.includes("[")) {
|
|
144
|
-
let pathSegments = path.split(/[.[]/);
|
|
145
|
-
if (path.includes("[")) {
|
|
146
|
-
pathSegments = pathSegments.map((segment) => segment.replace("]", ""));
|
|
147
|
-
}
|
|
148
|
-
const firstSegment = pathSegments[0];
|
|
149
|
-
const isArrayAndIndexExists = Array.isArray(o[firstSegment]) && !isNaN$1(parseInt(pathSegments[1]));
|
|
150
|
-
const nextObject = isArrayAndIndexExists ? o[firstSegment][parseInt(pathSegments[1])] : o[firstSegment];
|
|
151
|
-
const nextPath = pathSegments.slice(isArrayAndIndexExists ? 2 : 1).join(".");
|
|
152
|
-
if (nextPath === "") return nextObject;
|
|
153
|
-
return getValueInPath(nextObject, nextPath);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return void 0;
|
|
157
|
-
}
|
|
158
|
-
function removeInPath(o, path) {
|
|
159
|
-
let currentObject = {
|
|
160
|
-
...o
|
|
161
|
-
};
|
|
162
|
-
const parts = path.split(".");
|
|
163
|
-
const last = parts.pop();
|
|
164
|
-
for (const part of parts) {
|
|
165
|
-
currentObject = currentObject[part];
|
|
166
|
-
}
|
|
167
|
-
if (last) delete currentObject[last];
|
|
168
|
-
return currentObject;
|
|
169
|
-
}
|
|
170
|
-
function removeFunctions(o) {
|
|
171
|
-
if (o === void 0) return void 0;
|
|
172
|
-
if (o === null) return null;
|
|
173
|
-
if (typeof o === "object") {
|
|
174
|
-
if (Array.isArray(o)) {
|
|
175
|
-
return o.map((v) => removeFunctions(v));
|
|
176
|
-
}
|
|
177
|
-
if (!isPlainObject(o)) {
|
|
178
|
-
return o;
|
|
179
|
-
}
|
|
180
|
-
return Object.entries(o).filter(([_, value]) => typeof value !== "function").map(([key, value]) => {
|
|
181
|
-
if (Array.isArray(value)) {
|
|
182
|
-
return {
|
|
183
|
-
[key]: value.map((v) => removeFunctions(v))
|
|
184
|
-
};
|
|
185
|
-
} else if (typeof value === "object") {
|
|
186
|
-
return {
|
|
187
|
-
[key]: removeFunctions(value)
|
|
188
|
-
};
|
|
189
|
-
} else return {
|
|
190
|
-
[key]: value
|
|
191
|
-
};
|
|
192
|
-
}).reduce((a, b) => ({
|
|
193
|
-
...a,
|
|
194
|
-
...b
|
|
195
|
-
}), {});
|
|
196
|
-
}
|
|
197
|
-
return o;
|
|
198
|
-
}
|
|
199
|
-
function getHashValue(v) {
|
|
200
|
-
if (!v) return null;
|
|
201
|
-
if (typeof v === "object" && v !== null) {
|
|
202
|
-
if ("id" in v) return String(v.id);
|
|
203
|
-
else if (v instanceof Date) return v.toLocaleString();
|
|
204
|
-
else if (v instanceof types.GeoPoint) return hash(v);
|
|
205
|
-
}
|
|
206
|
-
return hash(v, {
|
|
207
|
-
ignoreUnknown: true
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
function removeUndefined(value, removeEmptyStrings) {
|
|
211
|
-
if (typeof value === "function") {
|
|
212
|
-
return value;
|
|
213
|
-
}
|
|
214
|
-
if (Array.isArray(value)) {
|
|
215
|
-
return value.map((v) => removeUndefined(v, removeEmptyStrings));
|
|
216
|
-
}
|
|
217
|
-
if (typeof value === "object") {
|
|
218
|
-
if (value === null) return value;
|
|
219
|
-
if (!isPlainObject(value)) {
|
|
220
|
-
return value;
|
|
221
|
-
}
|
|
222
|
-
const res = {};
|
|
223
|
-
Object.keys(value).forEach((key) => {
|
|
224
|
-
if (!isEmptyObject(value)) {
|
|
225
|
-
const childRes = removeUndefined(value[key], removeEmptyStrings);
|
|
226
|
-
const isString = typeof childRes === "string";
|
|
227
|
-
const shouldKeepIfString = !removeEmptyStrings || removeEmptyStrings && !isString || removeEmptyStrings && isString && childRes !== "";
|
|
228
|
-
if (childRes !== void 0 && !isEmptyObject(childRes) && shouldKeepIfString) res[key] = childRes;
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
return res;
|
|
232
|
-
}
|
|
233
|
-
return value;
|
|
234
|
-
}
|
|
235
|
-
function removeNulls(value) {
|
|
236
|
-
if (typeof value === "function") {
|
|
237
|
-
return value;
|
|
238
|
-
}
|
|
239
|
-
if (Array.isArray(value)) {
|
|
240
|
-
return value.map((v) => removeNulls(v));
|
|
241
|
-
}
|
|
242
|
-
if (typeof value === "object") {
|
|
243
|
-
if (value === null) return value;
|
|
244
|
-
if (!isPlainObject(value)) {
|
|
245
|
-
return value;
|
|
246
|
-
}
|
|
247
|
-
const res = {};
|
|
248
|
-
const obj = value;
|
|
249
|
-
Object.keys(obj).forEach((key) => {
|
|
250
|
-
if (obj[key] !== null) res[key] = removeNulls(obj[key]);
|
|
251
|
-
});
|
|
252
|
-
return res;
|
|
253
|
-
}
|
|
254
|
-
return value;
|
|
255
|
-
}
|
|
256
|
-
function isEmptyObject(obj) {
|
|
257
|
-
return obj && Object.getPrototypeOf(obj) === Object.prototype && Object.keys(obj).length === 0;
|
|
258
|
-
}
|
|
259
|
-
function removePropsIfExisting(source, comparison) {
|
|
260
|
-
const isObject2 = (val) => typeof val === "object" && val !== null;
|
|
261
|
-
const isArray = (val) => Array.isArray(val);
|
|
262
|
-
if (!isObject2(source) || !isObject2(comparison)) {
|
|
263
|
-
return source;
|
|
264
|
-
}
|
|
265
|
-
const res = isArray(source) ? [...source] : {
|
|
266
|
-
...source
|
|
267
|
-
};
|
|
268
|
-
if (isArray(res)) {
|
|
269
|
-
for (let i = res.length - 1; i >= 0; i--) {
|
|
270
|
-
if (res[i] === comparison[i]) {
|
|
271
|
-
res.splice(i, 1);
|
|
272
|
-
} else if (isObject2(res[i]) && isObject2(comparison[i])) {
|
|
273
|
-
res[i] = removePropsIfExisting(res[i], comparison[i]);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
Object.keys(comparison).forEach((key) => {
|
|
278
|
-
if (key in res) {
|
|
279
|
-
if (isObject2(res[key]) && isObject2(comparison[key])) {
|
|
280
|
-
res[key] = removePropsIfExisting(res[key], comparison[key]);
|
|
281
|
-
} else if (res[key] === comparison[key]) {
|
|
282
|
-
delete res[key];
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
return res;
|
|
288
|
-
}
|
|
289
7
|
function isReadOnly(property) {
|
|
290
8
|
if (property.readOnly) return true;
|
|
291
9
|
if (property.type === "date") {
|
|
292
10
|
if (property.autoValue) return true;
|
|
293
11
|
}
|
|
294
12
|
if (property.type === "reference") {
|
|
295
|
-
return !property.path && !property.Field;
|
|
13
|
+
return !property.path && !("Field" in property && property.Field);
|
|
296
14
|
}
|
|
297
15
|
return false;
|
|
298
16
|
}
|
|
@@ -378,12 +96,20 @@
|
|
|
378
96
|
return new types.EntityReference({
|
|
379
97
|
id: entity.id,
|
|
380
98
|
path: entity.path,
|
|
381
|
-
|
|
99
|
+
driver: entity.driver,
|
|
382
100
|
databaseId: entity.databaseId
|
|
383
101
|
});
|
|
384
102
|
}
|
|
385
103
|
function getRelationFrom(entity) {
|
|
386
|
-
return new types.EntityRelation(entity.id, entity.path);
|
|
104
|
+
return new types.EntityRelation(entity.id, entity.path, entity);
|
|
105
|
+
}
|
|
106
|
+
function normalizeToEntityRelation(value) {
|
|
107
|
+
if (value instanceof types.EntityRelation) return value;
|
|
108
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
109
|
+
const obj = value;
|
|
110
|
+
const isRelationLike = obj.__type === "relation" || typeof obj.isEntityRelation === "function" && obj.isEntityRelation();
|
|
111
|
+
if (!isRelationLike) return null;
|
|
112
|
+
return new types.EntityRelation(obj.id, obj.path, obj.data);
|
|
387
113
|
}
|
|
388
114
|
function traverseValuesProperties(inputValues, properties, operation) {
|
|
389
115
|
const safeInputValues = inputValues ?? {};
|
|
@@ -399,7 +125,7 @@
|
|
|
399
125
|
...a,
|
|
400
126
|
...b
|
|
401
127
|
}), {});
|
|
402
|
-
const result = mergeDeep(safeInputValues, updatedValues);
|
|
128
|
+
const result = utils.mergeDeep(safeInputValues, updatedValues);
|
|
403
129
|
if (!result || Object.keys(result).length === 0) return void 0;
|
|
404
130
|
return result;
|
|
405
131
|
}
|
|
@@ -537,58 +263,6 @@
|
|
|
537
263
|
}
|
|
538
264
|
return ["id"];
|
|
539
265
|
}
|
|
540
|
-
const kebabCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;
|
|
541
|
-
const toKebabCase = (str) => {
|
|
542
|
-
const regExpMatchArray = str.match(kebabCaseRegex);
|
|
543
|
-
if (!regExpMatchArray) return "";
|
|
544
|
-
return regExpMatchArray.map((x) => x.toLowerCase()).join("-");
|
|
545
|
-
};
|
|
546
|
-
const snakeCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g;
|
|
547
|
-
const toSnakeCase = (str) => {
|
|
548
|
-
const regExpMatchArray = str.match(snakeCaseRegex);
|
|
549
|
-
if (!regExpMatchArray) return "";
|
|
550
|
-
return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
|
|
551
|
-
};
|
|
552
|
-
function randomString(strLength = 5) {
|
|
553
|
-
return Math.random().toString(36).slice(2, 2 + strLength);
|
|
554
|
-
}
|
|
555
|
-
function randomColor() {
|
|
556
|
-
return Math.floor(Math.random() * 16777215).toString(16);
|
|
557
|
-
}
|
|
558
|
-
function slugify(text, separator = "_", lowercase = true) {
|
|
559
|
-
if (!text) return "";
|
|
560
|
-
const from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;-";
|
|
561
|
-
const to = `aaaaaeeeeeiiiiooooouuuunc${separator}${separator}${separator}${separator}${separator}${separator}${separator}`;
|
|
562
|
-
for (let i = 0, l = from.length; i < l; i++) {
|
|
563
|
-
text = text.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
|
|
564
|
-
}
|
|
565
|
-
text = text.toString().replace(/\s+/g, separator).replace(/&/g, separator).replace(/[^\w\\-]+/g, "").replace(new RegExp("\\" + separator + "\\" + separator + "+", "g"), separator).trim().replace(/^\s+|\s+$/g, "");
|
|
566
|
-
return lowercase ? text.toLowerCase() : text;
|
|
567
|
-
}
|
|
568
|
-
function unslugify(slug) {
|
|
569
|
-
if (!slug) return "";
|
|
570
|
-
if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
|
|
571
|
-
const result = slug.replace(/[-_]/g, " ");
|
|
572
|
-
return result.replace(/\w\S*/g, function(txt) {
|
|
573
|
-
return txt.charAt(0).toUpperCase() + txt.substring(1);
|
|
574
|
-
}).trim();
|
|
575
|
-
} else {
|
|
576
|
-
return slug.trim();
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
function prettifyIdentifier(input) {
|
|
580
|
-
if (!input) return "";
|
|
581
|
-
let text = input;
|
|
582
|
-
text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
|
|
583
|
-
text = text.replace(/[_-]+/g, " ");
|
|
584
|
-
const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
585
|
-
console.log("Prettified identifier:", {
|
|
586
|
-
input,
|
|
587
|
-
s
|
|
588
|
-
});
|
|
589
|
-
return s;
|
|
590
|
-
}
|
|
591
|
-
const defaultDateFormat = "MMMM dd, yyyy, HH:mm:ss";
|
|
592
266
|
function enumToObjectEntries(enumValues) {
|
|
593
267
|
if (Array.isArray(enumValues)) {
|
|
594
268
|
return enumValues;
|
|
@@ -623,28 +297,6 @@
|
|
|
623
297
|
function fullPathToCollectionSegments(path) {
|
|
624
298
|
return path.split("/").filter((e, i) => i % 2 === 0);
|
|
625
299
|
}
|
|
626
|
-
function serializeRegExp(input) {
|
|
627
|
-
if (!input) return "";
|
|
628
|
-
return input.toString();
|
|
629
|
-
}
|
|
630
|
-
function hydrateRegExp(input) {
|
|
631
|
-
if (!input) return void 0;
|
|
632
|
-
const fragments = input.match(/\/(.*?)\/([a-z]*)?$/i);
|
|
633
|
-
if (fragments) {
|
|
634
|
-
return new RegExp(fragments[1], fragments[2] || "");
|
|
635
|
-
} else {
|
|
636
|
-
return new RegExp(input, "");
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
function isValidRegExp(input) {
|
|
640
|
-
const fullRegexp = input.match(/\/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/);
|
|
641
|
-
if (fullRegexp) return true;
|
|
642
|
-
const simpleRegexp = input.match(/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)/);
|
|
643
|
-
return !!simpleRegexp;
|
|
644
|
-
}
|
|
645
|
-
function isDefaultFieldConfigId(id) {
|
|
646
|
-
return ["text_field", "multiline", "markdown", "url", "email", "switch", "select", "multi_select", "number_input", "number_select", "multi_number_select", "file_upload", "multi_file_upload", "reference_as_string", "reference", "multi_references", "relation", "date_time", "group", "key_value", "repeat", "custom_array", "block"].includes(id);
|
|
647
|
-
}
|
|
648
300
|
function resolveProperty(props) {
|
|
649
301
|
const {
|
|
650
302
|
property,
|
|
@@ -655,7 +307,7 @@
|
|
|
655
307
|
if (isPropertyBuilder(property)) {
|
|
656
308
|
const path = rest.path;
|
|
657
309
|
if (!path) throw Error("Trying to resolve a property builder without specifying the entity path");
|
|
658
|
-
const usedPropertyValue = rest.propertyKey ? getIn
|
|
310
|
+
const usedPropertyValue = rest.propertyKey ? utils.getIn(rest.values, rest.propertyKey) : void 0;
|
|
659
311
|
const dynamicProps = property.dynamicProps?.({
|
|
660
312
|
...rest,
|
|
661
313
|
path,
|
|
@@ -663,14 +315,14 @@
|
|
|
663
315
|
values: rest.values ?? {},
|
|
664
316
|
previousValues: rest.previousValues ?? rest.values ?? {}
|
|
665
317
|
});
|
|
666
|
-
resultProperty = mergeDeep(property, dynamicProps ?? {});
|
|
318
|
+
resultProperty = utils.mergeDeep(property, dynamicProps ?? {});
|
|
667
319
|
} else {
|
|
668
320
|
resultProperty = property;
|
|
669
321
|
}
|
|
670
322
|
if (resultProperty.dynamicProps) {
|
|
671
323
|
const path = rest.path;
|
|
672
324
|
if (!path) throw Error("Trying to resolve dynamicProps without specifying the entity path");
|
|
673
|
-
const usedPropertyValue = rest.propertyKey ? getIn
|
|
325
|
+
const usedPropertyValue = rest.propertyKey ? utils.getIn(rest.values, rest.propertyKey) : void 0;
|
|
674
326
|
const dynamicPropsResult = resultProperty.dynamicProps({
|
|
675
327
|
...rest,
|
|
676
328
|
path,
|
|
@@ -679,7 +331,7 @@
|
|
|
679
331
|
previousValues: rest.previousValues ?? rest.values ?? {}
|
|
680
332
|
});
|
|
681
333
|
if (dynamicPropsResult) {
|
|
682
|
-
resultProperty = mergeDeep(resultProperty, dynamicPropsResult);
|
|
334
|
+
resultProperty = utils.mergeDeep(resultProperty, dynamicPropsResult);
|
|
683
335
|
}
|
|
684
336
|
}
|
|
685
337
|
let resolvedProperty;
|
|
@@ -700,7 +352,7 @@
|
|
|
700
352
|
} else {
|
|
701
353
|
resolvedProperty = resultProperty;
|
|
702
354
|
}
|
|
703
|
-
if (resolvedProperty?.propertyConfig && !isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {
|
|
355
|
+
if (resolvedProperty?.propertyConfig && !utils.isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {
|
|
704
356
|
const cmsFields = rest.propertyConfigs;
|
|
705
357
|
if (!cmsFields && !ignoreMissingFields) {
|
|
706
358
|
throw Error(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property configs were provided. Use the property 'propertyConfigs' in your app config to provide them`);
|
|
@@ -711,10 +363,10 @@
|
|
|
711
363
|
return resolvedProperty;
|
|
712
364
|
}
|
|
713
365
|
if (customField.property) {
|
|
714
|
-
const {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
366
|
+
const restConfigProperty = {
|
|
367
|
+
...customField.property
|
|
368
|
+
};
|
|
369
|
+
delete restConfigProperty.propertyConfig;
|
|
718
370
|
const customFieldProperty = resolveProperty({
|
|
719
371
|
property: {
|
|
720
372
|
name: "",
|
|
@@ -724,7 +376,7 @@
|
|
|
724
376
|
...rest
|
|
725
377
|
});
|
|
726
378
|
if (customFieldProperty) {
|
|
727
|
-
resolvedProperty = mergeDeep(customFieldProperty, resolvedProperty);
|
|
379
|
+
resolvedProperty = utils.mergeDeep(customFieldProperty, resolvedProperty);
|
|
728
380
|
}
|
|
729
381
|
}
|
|
730
382
|
}
|
|
@@ -777,7 +429,7 @@
|
|
|
777
429
|
ignoreMissingFields = false,
|
|
778
430
|
...props
|
|
779
431
|
}) {
|
|
780
|
-
const propertyValue = propertyKey ? getIn
|
|
432
|
+
const propertyValue = propertyKey ? utils.getIn(props.values, propertyKey) : void 0;
|
|
781
433
|
if (property.of) {
|
|
782
434
|
if (Array.isArray(property.of)) {
|
|
783
435
|
return property.of.map((p, index) => {
|
|
@@ -826,7 +478,7 @@
|
|
|
826
478
|
});
|
|
827
479
|
}).filter((e) => Boolean(e)) : [];
|
|
828
480
|
return resolvedProperties;
|
|
829
|
-
} else if (!property.Field) {
|
|
481
|
+
} else if (!("Field" in property && property.Field)) {
|
|
830
482
|
throw Error(`The array property (${propertyKey}) needs to declare an 'of' or a 'oneOf' property, or provide a custom \`Field\` component`);
|
|
831
483
|
} else {
|
|
832
484
|
return [];
|
|
@@ -861,209 +513,21 @@
|
|
|
861
513
|
return void 0;
|
|
862
514
|
}
|
|
863
515
|
}
|
|
864
|
-
function resolveEntityView$1(entityView, contextEntityViews) {
|
|
865
|
-
if (typeof entityView === "string") {
|
|
866
|
-
return contextEntityViews?.find((entry) => entry.key === entityView);
|
|
867
|
-
} else {
|
|
868
|
-
return entityView;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
function resolveEntityAction(entityAction, contextEntityActions) {
|
|
872
|
-
if (typeof entityAction === "string") {
|
|
873
|
-
return contextEntityActions?.find((entry) => entry.key === entityAction);
|
|
874
|
-
} else {
|
|
875
|
-
return entityAction;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
function resolvedSelectedEntityView(customViews, customizationController, selectedTab, canEdit) {
|
|
879
|
-
const resolvedEntityViews = customViews ? customViews.map((e) => resolveEntityView$1(e, customizationController.entityViews)).filter((e) => Boolean(e)) : [];
|
|
880
|
-
const selectedEntityView = resolvedEntityViews.find((e) => e.key === selectedTab);
|
|
881
|
-
const selectedSecondaryForm = customViews && resolvedEntityViews.filter((e) => e.includeActions).find((e) => e.key === selectedTab);
|
|
882
|
-
return {
|
|
883
|
-
resolvedEntityViews,
|
|
884
|
-
selectedEntityView,
|
|
885
|
-
selectedSecondaryForm
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
516
|
function getSubcollections(collection) {
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
subcollections.push(...(collection.relations ?? []).filter((rel) => rel.cardinality === "many").map((relation) => {
|
|
892
|
-
const targetCollection = relation.target();
|
|
893
|
-
const overrides = relation.overrides;
|
|
894
|
-
return overrides ? mergeDeep(targetCollection, overrides) : targetCollection;
|
|
895
|
-
}) ?? []);
|
|
896
|
-
return subcollections;
|
|
897
|
-
}
|
|
898
|
-
function removeInitialAndTrailingSlashes(s) {
|
|
899
|
-
return removeInitialSlash(removeTrailingSlash(s));
|
|
900
|
-
}
|
|
901
|
-
function removeInitialSlash(s) {
|
|
902
|
-
if (s.startsWith("/")) return s.slice(1);
|
|
903
|
-
else return s;
|
|
904
|
-
}
|
|
905
|
-
function removeTrailingSlash(s) {
|
|
906
|
-
if (s.endsWith("/")) return s.slice(0, -1);
|
|
907
|
-
else return s;
|
|
908
|
-
}
|
|
909
|
-
function addInitialSlash(s) {
|
|
910
|
-
if (s.startsWith("/")) return s;
|
|
911
|
-
else return `/${s}`;
|
|
912
|
-
}
|
|
913
|
-
function getLastSegment(path) {
|
|
914
|
-
const cleanPath = removeInitialAndTrailingSlashes(path);
|
|
915
|
-
if (cleanPath.includes("/")) {
|
|
916
|
-
const segments = cleanPath.split("/");
|
|
917
|
-
return segments[segments.length - 1];
|
|
517
|
+
if (collection.childCollections) {
|
|
518
|
+
return collection.childCollections() ?? [];
|
|
918
519
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
function resolveCollectionPathIds(path, allCollections) {
|
|
922
|
-
let remainingPath = removeInitialAndTrailingSlashes(path);
|
|
923
|
-
if (!remainingPath) {
|
|
924
|
-
return "";
|
|
520
|
+
if (types.isFirebaseCollection(collection) && collection.subcollections) {
|
|
521
|
+
return collection.subcollections() ?? [];
|
|
925
522
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
resolvedPathParts.push(remainingPath);
|
|
932
|
-
remainingPath = "";
|
|
933
|
-
break;
|
|
934
|
-
}
|
|
935
|
-
let foundMatch = false;
|
|
936
|
-
const potentialMatches = currentCollections.flatMap((col) => [{
|
|
937
|
-
col,
|
|
938
|
-
match: col.slug
|
|
939
|
-
}]).filter((p) => p.match && remainingPath.startsWith(p.match)).sort((a, b) => b.match.length - a.match.length);
|
|
940
|
-
if (potentialMatches.length > 0) {
|
|
941
|
-
const {
|
|
942
|
-
col: foundCollection,
|
|
943
|
-
match: matchString
|
|
944
|
-
} = potentialMatches[0];
|
|
945
|
-
resolvedPathParts.push(foundCollection.dbPath);
|
|
946
|
-
remainingPath = removeInitialSlash(remainingPath.substring(matchString.length));
|
|
947
|
-
if (remainingPath.length === 0) {
|
|
948
|
-
foundMatch = true;
|
|
949
|
-
break;
|
|
950
|
-
}
|
|
951
|
-
const idSeparatorIndex = remainingPath.indexOf("/");
|
|
952
|
-
let entityId;
|
|
953
|
-
if (idSeparatorIndex > -1) {
|
|
954
|
-
entityId = remainingPath.substring(0, idSeparatorIndex);
|
|
955
|
-
remainingPath = remainingPath.substring(idSeparatorIndex + 1);
|
|
956
|
-
} else {
|
|
957
|
-
entityId = remainingPath;
|
|
958
|
-
remainingPath = "";
|
|
959
|
-
console.warn(`resolveCollectionPathIds: Path seems to end with an entity ID "${entityId}" instead of a collection segment in original path "${path}". This might indicate an invalid input path.`);
|
|
960
|
-
}
|
|
961
|
-
resolvedPathParts.push(entityId);
|
|
962
|
-
currentCollections = getSubcollections(foundCollection);
|
|
963
|
-
foundMatch = true;
|
|
964
|
-
if (!currentCollections && remainingPath.length > 0) {
|
|
965
|
-
console.warn(`resolveCollectionPathIds: Path continues after entity ID "${entityId}", but no subcollections are defined for the preceding collection "${foundCollection.slug}" in path "${path}". Appending remaining original path.`);
|
|
966
|
-
resolvedPathParts.push(remainingPath);
|
|
967
|
-
remainingPath = "";
|
|
968
|
-
break;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
if (!foundMatch) {
|
|
972
|
-
console.warn(`resolveCollectionPathIds: Collection definition not found for segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
|
|
973
|
-
resolvedPathParts.push(remainingPath);
|
|
974
|
-
remainingPath = "";
|
|
975
|
-
break;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
return resolvedPathParts.join("/");
|
|
979
|
-
}
|
|
980
|
-
function getCollectionBySlugWithin(slugOrPath, collections) {
|
|
981
|
-
const subpaths = removeInitialAndTrailingSlashes(slugOrPath).split("/");
|
|
982
|
-
if (subpaths.length % 2 === 0) {
|
|
983
|
-
throw Error(`getCollectionBySlug: Collection paths must have an odd number of segments: ${slugOrPath}`);
|
|
984
|
-
}
|
|
985
|
-
const subpathCombinations = getCollectionPathsCombinations(subpaths);
|
|
986
|
-
let result;
|
|
987
|
-
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
988
|
-
const subpathCombination = subpathCombinations[i];
|
|
989
|
-
const navigationEntry = collections && collections.sort((a, b) => (a.slug ?? "").localeCompare(b.slug ?? "")).find((entry) => entry.slug === subpathCombination);
|
|
990
|
-
if (navigationEntry) {
|
|
991
|
-
if (subpathCombination === slugOrPath) {
|
|
992
|
-
result = navigationEntry;
|
|
993
|
-
} else if (navigationEntry.subcollections) {
|
|
994
|
-
const newPath = slugOrPath.replace(subpathCombination, "").split("/").slice(2).join("/");
|
|
995
|
-
if (newPath.length > 0) result = getCollectionBySlugWithin(newPath, getSubcollections(navigationEntry));
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
if (result) break;
|
|
999
|
-
}
|
|
1000
|
-
return result;
|
|
1001
|
-
}
|
|
1002
|
-
function getCollectionPathsCombinations(subpaths) {
|
|
1003
|
-
const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;
|
|
1004
|
-
const length = entries.length;
|
|
1005
|
-
const result = [];
|
|
1006
|
-
for (let i = length; i > 0; i = i - 2) {
|
|
1007
|
-
result.push(entries.slice(0, i).join("/"));
|
|
1008
|
-
}
|
|
1009
|
-
return result;
|
|
1010
|
-
}
|
|
1011
|
-
function navigateToEntity({
|
|
1012
|
-
openEntityMode,
|
|
1013
|
-
collection,
|
|
1014
|
-
entityId,
|
|
1015
|
-
copy,
|
|
1016
|
-
path,
|
|
1017
|
-
selectedTab,
|
|
1018
|
-
sideEntityController,
|
|
1019
|
-
onClose,
|
|
1020
|
-
navigation
|
|
1021
|
-
}) {
|
|
1022
|
-
if (openEntityMode === "side_panel") {
|
|
1023
|
-
sideEntityController.open({
|
|
1024
|
-
entityId,
|
|
1025
|
-
path,
|
|
1026
|
-
copy,
|
|
1027
|
-
selectedTab,
|
|
1028
|
-
collection,
|
|
1029
|
-
updateUrl: true,
|
|
1030
|
-
onClose
|
|
523
|
+
if (types.isPostgresCollection(collection) && collection.relations) {
|
|
524
|
+
const manyRelations = collection.relations.filter((r) => r.cardinality === "many");
|
|
525
|
+
return manyRelations.map((r) => {
|
|
526
|
+
const target = r.target();
|
|
527
|
+
return r.overrides ? utils.mergeDeep(target, r.overrides) : target;
|
|
1031
528
|
});
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
if (entityId && selectedTab) {
|
|
1035
|
-
to += `/${selectedTab}`;
|
|
1036
|
-
}
|
|
1037
|
-
if (!entityId) {
|
|
1038
|
-
to += "#new";
|
|
1039
|
-
}
|
|
1040
|
-
if (copy) {
|
|
1041
|
-
to += "#copy";
|
|
1042
|
-
}
|
|
1043
|
-
navigation.navigate(to);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
const reservedKeys = ["edit", "copy", "delete"];
|
|
1047
|
-
function mergeEntityActions(currentActions, newActions) {
|
|
1048
|
-
const updatedActions = [];
|
|
1049
|
-
currentActions.forEach((action) => {
|
|
1050
|
-
const newAction = newActions.find((a) => a.key === action.key);
|
|
1051
|
-
if (newAction) {
|
|
1052
|
-
const mergedAction = {
|
|
1053
|
-
...action,
|
|
1054
|
-
...newAction
|
|
1055
|
-
};
|
|
1056
|
-
updatedActions.push(mergedAction);
|
|
1057
|
-
} else {
|
|
1058
|
-
updatedActions.push(action);
|
|
1059
|
-
}
|
|
1060
|
-
});
|
|
1061
|
-
newActions.forEach((action) => {
|
|
1062
|
-
if (!currentActions.find((a) => a.key === action.key) && (!action.key || !reservedKeys.includes(action.key))) {
|
|
1063
|
-
updatedActions.push(action);
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
return updatedActions;
|
|
529
|
+
}
|
|
530
|
+
return [];
|
|
1067
531
|
}
|
|
1068
532
|
function evaluateAST(sqlString, auth, entity) {
|
|
1069
533
|
if (!entity) return true;
|
|
@@ -1163,10 +627,11 @@
|
|
|
1163
627
|
return true;
|
|
1164
628
|
}
|
|
1165
629
|
function checkOperation(collection, authController, entity, targetOperation) {
|
|
1166
|
-
|
|
630
|
+
const securityRules = types.isPostgresCollection(collection) ? collection.securityRules : void 0;
|
|
631
|
+
if (!securityRules || securityRules.length === 0) {
|
|
1167
632
|
return true;
|
|
1168
633
|
}
|
|
1169
|
-
const applicableRules =
|
|
634
|
+
const applicableRules = securityRules.filter((r) => r.operation === targetOperation || r.operation === "all" || r.operations?.includes(targetOperation) || r.operations?.includes("all"));
|
|
1170
635
|
if (applicableRules.length === 0) return false;
|
|
1171
636
|
const userRoleIds = authController.user?.roles ?? [];
|
|
1172
637
|
const userRoles = [...userRoleIds, "public"];
|
|
@@ -1203,127 +668,11 @@
|
|
|
1203
668
|
return checkOperation(collection, authController, entity, "update");
|
|
1204
669
|
}
|
|
1205
670
|
function canCreateEntity(collection, authController, path, entity) {
|
|
1206
|
-
if (collection.collectionGroup) return false;
|
|
1207
671
|
return checkOperation(collection, authController, entity, "insert");
|
|
1208
672
|
}
|
|
1209
673
|
function canDeleteEntity(collection, authController, path, entity) {
|
|
1210
674
|
return checkOperation(collection, authController, entity, "delete");
|
|
1211
675
|
}
|
|
1212
|
-
function plural(word, amount) {
|
|
1213
|
-
if (amount !== void 0 && amount === 1) {
|
|
1214
|
-
return word;
|
|
1215
|
-
}
|
|
1216
|
-
const plurals = {
|
|
1217
|
-
"(quiz)$": "$1zes",
|
|
1218
|
-
"^(ox)$": "$1en",
|
|
1219
|
-
"([m|l])ouse$": "$1ice",
|
|
1220
|
-
"(matr|vert|ind)ix|ex$": "$1ices",
|
|
1221
|
-
"(x|ch|ss|sh)$": "$1es",
|
|
1222
|
-
"([^aeiouy]|qu)y$": "$1ies",
|
|
1223
|
-
"(hive)$": "$1s",
|
|
1224
|
-
"(?:([^f])fe|([lr])f)$": "$1$2ves",
|
|
1225
|
-
"(shea|lea|loa|thie)f$": "$1ves",
|
|
1226
|
-
sis$: "ses",
|
|
1227
|
-
"([ti])um$": "$1a",
|
|
1228
|
-
"(tomat|potat|ech|her|vet)o$": "$1oes",
|
|
1229
|
-
"(bu)s$": "$1ses",
|
|
1230
|
-
"(alias)$": "$1es",
|
|
1231
|
-
"(octop)us$": "$1i",
|
|
1232
|
-
"(ax|test)is$": "$1es",
|
|
1233
|
-
"(us)$": "$1es",
|
|
1234
|
-
"([^s]+)$": "$1s"
|
|
1235
|
-
};
|
|
1236
|
-
const irregular = {
|
|
1237
|
-
move: "moves",
|
|
1238
|
-
foot: "feet",
|
|
1239
|
-
goose: "geese",
|
|
1240
|
-
sex: "sexes",
|
|
1241
|
-
child: "children",
|
|
1242
|
-
man: "men",
|
|
1243
|
-
tooth: "teeth",
|
|
1244
|
-
person: "people"
|
|
1245
|
-
};
|
|
1246
|
-
const uncountable = ["sheep", "fish", "deer", "moose", "series", "species", "money", "rice", "information", "equipment", "bison", "cod", "offspring", "pike", "salmon", "shrimp", "swine", "trout", "aircraft", "hovercraft", "spacecraft", "sugar", "tuna", "you", "wood"];
|
|
1247
|
-
if (uncountable.indexOf(word.toLowerCase()) >= 0) {
|
|
1248
|
-
return word;
|
|
1249
|
-
}
|
|
1250
|
-
for (const w in irregular) {
|
|
1251
|
-
const pattern = new RegExp(`${w}$`, "i");
|
|
1252
|
-
const replace = irregular[w];
|
|
1253
|
-
if (pattern.test(word)) {
|
|
1254
|
-
return word.replace(pattern, replace);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
for (const reg in plurals) {
|
|
1258
|
-
const pattern = new RegExp(reg, "i");
|
|
1259
|
-
if (pattern.test(word)) {
|
|
1260
|
-
return word.replace(pattern, plurals[reg]);
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
return word;
|
|
1264
|
-
}
|
|
1265
|
-
function singular(word, amount) {
|
|
1266
|
-
if (amount !== void 0 && amount !== 1) {
|
|
1267
|
-
return word;
|
|
1268
|
-
}
|
|
1269
|
-
const singulars = {
|
|
1270
|
-
"(quiz)zes$": "$1",
|
|
1271
|
-
"(matr)ices$": "$1ix",
|
|
1272
|
-
"(vert|ind)ices$": "$1ex",
|
|
1273
|
-
"^(ox)en$": "$1",
|
|
1274
|
-
"(alias)es$": "$1",
|
|
1275
|
-
"(octop|vir)i$": "$1us",
|
|
1276
|
-
"(cris|ax|test)es$": "$1is",
|
|
1277
|
-
"(shoe)s$": "$1",
|
|
1278
|
-
"(o)es$": "$1",
|
|
1279
|
-
"(bus)es$": "$1",
|
|
1280
|
-
"([m|l])ice$": "$1ouse",
|
|
1281
|
-
"(x|ch|ss|sh)es$": "$1",
|
|
1282
|
-
"(m)ovies$": "$1ovie",
|
|
1283
|
-
"(s)eries$": "$1eries",
|
|
1284
|
-
"([^aeiouy]|qu)ies$": "$1y",
|
|
1285
|
-
"([lr])ves$": "$1f",
|
|
1286
|
-
"(tive)s$": "$1",
|
|
1287
|
-
"(hive)s$": "$1",
|
|
1288
|
-
"(li|wi|kni)ves$": "$1fe",
|
|
1289
|
-
"(shea|loa|lea|thie)ves$": "$1f",
|
|
1290
|
-
"(^analy)ses$": "$1sis",
|
|
1291
|
-
"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$": "$1$2sis",
|
|
1292
|
-
"([ti])a$": "$1um",
|
|
1293
|
-
"(n)ews$": "$1ews",
|
|
1294
|
-
"(h|bl)ouses$": "$1ouse",
|
|
1295
|
-
"(corpse)s$": "$1",
|
|
1296
|
-
"(us)es$": "$1",
|
|
1297
|
-
s$: ""
|
|
1298
|
-
};
|
|
1299
|
-
const irregular = {
|
|
1300
|
-
move: "moves",
|
|
1301
|
-
foot: "feet",
|
|
1302
|
-
goose: "geese",
|
|
1303
|
-
sex: "sexes",
|
|
1304
|
-
child: "children",
|
|
1305
|
-
man: "men",
|
|
1306
|
-
tooth: "teeth",
|
|
1307
|
-
person: "people"
|
|
1308
|
-
};
|
|
1309
|
-
const uncountable = ["sheep", "fish", "deer", "moose", "series", "species", "money", "rice", "information", "equipment", "bison", "cod", "offspring", "pike", "salmon", "shrimp", "swine", "trout", "aircraft", "hovercraft", "spacecraft", "sugar", "tuna", "you", "wood"];
|
|
1310
|
-
if (uncountable.indexOf(word.toLowerCase()) >= 0) {
|
|
1311
|
-
return word;
|
|
1312
|
-
}
|
|
1313
|
-
for (const w in irregular) {
|
|
1314
|
-
const pattern = new RegExp(`${irregular[w]}$`, "i");
|
|
1315
|
-
if (pattern.test(word)) {
|
|
1316
|
-
return word.replace(pattern, w);
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
for (const reg in singulars) {
|
|
1320
|
-
const pattern = new RegExp(reg, "i");
|
|
1321
|
-
if (pattern.test(word)) {
|
|
1322
|
-
return word.replace(pattern, singulars[reg]);
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
return word;
|
|
1326
|
-
}
|
|
1327
676
|
function getEntityImagePreviewPropertyKey(collection) {
|
|
1328
677
|
for (const key in collection.properties) {
|
|
1329
678
|
const property = collection.properties[key];
|
|
@@ -1345,46 +694,136 @@
|
|
|
1345
694
|
}
|
|
1346
695
|
for (const key in collection.properties) {
|
|
1347
696
|
const property = collection.properties[key];
|
|
1348
|
-
if (property.type === "array" && property.of
|
|
697
|
+
if (property.type === "array" && property.of && !Array.isArray(property.of) && property.of.type === "string" && property.of.url === "image") {
|
|
698
|
+
return key;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
for (const key in collection.properties) {
|
|
702
|
+
const property = collection.properties[key];
|
|
703
|
+
if (property.type === "string" && property.storage && !property.storage.acceptedFiles) {
|
|
704
|
+
return key;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
for (const key in collection.properties) {
|
|
708
|
+
const property = collection.properties[key];
|
|
709
|
+
if (property.type === "array" && !Array.isArray(property.of) && property.of?.type === "string" && property.of.storage && !property.of.storage.acceptedFiles) {
|
|
1349
710
|
return key;
|
|
1350
711
|
}
|
|
1351
712
|
}
|
|
1352
713
|
return void 0;
|
|
1353
714
|
}
|
|
1354
|
-
function
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
715
|
+
function removeInitialAndTrailingSlashes(s) {
|
|
716
|
+
return removeInitialSlash(removeTrailingSlash(s));
|
|
717
|
+
}
|
|
718
|
+
function removeInitialSlash(s) {
|
|
719
|
+
if (s.startsWith("/")) return s.slice(1);
|
|
720
|
+
else return s;
|
|
721
|
+
}
|
|
722
|
+
function removeTrailingSlash(s) {
|
|
723
|
+
if (s.endsWith("/")) return s.slice(0, -1);
|
|
724
|
+
else return s;
|
|
725
|
+
}
|
|
726
|
+
function addInitialSlash(s) {
|
|
727
|
+
if (s.startsWith("/")) return s;
|
|
728
|
+
else return `/${s}`;
|
|
729
|
+
}
|
|
730
|
+
function getLastSegment(path) {
|
|
731
|
+
const cleanPath = removeInitialAndTrailingSlashes(path);
|
|
732
|
+
if (cleanPath.includes("/")) {
|
|
733
|
+
const segments = cleanPath.split("/");
|
|
734
|
+
return segments[segments.length - 1];
|
|
735
|
+
}
|
|
736
|
+
return cleanPath;
|
|
737
|
+
}
|
|
738
|
+
function resolveCollectionPathIds(path, allCollections) {
|
|
739
|
+
let remainingPath = removeInitialAndTrailingSlashes(path);
|
|
740
|
+
if (!remainingPath) {
|
|
741
|
+
return "";
|
|
742
|
+
}
|
|
743
|
+
let currentCollections = allCollections;
|
|
744
|
+
const resolvedPathParts = [];
|
|
745
|
+
while (remainingPath.length > 0) {
|
|
746
|
+
if (!currentCollections || currentCollections.length === 0) {
|
|
747
|
+
console.warn(`resolveCollectionPathIds: Path structure implies subcollections, but none found before segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
|
|
748
|
+
resolvedPathParts.push(remainingPath);
|
|
749
|
+
remainingPath = "";
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
let foundMatch = false;
|
|
753
|
+
const potentialMatches = currentCollections.flatMap((col) => [{
|
|
754
|
+
col,
|
|
755
|
+
match: col.slug
|
|
756
|
+
}]).filter((p) => p.match && remainingPath.startsWith(p.match)).sort((a, b) => b.match.length - a.match.length);
|
|
757
|
+
if (potentialMatches.length > 0) {
|
|
758
|
+
const {
|
|
759
|
+
col: foundCollection,
|
|
760
|
+
match: matchString
|
|
761
|
+
} = potentialMatches[0];
|
|
762
|
+
resolvedPathParts.push(foundCollection.slug);
|
|
763
|
+
remainingPath = removeInitialSlash(remainingPath.substring(matchString.length));
|
|
764
|
+
if (remainingPath.length === 0) {
|
|
765
|
+
foundMatch = true;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
const idSeparatorIndex = remainingPath.indexOf("/");
|
|
769
|
+
let entityId;
|
|
770
|
+
if (idSeparatorIndex > -1) {
|
|
771
|
+
entityId = remainingPath.substring(0, idSeparatorIndex);
|
|
772
|
+
remainingPath = remainingPath.substring(idSeparatorIndex + 1);
|
|
1363
773
|
} else {
|
|
1364
|
-
|
|
774
|
+
entityId = remainingPath;
|
|
775
|
+
remainingPath = "";
|
|
776
|
+
console.warn(`resolveCollectionPathIds: Path seems to end with an entity ID "${entityId}" instead of a collection segment in original path "${path}". This might indicate an invalid input path.`);
|
|
1365
777
|
}
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
Object.entries(obj).forEach(([key, value]) => {
|
|
1375
|
-
if (Array.isArray(value)) {
|
|
1376
|
-
acc[key] = Math.max(acc[key] || 0, value.length);
|
|
778
|
+
resolvedPathParts.push(entityId);
|
|
779
|
+
currentCollections = getSubcollections(foundCollection);
|
|
780
|
+
foundMatch = true;
|
|
781
|
+
if (!currentCollections && remainingPath.length > 0) {
|
|
782
|
+
console.warn(`resolveCollectionPathIds: Path continues after entity ID "${entityId}", but no subcollections are defined for the preceding collection "${foundCollection.slug}" in path "${path}". Appending remaining original path.`);
|
|
783
|
+
resolvedPathParts.push(remainingPath);
|
|
784
|
+
remainingPath = "";
|
|
785
|
+
break;
|
|
1377
786
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
787
|
+
}
|
|
788
|
+
if (!foundMatch) {
|
|
789
|
+
console.warn(`resolveCollectionPathIds: Collection definition not found for segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
|
|
790
|
+
resolvedPathParts.push(remainingPath);
|
|
791
|
+
remainingPath = "";
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
return resolvedPathParts.join("/");
|
|
796
|
+
}
|
|
797
|
+
function getCollectionBySlugWithin(slugOrPath, collections) {
|
|
798
|
+
const subpaths = removeInitialAndTrailingSlashes(slugOrPath).split("/");
|
|
799
|
+
if (subpaths.length % 2 === 0) {
|
|
800
|
+
throw Error(`getCollectionBySlug: Collection paths must have an odd number of segments: ${slugOrPath}`);
|
|
801
|
+
}
|
|
802
|
+
const subpathCombinations = getCollectionPathsCombinations(subpaths);
|
|
803
|
+
let result;
|
|
804
|
+
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
805
|
+
const subpathCombination = subpathCombinations[i];
|
|
806
|
+
const navigationEntry = collections && collections.sort((a, b) => (a.slug ?? "").localeCompare(b.slug ?? "")).find((entry) => entry.slug === subpathCombination);
|
|
807
|
+
if (navigationEntry) {
|
|
808
|
+
if (subpathCombination === slugOrPath) {
|
|
809
|
+
result = navigationEntry;
|
|
810
|
+
} else if (getSubcollections(navigationEntry).length > 0) {
|
|
811
|
+
const newPath = slugOrPath.replace(subpathCombination, "").split("/").slice(2).join("/");
|
|
812
|
+
if (newPath.length > 0) result = getCollectionBySlugWithin(newPath, getSubcollections(navigationEntry));
|
|
1384
813
|
}
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
}
|
|
814
|
+
}
|
|
815
|
+
if (result) break;
|
|
816
|
+
}
|
|
817
|
+
return result;
|
|
818
|
+
}
|
|
819
|
+
function getCollectionPathsCombinations(subpaths) {
|
|
820
|
+
const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;
|
|
821
|
+
const length = entries.length;
|
|
822
|
+
const result = [];
|
|
823
|
+
for (let i = length; i > 0; i = i - 2) {
|
|
824
|
+
result.push(entries.slice(0, i).join("/"));
|
|
825
|
+
}
|
|
826
|
+
return result;
|
|
1388
827
|
}
|
|
1389
828
|
function getNavigationEntriesFromPath(props) {
|
|
1390
829
|
const {
|
|
@@ -1425,7 +864,7 @@
|
|
|
1425
864
|
throw Error("collection not found resolving path: " + collection);
|
|
1426
865
|
}
|
|
1427
866
|
const entityViews = collection.entityViews;
|
|
1428
|
-
const customView = entityViews && entityViews.map((entry) => resolveEntityView(entry, props.contextEntityViews)).filter(
|
|
867
|
+
const customView = entityViews && entityViews.map((entry) => resolveEntityView(entry, props.contextEntityViews)).filter((v) => v != null).find((entry) => entry.key === newPath);
|
|
1429
868
|
const subcollections = getSubcollections(collection);
|
|
1430
869
|
if (customView) {
|
|
1431
870
|
result.push({
|
|
@@ -1485,7 +924,7 @@
|
|
|
1485
924
|
if (!collection) {
|
|
1486
925
|
throw Error("collection not found resolving path: " + collection);
|
|
1487
926
|
}
|
|
1488
|
-
if (collection.
|
|
927
|
+
if (getSubcollections(collection).length > 0) {
|
|
1489
928
|
result.push(...getParentReferencesFromPath({
|
|
1490
929
|
path: newPath,
|
|
1491
930
|
collections: getSubcollections(collection),
|
|
@@ -1523,9 +962,6 @@
|
|
|
1523
962
|
function buildAdditionalFieldDelegate(additionalFieldDelegate) {
|
|
1524
963
|
return additionalFieldDelegate;
|
|
1525
964
|
}
|
|
1526
|
-
function buildFieldConfig(propertyConfig) {
|
|
1527
|
-
return propertyConfig;
|
|
1528
|
-
}
|
|
1529
965
|
async function resolveStorageFilenameString({
|
|
1530
966
|
input,
|
|
1531
967
|
storage,
|
|
@@ -1557,7 +993,7 @@
|
|
|
1557
993
|
path
|
|
1558
994
|
});
|
|
1559
995
|
}
|
|
1560
|
-
if (!result) result = randomString() + "_" + file.name;
|
|
996
|
+
if (!result) result = utils.randomString() + "_" + file.name;
|
|
1561
997
|
return result;
|
|
1562
998
|
}
|
|
1563
999
|
function resolveStoragePathString({
|
|
@@ -1591,7 +1027,7 @@
|
|
|
1591
1027
|
path
|
|
1592
1028
|
});
|
|
1593
1029
|
}
|
|
1594
|
-
if (!result) result = randomString() + "_" + file.name;
|
|
1030
|
+
if (!result) result = utils.randomString() + "_" + file.name;
|
|
1595
1031
|
return result;
|
|
1596
1032
|
}
|
|
1597
1033
|
function replacePlaceholders({
|
|
@@ -1602,7 +1038,7 @@
|
|
|
1602
1038
|
path
|
|
1603
1039
|
}) {
|
|
1604
1040
|
const ext = file.name.split(".").pop();
|
|
1605
|
-
let result = input.replace("{propertyKey}", propertyKey).replace("{rand}", randomString()).replace("{file}", file.name).replace("{file.type}", file.type);
|
|
1041
|
+
let result = input.replace("{propertyKey}", propertyKey).replace("{rand}", utils.randomString()).replace("{file}", file.name).replace("{file.type}", file.type);
|
|
1606
1042
|
if (entityId) {
|
|
1607
1043
|
result = result.replace("{entityId}", String(entityId));
|
|
1608
1044
|
}
|
|
@@ -1614,12 +1050,9 @@
|
|
|
1614
1050
|
const name = file.name.replace(`.${ext}`, "");
|
|
1615
1051
|
result = result.replace("{file.name}", name);
|
|
1616
1052
|
}
|
|
1617
|
-
if (!result) result = randomString() + "_" + file.name;
|
|
1053
|
+
if (!result) result = utils.randomString() + "_" + file.name;
|
|
1618
1054
|
return result;
|
|
1619
1055
|
}
|
|
1620
|
-
function toArray(input) {
|
|
1621
|
-
return Array.isArray(input) ? input : input ? [input] : [];
|
|
1622
|
-
}
|
|
1623
1056
|
function hasPropertyCallbacks(properties, callbackName) {
|
|
1624
1057
|
if (!properties) return false;
|
|
1625
1058
|
for (const property of Object.values(properties)) {
|
|
@@ -1638,13 +1071,13 @@
|
|
|
1638
1071
|
}
|
|
1639
1072
|
async function processProperties(properties, values, previousValues, propsContext, callbackName) {
|
|
1640
1073
|
if (!values || typeof values !== "object") return values;
|
|
1641
|
-
|
|
1074
|
+
const result = {
|
|
1642
1075
|
...values
|
|
1643
1076
|
};
|
|
1644
1077
|
for (const [key, property] of Object.entries(properties)) {
|
|
1645
1078
|
if (result[key] === void 0) continue;
|
|
1646
1079
|
let currentValue = result[key];
|
|
1647
|
-
|
|
1080
|
+
const previousValue = previousValues?.[key];
|
|
1648
1081
|
if (property.type === "array" && Array.isArray(currentValue)) {
|
|
1649
1082
|
if (property.of && !Array.isArray(property.of)) {
|
|
1650
1083
|
currentValue = await Promise.all(currentValue.map(async (item, index) => {
|
|
@@ -1696,22 +1129,6 @@
|
|
|
1696
1129
|
}
|
|
1697
1130
|
return Object.keys(propertyCallbacks).length > 0 ? propertyCallbacks : void 0;
|
|
1698
1131
|
};
|
|
1699
|
-
function hashString(str) {
|
|
1700
|
-
let hash2 = 0;
|
|
1701
|
-
let i;
|
|
1702
|
-
let chr;
|
|
1703
|
-
for (i = 0; i < str.length; i++) {
|
|
1704
|
-
chr = str.charCodeAt(i);
|
|
1705
|
-
hash2 = (hash2 << 5) - hash2 + chr;
|
|
1706
|
-
hash2 |= 0;
|
|
1707
|
-
}
|
|
1708
|
-
return Math.abs(hash2);
|
|
1709
|
-
}
|
|
1710
|
-
function generateForeignKeyName(name) {
|
|
1711
|
-
const snakeCaseName = toSnakeCase(name);
|
|
1712
|
-
const singularName = snakeCaseName.endsWith("s") ? snakeCaseName.slice(0, -1) : snakeCaseName;
|
|
1713
|
-
return `${singularName}_id`;
|
|
1714
|
-
}
|
|
1715
1132
|
function sanitizeRelation(relation, sourceCollection) {
|
|
1716
1133
|
if (!relation.target) {
|
|
1717
1134
|
throw new Error("Relation is missing a `target` collection.");
|
|
@@ -1721,7 +1138,7 @@
|
|
|
1721
1138
|
...relation
|
|
1722
1139
|
};
|
|
1723
1140
|
if (!newRelation.relationName) {
|
|
1724
|
-
newRelation.relationName = toSnakeCase(targetCollection.slug
|
|
1141
|
+
newRelation.relationName = utils.toSnakeCase(targetCollection.slug);
|
|
1725
1142
|
}
|
|
1726
1143
|
if (!newRelation.direction) {
|
|
1727
1144
|
if (newRelation.foreignKeyOnTarget) newRelation.direction = "inverse";
|
|
@@ -1730,10 +1147,10 @@
|
|
|
1730
1147
|
else newRelation.direction = "owning";
|
|
1731
1148
|
}
|
|
1732
1149
|
if (!newRelation.joinPath) {
|
|
1733
|
-
const sourceName = toSnakeCase(sourceCollection.slug ?? sourceCollection.name);
|
|
1150
|
+
const sourceName = utils.toSnakeCase(sourceCollection.slug ?? sourceCollection.name);
|
|
1734
1151
|
if (newRelation.cardinality === "one" && newRelation.direction === "owning") {
|
|
1735
1152
|
if (!newRelation.localKey) {
|
|
1736
|
-
newRelation.localKey = generateForeignKeyName(newRelation.relationName);
|
|
1153
|
+
newRelation.localKey = utils.generateForeignKeyName(newRelation.relationName);
|
|
1737
1154
|
}
|
|
1738
1155
|
} else if (newRelation.cardinality === "one" && newRelation.direction === "inverse") {
|
|
1739
1156
|
if (!newRelation.foreignKeyOnTarget) {
|
|
@@ -1744,7 +1161,7 @@
|
|
|
1744
1161
|
if (targetRel.direction === "owning" && targetRel.cardinality === "one" && targetRel.localKey) {
|
|
1745
1162
|
try {
|
|
1746
1163
|
const targetRelTarget = targetRel.target();
|
|
1747
|
-
if (targetRelTarget.slug === sourceCollection.slug
|
|
1164
|
+
if (targetRelTarget.slug === sourceCollection.slug) {
|
|
1748
1165
|
newRelation.foreignKeyOnTarget = targetRel.localKey;
|
|
1749
1166
|
foundForeignKey = true;
|
|
1750
1167
|
break;
|
|
@@ -1757,8 +1174,8 @@
|
|
|
1757
1174
|
} catch (e) {
|
|
1758
1175
|
}
|
|
1759
1176
|
if (!foundForeignKey) {
|
|
1760
|
-
const keyPrefix = newRelation.inverseRelationName ? toSnakeCase(newRelation.inverseRelationName) : sourceName;
|
|
1761
|
-
newRelation.foreignKeyOnTarget = generateForeignKeyName(keyPrefix);
|
|
1177
|
+
const keyPrefix = newRelation.inverseRelationName ? utils.toSnakeCase(newRelation.inverseRelationName) : sourceName;
|
|
1178
|
+
newRelation.foreignKeyOnTarget = utils.generateForeignKeyName(keyPrefix);
|
|
1762
1179
|
}
|
|
1763
1180
|
}
|
|
1764
1181
|
} else if (newRelation.cardinality === "many" && newRelation.direction === "inverse") {
|
|
@@ -1767,7 +1184,7 @@
|
|
|
1767
1184
|
try {
|
|
1768
1185
|
const targetRelations = targetCollection.relations || [];
|
|
1769
1186
|
for (const targetRel of targetRelations) {
|
|
1770
|
-
if (targetRel.cardinality === "many" && targetRel.direction === "owning"
|
|
1187
|
+
if (targetRel.cardinality === "many" && (targetRel.direction === "owning" || !targetRel.direction) && targetRel.relationName === newRelation.inverseRelationName) {
|
|
1771
1188
|
isManyToManyInverse = true;
|
|
1772
1189
|
break;
|
|
1773
1190
|
}
|
|
@@ -1776,15 +1193,15 @@
|
|
|
1776
1193
|
}
|
|
1777
1194
|
}
|
|
1778
1195
|
if (!isManyToManyInverse && !newRelation.foreignKeyOnTarget) {
|
|
1779
|
-
newRelation.foreignKeyOnTarget = generateForeignKeyName(sourceName);
|
|
1196
|
+
newRelation.foreignKeyOnTarget = utils.generateForeignKeyName(sourceName);
|
|
1780
1197
|
}
|
|
1781
1198
|
} else if (newRelation.cardinality === "many" && newRelation.direction === "owning") {
|
|
1782
1199
|
const sourceTableName = getTableName(sourceCollection);
|
|
1783
1200
|
const targetTableName = getTableName(targetCollection);
|
|
1784
1201
|
newRelation.through = {
|
|
1785
1202
|
table: newRelation.through?.table ?? [sourceTableName, targetTableName].sort().join("_"),
|
|
1786
|
-
sourceColumn: newRelation.through?.sourceColumn ?? generateForeignKeyName(sourceName),
|
|
1787
|
-
targetColumn: newRelation.through?.targetColumn ?? generateForeignKeyName(newRelation.relationName)
|
|
1203
|
+
sourceColumn: newRelation.through?.sourceColumn ?? utils.generateForeignKeyName(sourceName),
|
|
1204
|
+
targetColumn: newRelation.through?.targetColumn ?? utils.generateForeignKeyName(newRelation.relationName)
|
|
1788
1205
|
};
|
|
1789
1206
|
}
|
|
1790
1207
|
}
|
|
@@ -1794,7 +1211,7 @@
|
|
|
1794
1211
|
if (newRelation.cardinality === "one" && newRelation.direction === "inverse" && !newRelation.foreignKeyOnTarget && !newRelation.joinPath) {
|
|
1795
1212
|
throw new Error(`Configuration Error in relation from '${sourceCollection.name}': An 'inverse' one-to-one relation requires a 'foreignKeyOnTarget'. Check the relation config for '${newRelation.relationName}'`);
|
|
1796
1213
|
}
|
|
1797
|
-
if (newRelation.cardinality === "many" && newRelation.direction === "inverse" && !newRelation.foreignKeyOnTarget && !newRelation.joinPath) {
|
|
1214
|
+
if (newRelation.cardinality === "many" && newRelation.direction === "inverse" && !newRelation.foreignKeyOnTarget && !newRelation.joinPath && !newRelation.inverseRelationName) {
|
|
1798
1215
|
throw new Error(`Configuration Error in relation from '${sourceCollection.name}': An 'inverse' one-to-many relation requires a 'foreignKeyOnTarget'. Check the relation config for '${newRelation.relationName}'`);
|
|
1799
1216
|
}
|
|
1800
1217
|
return newRelation;
|
|
@@ -1835,15 +1252,18 @@
|
|
|
1835
1252
|
sourceCollection
|
|
1836
1253
|
}) {
|
|
1837
1254
|
if (property.type !== "relation") return void 0;
|
|
1838
|
-
const relation = sourceCollection.relations
|
|
1255
|
+
const relation = (sourceCollection.relations ?? []).find((rel) => rel.relationName === property.relationName);
|
|
1839
1256
|
if (!relation) {
|
|
1840
|
-
console.warn(`Unrecognized relation format for property '${propertyKey}' in collection '${sourceCollection.slug
|
|
1257
|
+
console.warn(`Unrecognized relation format for property '${propertyKey}' in collection '${sourceCollection.slug}'`);
|
|
1841
1258
|
return void 0;
|
|
1842
1259
|
}
|
|
1843
1260
|
return relation;
|
|
1844
1261
|
}
|
|
1845
1262
|
function getTableName(collection) {
|
|
1846
|
-
|
|
1263
|
+
if (types.isPostgresCollection(collection)) {
|
|
1264
|
+
return collection.table ?? utils.toSnakeCase(collection.slug) ?? utils.toSnakeCase(collection.name);
|
|
1265
|
+
}
|
|
1266
|
+
return utils.toSnakeCase(collection.slug) ?? utils.toSnakeCase(collection.name);
|
|
1847
1267
|
}
|
|
1848
1268
|
function getTableVarName(tableName) {
|
|
1849
1269
|
return tableName.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
|
|
@@ -1941,7 +1361,7 @@
|
|
|
1941
1361
|
email: user?.email ?? null,
|
|
1942
1362
|
displayName: user?.displayName ?? null,
|
|
1943
1363
|
photoURL: user?.photoURL ?? null,
|
|
1944
|
-
roles: user?.roles ?? []
|
|
1364
|
+
roles: (user?.roles ?? []).map((r) => typeof r === "string" ? r : r.id)
|
|
1945
1365
|
},
|
|
1946
1366
|
now: Date.now()
|
|
1947
1367
|
};
|
|
@@ -1991,8 +1411,8 @@
|
|
|
1991
1411
|
if (context.isNew && conditions.defaultValue !== void 0) {
|
|
1992
1412
|
result.defaultValue = evaluateCondition(conditions.defaultValue, context);
|
|
1993
1413
|
}
|
|
1994
|
-
if ("
|
|
1995
|
-
result.
|
|
1414
|
+
if ("enum" in result && result.enum && (conditions.enumConditions || conditions.allowedEnumValues || conditions.excludedEnumValues)) {
|
|
1415
|
+
result.enum = applyEnumConditions(result.enum, conditions, context);
|
|
1996
1416
|
}
|
|
1997
1417
|
if (result.type === "reference") {
|
|
1998
1418
|
if (conditions.referencePath) {
|
|
@@ -2058,11 +1478,11 @@
|
|
|
2058
1478
|
}
|
|
2059
1479
|
class CollectionRegistry {
|
|
2060
1480
|
// Normalized runtime layer (used by Data Grid / UI)
|
|
2061
|
-
|
|
1481
|
+
collectionsByTableName = /* @__PURE__ */ new Map();
|
|
2062
1482
|
collectionsBySlug = /* @__PURE__ */ new Map();
|
|
2063
1483
|
rootCollections = [];
|
|
2064
1484
|
// Raw configuration layer (used by Collection Editor AST generator)
|
|
2065
|
-
|
|
1485
|
+
rawCollectionsByTableName = /* @__PURE__ */ new Map();
|
|
2066
1486
|
rawCollectionsBySlug = /* @__PURE__ */ new Map();
|
|
2067
1487
|
rawRootCollections = [];
|
|
2068
1488
|
// Snapshot of raw input for idempotency check — compared BEFORE normalization
|
|
@@ -2074,10 +1494,10 @@
|
|
|
2074
1494
|
}
|
|
2075
1495
|
}
|
|
2076
1496
|
reset() {
|
|
2077
|
-
this.
|
|
1497
|
+
this.collectionsByTableName.clear();
|
|
2078
1498
|
this.collectionsBySlug.clear();
|
|
2079
1499
|
this.rootCollections = [];
|
|
2080
|
-
this.
|
|
1500
|
+
this.rawCollectionsByTableName.clear();
|
|
2081
1501
|
this.rawCollectionsBySlug.clear();
|
|
2082
1502
|
this.rawRootCollections = [];
|
|
2083
1503
|
}
|
|
@@ -2090,7 +1510,7 @@
|
|
|
2090
1510
|
* @param collections
|
|
2091
1511
|
*/
|
|
2092
1512
|
registerMultiple(collections) {
|
|
2093
|
-
const rawSnapshot = collections.map((c) => removeFunctions(c));
|
|
1513
|
+
const rawSnapshot = collections.map((c) => utils.removeFunctions(c));
|
|
2094
1514
|
if (this.lastRawInputSnapshot && fastEquals.deepEqual(this.lastRawInputSnapshot, rawSnapshot)) {
|
|
2095
1515
|
return false;
|
|
2096
1516
|
}
|
|
@@ -2098,7 +1518,29 @@
|
|
|
2098
1518
|
const normalizedCollections = collections.map((c) => this.normalizeCollection({
|
|
2099
1519
|
...c
|
|
2100
1520
|
}));
|
|
2101
|
-
normalizedCollections.forEach((c, index) =>
|
|
1521
|
+
normalizedCollections.forEach((c, index) => {
|
|
1522
|
+
const raw = cloneDeep(collections[index]);
|
|
1523
|
+
this.rootCollections.push(c);
|
|
1524
|
+
this.rawRootCollections.push(raw);
|
|
1525
|
+
const normalized = this.normalizeCollection(c);
|
|
1526
|
+
this.collectionsByTableName.set(getTableName(normalized), normalized);
|
|
1527
|
+
this.rawCollectionsByTableName.set(getTableName(raw), raw);
|
|
1528
|
+
if (normalized.slug) {
|
|
1529
|
+
this.collectionsBySlug.set(normalized.slug, normalized);
|
|
1530
|
+
}
|
|
1531
|
+
if (raw.slug) {
|
|
1532
|
+
this.rawCollectionsBySlug.set(raw.slug, raw);
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
normalizedCollections.forEach((c, index) => {
|
|
1536
|
+
const subcollections = getSubcollections(c);
|
|
1537
|
+
const rawSubcollections = getSubcollections(collections[index]);
|
|
1538
|
+
if (subcollections && rawSubcollections) {
|
|
1539
|
+
subcollections.forEach((subCollection, subIndex) => {
|
|
1540
|
+
this._registerRecursively(this.normalizeCollection(subCollection), cloneDeep(rawSubcollections[subIndex]));
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
});
|
|
2102
1544
|
this.lastRawInputSnapshot = rawSnapshot;
|
|
2103
1545
|
return true;
|
|
2104
1546
|
}
|
|
@@ -2109,12 +1551,12 @@
|
|
|
2109
1551
|
this._registerRecursively(collection, raw);
|
|
2110
1552
|
}
|
|
2111
1553
|
_registerRecursively(collection, rawCollection) {
|
|
2112
|
-
if (this.
|
|
1554
|
+
if (this.collectionsByTableName.has(getTableName(collection))) {
|
|
2113
1555
|
return;
|
|
2114
1556
|
}
|
|
2115
1557
|
const normalizedCollection = this.normalizeCollection(collection);
|
|
2116
|
-
this.
|
|
2117
|
-
this.
|
|
1558
|
+
this.collectionsByTableName.set(getTableName(normalizedCollection), normalizedCollection);
|
|
1559
|
+
this.rawCollectionsByTableName.set(getTableName(rawCollection), rawCollection);
|
|
2118
1560
|
if (normalizedCollection.slug) {
|
|
2119
1561
|
this.collectionsBySlug.set(normalizedCollection.slug, normalizedCollection);
|
|
2120
1562
|
}
|
|
@@ -2130,8 +1572,22 @@
|
|
|
2130
1572
|
}
|
|
2131
1573
|
}
|
|
2132
1574
|
normalizeCollection(collection) {
|
|
2133
|
-
const
|
|
1575
|
+
const relations = types.isPostgresCollection(collection) ? collection.relations ?? [] : [];
|
|
1576
|
+
const properties = this.normalizeProperties(collection.properties, relations);
|
|
2134
1577
|
collection.properties = properties;
|
|
1578
|
+
if (!collection.childCollections) {
|
|
1579
|
+
if (types.isFirebaseCollection(collection) && collection.subcollections) {
|
|
1580
|
+
collection.childCollections = collection.subcollections;
|
|
1581
|
+
} else if (types.isPostgresCollection(collection) && collection.relations) {
|
|
1582
|
+
const manyRelations = collection.relations.filter((r) => r.cardinality === "many");
|
|
1583
|
+
if (manyRelations.length > 0) {
|
|
1584
|
+
collection.childCollections = () => manyRelations.map((r) => {
|
|
1585
|
+
const target = r.target();
|
|
1586
|
+
return r.overrides ? utils.mergeDeep(target, r.overrides) : target;
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
2135
1591
|
return collection;
|
|
2136
1592
|
}
|
|
2137
1593
|
normalizeProperties(properties, relations) {
|
|
@@ -2148,10 +1604,15 @@
|
|
|
2148
1604
|
if (newProperty.type === "map" && newProperty.properties) {
|
|
2149
1605
|
newProperty.properties = this.normalizeProperties(newProperty.properties, relations);
|
|
2150
1606
|
} else if (newProperty.type === "array") {
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
1607
|
+
const arrayProp = newProperty;
|
|
1608
|
+
if (arrayProp.of) {
|
|
1609
|
+
if (Array.isArray(arrayProp.of)) {
|
|
1610
|
+
arrayProp.of = arrayProp.of.map((p) => this.normalizeProperty(p, relations));
|
|
1611
|
+
} else {
|
|
1612
|
+
arrayProp.of = this.normalizeProperty(arrayProp.of, relations);
|
|
1613
|
+
}
|
|
1614
|
+
} else if (arrayProp.oneOf && arrayProp.oneOf.properties) {
|
|
1615
|
+
arrayProp.oneOf.properties = this.normalizeProperties(arrayProp.oneOf.properties, relations);
|
|
2155
1616
|
}
|
|
2156
1617
|
} else if ((newProperty.type === "string" || newProperty.type === "number") && newProperty.enum) {
|
|
2157
1618
|
const stringOrNumberProperty = newProperty;
|
|
@@ -2172,7 +1633,7 @@
|
|
|
2172
1633
|
get(path) {
|
|
2173
1634
|
const bySlug = this.collectionsBySlug.get(path);
|
|
2174
1635
|
if (bySlug) return bySlug;
|
|
2175
|
-
return this.
|
|
1636
|
+
return this.collectionsByTableName.get(path);
|
|
2176
1637
|
}
|
|
2177
1638
|
/**
|
|
2178
1639
|
* Gets the pristine, un-normalized collection exactly as it was provided.
|
|
@@ -2181,7 +1642,7 @@
|
|
|
2181
1642
|
getRaw(path) {
|
|
2182
1643
|
const bySlug = this.rawCollectionsBySlug.get(path);
|
|
2183
1644
|
if (bySlug) return bySlug;
|
|
2184
|
-
return this.
|
|
1645
|
+
return this.rawCollectionsByTableName.get(path);
|
|
2185
1646
|
}
|
|
2186
1647
|
/**
|
|
2187
1648
|
* Get collection by resolving multi-segment paths through relations
|
|
@@ -2202,10 +1663,13 @@
|
|
|
2202
1663
|
}
|
|
2203
1664
|
for (let i = 2; i < pathSegments.length; i += 2) {
|
|
2204
1665
|
const relationKey = pathSegments[i];
|
|
1666
|
+
if (!types.isPostgresCollection(currentCollection)) {
|
|
1667
|
+
throw new Error(`Relation path navigation requires a PostgreSQL collection, but '${currentCollection.slug}' uses driver '${currentCollection.driver}'`);
|
|
1668
|
+
}
|
|
2205
1669
|
const resolvedRelations = resolveCollectionRelations(currentCollection);
|
|
2206
1670
|
const relation = resolvedRelations[relationKey];
|
|
2207
1671
|
if (!relation) {
|
|
2208
|
-
throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug
|
|
1672
|
+
throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);
|
|
2209
1673
|
}
|
|
2210
1674
|
currentCollection = relation.target();
|
|
2211
1675
|
if (i + 1 < pathSegments.length) ;
|
|
@@ -2213,10 +1677,10 @@
|
|
|
2213
1677
|
return currentCollection;
|
|
2214
1678
|
}
|
|
2215
1679
|
getCollections() {
|
|
2216
|
-
return Array.from(this.
|
|
1680
|
+
return Array.from(this.collectionsByTableName.values());
|
|
2217
1681
|
}
|
|
2218
1682
|
getRawCollections() {
|
|
2219
|
-
return Array.from(this.
|
|
1683
|
+
return Array.from(this.rawCollectionsByTableName.values());
|
|
2220
1684
|
}
|
|
2221
1685
|
/**
|
|
2222
1686
|
* Resolves a multi-segment path like "products/123/locales" and returns
|
|
@@ -2242,13 +1706,13 @@
|
|
|
2242
1706
|
entityIds.push(entityId);
|
|
2243
1707
|
if (i + 1 < pathSegments.length) {
|
|
2244
1708
|
const subcollectionSlug = pathSegments[i + 1];
|
|
2245
|
-
const subcollections = currentCollection
|
|
2246
|
-
if (!subcollections) {
|
|
2247
|
-
throw new Error(`No subcollections found for ${currentCollection.slug
|
|
1709
|
+
const subcollections = getSubcollections(currentCollection);
|
|
1710
|
+
if (!subcollections || subcollections.length === 0) {
|
|
1711
|
+
throw new Error(`No subcollections found for ${currentCollection.slug} in path: ${path}`);
|
|
2248
1712
|
}
|
|
2249
1713
|
const subcollection = subcollections.find((c) => c.slug === subcollectionSlug);
|
|
2250
1714
|
if (!subcollection) {
|
|
2251
|
-
throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug
|
|
1715
|
+
throw new Error(`Subcollection '${subcollectionSlug}' not found in ${currentCollection.slug}`);
|
|
2252
1716
|
}
|
|
2253
1717
|
currentCollection = subcollection;
|
|
2254
1718
|
collections.push(currentCollection);
|
|
@@ -2261,6 +1725,166 @@
|
|
|
2261
1725
|
};
|
|
2262
1726
|
}
|
|
2263
1727
|
}
|
|
1728
|
+
function convertWhereToFilter(where) {
|
|
1729
|
+
if (!where) return void 0;
|
|
1730
|
+
const operatorMap = {
|
|
1731
|
+
"eq": "==",
|
|
1732
|
+
"neq": "!=",
|
|
1733
|
+
"gt": ">",
|
|
1734
|
+
"gte": ">=",
|
|
1735
|
+
"lt": "<",
|
|
1736
|
+
"lte": "<=",
|
|
1737
|
+
"in": "in",
|
|
1738
|
+
"nin": "not-in",
|
|
1739
|
+
"cs": "array-contains",
|
|
1740
|
+
"csa": "array-contains-any"
|
|
1741
|
+
};
|
|
1742
|
+
const filter = {};
|
|
1743
|
+
for (const [field, rawValue] of Object.entries(where)) {
|
|
1744
|
+
const dotIndex = rawValue.indexOf(".");
|
|
1745
|
+
if (dotIndex === -1) continue;
|
|
1746
|
+
const op = rawValue.substring(0, dotIndex);
|
|
1747
|
+
let value = rawValue.substring(dotIndex + 1);
|
|
1748
|
+
if (typeof value === "string" && value.startsWith("(") && value.endsWith(")")) {
|
|
1749
|
+
value = value.slice(1, -1).split(",").map((v) => v.trim());
|
|
1750
|
+
}
|
|
1751
|
+
if (typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "") {
|
|
1752
|
+
value = Number(value);
|
|
1753
|
+
}
|
|
1754
|
+
const mappedOp = operatorMap[op];
|
|
1755
|
+
if (mappedOp) {
|
|
1756
|
+
filter[field] = [mappedOp, value];
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
return Object.keys(filter).length > 0 ? filter : void 0;
|
|
1760
|
+
}
|
|
1761
|
+
function parseOrderBy(orderBy) {
|
|
1762
|
+
if (!orderBy) return void 0;
|
|
1763
|
+
const parts = orderBy.split(":");
|
|
1764
|
+
const field = parts[0];
|
|
1765
|
+
const direction = parts[1] || "asc";
|
|
1766
|
+
return [field, direction];
|
|
1767
|
+
}
|
|
1768
|
+
function createDriverAccessor(driver, slug) {
|
|
1769
|
+
return {
|
|
1770
|
+
async find(params) {
|
|
1771
|
+
const orderParsed = parseOrderBy(params?.orderBy);
|
|
1772
|
+
const entities = await driver.fetchCollection({
|
|
1773
|
+
path: slug,
|
|
1774
|
+
limit: params?.limit,
|
|
1775
|
+
startAfter: params?.offset,
|
|
1776
|
+
filter: convertWhereToFilter(params?.where),
|
|
1777
|
+
orderBy: orderParsed?.[0],
|
|
1778
|
+
order: orderParsed?.[1],
|
|
1779
|
+
searchString: params?.searchString
|
|
1780
|
+
});
|
|
1781
|
+
const limit = params?.limit ?? 20;
|
|
1782
|
+
const offset = params?.offset ?? 0;
|
|
1783
|
+
return {
|
|
1784
|
+
data: entities,
|
|
1785
|
+
meta: {
|
|
1786
|
+
total: entities.length,
|
|
1787
|
+
limit,
|
|
1788
|
+
offset,
|
|
1789
|
+
hasMore: entities.length >= limit
|
|
1790
|
+
}
|
|
1791
|
+
};
|
|
1792
|
+
},
|
|
1793
|
+
async findById(id) {
|
|
1794
|
+
return driver.fetchEntity({
|
|
1795
|
+
path: slug,
|
|
1796
|
+
entityId: id
|
|
1797
|
+
});
|
|
1798
|
+
},
|
|
1799
|
+
async create(data, id) {
|
|
1800
|
+
return driver.saveEntity({
|
|
1801
|
+
path: slug,
|
|
1802
|
+
values: data,
|
|
1803
|
+
entityId: id,
|
|
1804
|
+
status: "new"
|
|
1805
|
+
});
|
|
1806
|
+
},
|
|
1807
|
+
async update(id, data) {
|
|
1808
|
+
return driver.saveEntity({
|
|
1809
|
+
path: slug,
|
|
1810
|
+
values: data,
|
|
1811
|
+
entityId: id,
|
|
1812
|
+
status: "existing"
|
|
1813
|
+
});
|
|
1814
|
+
},
|
|
1815
|
+
async delete(id) {
|
|
1816
|
+
return driver.deleteEntity({
|
|
1817
|
+
entity: {
|
|
1818
|
+
id,
|
|
1819
|
+
path: slug,
|
|
1820
|
+
values: {}
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
},
|
|
1824
|
+
count: driver.countEntities ? async (params) => {
|
|
1825
|
+
return driver.countEntities({
|
|
1826
|
+
path: slug,
|
|
1827
|
+
filter: convertWhereToFilter(params?.where)
|
|
1828
|
+
});
|
|
1829
|
+
} : void 0,
|
|
1830
|
+
listen: driver.listenCollection ? (params, onUpdate, onError) => {
|
|
1831
|
+
const orderParsed = parseOrderBy(params?.orderBy);
|
|
1832
|
+
const limit = params?.limit ?? 20;
|
|
1833
|
+
const offset = params?.offset ?? 0;
|
|
1834
|
+
return driver.listenCollection({
|
|
1835
|
+
path: slug,
|
|
1836
|
+
limit: params?.limit,
|
|
1837
|
+
startAfter: params?.offset,
|
|
1838
|
+
filter: convertWhereToFilter(params?.where),
|
|
1839
|
+
orderBy: orderParsed?.[0],
|
|
1840
|
+
order: orderParsed?.[1],
|
|
1841
|
+
searchString: params?.searchString,
|
|
1842
|
+
onUpdate: (entities) => {
|
|
1843
|
+
onUpdate({
|
|
1844
|
+
data: entities,
|
|
1845
|
+
meta: {
|
|
1846
|
+
total: entities.length,
|
|
1847
|
+
limit,
|
|
1848
|
+
offset,
|
|
1849
|
+
hasMore: entities.length >= limit
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
},
|
|
1853
|
+
onError
|
|
1854
|
+
});
|
|
1855
|
+
} : void 0,
|
|
1856
|
+
listenById: driver.listenEntity ? (id, onUpdate, onError) => {
|
|
1857
|
+
return driver.listenEntity({
|
|
1858
|
+
path: slug,
|
|
1859
|
+
entityId: id,
|
|
1860
|
+
onUpdate: (entity) => onUpdate(entity ?? void 0),
|
|
1861
|
+
onError
|
|
1862
|
+
});
|
|
1863
|
+
} : void 0
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
function buildRebaseData(driver) {
|
|
1867
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1868
|
+
function getAccessor(slug) {
|
|
1869
|
+
let accessor = cache.get(slug);
|
|
1870
|
+
if (!accessor) {
|
|
1871
|
+
accessor = createDriverAccessor(driver, slug);
|
|
1872
|
+
cache.set(slug, accessor);
|
|
1873
|
+
}
|
|
1874
|
+
return accessor;
|
|
1875
|
+
}
|
|
1876
|
+
const target = {
|
|
1877
|
+
collection: getAccessor
|
|
1878
|
+
};
|
|
1879
|
+
return new Proxy(target, {
|
|
1880
|
+
get(_target, prop) {
|
|
1881
|
+
if (prop === "collection") return getAccessor;
|
|
1882
|
+
if (typeof prop === "symbol") return void 0;
|
|
1883
|
+
if (prop === "then" || prop === "toJSON" || prop === "$$typeof") return void 0;
|
|
1884
|
+
return getAccessor(prop);
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
2264
1888
|
exports2.COLLECTION_PATH_SEPARATOR = COLLECTION_PATH_SEPARATOR;
|
|
2265
1889
|
exports2.CollectionRegistry = CollectionRegistry;
|
|
2266
1890
|
exports2.DEFAULT_ONE_OF_TYPE = DEFAULT_ONE_OF_TYPE;
|
|
@@ -2273,23 +1897,19 @@
|
|
|
2273
1897
|
exports2.buildEntityCallbacks = buildEntityCallbacks;
|
|
2274
1898
|
exports2.buildEnum = buildEnum;
|
|
2275
1899
|
exports2.buildEnumValueConfig = buildEnumValueConfig;
|
|
2276
|
-
exports2.buildFieldConfig = buildFieldConfig;
|
|
2277
1900
|
exports2.buildProperties = buildProperties;
|
|
2278
1901
|
exports2.buildPropertiesOrBuilder = buildPropertiesOrBuilder;
|
|
2279
1902
|
exports2.buildProperty = buildProperty;
|
|
2280
1903
|
exports2.buildPropertyCallbacks = buildPropertyCallbacks;
|
|
1904
|
+
exports2.buildRebaseData = buildRebaseData;
|
|
2281
1905
|
exports2.canCreateEntity = canCreateEntity;
|
|
2282
1906
|
exports2.canDeleteEntity = canDeleteEntity;
|
|
2283
1907
|
exports2.canEditEntity = canEditEntity;
|
|
2284
1908
|
exports2.canReadCollection = canReadCollection;
|
|
2285
|
-
exports2.clone = clone;
|
|
2286
|
-
exports2.defaultDateFormat = defaultDateFormat;
|
|
2287
1909
|
exports2.enumToObjectEntries = enumToObjectEntries;
|
|
2288
1910
|
exports2.evaluateCondition = evaluateCondition;
|
|
2289
|
-
exports2.flattenObject = flattenObject;
|
|
2290
1911
|
exports2.fullPathToCollectionSegments = fullPathToCollectionSegments;
|
|
2291
1912
|
exports2.getArrayResolvedProperties = getArrayResolvedProperties;
|
|
2292
|
-
exports2.getArrayValuesCount = getArrayValuesCount;
|
|
2293
1913
|
exports2.getCollectionBySlugWithin = getCollectionBySlugWithin;
|
|
2294
1914
|
exports2.getCollectionPathsCombinations = getCollectionPathsCombinations;
|
|
2295
1915
|
exports2.getColumnName = getColumnName;
|
|
@@ -2298,8 +1918,6 @@
|
|
|
2298
1918
|
exports2.getDefaultValuesFor = getDefaultValuesFor;
|
|
2299
1919
|
exports2.getEntityImagePreviewPropertyKey = getEntityImagePreviewPropertyKey;
|
|
2300
1920
|
exports2.getEnumVarName = getEnumVarName;
|
|
2301
|
-
exports2.getHashValue = getHashValue;
|
|
2302
|
-
exports2.getIn = getIn$1;
|
|
2303
1921
|
exports2.getLabelOrConfigFrom = getLabelOrConfigFrom;
|
|
2304
1922
|
exports2.getLastSegment = getLastSegment;
|
|
2305
1923
|
exports2.getLocalChangesBackup = getLocalChangesBackup;
|
|
@@ -2311,44 +1929,18 @@
|
|
|
2311
1929
|
exports2.getSubcollections = getSubcollections;
|
|
2312
1930
|
exports2.getTableName = getTableName;
|
|
2313
1931
|
exports2.getTableVarName = getTableVarName;
|
|
2314
|
-
exports2.getValueInPath = getValueInPath;
|
|
2315
|
-
exports2.hashString = hashString;
|
|
2316
|
-
exports2.hydrateRegExp = hydrateRegExp;
|
|
2317
|
-
exports2.isDefaultFieldConfigId = isDefaultFieldConfigId;
|
|
2318
|
-
exports2.isEmptyArray = isEmptyArray;
|
|
2319
|
-
exports2.isEmptyObject = isEmptyObject;
|
|
2320
|
-
exports2.isFunction = isFunction;
|
|
2321
1932
|
exports2.isHidden = isHidden;
|
|
2322
|
-
exports2.isInteger = isInteger;
|
|
2323
|
-
exports2.isNaN = isNaN$1;
|
|
2324
|
-
exports2.isObject = isObject;
|
|
2325
|
-
exports2.isPlainObject = isPlainObject;
|
|
2326
1933
|
exports2.isPropertyBuilder = isPropertyBuilder;
|
|
2327
1934
|
exports2.isReadOnly = isReadOnly;
|
|
2328
|
-
exports2.
|
|
2329
|
-
exports2.mergeDeep = mergeDeep;
|
|
2330
|
-
exports2.mergeEntityActions = mergeEntityActions;
|
|
2331
|
-
exports2.navigateToEntity = navigateToEntity;
|
|
2332
|
-
exports2.pick = pick;
|
|
2333
|
-
exports2.plural = plural;
|
|
2334
|
-
exports2.prettifyIdentifier = prettifyIdentifier;
|
|
2335
|
-
exports2.randomColor = randomColor;
|
|
2336
|
-
exports2.randomString = randomString;
|
|
1935
|
+
exports2.normalizeToEntityRelation = normalizeToEntityRelation;
|
|
2337
1936
|
exports2.registerConditionOperations = registerConditionOperations;
|
|
2338
|
-
exports2.removeFunctions = removeFunctions;
|
|
2339
|
-
exports2.removeInPath = removeInPath;
|
|
2340
1937
|
exports2.removeInitialAndTrailingSlashes = removeInitialAndTrailingSlashes;
|
|
2341
1938
|
exports2.removeInitialSlash = removeInitialSlash;
|
|
2342
|
-
exports2.removeNulls = removeNulls;
|
|
2343
|
-
exports2.removePropsIfExisting = removePropsIfExisting;
|
|
2344
1939
|
exports2.removeTrailingSlash = removeTrailingSlash;
|
|
2345
|
-
exports2.removeUndefined = removeUndefined;
|
|
2346
1940
|
exports2.resolveArrayProperties = resolveArrayProperties;
|
|
2347
1941
|
exports2.resolveCollectionPathIds = resolveCollectionPathIds;
|
|
2348
1942
|
exports2.resolveCollectionRelations = resolveCollectionRelations;
|
|
2349
1943
|
exports2.resolveDefaultSelectedView = resolveDefaultSelectedView;
|
|
2350
|
-
exports2.resolveEntityAction = resolveEntityAction;
|
|
2351
|
-
exports2.resolveEntityView = resolveEntityView$1;
|
|
2352
1944
|
exports2.resolveEnumValues = resolveEnumValues;
|
|
2353
1945
|
exports2.resolveProperties = resolveProperties;
|
|
2354
1946
|
exports2.resolveProperty = resolveProperty;
|
|
@@ -2357,22 +1949,13 @@
|
|
|
2357
1949
|
exports2.resolveRelationProperty = resolveRelationProperty;
|
|
2358
1950
|
exports2.resolveStorageFilenameString = resolveStorageFilenameString;
|
|
2359
1951
|
exports2.resolveStoragePathString = resolveStoragePathString;
|
|
2360
|
-
exports2.resolvedSelectedEntityView = resolvedSelectedEntityView;
|
|
2361
1952
|
exports2.sanitizeData = sanitizeData;
|
|
2362
1953
|
exports2.sanitizeRelation = sanitizeRelation;
|
|
2363
1954
|
exports2.segmentsToStrippedPath = segmentsToStrippedPath;
|
|
2364
|
-
exports2.serializeRegExp = serializeRegExp;
|
|
2365
|
-
exports2.setIn = setIn;
|
|
2366
|
-
exports2.singular = singular;
|
|
2367
|
-
exports2.slugify = slugify;
|
|
2368
1955
|
exports2.sortProperties = sortProperties;
|
|
2369
1956
|
exports2.stripCollectionPath = stripCollectionPath;
|
|
2370
|
-
exports2.toArray = toArray;
|
|
2371
|
-
exports2.toKebabCase = toKebabCase;
|
|
2372
|
-
exports2.toSnakeCase = toSnakeCase;
|
|
2373
1957
|
exports2.traverseValueProperty = traverseValueProperty;
|
|
2374
1958
|
exports2.traverseValuesProperties = traverseValuesProperties;
|
|
2375
|
-
exports2.unslugify = unslugify;
|
|
2376
1959
|
exports2.updateDateAutoValues = updateDateAutoValues;
|
|
2377
1960
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
2378
1961
|
});
|