@firecms/schema_inference 3.0.0-canary.23 → 3.0.0-canary.231

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,244 +1,432 @@
1
- import { unslugify as b, resolveEnumValues as T, mergeDeep as j } from "@firecms/core";
2
- import { DocumentReference as P } from "firebase/firestore";
3
- function y(r) {
4
- if (!r)
5
- return;
6
- function e(i) {
7
- return typeof i == "string" ? i : i instanceof P ? i.path : void 0;
8
- }
9
- const s = r.values.map((i) => e(i)).filter((i) => !!i).find((i) => i.includes("/"));
10
- if (!s)
11
- return;
12
- const n = s.substr(0, s.lastIndexOf("/"));
13
- return r.values.filter((i) => {
14
- const a = e(i);
15
- return a ? a.startsWith(n) : !1;
16
- }).length > r.values.length / 3 * 2 ? n : void 0;
17
- }
18
- function d(r) {
19
- if (!Array.isArray(r))
1
+ import { unslugify, resolveEnumValues, mergeDeep } from "@firecms/core";
2
+ import { DocumentReference } from "@firebase/firestore";
3
+ function findCommonInitialStringInPath(valuesCount) {
4
+ if (!valuesCount) return void 0;
5
+ function getPath(value) {
6
+ if (typeof value === "string") return value;
7
+ else if (value instanceof DocumentReference) return value.path;
8
+ else return void 0;
9
+ }
10
+ const strings = valuesCount.values.map((v) => getPath(v)).filter((v) => !!v);
11
+ const pathWithSlash = strings.find((s) => s.includes("/"));
12
+ if (!pathWithSlash)
13
+ return void 0;
14
+ const searchedPath = pathWithSlash.substr(0, pathWithSlash.lastIndexOf("/"));
15
+ const yep = valuesCount.values.filter((value) => {
16
+ const path = getPath(value);
17
+ if (!path) return false;
18
+ return path.startsWith(searchedPath);
19
+ }).length > valuesCount.values.length / 3 * 2;
20
+ return yep ? searchedPath : void 0;
21
+ }
22
+ function extractEnumFromValues(values) {
23
+ if (!Array.isArray(values)) {
20
24
  return [];
21
- const e = r.map((t) => typeof t == "string" ? { id: t, label: b(t) } : null).filter(Boolean);
22
- return e.sort((t, s) => t.label.localeCompare(s.label)), e;
25
+ }
26
+ const enumValues = values.map((value) => {
27
+ if (typeof value === "string") {
28
+ return { id: value, label: unslugify(value) };
29
+ } else
30
+ return null;
31
+ }).filter(Boolean);
32
+ enumValues.sort((a, b) => a.label.localeCompare(b.label));
33
+ return enumValues;
23
34
  }
24
- const I = [".jpg", ".png", ".webp", ".gif"], S = [".mp3", ".ogg", ".opus", ".aac"], M = [".avi", ".mp4"], x = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
25
- function C({
26
- totalDocsCount: r,
27
- valuesResult: e
35
+ const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".avif"];
36
+ const AUDIO_EXTENSIONS = [".mp3", ".ogg", ".opus", ".aac"];
37
+ const VIDEO_EXTENSIONS = [".avi", ".mp4"];
38
+ const emailRegEx = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
39
+ function buildStringProperty({
40
+ totalDocsCount,
41
+ valuesResult
28
42
  }) {
29
- let t = {
43
+ let stringProperty = {
30
44
  dataType: "string"
31
45
  };
32
- if (e) {
33
- const s = e.values.length, n = Array.from(e.valuesCount.keys()).length, o = {}, i = e.values.filter((f) => typeof f == "string" && f.toString().startsWith("http")).length > r / 3 * 2;
34
- i && (o.url = !0);
35
- const a = e.values.filter((f) => typeof f == "string" && x.test(f)).length > r / 3 * 2;
36
- a && (o.email = !0);
37
- const c = e.values.filter((f) => typeof f == "string" && f.length === 28 && !f.includes(" ")).length > r / 3 * 2;
38
- if (c && (o.readOnly = !0), !a && !i && !c && !i && n < s / 3) {
39
- const f = d(Array.from(e.valuesCount.keys()));
40
- Object.keys(f).length > 1 && (o.enumValues = f);
41
- }
42
- if (!a && !i && !c && !i && !o.enumValues) {
43
- const f = F(e, r);
44
- f && (o.storage = {
45
- acceptedFiles: [f],
46
- storagePath: y(e) ?? "/"
47
- });
46
+ if (valuesResult) {
47
+ const totalEntriesCount = valuesResult.values.length;
48
+ const totalValues = Array.from(valuesResult.valuesCount.keys()).length;
49
+ const config = {};
50
+ const probablyAURL = valuesResult.values.filter((value) => typeof value === "string" && value.toString().startsWith("http")).length > totalDocsCount / 3 * 2;
51
+ if (probablyAURL) {
52
+ config.url = true;
48
53
  }
49
- Object.keys(o).length > 0 && (t = {
50
- ...t,
51
- ...o,
52
- editable: !0
53
- });
54
+ const probablyAnEmail = valuesResult.values.filter((value) => typeof value === "string" && emailRegEx.test(value)).length > totalDocsCount / 3 * 2;
55
+ if (probablyAnEmail) {
56
+ config.email = true;
57
+ }
58
+ const probablyUserIds = valuesResult.values.filter((value) => typeof value === "string" && value.length === 28 && !value.includes(" ")).length > totalDocsCount / 3 * 2;
59
+ if (probablyUserIds)
60
+ config.readOnly = true;
61
+ if (!probablyAnEmail && !probablyAURL && !probablyUserIds && !probablyAURL && totalValues < totalEntriesCount / 3) {
62
+ const enumValues = extractEnumFromValues(Array.from(valuesResult.valuesCount.keys()));
63
+ if (Object.keys(enumValues).length > 1)
64
+ config.enumValues = enumValues;
65
+ }
66
+ if (!probablyAnEmail && !probablyAURL && !probablyUserIds && !probablyAURL && !config.enumValues) {
67
+ const fileType = probableFileType(valuesResult, totalDocsCount);
68
+ if (fileType) {
69
+ config.storage = {
70
+ acceptedFiles: [fileType],
71
+ storagePath: findCommonInitialStringInPath(valuesResult) ?? "/"
72
+ };
73
+ }
74
+ }
75
+ if (Object.keys(config).length > 0)
76
+ stringProperty = {
77
+ ...stringProperty,
78
+ ...config,
79
+ editable: true
80
+ };
54
81
  }
55
- return t;
82
+ return stringProperty;
56
83
  }
57
- function F(r, e) {
58
- const t = r.values.filter((i) => typeof i == "string" && I.some((a) => i.toString().endsWith(a))).length > e / 3 * 2, s = r.values.filter((i) => typeof i == "string" && S.some((a) => i.toString().endsWith(a))).length > e / 3 * 2, n = r.values.filter((i) => typeof i == "string" && M.some((a) => i.toString().endsWith(a))).length > e / 3 * 2;
59
- return t ? "image/*" : s ? "audio/*" : n ? "video/*" : !1;
84
+ function probableFileType(valuesCount, totalDocsCount) {
85
+ const probablyAnImage = valuesCount.values.filter((value) => typeof value === "string" && IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;
86
+ const probablyAudio = valuesCount.values.filter((value) => typeof value === "string" && AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;
87
+ const probablyVideo = valuesCount.values.filter((value) => typeof value === "string" && VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;
88
+ const fileType = probablyAnImage ? "image/*" : probablyAudio ? "audio/*" : probablyVideo ? "video/*" : false;
89
+ return fileType;
60
90
  }
61
- function V({
62
- totalDocsCount: r,
63
- valuesResult: e
91
+ function buildValidation({
92
+ totalDocsCount,
93
+ valuesResult
64
94
  }) {
65
- if (e) {
66
- const t = e.values.length;
67
- if (r === t)
95
+ if (valuesResult) {
96
+ const totalEntriesCount = valuesResult.values.length;
97
+ if (totalDocsCount === totalEntriesCount)
68
98
  return {
69
- required: !0
99
+ required: true
70
100
  };
71
101
  }
102
+ return void 0;
72
103
  }
73
- function _({
74
- totalDocsCount: r,
75
- valuesResult: e
104
+ function buildReferenceProperty({
105
+ totalDocsCount,
106
+ valuesResult
76
107
  }) {
77
- return {
108
+ const property = {
78
109
  dataType: "reference",
79
- path: y(e) ?? "!!!FIX_ME!!!",
80
- editable: !0
110
+ path: findCommonInitialStringInPath(valuesResult) ?? "!!!FIX_ME!!!",
111
+ editable: true
81
112
  };
113
+ return property;
82
114
  }
83
- async function k(r, e) {
84
- const t = {}, s = {};
85
- return r && r.forEach((n) => {
86
- n && Object.entries(n).forEach(([o, i]) => {
87
- E(t, o, i, e), p(s, o, i, e);
115
+ async function buildEntityPropertiesFromData(data, getType) {
116
+ const typesCount = {};
117
+ const valuesCount = {};
118
+ if (data) {
119
+ data.forEach((entry) => {
120
+ if (entry) {
121
+ Object.entries(entry).forEach(([key, value]) => {
122
+ increaseMapTypeCount(typesCount, key, value, getType);
123
+ increaseValuesCount(valuesCount, key, value, getType);
124
+ });
125
+ }
88
126
  });
89
- }), O(r.length, t, s);
127
+ }
128
+ return buildPropertiesFromCount(data.length, typesCount, valuesCount);
90
129
  }
91
- function w(r, e, t) {
92
- const s = {}, n = {};
93
- r && r.forEach((a) => {
94
- l(e.dataType, s, a, t), p(n, "inferred_prop", a, t);
95
- });
96
- const o = "enumValues" in e ? T(e.enumValues) : void 0;
97
- if (o) {
98
- const a = d(Array.from(n.inferred_prop.valuesCount.keys()));
130
+ function buildPropertyFromData(data, property, getType) {
131
+ const typesCount = {};
132
+ const valuesCount = {};
133
+ if (data) {
134
+ data.forEach((entry) => {
135
+ increaseTypeCount(property.dataType, typesCount, entry, getType);
136
+ increaseValuesCount(valuesCount, "inferred_prop", entry, getType);
137
+ });
138
+ }
139
+ const enumValues = "enumValues" in property ? resolveEnumValues(property["enumValues"]) : void 0;
140
+ if (enumValues) {
141
+ const newEnumValues = extractEnumFromValues(Array.from(valuesCount["inferred_prop"].valuesCount.keys()));
99
142
  return {
100
- ...e,
101
- enumValues: [...a, ...o]
143
+ ...property,
144
+ enumValues: [...newEnumValues, ...enumValues]
102
145
  };
103
146
  }
104
- const i = g("inferred_prop", r.length, e.dataType, s, n.inferred_prop);
105
- return j(i, e);
147
+ const generatedProperty = buildPropertyFromCount(
148
+ "inferred_prop",
149
+ data.length,
150
+ property.dataType,
151
+ typesCount,
152
+ valuesCount["inferred_prop"]
153
+ );
154
+ return mergeDeep(generatedProperty, property);
155
+ }
156
+ function buildPropertiesOrder(properties, propertiesOrder, priorityKeys) {
157
+ const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());
158
+ function propOrder(s) {
159
+ const k = s.toLowerCase();
160
+ if (lowerCasePriorityKeys.includes(k)) return 4;
161
+ if (k === "title" || k === "name") return 3;
162
+ if (k.includes("title") || k.includes("name")) return 2;
163
+ if (k.includes("image") || k.includes("picture")) return 1;
164
+ return 0;
165
+ }
166
+ const keys = propertiesOrder ?? Object.keys(properties);
167
+ keys.sort();
168
+ keys.sort((a, b) => {
169
+ return propOrder(b) - propOrder(a);
170
+ });
171
+ return keys;
106
172
  }
107
- function U(r) {
108
- function e(s) {
109
- const n = s.toLowerCase();
110
- return n === "title" || n === "name" ? 3 : n.includes("title") || n.includes("name") ? 2 : n.includes("image") || n.includes("picture") ? 1 : 0;
173
+ function increaseTypeCount(type, typesCount, fieldValue, getType) {
174
+ if (type === "map") {
175
+ if (fieldValue) {
176
+ let mapTypesCount = typesCount[type];
177
+ if (!mapTypesCount) {
178
+ mapTypesCount = {};
179
+ typesCount[type] = mapTypesCount;
180
+ }
181
+ Object.entries(fieldValue).forEach(([key, value]) => {
182
+ increaseMapTypeCount(mapTypesCount, key, value, getType);
183
+ });
184
+ }
185
+ } else if (type === "array") {
186
+ let arrayTypesCount = typesCount[type];
187
+ if (!arrayTypesCount) {
188
+ arrayTypesCount = {};
189
+ typesCount[type] = arrayTypesCount;
190
+ }
191
+ if (fieldValue && Array.isArray(fieldValue) && fieldValue.length > 0) {
192
+ const arrayType = getMostProbableTypeInArray(fieldValue, getType);
193
+ if (arrayType === "map") {
194
+ let mapTypesCount = arrayTypesCount[arrayType];
195
+ if (!mapTypesCount) {
196
+ mapTypesCount = {};
197
+ }
198
+ fieldValue.forEach((value) => {
199
+ Object.entries(value).forEach(
200
+ ([key, v]) => increaseMapTypeCount(mapTypesCount, key, v, getType)
201
+ );
202
+ });
203
+ arrayTypesCount[arrayType] = mapTypesCount;
204
+ } else {
205
+ if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;
206
+ else arrayTypesCount[arrayType]++;
207
+ }
208
+ }
209
+ } else {
210
+ if (!typesCount[type]) typesCount[type] = 1;
211
+ else typesCount[type]++;
111
212
  }
112
- const t = Object.keys(r);
113
- return t.sort(), t.sort((s, n) => e(n) - e(s)), t;
114
213
  }
115
- function l(r, e, t, s) {
116
- if (r === "map") {
117
- if (t) {
118
- let n = e[r];
119
- n || (n = {}, e[r] = n), Object.entries(t).forEach(([o, i]) => {
120
- E(n, o, i, s);
214
+ function increaseMapTypeCount(typesCountRecord, key, fieldValue, getType) {
215
+ let typesCount = typesCountRecord[key];
216
+ if (!typesCount) {
217
+ typesCount = {};
218
+ typesCountRecord[key] = typesCount;
219
+ }
220
+ if (fieldValue != null) {
221
+ const type = getType(fieldValue);
222
+ increaseTypeCount(type, typesCount, fieldValue, getType);
223
+ }
224
+ }
225
+ function increaseValuesCount(typeValuesRecord, key, fieldValue, getType) {
226
+ const dataType = getType(fieldValue);
227
+ let valuesRecord = typeValuesRecord[key];
228
+ if (!valuesRecord) {
229
+ valuesRecord = {
230
+ values: [],
231
+ valuesCount: /* @__PURE__ */ new Map()
232
+ };
233
+ typeValuesRecord[key] = valuesRecord;
234
+ }
235
+ if (dataType === "map") {
236
+ let mapValuesRecord = valuesRecord.map;
237
+ if (!mapValuesRecord) {
238
+ mapValuesRecord = {};
239
+ valuesRecord.map = mapValuesRecord;
240
+ }
241
+ if (fieldValue)
242
+ Object.entries(fieldValue).forEach(
243
+ ([key2, value]) => increaseValuesCount(mapValuesRecord, key2, value, getType)
244
+ );
245
+ } else if (dataType === "array") {
246
+ if (Array.isArray(fieldValue)) {
247
+ fieldValue.forEach((value) => {
248
+ valuesRecord.values.push(value);
249
+ valuesRecord.valuesCount.set(value, (valuesRecord.valuesCount.get(value) ?? 0) + 1);
121
250
  });
122
251
  }
123
- } else if (r === "array") {
124
- let n = e[r];
125
- if (n || (n = {}, e[r] = n), t && Array.isArray(t) && t.length > 0) {
126
- const o = z(t, s);
127
- n[o] ? n[o]++ : n[o] = 1;
128
- }
129
- } else
130
- e[r] ? e[r]++ : e[r] = 1;
131
- }
132
- function E(r, e, t, s) {
133
- let n = r[e];
134
- if (n || (n = {}, r[e] = n), t != null) {
135
- const o = s(t);
136
- l(o, n, t, s);
137
- }
138
- }
139
- function p(r, e, t, s) {
140
- const n = s(t);
141
- let o = r[e];
142
- if (o || (o = {
143
- values: [],
144
- valuesCount: /* @__PURE__ */ new Map()
145
- }, r[e] = o), n === "map") {
146
- let i = o.map;
147
- i || (i = {}, o.map = i), t && Object.entries(t).forEach(([a, c]) => p(i, a, c, s));
148
- } else
149
- n === "array" ? Array.isArray(t) && t.forEach((i) => {
150
- o.values.push(i), o.valuesCount.set(i, (o.valuesCount.get(i) ?? 0) + 1);
151
- }) : t && (o.values.push(t), o.valuesCount.set(t, (o.valuesCount.get(t) ?? 0) + 1));
152
- }
153
- function m(r) {
154
- let e = 0;
155
- return Object.entries(r).forEach(([t, s]) => {
156
- let n = 0;
157
- t === "map" ? n = A(s) : t === "array" ? n = m(s) : n = s, n > e && (e = n);
158
- }), e;
159
- }
160
- function A(r) {
161
- return Object.entries(r).map(([e, t]) => m(t)).reduce((e, t) => Math.max(e, t), 0);
162
- }
163
- function h(r) {
164
- let e = -1, t = "string";
165
- return Object.entries(r).forEach(([s, n]) => {
166
- let o;
167
- s === "map" ? o = A(n) : s === "array" ? o = m(n) : o = n, o > e && (e = o, t = s);
168
- }), t;
169
- }
170
- function g(r, e, t, s, n) {
171
- let o;
172
- r && (o = b(r));
173
- let i;
174
- if (t === "map") {
175
- W(s) && (i = {
176
- dataType: "map",
177
- name: o,
178
- keyValue: !0,
179
- properties: {}
180
- });
181
- const c = O(e, s.map, n ? n.mapValues : void 0);
182
- i = {
252
+ } else {
253
+ if (fieldValue) {
254
+ valuesRecord.values.push(fieldValue);
255
+ valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);
256
+ }
257
+ }
258
+ }
259
+ function getHighestTypesCount(typesCount) {
260
+ let highestCount = 0;
261
+ Object.entries(typesCount).forEach(([type, count]) => {
262
+ let countValue = 0;
263
+ if (type === "map") {
264
+ countValue = getHighestRecordCount(count);
265
+ } else if (type === "array") {
266
+ countValue = getHighestTypesCount(count);
267
+ } else {
268
+ countValue = count;
269
+ }
270
+ if (countValue > highestCount) {
271
+ highestCount = countValue;
272
+ }
273
+ });
274
+ return highestCount;
275
+ }
276
+ function getHighestRecordCount(record) {
277
+ return Object.entries(record).map(([key, typesCount]) => getHighestTypesCount(typesCount)).reduce((a, b) => Math.max(a, b), 0);
278
+ }
279
+ function getMostProbableType(typesCount) {
280
+ let highestCount = -1;
281
+ let probableType = "string";
282
+ Object.entries(typesCount).forEach(([type, count]) => {
283
+ let countValue;
284
+ if (type === "map") {
285
+ countValue = getHighestRecordCount(count);
286
+ } else if (type === "array") {
287
+ countValue = getHighestTypesCount(count);
288
+ } else {
289
+ countValue = count;
290
+ }
291
+ if (countValue > highestCount) {
292
+ highestCount = countValue;
293
+ probableType = type;
294
+ }
295
+ });
296
+ return probableType;
297
+ }
298
+ function buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesResult) {
299
+ let title;
300
+ if (key) {
301
+ title = formatString(key.toLowerCase());
302
+ }
303
+ let result = void 0;
304
+ if (mostProbableType === "map") {
305
+ const highVariability = checkTypesCountHighVariability(typesCount);
306
+ if (highVariability) {
307
+ result = {
308
+ dataType: "map",
309
+ name: title,
310
+ keyValue: true,
311
+ properties: {}
312
+ };
313
+ }
314
+ const properties = buildPropertiesFromCount(
315
+ totalDocsCount,
316
+ typesCount.map,
317
+ valuesResult ? valuesResult.mapValues : void 0
318
+ );
319
+ result = {
183
320
  dataType: "map",
184
- name: o,
185
- properties: c
321
+ name: title,
322
+ properties
186
323
  };
187
- } else if (t === "array") {
188
- const a = s.array, c = h(a), f = g(r, e, c, a, n);
189
- i = {
324
+ } else if (mostProbableType === "array") {
325
+ const arrayTypesCount = typesCount.array;
326
+ const arrayMostProbableType = getMostProbableType(arrayTypesCount);
327
+ const of = buildPropertyFromCount(
328
+ key,
329
+ totalDocsCount,
330
+ arrayMostProbableType,
331
+ arrayTypesCount,
332
+ valuesResult
333
+ );
334
+ result = {
190
335
  dataType: "array",
191
- name: o,
192
- of: f
336
+ name: title,
337
+ of
193
338
  };
194
339
  }
195
- if (!i) {
196
- const a = {
197
- name: r,
198
- totalDocsCount: e,
199
- valuesResult: n
340
+ if (!result) {
341
+ const propertyProps = {
342
+ name: key,
343
+ totalDocsCount,
344
+ valuesResult
200
345
  };
201
- t === "string" ? i = C(a) : t === "reference" ? i = _(a) : i = {
202
- dataType: t
203
- }, o && (i.name = o);
204
- const c = V(a);
205
- c && (i.validation = c);
346
+ if (mostProbableType === "string") {
347
+ result = buildStringProperty(propertyProps);
348
+ } else if (mostProbableType === "reference") {
349
+ result = buildReferenceProperty(propertyProps);
350
+ } else {
351
+ result = {
352
+ dataType: mostProbableType
353
+ };
354
+ }
355
+ if (title) {
356
+ result.name = title;
357
+ }
358
+ const validation = buildValidation(propertyProps);
359
+ if (validation) {
360
+ result.validation = validation;
361
+ }
206
362
  }
207
363
  return {
208
- ...i,
209
- editable: !0
364
+ ...result,
365
+ editable: true
210
366
  };
211
367
  }
212
- function O(r, e, t) {
213
- const s = {};
214
- return Object.entries(e).forEach(([n, o]) => {
215
- const i = h(o);
216
- s[n] = g(n, r, i, o, t ? t[n] : void 0);
217
- }), s;
218
- }
219
- function u(r) {
220
- let e = 0;
221
- return Object.entries(r).forEach(([t, s]) => {
222
- typeof s == "object" ? e = Math.max(e, u(s)) : e = Math.max(e, s);
223
- }), e;
224
- }
225
- function z(r, e) {
226
- let t = {};
227
- return r.forEach((s) => {
228
- l(e(s), t, s, e);
229
- }), h(t);
230
- }
231
- function W(r) {
232
- const e = u(r);
233
- let t = 0;
234
- return Object.entries(r.map ?? {}).forEach(([s, n]) => {
235
- u(n) < e / 3 && t++;
236
- }), t / Object.entries(r.map ?? {}).length > 0.5;
368
+ function buildPropertiesFromCount(totalDocsCount, typesCountRecord, valuesCountRecord) {
369
+ const res = {};
370
+ Object.entries(typesCountRecord).forEach(([key, typesCount]) => {
371
+ const mostProbableType = getMostProbableType(typesCount);
372
+ res[key] = buildPropertyFromCount(
373
+ key,
374
+ totalDocsCount,
375
+ mostProbableType,
376
+ typesCount,
377
+ valuesCountRecord ? valuesCountRecord[key] : void 0
378
+ );
379
+ });
380
+ return res;
381
+ }
382
+ function countMaxDocumentsUnder(typesCount) {
383
+ let count = 0;
384
+ Object.entries(typesCount).forEach(([type, value]) => {
385
+ if (typeof value === "object") {
386
+ count = Math.max(count, countMaxDocumentsUnder(value));
387
+ } else {
388
+ count = Math.max(count, value);
389
+ }
390
+ });
391
+ return count;
392
+ }
393
+ function getMostProbableTypeInArray(array, getType) {
394
+ let typesCount = {};
395
+ array.forEach((value) => {
396
+ increaseTypeCount(getType(value), typesCount, value, getType);
397
+ });
398
+ return getMostProbableType(typesCount);
399
+ }
400
+ function checkTypesCountHighVariability(typesCount) {
401
+ const maxCount = countMaxDocumentsUnder(typesCount);
402
+ let keysWithFewValues = 0;
403
+ Object.entries(typesCount.map ?? {}).forEach(([key, value]) => {
404
+ const count = countMaxDocumentsUnder(value);
405
+ if (count < maxCount / 3) {
406
+ keysWithFewValues++;
407
+ }
408
+ });
409
+ return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;
410
+ }
411
+ function formatString(input) {
412
+ const normalized = input.replace(/[_\-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
413
+ const words = normalized.split(" ");
414
+ const formatted = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
415
+ return formatted;
416
+ }
417
+ function inferTypeFromValue(value) {
418
+ if (typeof value === "string") return "string";
419
+ if (typeof value === "number") return "number";
420
+ if (typeof value === "boolean") return "boolean";
421
+ if (Array.isArray(value)) return "array";
422
+ if (typeof value === "object") return "map";
423
+ return "string";
237
424
  }
238
425
  export {
239
- k as buildEntityPropertiesFromData,
240
- U as buildPropertiesOrder,
241
- w as buildPropertyFromData,
242
- d as extractEnumFromValues
426
+ buildEntityPropertiesFromData,
427
+ buildPropertiesOrder,
428
+ buildPropertyFromData,
429
+ extractEnumFromValues,
430
+ inferTypeFromValue
243
431
  };
244
432
  //# sourceMappingURL=index.es.js.map