@rebasepro/utils 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -1,606 +1,565 @@
1
1
  import hash from "object-hash";
2
2
  import { GeoPoint } from "@rebasepro/types";
3
- const tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
4
- const toKebabCase = (str) => {
5
- if (!str || typeof str !== "string") return "";
6
- const regExpMatchArray = str.match(tokenizeRegex);
7
- if (!regExpMatchArray) return "";
8
- return regExpMatchArray.map((x) => x.toLowerCase()).join("-");
3
+ //#region src/strings.ts
4
+ var tokenizeRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
5
+ var toKebabCase = (str) => {
6
+ if (!str || typeof str !== "string") return "";
7
+ const regExpMatchArray = str.match(tokenizeRegex);
8
+ if (!regExpMatchArray) return "";
9
+ return regExpMatchArray.map((x) => x.toLowerCase()).join("-");
9
10
  };
10
- const snakeCaseRegex = tokenizeRegex;
11
- const toSnakeCase = (str) => {
12
- if (!str || typeof str !== "string") return "";
13
- const regExpMatchArray = str.match(snakeCaseRegex);
14
- if (!regExpMatchArray) return "";
15
- return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
11
+ var snakeCaseRegex = tokenizeRegex;
12
+ var toSnakeCase = (str) => {
13
+ if (!str || typeof str !== "string") return "";
14
+ const regExpMatchArray = str.match(snakeCaseRegex);
15
+ if (!regExpMatchArray) return "";
16
+ return regExpMatchArray.map((x) => x.toLowerCase()).join("_");
16
17
  };
17
18
  function camelCase(str) {
18
- if (!str) return "";
19
- if (str.length === 1) return str.toLowerCase();
20
- const parts = str.split(/[-_ ]+/).filter(Boolean);
21
- if (parts.length === 0) return "";
22
- return parts[0].toLowerCase() + // Transform remaining parts to have first letter uppercase
23
- parts.slice(1).map((part) => part.charAt(0).toUpperCase() + part.substring(1).toLowerCase()).join("");
19
+ if (!str) return "";
20
+ if (str.length === 1) return str.toLowerCase();
21
+ const parts = str.split(/[-_ ]+/).filter(Boolean);
22
+ if (parts.length === 0) return "";
23
+ return parts[0].toLowerCase() + parts.slice(1).map((part) => part.charAt(0).toUpperCase() + part.substring(1).toLowerCase()).join("");
24
24
  }
25
25
  function randomString(strLength = 5) {
26
- return Math.random().toString(36).slice(2, 2 + strLength);
26
+ return Math.random().toString(36).slice(2, 2 + strLength);
27
27
  }
28
28
  function randomColor() {
29
- return Math.floor(Math.random() * 16777215).toString(16);
29
+ return Math.floor(Math.random() * 16777215).toString(16);
30
30
  }
31
31
  function slugify(text, separator = "_", lowercase = true) {
32
- if (!text) return "";
33
- const from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;-";
34
- const to = `aaaaaeeeeeiiiiooooouuuunc${separator}${separator}${separator}${separator}${separator}${separator}${separator}`;
35
- for (let i = 0, l = from.length; i < l; i++) {
36
- text = text.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
37
- }
38
- text = text.toString().trim().replace(/^\s+|\s+$/g, "").replace(/\s+/g, separator).replace(/&/g, separator).replace(/[^\w\\-]+/g, "").replace(new RegExp("\\" + separator + "\\" + separator + "+", "g"), separator);
39
- return lowercase ? text.toLowerCase() : text;
32
+ if (!text) return "";
33
+ const from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;-";
34
+ const to = `aaaaaeeeeeiiiiooooouuuunc${separator}${separator}${separator}${separator}${separator}${separator}${separator}`;
35
+ for (let i = 0, l = 32; i < l; i++) text = text.replace(new RegExp(from.charAt(i), "g"), to.charAt(i));
36
+ text = text.toString().trim().replace(/^\s+|\s+$/g, "").replace(/\s+/g, separator).replace(/&/g, separator).replace(/[^\w\\-]+/g, "").replace(new RegExp("\\" + separator + "\\" + separator + "+", "g"), separator);
37
+ return lowercase ? text.toLowerCase() : text;
40
38
  }
41
39
  function unslugify(slug) {
42
- if (!slug) return "";
43
- if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
44
- const result = slug.replace(/[-_]/g, " ");
45
- return result.replace(/\w\S*/g, function(txt) {
46
- return txt.charAt(0).toUpperCase() + txt.substring(1);
47
- }).trim();
48
- } else {
49
- return slug.trim();
50
- }
40
+ if (!slug) return "";
41
+ if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) return slug.replace(/[-_]/g, " ").replace(/\w\S*/g, function(txt) {
42
+ return txt.charAt(0).toUpperCase() + txt.substring(1);
43
+ }).trim();
44
+ else return slug.trim();
51
45
  }
