@firecms/schema_inference 3.0.0-beta.7 → 3.0.0-beta.9
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/LICENSE +2 -1
- package/dist/index.es.js +368 -220
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +433 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +6 -6
package/dist/index.es.js
CHANGED
@@ -1,284 +1,432 @@
|
|
1
|
-
import { unslugify
|
2
|
-
import { DocumentReference
|
3
|
-
function
|
4
|
-
if (!
|
5
|
-
|
6
|
-
|
7
|
-
|
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;
|
8
9
|
}
|
9
|
-
const
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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;
|
17
21
|
}
|
18
|
-
function
|
19
|
-
if (!Array.isArray(
|
22
|
+
function extractEnumFromValues(values) {
|
23
|
+
if (!Array.isArray(values)) {
|
20
24
|
return [];
|
21
|
-
|
22
|
-
|
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
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
43
|
+
let stringProperty = {
|
30
44
|
dataType: "string"
|
31
45
|
};
|
32
|
-
if (
|
33
|
-
const
|
34
|
-
|
35
|
-
const
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
const f = d(Array.from(e.valuesCount.keys()));
|
40
|
-
Object.keys(f).length > 1 && (o.enumValues = f);
|
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;
|
41
53
|
}
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
acceptedFiles: [f],
|
46
|
-
storagePath: b(e) ?? "/"
|
47
|
-
});
|
54
|
+
const probablyAnEmail = valuesResult.values.filter((value) => typeof value === "string" && emailRegEx.test(value)).length > totalDocsCount / 3 * 2;
|
55
|
+
if (probablyAnEmail) {
|
56
|
+
config.email = true;
|
48
57
|
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
82
|
+
return stringProperty;
|
56
83
|
}
|
57
|
-
function
|
58
|
-
const
|
59
|
-
|
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
|
62
|
-
totalDocsCount
|
63
|
-
valuesResult
|
91
|
+
function buildValidation({
|
92
|
+
totalDocsCount,
|
93
|
+
valuesResult
|
64
94
|
}) {
|
65
|
-
if (
|
66
|
-
const
|
67
|
-
if (
|
95
|
+
if (valuesResult) {
|
96
|
+
const totalEntriesCount = valuesResult.values.length;
|
97
|
+
if (totalDocsCount === totalEntriesCount)
|
68
98
|
return {
|
69
|
-
required:
|
99
|
+
required: true
|
70
100
|
};
|
71
101
|
}
|
102
|
+
return void 0;
|
72
103
|
}
|
73
|
-
function
|
74
|
-
totalDocsCount
|
75
|
-
valuesResult
|
104
|
+
function buildReferenceProperty({
|
105
|
+
totalDocsCount,
|
106
|
+
valuesResult
|
76
107
|
}) {
|
77
|
-
|
108
|
+
const property = {
|
78
109
|
dataType: "reference",
|
79
|
-
path:
|
80
|
-
editable:
|
110
|
+
path: findCommonInitialStringInPath(valuesResult) ?? "!!!FIX_ME!!!",
|
111
|
+
editable: true
|
81
112
|
};
|
113
|
+
return property;
|
82
114
|
}
|
83
|
-
async function
|
84
|
-
const
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
}
|
127
|
+
}
|
128
|
+
return buildPropertiesFromCount(data.length, typesCount, valuesCount);
|
90
129
|
}
|
91
|
-
function
|
92
|
-
const
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
-
...
|
101
|
-
enumValues: [...
|
143
|
+
...property,
|
144
|
+
enumValues: [...newEnumValues, ...enumValues]
|
102
145
|
};
|
103
146
|
}
|
104
|
-
const
|
147
|
+
const generatedProperty = buildPropertyFromCount(
|
105
148
|
"inferred_prop",
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
149
|
+
data.length,
|
150
|
+
property.dataType,
|
151
|
+
typesCount,
|
152
|
+
valuesCount["inferred_prop"]
|
110
153
|
);
|
111
|
-
return
|
154
|
+
return mergeDeep(generatedProperty, property);
|
112
155
|
}
|
113
|
-
function
|
114
|
-
const
|
115
|
-
function
|
116
|
-
const
|
117
|
-
|
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;
|
118
165
|
}
|
119
|
-
const
|
120
|
-
|
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;
|
121
172
|
}
|
122
|
-
function
|
123
|
-
if (
|
124
|
-
if (
|
125
|
-
let
|
126
|
-
|
127
|
-
|
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);
|
128
183
|
});
|
129
184
|
}
|
130
|
-
} else if (
|
131
|
-
let
|
132
|
-
if (
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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)
|
139
201
|
);
|
140
|
-
})
|
141
|
-
|
142
|
-
|
202
|
+
});
|
203
|
+
arrayTypesCount[arrayType] = mapTypesCount;
|
204
|
+
} else {
|
205
|
+
if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;
|
206
|
+
else arrayTypesCount[arrayType]++;
|
207
|
+
}
|
143
208
|
}
|
144
|
-
} else
|
145
|
-
|
209
|
+
} else {
|
210
|
+
if (!typesCount[type]) typesCount[type] = 1;
|
211
|
+
else typesCount[type]++;
|
212
|
+
}
|
146
213
|
}
|
147
|
-
function
|
148
|
-
let
|
149
|
-
if (
|
150
|
-
|
151
|
-
|
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);
|
152
223
|
}
|
153
224
|
}
|
154
|
-
function
|
155
|
-
const
|
156
|
-
let
|
157
|
-
if (
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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);
|
250
|
+
});
|
251
|
+
}
|
252
|
+
} else {
|
253
|
+
if (fieldValue) {
|
254
|
+
valuesRecord.values.push(fieldValue);
|
255
|
+
valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);
|
256
|
+
}
|
257
|
+
}
|
169
258
|
}
|
170
|
-
function
|
171
|
-
let
|
172
|
-
|
173
|
-
let
|
174
|
-
|
175
|
-
|
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;
|
176
275
|
}
|
177
|
-
function
|
178
|
-
return Object.entries(
|
276
|
+
function getHighestRecordCount(record) {
|
277
|
+
return Object.entries(record).map(([key, typesCount]) => getHighestTypesCount(typesCount)).reduce((a, b) => Math.max(a, b), 0);
|
179
278
|
}
|
180
|
-
function
|
181
|
-
let
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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;
|
186
297
|
}
|
187
|
-
function
|
188
|
-
let
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
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
|
202
318
|
);
|
203
|
-
|
319
|
+
result = {
|
204
320
|
dataType: "map",
|
205
|
-
name:
|
206
|
-
properties
|
321
|
+
name: title,
|
322
|
+
properties
|
207
323
|
};
|
208
|
-
} else if (
|
209
|
-
const
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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
|
215
333
|
);
|
216
|
-
|
334
|
+
result = {
|
217
335
|
dataType: "array",
|
218
|
-
name:
|
219
|
-
of
|
336
|
+
name: title,
|
337
|
+
of
|
220
338
|
};
|
221
339
|
}
|
222
|
-
if (!
|
223
|
-
const
|
224
|
-
name:
|
225
|
-
totalDocsCount
|
226
|
-
valuesResult
|
340
|
+
if (!result) {
|
341
|
+
const propertyProps = {
|
342
|
+
name: key,
|
343
|
+
totalDocsCount,
|
344
|
+
valuesResult
|
227
345
|
};
|
228
|
-
|
229
|
-
|
230
|
-
}
|
231
|
-
|
232
|
-
|
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
|
+
}
|
233
362
|
}
|
234
363
|
return {
|
235
|
-
...
|
236
|
-
editable:
|
364
|
+
...result,
|
365
|
+
editable: true
|
237
366
|
};
|
238
367
|
}
|
239
|
-
function
|
240
|
-
const
|
241
|
-
|
242
|
-
const
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
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
|
249
378
|
);
|
250
|
-
})
|
379
|
+
});
|
380
|
+
return res;
|
251
381
|
}
|
252
|
-
function
|
253
|
-
let
|
254
|
-
|
255
|
-
typeof
|
256
|
-
|
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;
|
257
392
|
}
|
258
|
-
function
|
259
|
-
let
|
260
|
-
|
261
|
-
|
262
|
-
})
|
393
|
+
function getMostProbableTypeInArray(array, getType) {
|
394
|
+
let typesCount = {};
|
395
|
+
array.forEach((value) => {
|
396
|
+
increaseTypeCount(getType(value), typesCount, value, getType);
|
397
|
+
});
|
398
|
+
return getMostProbableType(typesCount);
|
263
399
|
}
|
264
|
-
function
|
265
|
-
const
|
266
|
-
let
|
267
|
-
|
268
|
-
|
269
|
-
|
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;
|
270
410
|
}
|
271
|
-
function
|
272
|
-
|
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;
|
273
416
|
}
|
274
|
-
function
|
275
|
-
|
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";
|
276
424
|
}
|
277
425
|
export {
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
426
|
+
buildEntityPropertiesFromData,
|
427
|
+
buildPropertiesOrder,
|
428
|
+
buildPropertyFromData,
|
429
|
+
extractEnumFromValues,
|
430
|
+
inferTypeFromValue
|
283
431
|
};
|
284
432
|
//# sourceMappingURL=index.es.js.map
|