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