@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.
Files changed (63) hide show
  1. package/README.md +1 -1
  2. package/dist/collections/CollectionRegistry.d.ts +2 -2
  3. package/dist/data/buildRebaseData.d.ts +14 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.es.js +398 -815
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +418 -835
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/util/builders.d.ts +6 -13
  10. package/dist/util/collections.d.ts +2 -2
  11. package/dist/util/entities.d.ts +16 -8
  12. package/dist/util/index.d.ts +1 -11
  13. package/dist/util/navigation_from_path.d.ts +10 -5
  14. package/dist/util/navigation_utils.d.ts +1 -12
  15. package/dist/util/permissions.d.ts +4 -4
  16. package/dist/util/references.d.ts +1 -1
  17. package/dist/util/relations.d.ts +4 -4
  18. package/dist/util/resolutions.d.ts +10 -12
  19. package/dist/util/storage.d.ts +4 -4
  20. package/package.json +11 -16
  21. package/src/collections/CollectionRegistry.ts +96 -33
  22. package/src/data/buildRebaseData.ts +221 -0
  23. package/src/index.ts +1 -0
  24. package/src/types/json-logic-js.d.ts +8 -0
  25. package/src/util/builders.ts +8 -18
  26. package/src/util/callbacks.ts +3 -4
  27. package/src/util/collections.ts +4 -4
  28. package/src/util/conditions.ts +4 -4
  29. package/src/util/entities.ts +37 -12
  30. package/src/util/index.ts +1 -11
  31. package/src/util/navigation_from_path.ts +8 -7
  32. package/src/util/navigation_utils.ts +4 -56
  33. package/src/util/parent_references_from_path.ts +1 -1
  34. package/src/util/permissions.test.ts +24 -28
  35. package/src/util/permissions.ts +14 -14
  36. package/src/util/references.ts +16 -2
  37. package/src/util/relations.ts +23 -19
  38. package/src/util/resolutions.ts +31 -62
  39. package/src/util/storage.ts +5 -5
  40. package/dist/util/arrays.d.ts +0 -1
  41. package/dist/util/dates.d.ts +0 -1
  42. package/dist/util/entity_actions.d.ts +0 -2
  43. package/dist/util/fields.d.ts +0 -2
  44. package/dist/util/flatten_object.d.ts +0 -5
  45. package/dist/util/hash.d.ts +0 -1
  46. package/dist/util/names.d.ts +0 -22
  47. package/dist/util/objects.d.ts +0 -26
  48. package/dist/util/os.d.ts +0 -2
  49. package/dist/util/plurals.d.ts +0 -16
  50. package/dist/util/regexp.d.ts +0 -7
  51. package/dist/util/strings.d.ts +0 -7
  52. package/src/util/arrays.ts +0 -3
  53. package/src/util/dates.ts +0 -1
  54. package/src/util/entity_actions.ts +0 -28
  55. package/src/util/fields.ts +0 -28
  56. package/src/util/flatten_object.ts +0 -45
  57. package/src/util/hash.ts +0 -11
  58. package/src/util/names.ts +0 -30
  59. package/src/util/objects.ts +0 -376
  60. package/src/util/os.ts +0 -13
  61. package/src/util/plurals.ts +0 -188
  62. package/src/util/regexp.ts +0 -32
  63. 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("object-hash"), require("json-logic-js"), require("fast-equals"), require("lodash/cloneDeep.js")) : typeof define === "function" && define.amd ? define(["exports", "@rebasepro/types", "object-hash", "json-logic-js", "fast-equals", "lodash/cloneDeep.js"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["Rebase Util"] = {}, global.types, global.hash, global.jsonLogic, global.fastEquals, global.cloneDeep));