52
46
  function prettifyIdentifier(input) {
53
- if (!input) return "";
54
- let text = input;
55
- text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
56
- text = text.replace(/[_-]+/g, " ");
57
- const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
58
- return s;
59
- }
60
- const isEmptyArray = (value) => Array.isArray(value) && value.length === 0;
61
- const isFunction = (obj) => typeof obj === "function";
62
- const isInteger = (obj) => String(Math.floor(Number(obj))) === String(obj);
63
- const isNaN = (obj) => obj !== obj;
47
+ if (!input) return "";
48
+ let text = input;
49
+ text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
50
+ text = text.replace(/[_-]+/g, " ");
51
+ return text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
52
+ }
53
+ //#endregion
54
+ //#region src/objects.ts
55
+ /** @private is the value an empty array? */
56
+ var isEmptyArray = (value) => Array.isArray(value) && value.length === 0;
57
+ /** @private is the given object a Function? */
58
+ var isFunction = (obj) => typeof obj === "function";
59
+ /** @private is the given object an integer? */
60
+ var isInteger = (obj) => String(Math.floor(Number(obj))) === String(obj);
61
+ /** @private is the given object a NaN? */
62
+ var isNaN = (obj) => obj !== obj;
63
+ /**
64
+ * Deeply get a value from an object via its path.
65
+ */
64
66
  function getIn(obj, key, def, p = 0) {
65
- const path = toPath(key);
66
- while (obj && p < path.length) {
67
- obj = obj[path[p++]];
68
- }
69
- if (p !== path.length && !obj) {
70
- return def;
71
- }
72
- return obj === void 0 ? def : obj;
67
+ const path = toPath(key);
68
+ while (obj && p < path.length) obj = obj[path[p++]];
69
+ if (p !== path.length && !obj) return def;
70
+ return obj === void 0 ? def : obj;
73
71
  }
74
72
  function setIn(obj, path, value) {
75
- const res = clone(obj);
76
- let resVal = res;
77
- let i = 0;
78
- const pathArray = toPath(path);
79
- for (; i < pathArray.length - 1; i++) {
80
- const currentPath = pathArray[i];
81
- const currentObj = getIn(obj, pathArray.slice(0, i + 1));
82
- if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) {
83
- resVal = resVal[currentPath] = clone(currentObj);
84
- } else {
85
- const nextPath = pathArray[i + 1];
86
- resVal = resVal[currentPath] = isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};
87
- }
88
- }
89
- if ((i === 0 ? obj : resVal)[pathArray[i]] === value) {
90
- return obj;
91
- }
92
- if (value === void 0) {
93
- delete resVal[pathArray[i]];
94
- } else {
95
- resVal[pathArray[i]] = value;
96
- }
97
- if (i === 0 && value === void 0) {
98
- delete res[pathArray[i]];
99
- }
100
- return res;
73
+ const res = clone(obj);
74
+ let resVal = res;
75
+ let i = 0;
76
+ const pathArray = toPath(path);
77
+ for (; i < pathArray.length - 1; i++) {
78
+ const currentPath = pathArray[i];
79
+ const currentObj = getIn(obj, pathArray.slice(0, i + 1));
80
+ if (currentObj && (isObject(currentObj) || Array.isArray(currentObj))) resVal = resVal[currentPath] = clone(currentObj);
81
+ else {
82
+ const nextPath = pathArray[i + 1];
83
+ resVal = resVal[currentPath] = isInteger(nextPath) && Number(nextPath) >= 0 ? [] : {};
84
+ }
85
+ }
86
+ if ((i === 0 ? obj : resVal)[pathArray[i]] === value) return obj;
87
+ if (value === void 0) delete resVal[pathArray[i]];
88
+ else resVal[pathArray[i]] = value;
89
+ if (i === 0 && value === void 0) delete res[pathArray[i]];
90
+ return res;
101
91
  }
102
92
  function clone(value) {
103
- if (Array.isArray(value)) {
104
- return [...value];
105
- } else if (typeof value === "object" && value !== null) {
106
- return {
107
- ...value
108
- };
109
- } else {
110
- return value;
111
- }
112
- }
93
+ if (Array.isArray(value)) return [...value];
94
+ else if (typeof value === "object" && value !== null) return { ...value };
95
+ else return value;
96
+ }
97
+ /**
98
+ * Deep clone a value, preserving function references and class instances.
99
+ * Unlike structuredClone, this handles objects that contain functions
100
+ * (e.g. EntityCollection with target(), childCollections(), callbacks).
101
+ */
113
102
  function deepClone(value) {
114
- if (value === null || value === void 0) return value;
115
- if (typeof value === "function") return value;
116
- if (typeof value !== "object") return value;
117
- if (Array.isArray(value)) {
118
- return value.map((item) => deepClone(item));
119
- }
120
- if (Object.getPrototypeOf(value) !== Object.prototype) {
121
- return value;
122
- }
123
- const result = {};
124
- for (const key of Object.keys(value)) {
125
- result[key] = deepClone(value[key]);
126
- }
127
- return result;
103
+ if (value === null || value === void 0) return value;
104
+ if (typeof value === "function") return value;
105
+ if (typeof value !== "object") return value;
106
+ if (Array.isArray(value)) return value.map((item) => deepClone(item));
107
+ if (Object.getPrototypeOf(value) !== Object.prototype) return value;
108
+ const result = {};
109
+ for (const key of Object.keys(value)) result[key] = deepClone(value[key]);
110
+ return result;
128
111
  }
129
112
  function toPath(value) {
130
- if (Array.isArray(value)) return value;
131
- return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
132
- }
133
- const pick = (obj, ...args) => ({
134
- ...args.reduce((res, key) => ({
135
- ...res,
136
- [key]: obj[key]
137
- }), {})
138
- });
113
+ if (Array.isArray(value)) return value;
114
+ return value.replace(/\[(\d+)]/g, ".$1").replace(/^\./, "").replace(/\.$/, "").split(".");
115
+ }
116
+ var pick = (obj, ...args) => ({ ...args.reduce((res, key) => ({
117
+ ...res,
118
+ [key]: obj[key]
119
+ }), {}) });
139
120
  function isObject(item) {
140
- return !!item && typeof item === "object" && !Array.isArray(item);
121
+ return !!item && typeof item === "object" && !Array.isArray(item);
141
122
  }
