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