3
- })(this, function(exports2, types, hash, jsonLogic, fastEquals, cloneDeep) {
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
- datasource: entity.datasource,
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$1(rest.values, rest.propertyKey) : void 0;
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$1(rest.values, rest.propertyKey) : void 0;
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
- propertyConfig: _unused,
716
- ...restConfigProperty
717
- } = customField.property;
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$1(props.values, propertyKey) : void 0;
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
- const subcollections = [];
890
- subcollections.push(...collection.subcollections?.() ?? []);
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
- return cleanPath;
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
- let currentCollections = allCollections;
927
- const resolvedPathParts = [];
928
- while (remainingPath.length > 0) {
929
- if (!currentCollections || currentCollections.length === 0) {
930
- console.warn(`resolveCollectionPathIds: Path structure implies subcollections, but none found before segment starting with "${remainingPath}" in original path "${path}". Appending remaining original path.`);
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
- } else {
1033
- let to = navigation.buildUrlCollectionPath(entityId ? `${path ?? path}/${entityId}` : path ?? path);
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
- if (!collection.securityRules || collection.securityRules.length === 0) {
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 = collection.securityRules.filter((r) => r.operation === targetOperation || r.operation === "all" || r.operations?.includes(targetOperation) || r.operations?.includes("all"));
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?.type === "string" && property.of.url === "image") {
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 flattenObject(obj, parentKey = "") {
1355
- if (!obj) return obj;
1356
- return Object.keys(obj).reduce((flatObj, key) => {
1357
- const newKey = parentKey ? `${parentKey}.${key}` : key;
1358
- if (typeof obj[key] === "object" && obj[key] !== null) {
1359
- if (Array.isArray(obj[key])) {
1360
- obj[key].forEach((item, index) => {
1361
- Object.assign(flatObj, flattenObject(item, `${newKey}[${index}]`));
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
- Object.assign(flatObj, flattenObject(obj[key], newKey));
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
- } else {
1367
- flatObj[newKey] = obj[key];
1368
- }
1369
- return flatObj;
1370
- }, {});
1371
- }
1372
- function getArrayValuesCount(array) {
1373
- return array.reduce((acc, obj) => {
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
- if (typeof value === "object" && value !== null) {
1379
- const nested = getArrayValuesCount([value]);
1380
- Object.entries(nested).forEach(([nestedKey, nestedCount]) => {
1381
- const compoundKey = `${key}.${nestedKey}`;
1382
- acc[compoundKey] = Math.max(acc[compoundKey] || 0, nestedCount);
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
- return acc;
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(Boolean).find((entry) => entry.key === newPath);
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.subcollections) {
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
- let result = {
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
- let previousValue = previousValues?.[key];
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 ?? targetCollection.dbPath);
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 || targetRelTarget.dbPath === sourceCollection.dbPath) {
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" && targetRel.through && targetRel.relationName === newRelation.inverseRelationName) {
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?.find((rel) => rel.relationName === property.relationName);
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 || sourceCollection.dbPath}'`);
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
- return collection.dbPath ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
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 ("enumValues" in result && result.enumValues && (conditions.enumConditions || conditions.allowedEnumValues || conditions.excludedEnumValues)) {
1995
- result.enumValues = applyEnumConditions(result.enumValues, conditions, context);
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
- collectionsByDbPath = /* @__PURE__ */ new Map();
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
- rawCollectionsByDbPath = /* @__PURE__ */ new Map();
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.collectionsByDbPath.clear();
1497
+ this.collectionsByTableName.clear();
2078
1498
  this.collectionsBySlug.clear();
2079
1499
  this.rootCollections = [];
2080
- this.rawCollectionsByDbPath.clear();
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) => this.register(c, collections[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.collectionsByDbPath.has(collection.dbPath)) {
1554
+ if (this.collectionsByTableName.has(getTableName(collection))) {
2113
1555
  return;
2114
1556
  }
2115
1557
  const normalizedCollection = this.normalizeCollection(collection);
2116
- this.collectionsByDbPath.set(normalizedCollection.dbPath, normalizedCollection);
2117
- this.rawCollectionsByDbPath.set(rawCollection.dbPath, rawCollection);
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 properties = this.normalizeProperties(collection.properties, collection.relations ?? []);
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
- if (newProperty.of) {
2152
- newProperty.of = this.normalizeProperty(newProperty.of, relations);
2153
- } else if (newProperty.oneOf && newProperty.oneOf.properties) {
2154
- newProperty.oneOf.properties = this.normalizeProperties(newProperty.oneOf.properties, relations);
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.collectionsByDbPath.get(path);
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.rawCollectionsByDbPath.get(path);
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 || currentCollection.dbPath}'`);
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.collectionsByDbPath.values());
1680
+ return Array.from(this.collectionsByTableName.values());
2217
1681
  }
2218
1682
  getRawCollections() {
2219
- return Array.from(this.rawCollectionsByDbPath.values());
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.subcollections?.();
2246
- if (!subcollections) {
2247
- throw new Error(`No subcollections found for ${currentCollection.slug || currentCollection.dbPath} in path: ${path}`);
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 || currentCollection.dbPath}`);
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.isValidRegExp = isValidRegExp;
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
  });