142
123
  function isPlainObject(obj) {
143
- if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
144
- return false;
145
- }
146
- const proto = Object.getPrototypeOf(obj);
147
- return proto === Object.prototype;
124
+ if (typeof obj !== "object" || obj === null || Array.isArray(obj)) return false;
125
+ return Object.getPrototypeOf(obj) === Object.prototype;
148
126
  }
149
127
  function mergeDeep(target, source, ignoreUndefined = false) {
150
- if (!isObject(target)) {
151
- return target;
152
- }
153
- const output = {
154
- ...target
155
- };
156
- if (!isObject(source)) {
157
- return output;
158
- }
159
- for (const key in source) {
160
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
161
- continue;
162
- }
163
- if (Object.prototype.hasOwnProperty.call(source, key)) {
164
- const sourceValue = source[key];
165
- const outputValue = output[key];
166
- if (ignoreUndefined && sourceValue === void 0) {
167
- continue;
168
- }
169
- if (sourceValue instanceof Date) {
170
- output[key] = new Date(sourceValue.getTime());
171
- } else if (Array.isArray(sourceValue)) {
172
- if (Array.isArray(outputValue)) {
173
- const newArray = [];
174
- const maxLength = Math.max(outputValue.length, sourceValue.length);
175
- for (let i = 0; i < maxLength; i++) {
176
- const sourceItem = sourceValue[i];
177
- const targetItem = outputValue[i];
178
- if (i >= sourceValue.length) {
179
- newArray[i] = targetItem;
180
- } else if (i >= outputValue.length) {
181
- newArray[i] = sourceItem;
182
- } else if (sourceItem === null) {
183
- newArray[i] = targetItem;
184
- } else if (isPlainObject(sourceItem) && isPlainObject(targetItem)) {
185
- newArray[i] = mergeDeep(targetItem, sourceItem, ignoreUndefined);
186
- } else {
187
- newArray[i] = sourceItem;
188
- }
189
- }
190
- output[key] = newArray;
191
- } else {
192
- output[key] = [...sourceValue];
193
- }
194
- } else if (isPlainObject(sourceValue)) {
195
- if (isPlainObject(outputValue)) {
196
- output[key] = mergeDeep(outputValue, sourceValue, ignoreUndefined);
197
- } else {
198
- output[key] = sourceValue;
199
- }
200
- } else if (isObject(sourceValue)) {
201
- output[key] = sourceValue;
202
- } else {
203
- output[key] = sourceValue;
204
- }
205
- }
206
- }
207
- return output;
128
+ if (!isObject(target)) return target;
129
+ const output = { ...target };
130
+ if (!isObject(source)) return output;
131
+ for (const key in source) {
132
+ if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
133
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
134
+ const sourceValue = source[key];
135
+ const outputValue = output[key];
136
+ if (ignoreUndefined && sourceValue === void 0) continue;
137
+ if (sourceValue instanceof Date) output[key] = new Date(sourceValue.getTime());
138
+ else if (Array.isArray(sourceValue)) if (Array.isArray(outputValue)) if (!(sourceValue.some(isPlainObject) || outputValue.some(isPlainObject))) output[key] = [...sourceValue];
139
+ else {
140
+ const newArray = [];
141
+ const maxLength = Math.max(outputValue.length, sourceValue.length);
142
+ for (let i = 0; i < maxLength; i++) {
143
+ const sourceItem = sourceValue[i];
144
+ const targetItem = outputValue[i];
145
+ if (i >= sourceValue.length) newArray[i] = targetItem;
146
+ else if (i >= outputValue.length) newArray[i] = sourceItem;
147
+ else if (sourceItem === null) newArray[i] = targetItem;
148
+ else if (isPlainObject(sourceItem) && isPlainObject(targetItem)) newArray[i] = mergeDeep(targetItem, sourceItem, ignoreUndefined);
149
+ else newArray[i] = sourceItem;
150
+ }
151
+ output[key] = newArray;
152
+ }
153
+ else output[key] = [...sourceValue];
154
+ else if (isPlainObject(sourceValue)) if (isPlainObject(outputValue)) output[key] = mergeDeep(outputValue, sourceValue, ignoreUndefined);
155
+ else output[key] = sourceValue;
156
+ else if (isObject(sourceValue)) output[key] = sourceValue;
157
+ else output[key] = sourceValue;
158
+ }
159
+ }
160
+ return output;
208
161
  }
209
162
  function getValueInPath(o, path) {
210
- if (!o) return void 0;
211
- if (typeof o === "object") {
212
- if (path in o) {
213
- return o[path];
214
- }
215
- if (path.includes(".") || path.includes("[")) {
216
- let pathSegments = path.split(/[.[]/);
217
- if (path.includes("[")) {
218
- pathSegments = pathSegments.map((segment) => segment.replace("]", ""));
219
- }
220
- const firstSegment = pathSegments[0];
221
- const isArrayAndIndexExists = Array.isArray(o[firstSegment]) && !isNaN(parseInt(pathSegments[1]));
222
- const nextObject = isArrayAndIndexExists ? o[firstSegment][parseInt(pathSegments[1])] : o[firstSegment];
223
- const nextPath = pathSegments.slice(isArrayAndIndexExists ? 2 : 1).join(".");
224
- if (nextPath === "") return nextObject;
225
- return getValueInPath(nextObject, nextPath);
226
- }
227
- }
228
- return void 0;
163
+ if (!o) return void 0;
164
+ if (typeof o === "object") {
165
+ if (path in o) return o[path];
166
+ if (path.includes(".") || path.includes("[")) {
167
+ let pathSegments = path.split(/[.[]/);
168
+ if (path.includes("[")) pathSegments = pathSegments.map((segment) => segment.replace("]", ""));
169
+ const firstSegment = pathSegments[0];
170
+ const isArrayAndIndexExists = Array.isArray(o[firstSegment]) && !isNaN(parseInt(pathSegments[1]));
171
+ const nextObject = isArrayAndIndexExists ? o[firstSegment][parseInt(pathSegments[1])] : o[firstSegment];
172
+ const nextPath = pathSegments.slice(isArrayAndIndexExists ? 2 : 1).join(".");
173
+ if (nextPath === "") return nextObject;
174
+ return getValueInPath(nextObject, nextPath);
175
+ }
176
+ }
229
177
  }
230
178
  function removeInPath(o, path) {
231
- const res = clone(o);
232
- let current = res;
233
- const parts = path.split(".");
234
- const last = parts.pop();
235
- for (const part of parts) {
236
- if (part in current && current[part] !== null && typeof current[part] === "object") {
237
- current[part] = clone(current[part]);
238
- current = current[part];
239
- } else {
240
- return res;
241
- }
242
- }
243
- if (last && current && typeof current === "object") {
244
- delete current[last];
245
- }
246
- return res;
179
+ const res = clone(o);
180
+ let current = res;
181
+ const parts = path.split(".");
182
+ const last = parts.pop();
183
+ for (const part of parts) if (part in current && current[part] !== null && typeof current[part] === "object") {
184
+ current[part] = clone(current[part]);
185
+ current = current[part];
186
+ } else return res;
187
+ if (last && current && typeof current === "object") delete current[last];
188
+ return res;
247
189
  }
248
190
  function removeFunctions(o) {
249
- if (o === void 0) return void 0;
250
- if (o === null) return null;
251
- if (typeof o === "object") {
252
- if (Array.isArray(o)) {
253
- return o.map((v) => removeFunctions(v));
254
- }
255
- if (!isPlainObject(o)) {
256
- return o;
257
- }
258
- return Object.entries(o).filter(([_, value]) => typeof value !== "function").map(([key, value]) => {
259
- if (Array.isArray(value)) {
260
- return {
261
- [key]: value.map((v) => removeFunctions(v))
262
- };
263
- } else if (typeof value === "object") {
264
- return {
265
- [key]: removeFunctions(value)
266
- };
267
- } else return {
268
- [key]: value
269
- };
270
- }).reduce((a, b) => ({
271
- ...a,
272
- ...b
273
- }), {});
274
- }
275
- return o;
191
+ if (o === void 0) return void 0;
192
+ if (o === null) return null;
193
+ if (typeof o === "object") {
194
+ if (Array.isArray(o)) return o.map((v) => removeFunctions(v));
195
+ if (!isPlainObject(o)) return o;
196
+ return Object.entries(o).filter(([_, value]) => typeof value !== "function").map(([key, value]) => {
197
+ if (Array.isArray(value)) return { [key]: value.map((v) => removeFunctions(v)) };
198
+ else if (typeof value === "object") return { [key]: removeFunctions(value) };
199
+ else return { [key]: value };
200
+ }).reduce((a, b) => ({
201
+ ...a,
202
+ ...b
203
+ }), {});
204
+ }
205
+ return o;
276
206
  }
277
207
  function getHashValue(v) {
278
- if (!v) return null;
279
- if (typeof v === "object" && v !== null) {
280
- if ("id" in v) return String(v.id);
281
- else if (v instanceof Date) return v.toLocaleString();
282
- else if (v instanceof GeoPoint) return hash(v);
283
- }
284
- return hash(v, {
285
- ignoreUnknown: true
286
- });
208
+ if (!v) return null;
209
+ if (typeof v === "object" && v !== null) {
210
+ if ("id" in v) return String(v.id);
211
+ else if (v instanceof Date) return v.toLocaleString();
212
+ else if (v instanceof GeoPoint) return hash(v);
213
+ }
214
+ return hash(v, { ignoreUnknown: true });
287
215
  }
288
216
  function removeUndefined(value, removeEmptyStrings) {
289
- if (typeof value === "function") {
290
- return value;
291
- }
292
- if (Array.isArray(value)) {
293
- return value.map((v) => removeUndefined(v, removeEmptyStrings));
294
- }
295
- if (typeof value === "object") {
296
- if (value === null) return value;
297
- if (!isPlainObject(value)) {
298
- return value;
299
- }
300
- const res = {};
301
- Object.keys(value).forEach((key) => {
302
- if (!isEmptyObject(value)) {
303
- const childRes = removeUndefined(value[key], removeEmptyStrings);
304
- const isString = typeof childRes === "string";
305
- const shouldKeepIfString = !removeEmptyStrings || removeEmptyStrings && !isString || removeEmptyStrings && isString && childRes !== "";
306
- if (childRes !== void 0 && !isEmptyObject(childRes) && shouldKeepIfString) res[key] = childRes;
307
- }
308
- });
309
- return res;
310
- }
311
- return value;
217
+ if (typeof value === "function") return value;
218
+ if (Array.isArray(value)) return value.map((v) => removeUndefined(v, removeEmptyStrings));
219
+ if (typeof value === "object") {
220
+ if (value === null) return value;
221
+ if (!isPlainObject(value)) return value;
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;
312
234
  }
313
235
  function removeNulls(value) {
314
- if (typeof value === "function") {
315
- return value;
316
- }
317
- if (Array.isArray(value)) {
318
- return value.map((v) => removeNulls(v));
319
- }
320
- if (typeof value === "object") {
321
- if (value === null) return value;
322
- if (!isPlainObject(value)) {
323
- return value;
324
- }
325
- const res = {};
326
- const obj = value;
327
- Object.keys(obj).forEach((key) => {
328
- if (obj[key] !== null) res[key] = removeNulls(obj[key]);
329
- });
330
- return res;
331
- }
332
- return value;
236
+ if (typeof value === "function") return value;
237
+ if (Array.isArray(value)) return value.map((v) => removeNulls(v));
238
+ if (typeof value === "object") {
239
+ if (value === null) return value;
240
+ if (!isPlainObject(value)) return value;
241
+ const res = {};
242
+ const obj = value;
243
+ Object.keys(obj).forEach((key) => {
244
+ if (obj[key] !== null) res[key] = removeNulls(obj[key]);
245
+ });
246
+ return res;
247
+ }
248
+ return value;
333
249
  }
334
250
  function isEmptyObject(obj) {
335
- return obj && Object.getPrototypeOf(obj) === Object.prototype && Object.keys(obj).length === 0;
251
+ return obj && Object.getPrototypeOf(obj) === Object.prototype && Object.keys(obj).length === 0;
336
252
  }
337
253
  function removePropsIfExisting(source, comparison) {
338
- const isObject2 = (val) => typeof val === "object" && val !== null;
339
- const isArray = (val) => Array.isArray(val);
340
- if (!isObject2(source) || !isObject2(comparison)) {
341
- return source;
342
- }
343
- const res = isArray(source) ? [...source] : {
344
- ...source
345
- };
346
- if (isArray(res)) {
347
- for (let i = res.length - 1; i >= 0; i--) {
348
- if (res[i] === comparison[i]) {
349
- res.splice(i, 1);
350
- } else if (isObject2(res[i]) && isObject2(comparison[i])) {
351
- res[i] = removePropsIfExisting(res[i], comparison[i]);
352
- }
353
- }
354
- } else {
355
- Object.keys(comparison).forEach((key) => {
356
- if (key in res) {
357
- if (isObject2(res[key]) && isObject2(comparison[key])) {
358
- res[key] = removePropsIfExisting(res[key], comparison[key]);
359
- } else if (res[key] === comparison[key]) {
360
- delete res[key];
361
- }
362
- }
363
- });
364
- }
365
- return res;
366
- }
254
+ const isObject = (val) => typeof val === "object" && val !== null;
255
+ const isArray = (val) => Array.isArray(val);
256
+ if (!isObject(source) || !isObject(comparison)) return source;
257
+ const res = isArray(source) ? [...source] : { ...source };
258
+ if (isArray(res)) {
259
+ for (let i = res.length - 1; i >= 0; i--) if (res[i] === comparison[i]) res.splice(i, 1);
260
+ else if (isObject(res[i]) && isObject(comparison[i])) res[i] = removePropsIfExisting(res[i], comparison[i]);
261
+ } else Object.keys(comparison).forEach((key) => {
262
+ if (key in res) {
263
+ if (isObject(res[key]) && isObject(comparison[key])) res[key] = removePropsIfExisting(res[key], comparison[key]);
264
+ else if (res[key] === comparison[key]) delete res[key];
265
+ }
266
+ });
267
+ return res;
268
+ }
269
+ //#endregion
270
+ //#region src/arrays.ts
367
271
  function toArray(input) {
368
- return Array.isArray(input) ? input : input ? [input] : [];
272
+ return Array.isArray(input) ? input : input ? [input] : [];
369
273
  }
370
- const defaultDateFormat = "MMMM dd, yyyy, HH:mm:ss";
274
+ //#endregion
275
+ //#region src/dates.ts
276
+ var defaultDateFormat = "MMMM dd, yyyy, HH:mm:ss";
277
+ //#endregion
278
+ //#region src/hash.ts
371
279
  function hashString(str) {
372
- if (!str) return 0;
373
- let hash2 = 0;
374
- let i;
375
- let chr;
376
- for (i = 0; i < str.length; i++) {
377
- chr = str.charCodeAt(i);
378
- hash2 = (hash2 << 5) - hash2 + chr;
379
- hash2 |= 0;
380
- }
381
- return Math.abs(hash2);
382
- }
280
+ if (!str) return 0;
281
+ let hash = 0;
282
+ let i;
283
+ let chr;
284
+ for (i = 0; i < str.length; i++) {
285
+ chr = str.charCodeAt(i);
286
+ hash = (hash << 5) - hash + chr;
287
+ hash |= 0;
288
+ }
289
+ return Math.abs(hash);
290
+ }
291
+ //#endregion
292
+ //#region src/regexp.ts
383
293
  function serializeRegExp(input) {
384
- if (!input) return "";
385
- return input.toString();
294
+ if (!input) return "";
295
+ return input.toString();
386
296
  }
297
+ /**
298
+ * Get a RegExp out of a serialized string
299
+ * @param input
300
+ */
387
301
  function hydrateRegExp(input) {
388
- if (!input) return void 0;
389
- const fragments = input.match(/\/(.*?)\/([a-z]*)?$/i);
390
- if (fragments) {
391
- return new RegExp(fragments[1], fragments[2] || "");
392
- } else {
393
- return new RegExp(input, "");
394
- }
302
+ if (!input) return void 0;
303
+ const fragments = input.match(/\/(.*?)\/([a-z]*)?$/i);
304
+ if (fragments) return new RegExp(fragments[1], fragments[2] || "");
305
+ else return new RegExp(input, "");
395
306
  }
396
307
  function isValidRegExp(input) {
397
- const fullRegexp = input.match(/\/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/);
398
- if (fullRegexp) return true;
399
- const simpleRegexp = input.match(/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)/);
400
- return !!simpleRegexp;
308
+ if (input.match(/\/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/)) return true;
309
+ return !!input.match(/((?![*+?])(?:[^\r\n[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*])+)/);
401
310
  }
311
+ //#endregion
312
+ //#region src/flatten_object.ts
402
313
  function flattenObject(obj, parentKey = "") {
403
- if (!obj) return obj;
404
- return Object.keys(obj).reduce((flatObj, key) => {
405
- const newKey = parentKey ? `${parentKey}.${key}` : key;
406
- if (typeof obj[key] === "object" && obj[key] !== null) {
407
- if (Array.isArray(obj[key])) {
408
- obj[key].forEach((item, index) => {
409
- if (typeof item === "object" && item !== null) {
410
- Object.assign(flatObj, flattenObject(item, `${newKey}[${index}]`));
411
- } else {
412
- flatObj[`${newKey}[${index}]`] = item;
413
- }
414
- });
415
- } else {
416
- Object.assign(flatObj, flattenObject(obj[key], newKey));
417
- }
418
- } else {
419
- flatObj[newKey] = obj[key];
420
- }
421
- return flatObj;
422
- }, {});
314
+ if (!obj) return obj;
315
+ return Object.keys(obj).reduce((flatObj, key) => {
316
+ const newKey = parentKey ? `${parentKey}.${key}` : key;
317
+ if (typeof obj[key] === "object" && obj[key] !== null) if (Array.isArray(obj[key])) obj[key].forEach((item, index) => {
318
+ if (typeof item === "object" && item !== null) Object.assign(flatObj, flattenObject(item, `${newKey}[${index}]`));
319
+ else flatObj[`${newKey}[${index}]`] = item;
320
+ });
321
+ else Object.assign(flatObj, flattenObject(obj[key], newKey));
322
+ else flatObj[newKey] = obj[key];
323
+ return flatObj;
324
+ }, {});
423
325
  }
424
326
  function getArrayValuesCount(array) {
425
- return array.reduce((acc, obj) => {
426
- Object.entries(obj).forEach(([key, value]) => {
427
- if (Array.isArray(value)) {
428
- acc[key] = Math.max(acc[key] || 0, value.length);
429
- }
430
- if (typeof value === "object" && value !== null) {
431
- const nested = getArrayValuesCount([value]);
432
- Object.entries(nested).forEach(([nestedKey, nestedCount]) => {
433
- const compoundKey = `${key}.${nestedKey}`;
434
- acc[compoundKey] = Math.max(acc[compoundKey] || 0, nestedCount);
435
- });
436
- }
437
- });
438
- return acc;
439
- }, {});
440
- }
327
+ return array.reduce((acc, obj) => {
328
+ Object.entries(obj).forEach(([key, value]) => {
329
+ if (Array.isArray(value)) acc[key] = Math.max(acc[key] || 0, value.length);
330
+ if (typeof value === "object" && value !== null) {
331
+ const nested = getArrayValuesCount([value]);
332
+ Object.entries(nested).forEach(([nestedKey, nestedCount]) => {
333
+ const compoundKey = `${key}.${nestedKey}`;
334
+ acc[compoundKey] = Math.max(acc[compoundKey] || 0, nestedCount);
335
+ });
336
+ }
337
+ });
338
+ return acc;
339
+ }, {});
340
+ }
341
+ //#endregion
342
+ //#region src/plurals.ts
343
+ /**
344
+ * Returns the plural of an English word.
345
+ *
346
+ * @param {string} word
347
+ * @param {number} [amount]
348
+ * @returns {string}
349
+ */
441
350
  function plural(word, amount) {
442
- if (amount !== void 0 && amount === 1) {
443
- return word;
444
- }
445
- const plurals = {
446
- "(quiz)$": "$1zes",
447
- "^(ox)$": "$1en",
448
- "([m|l])ouse$": "$1ice",
449
- "(matr|vert|ind)ix|ex$": "$1ices",
450
- "(x|ch|ss|sh)$": "$1es",
451
- "([^aeiouy]|qu)y$": "$1ies",
452
- "(hive)$": "$1s",
453
- "(?:([^f])fe|([lr])f)$": "$1$2ves",
454
- "(shea|lea|loa|thie)f$": "$1ves",
455
- sis$: "ses",
456
- "([ti])um$": "$1a",
457
- "(tomat|potat|ech|her|vet)o$": "$1oes",
458
- "(bu)s$": "$1ses",
459
- "(alias)$": "$1es",
460
- "(octop)us$": "$1i",
461
- "(ax|test)is$": "$1es",
462
- "(us)$": "$1es",
463
- "([^s]+)$": "$1s"
464
- };
465
- const irregular = {
466
- move: "moves",
467
- foot: "feet",
468
- goose: "geese",
469
- sex: "sexes",
470
- child: "children",
471
- man: "men",
472
- tooth: "teeth",
473
- person: "people"
474
- };
475
- 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"];
476
- if (uncountable.indexOf(word.toLowerCase()) >= 0) {
477
- return word;
478
- }
479
- for (const w in irregular) {
480
- const pattern = new RegExp(`${w}$`, "i");
481
- const replace = irregular[w];
482
- if (pattern.test(word)) {
483
- return word.replace(pattern, replace);
484
- }
485
- }
486
- for (const reg in plurals) {
487
- const pattern = new RegExp(reg, "i");
488
- if (pattern.test(word)) {
489
- return word.replace(pattern, plurals[reg]);
490
- }
491
- }
492
- return word;
493
- }
351
+ if (amount !== void 0 && amount === 1) return word;
352
+ const plurals = {
353
+ "(quiz)$": "$1zes",
354
+ "^(ox)$": "$1en",
355
+ "([m|l])ouse$": "$1ice",
356
+ "(matr|vert|ind)ix|ex$": "$1ices",
357
+ "(x|ch|ss|sh)$": "$1es",
358
+ "([^aeiouy]|qu)y$": "$1ies",
359
+ "(hive)$": "$1s",
360
+ "(?:([^f])fe|([lr])f)$": "$1$2ves",
361
+ "(shea|lea|loa|thie)f$": "$1ves",
362
+ sis$: "ses",
363
+ "([ti])um$": "$1a",
364
+ "(tomat|potat|ech|her|vet)o$": "$1oes",
365
+ "(bu)s$": "$1ses",
366
+ "(alias)$": "$1es",
367
+ "(octop)us$": "$1i",
368
+ "(ax|test)is$": "$1es",
369
+ "(us)$": "$1es",
370
+ "([^s]+)$": "$1s"
371
+ };
372
+ const irregular = {
373
+ move: "moves",
374
+ foot: "feet",
375
+ goose: "geese",
376
+ sex: "sexes",
377
+ child: "children",
378
+ man: "men",
379
+ tooth: "teeth",
380
+ person: "people"
381
+ };
382
+ if ([
383
+ "sheep",
384
+ "fish",
385
+ "deer",
386
+ "moose",
387
+ "series",
388
+ "species",
389
+ "money",
390
+ "rice",
391
+ "information",
392
+ "equipment",
393
+ "bison",
394
+ "cod",
395
+ "offspring",
396
+ "pike",
397
+ "salmon",
398
+ "shrimp",
399
+ "swine",
400
+ "trout",
401
+ "aircraft",
402
+ "hovercraft",
403
+ "spacecraft",
404
+ "sugar",
405
+ "tuna",
406
+ "you",
407
+ "wood"
408
+ ].indexOf(word.toLowerCase()) >= 0) return word;
409
+ for (const w in irregular) {
410
+ const pattern = new RegExp(`${w}$`, "i");
411
+ const replace = irregular[w];
412
+ if (pattern.test(word)) return word.replace(pattern, replace);
413
+ }
414
+ for (const reg in plurals) {
415
+ const pattern = new RegExp(reg, "i");
416
+ if (pattern.test(word)) return word.replace(pattern, plurals[reg]);
417
+ }
418
+ return word;
419
+ }
420
+ /**
421
+ * Returns the singular of an English word.
422
+ *
423
+ * @param {string} word
424
+ * @param {number} [amount]
425
+ * @returns {string}
426
+ */
494
427
  function singular(word, amount) {
495
- if (amount !== void 0 && amount !== 1) {
496
- return word;
497
- }
498
- const singulars = {
499
- "(quiz)zes$": "$1",
500
- "(matr)ices$": "$1ix",
501
- "(vert|ind)ices$": "$1ex",
502
- "^(ox)en$": "$1",
503
- "(alias)es$": "$1",
504
- "(octop|vir)i$": "$1us",
505
- "(cris|ax|test)es$": "$1is",
506
- "(shoe)s$": "$1",
507
- "(o)es$": "$1",
508
- "(bus)es$": "$1",
509
- "([m|l])ice$": "$1ouse",
510
- "(x|ch|ss|sh)es$": "$1",
511
- "(m)ovies$": "$1ovie",
512
- "(s)eries$": "$1eries",
513
- "([^aeiouy]|qu)ies$": "$1y",
514
- "([lr])ves$": "$1f",
515
- "(tive)s$": "$1",
516
- "(hive)s$": "$1",
517
- "(li|wi|kni)ves$": "$1fe",
518
- "(shea|loa|lea|thie)ves$": "$1f",
519
- "(^analy)ses$": "$1sis",
520
- "((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$": "$1$2sis",
521
- "([ti])a$": "$1um",
522
- "(n)ews$": "$1ews",
523
- "(h|bl)ouses$": "$1ouse",
524
- "(corpse)s$": "$1",
525
- "(us)es$": "$1",
526
- s$: ""
527
- };
528
- const irregular = {
529
- move: "moves",
530
- foot: "feet",
531
- goose: "geese",
532
- sex: "sexes",
533
- child: "children",
534
- man: "men",
535
- tooth: "teeth",
536
- person: "people"
537
- };
538
- 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"];
539
- if (uncountable.indexOf(word.toLowerCase()) >= 0) {
540
- return word;
541
- }
542
- for (const w in irregular) {
543
- const pattern = new RegExp(`${irregular[w]}$`, "i");
544
- if (pattern.test(word)) {
545
- return word.replace(pattern, w);
546
- }
547
- }
548
- for (const reg in singulars) {
549
- const pattern = new RegExp(reg, "i");
550
- if (pattern.test(word)) {
551
- return word.replace(pattern, singulars[reg]);
552
- }
553
- }
554
- return word;
555
- }
428
+ if (amount !== void 0 && amount !== 1) return word;
429
+ const singulars = {
430
+ "(quiz)zes$": "$1",
431
+ "(matr)ices$": "$1ix",
432
+ "(vert|ind)ices$": "$1ex",
433
+ "^(ox)en$": "$1",
434
+ "(alias)es$": "$1",
435
+ "(octop|vir)i$": "$1us",
436
+ "(cris|ax|test)es$": "$1is",
437
+ "(shoe)s$": "$1",
438
+ "(o)es$": "$1",
439
+ "(bus)es$": "$1",
440
+ "([m|l])ice$": "$1ouse",
441
+ "(x|ch|ss|sh)es$": "$1",
442
+ "(m)ovies$": "$1ovie",
443
+ "(s)eries$": "$1eries",
444
+ "([^aeiouy]|qu)ies$": "$1y",
445
+ "([lr])ves$": "$1f",
446
+ "(tive)s$": "$1",
447
+ "(hive)s$": "$1",
448
+ "(li|wi|kni)ves$": "$1fe",
449
+ "(shea|loa|lea|thie)ves$": "$1f",
450
+ "(^analy)ses$": "$1sis",
451
+ "((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$": "$1$2sis",
452
+ "([ti])a$": "$1um",
453
+ "(n)ews$": "$1ews",
454
+ "(h|bl)ouses$": "$1ouse",
455
+ "(corpse)s$": "$1",
456
+ "(us)es$": "$1",
457
+ s$: ""
458
+ };
459
+ const irregular = {
460
+ move: "moves",
461
+ foot: "feet",
462
+ goose: "geese",
463
+ sex: "sexes",
464
+ child: "children",
465
+ man: "men",
466
+ tooth: "teeth",
467
+ person: "people"
468
+ };
469
+ if ([
470
+ "sheep",
471
+ "fish",
472
+ "deer",
473
+ "moose",
474
+ "series",
475
+ "species",
476
+ "money",
477
+ "rice",
478
+ "information",
479
+ "equipment",
480
+ "bison",
481
+ "cod",
482
+ "offspring",
483
+ "pike",
484
+ "salmon",
485
+ "shrimp",
486
+ "swine",
487
+ "trout",
488
+ "aircraft",
489
+ "hovercraft",
490
+ "spacecraft",
491
+ "sugar",
492
+ "tuna",
493
+ "you",
494
+ "wood"
495
+ ].indexOf(word.toLowerCase()) >= 0) return word;
496
+ for (const w in irregular) {
497
+ const pattern = new RegExp(`${irregular[w]}$`, "i");
498
+ if (pattern.test(word)) return word.replace(pattern, w);
499
+ }
500
+ for (const reg in singulars) {
501
+ const pattern = new RegExp(reg, "i");
502
+ if (pattern.test(word)) return word.replace(pattern, singulars[reg]);
503
+ }
504
+ return word;
505
+ }
506
+ //#endregion
507
+ //#region src/names.ts
508
+ /**
509
+ * Generates a foreign key column name from a given string, typically a collection slug or name.
510
+ * It converts the name to snake_case, attempts to singularize it by removing a trailing 's'
511
+ * (a common convention for collection names), and appends '_id'.
512
+ *
513
+ * @param name The base name to convert to a foreign key.
514
+ * @returns A foreign key name in the format 'singular_name_id'.
515
+ *
516
+ * @example
517
+ * // returns "user_id"
518
+ * generateForeignKeyName("users")
519
+ *
520
+ * @example
521
+ * // returns "post_id"
522
+ * generateForeignKeyName("posts")
523
+ *
524
+ * @example
525
+ * // returns "product_id"
526
+ * generateForeignKeyName("Product")
527
+ *
528
+ */
556
529
  function generateForeignKeyName(name) {
557
- const snakeCaseName = toSnakeCase(name);
558
- const singularName = snakeCaseName.endsWith("s") ? snakeCaseName.slice(0, -1) : snakeCaseName;
559
- return `${singularName}_id`;
530
+ const snakeCaseName = toSnakeCase(name);
531
+ return `${snakeCaseName.endsWith("s") ? snakeCaseName.slice(0, -1) : snakeCaseName}_id`;
560
532
  }
533
+ //#endregion
534
+ //#region src/fields.ts
561
535
  function isDefaultFieldConfigId(id) {
562
- 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);
563
- }
564
- export {
565
- camelCase,
566
- clone,
567
- deepClone,
568
- defaultDateFormat,
569
- flattenObject,
570
- generateForeignKeyName,
571
- getArrayValuesCount,
572
- getHashValue,
573
- getIn,
574
- getValueInPath,
575
- hashString,
576
- hydrateRegExp,
577
- isDefaultFieldConfigId,
578
- isEmptyArray,
579
- isEmptyObject,
580
- isFunction,
581
- isInteger,
582
- isNaN,
583
- isObject,
584
- isPlainObject,
585
- isValidRegExp,
586
- mergeDeep,
587
- pick,
588
- plural,
589
- prettifyIdentifier,
590
- randomColor,
591
- randomString,
592
- removeFunctions,
593
- removeInPath,
594
- removeNulls,
595
- removePropsIfExisting,
596
- removeUndefined,
597
- serializeRegExp,
598
- setIn,
599
- singular,
600
- slugify,
601
- toArray,
602
- toKebabCase,
603
- toSnakeCase,
604
- unslugify
605
- };
606
- //# sourceMappingURL=index.es.js.map
536
+ return [
537
+ "text_field",
538
+ "multiline",
539
+ "markdown",
540
+ "url",
541
+ "email",
542
+ "switch",
543
+ "select",
544
+ "multi_select",
545
+ "number_input",
546
+ "number_select",
547
+ "multi_number_select",
548
+ "file_upload",
549
+ "multi_file_upload",
550
+ "reference_as_string",
551
+ "reference",
552
+ "multi_references",
553
+ "relation",
554
+ "date_time",
555
+ "group",
556
+ "key_value",
557
+ "repeat",
558
+ "custom_array",
559
+ "block"
560
+ ].includes(id);
561
+ }
562
+ //#endregion
563
+ export { camelCase, clone, deepClone, defaultDateFormat, flattenObject, generateForeignKeyName, getArrayValuesCount, getHashValue, getIn, getValueInPath, hashString, hydrateRegExp, isDefaultFieldConfigId, isEmptyArray, isEmptyObject, isFunction, isInteger, isNaN, isObject, isPlainObject, isValidRegExp, mergeDeep, pick, plural, prettifyIdentifier, randomColor, randomString, removeFunctions, removeInPath, removeNulls, removePropsIfExisting, removeUndefined, serializeRegExp, setIn, singular, slugify, toArray, toKebabCase, toSnakeCase, unslugify };
564
+
565
+ //# sourceMappingURL=index.es.js.map