@firecms/schema_inference 3.0.0-canary.42 → 3.0.0-canary.43

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.
@@ -3,3 +3,4 @@ export type InferenceTypeBuilder = (value: any) => DataType;
3
3
  export declare function buildEntityPropertiesFromData(data: object[], getType: InferenceTypeBuilder): Promise<Properties>;
4
4
  export declare function buildPropertyFromData(data: any[], property: Property, getType: InferenceTypeBuilder): Property;
5
5
  export declare function buildPropertiesOrder(properties: Properties<any>): string[];
6
+ export declare function inferTypeFromValue(value: any): DataType;
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { unslugify as O, resolveEnumValues as T, mergeDeep as j } from "@firecms/core";
2
2
  import { DocumentReference as P } from "firebase/firestore";
3
- function b(r) {
3
+ function y(r) {
4
4
  if (!r)
5
5
  return;
6
6
  function e(i) {
@@ -15,7 +15,7 @@ function b(r) {
15
15
  return a ? a.startsWith(n) : !1;
16
16
  }).length > r.values.length / 3 * 2 ? n : void 0;
17
17
  }
18
- function d(r) {
18
+ function b(r) {
19
19
  if (!Array.isArray(r))
20
20
  return [];
21
21
  const e = r.map((t) => typeof t == "string" ? { id: t, label: O(t) } : null).filter(Boolean);
@@ -30,20 +30,20 @@ function z({
30
30
  dataType: "string"
31
31
  };
32
32
  if (e) {
33
- const s = e.values.length, n = Array.from(e.valuesCount.keys()).length, o = {}, i = e.values.filter((c) => typeof c == "string" && c.toString().startsWith("http")).length > r / 3 * 2;
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
34
  i && (o.url = !0);
35
- const a = e.values.filter((c) => typeof c == "string" && M.test(c)).length > r / 3 * 2;
35
+ const a = e.values.filter((f) => typeof f == "string" && M.test(f)).length > r / 3 * 2;
36
36
  a && (o.email = !0);
37
- const f = e.values.filter((c) => typeof c == "string" && c.length === 28 && !c.includes(" ")).length > r / 3 * 2;
38
- if (f && (o.readOnly = !0), !a && !i && !f && !i && n < s / 3) {
39
- const c = d(Array.from(e.valuesCount.keys()));
40
- Object.keys(c).length > 1 && (o.enumValues = c);
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 = b(Array.from(e.valuesCount.keys()));
40
+ Object.keys(f).length > 1 && (o.enumValues = f);
41
41
  }
42
- if (!a && !i && !f && !i && !o.enumValues) {
43
- const c = _(e, r);
44
- c && (o.storage = {
45
- acceptedFiles: [c],
46
- storagePath: b(e) ?? "/"
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
47
  });
48
48
  }
49
49
  Object.keys(o).length > 0 && (t = {
@@ -54,11 +54,11 @@ function z({
54
54
  }
55
55
  return t;
56
56
  }
57
- function _(r, e) {
57
+ function F(r, e) {
58
58
  const t = r.values.filter((i) => typeof i == "string" && S.some((a) => i.toString().endsWith(a))).length > e / 3 * 2, s = r.values.filter((i) => typeof i == "string" && I.some((a) => i.toString().endsWith(a))).length > e / 3 * 2, n = r.values.filter((i) => typeof i == "string" && C.some((a) => i.toString().endsWith(a))).length > e / 3 * 2;
59
59
  return t ? "image/*" : s ? "audio/*" : n ? "video/*" : !1;
60
60
  }
61
- function x({
61
+ function V({
62
62
  totalDocsCount: r,
63
63
  valuesResult: e
64
64
  }) {
@@ -70,13 +70,13 @@ function x({
70
70
  };
71
71
  }
72
72
  }
73
- function F({
73
+ function _({
74
74
  totalDocsCount: r,
75
75
  valuesResult: e
76
76
  }) {
77
77
  return {
78
78
  dataType: "reference",
79
- path: b(e) ?? "!!!FIX_ME!!!",
79
+ path: y(e) ?? "!!!FIX_ME!!!",
80
80
  editable: !0
81
81
  };
82
82
  }
@@ -84,7 +84,7 @@ async function k(r, e) {
84
84
  const t = {}, s = {};
85
85
  return r && r.forEach((n) => {
86
86
  n && Object.entries(n).forEach(([o, i]) => {
87
- y(t, o, i, e), p(s, o, i, e);
87
+ d(t, o, i, e), p(s, o, i, e);
88
88
  });
89
89
  }), A(r.length, t, s);
90
90
  }
@@ -95,13 +95,13 @@ function U(r, e, t) {
95
95
  });
96
96
  const o = "enumValues" in e ? T(e.enumValues) : void 0;
97
97
  if (o) {
98
- const a = d(Array.from(n.inferred_prop.valuesCount.keys()));
98
+ const a = b(Array.from(n.inferred_prop.valuesCount.keys()));
99
99
  return {
100
100
  ...e,
101
101
  enumValues: [...a, ...o]
102
102
  };
103
103
  }
104
- const i = g("inferred_prop", r.length, e.dataType, s, n.inferred_prop);
104
+ const i = h("inferred_prop", r.length, e.dataType, s, n.inferred_prop);
105
105
  return j(i, e);
106
106
  }
107
107
  function L(r) {
@@ -117,19 +117,19 @@ function l(r, e, t, s) {
117
117
  if (t) {
118
118
  let n = e[r];
119
119
  n || (n = {}, e[r] = n), Object.entries(t).forEach(([o, i]) => {
120
- y(n, o, i, s);
120
+ d(n, o, i, s);
121
121
  });
122
122
  }
123
123
  } else if (r === "array") {
124
124
  let n = e[r];
125
125
  if (n || (n = {}, e[r] = n), t && Array.isArray(t) && t.length > 0) {
126
- const o = V(t, s);
126
+ const o = x(t, s);
127
127
  n[o] ? n[o]++ : n[o] = 1;
128
128
  }
129
129
  } else
130
130
  e[r] ? e[r]++ : e[r] = 1;
131
131
  }
132
- function y(r, e, t, s) {
132
+ function d(r, e, t, s) {
133
133
  let n = r[e];
134
134
  if (n || (n = {}, r[e] = n), t != null) {
135
135
  const o = s(t);
@@ -144,7 +144,7 @@ function p(r, e, t, s) {
144
144
  valuesCount: /* @__PURE__ */ new Map()
145
145
  }, r[e] = o), n === "map") {
146
146
  let i = o.map;
147
- i || (i = {}, o.map = i), t && Object.entries(t).forEach(([a, f]) => p(i, a, f, s));
147
+ i || (i = {}, o.map = i), t && Object.entries(t).forEach(([a, c]) => p(i, a, c, s));
148
148
  } else
149
149
  n === "array" ? Array.isArray(t) && t.forEach((i) => {
150
150
  o.values.push(i), o.valuesCount.set(i, (o.valuesCount.get(i) ?? 0) + 1);
@@ -160,14 +160,14 @@ function m(r) {
160
160
  function E(r) {
161
161
  return Object.entries(r).map(([e, t]) => m(t)).reduce((e, t) => Math.max(e, t), 0);
162
162
  }
163
- function h(r) {
163
+ function g(r) {
164
164
  let e = -1, t = "string";
165
165
  return Object.entries(r).forEach(([s, n]) => {
166
166
  let o;
167
167
  s === "map" ? o = E(n) : s === "array" ? o = m(n) : o = n, o > e && (e = o, t = s);
168
168
  }), t;
169
169
  }
170
- function g(r, e, t, s, n) {
170
+ function h(r, e, t, s, n) {
171
171
  let o;
172
172
  r && (o = Z(r.toLowerCase()));
173
173
  let i;
@@ -178,18 +178,18 @@ function g(r, e, t, s, n) {
178
178
  keyValue: !0,
179
179
  properties: {}
180
180
  });
181
- const f = A(e, s.map, n ? n.mapValues : void 0);
181
+ const c = A(e, s.map, n ? n.mapValues : void 0);
182
182
  i = {
183
183
  dataType: "map",
184
184
  name: o,
185
- properties: f
185
+ properties: c
186
186
  };
187
187
  } else if (t === "array") {
188
- const a = s.array, f = h(a), c = g(r, e, f, a, n);
188
+ const a = s.array, c = g(a), f = h(r, e, c, a, n);
189
189
  i = {
190
190
  dataType: "array",
191
191
  name: o,
192
- of: c
192
+ of: f
193
193
  };
194
194
  }
195
195
  if (!i) {
@@ -198,11 +198,11 @@ function g(r, e, t, s, n) {
198
198
  totalDocsCount: e,
199
199
  valuesResult: n
200
200
  };
201
- t === "string" ? i = z(a) : t === "reference" ? i = F(a) : i = {
201
+ t === "string" ? i = z(a) : t === "reference" ? i = _(a) : i = {
202
202
  dataType: t
203
203
  }, o && (i.name = o);
204
- const f = x(a);
205
- f && (i.validation = f);
204
+ const c = V(a);
205
+ c && (i.validation = c);
206
206
  }
207
207
  return {
208
208
  ...i,
@@ -212,8 +212,8 @@ function g(r, e, t, s, n) {
212
212
  function A(r, e, t) {
213
213
  const s = {};
214
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);
215
+ const i = g(o);
216
+ s[n] = h(n, r, i, o, t ? t[n] : void 0);
217
217
  }), s;
218
218
  }
219
219
  function u(r) {
@@ -222,11 +222,11 @@ function u(r) {
222
222
  typeof s == "object" ? e = Math.max(e, u(s)) : e = Math.max(e, s);
223
223
  }), e;
224
224
  }
225
- function V(r, e) {
225
+ function x(r, e) {
226
226
  let t = {};
227
227
  return r.forEach((s) => {
228
228
  l(e(s), t, s, e);
229
- }), h(t);
229
+ }), g(t);
230
230
  }
231
231
  function w(r) {
232
232
  const e = u(r);
@@ -238,10 +238,14 @@ function w(r) {
238
238
  function Z(r) {
239
239
  return r.replace(/[_\-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(" ").map((n) => n.charAt(0).toUpperCase() + n.slice(1)).join(" ");
240
240
  }
241
+ function X(r) {
242
+ return typeof r == "string" ? "string" : typeof r == "number" ? "number" : typeof r == "boolean" ? "boolean" : Array.isArray(r) ? "array" : typeof r == "object" ? "map" : "string";
243
+ }
241
244
  export {
242
245
  k as buildEntityPropertiesFromData,
243
246
  L as buildPropertiesOrder,
244
247
  U as buildPropertyFromData,
245
- d as extractEnumFromValues
248
+ b as extractEnumFromValues,
249
+ X as inferTypeFromValue
246
250
  };
247
251
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/strings.ts","../src/util.ts","../src/builders/string_property_builder.ts","../src/builders/validation_builder.ts","../src/builders/reference_property_builder.ts","../src/collection_builder.ts"],"sourcesContent":["import { ValuesCountEntry } from \"./types\";\nimport { DocumentReference } from \"firebase/firestore\";\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any) {\n if (typeof value === \"string\") return value;\n else if (value instanceof DocumentReference) return value.path;\n else return undefined;\n }\n\n const strings: string[] = valuesCount.values.map((v) => getPath(v)).filter(v => !!v) as string[];\n const pathWithSlash = strings.find((s) => s.includes(\"/\"));\n if (!pathWithSlash)\n return undefined;\n\n const searchedPath = pathWithSlash.substr(0, pathWithSlash.lastIndexOf(\"/\"));\n\n const yep = valuesCount.values\n .filter((value) => {\n const path = getPath(value);\n if (!path) return false;\n return path.startsWith(searchedPath)\n }).length > valuesCount.values.length / 3 * 2;\n\n return yep ? searchedPath : undefined;\n\n}\n\nexport function removeInitialAndTrailingSlashes(s: string): string {\n return removeInitialSlash(removeTrailingSlash(s));\n}\n\nexport function removeInitialSlash(s: string) {\n if (s.startsWith(\"/\"))\n return s.slice(1);\n else return s;\n}\n\nexport function removeTrailingSlash(s: string) {\n if (s.endsWith(\"/\"))\n return s.slice(0, -1);\n else return s;\n}\n","import { unslugify } from \"@firecms/core\";\n\nexport function extractEnumFromValues(values: unknown[]) {\n if (!Array.isArray(values)) {\n return [];\n }\n const enumValues = values\n .map((value) => {\n if (typeof value === \"string\") {\n return ({ id: value, label: unslugify(value) });\n } else\n return null;\n }).filter(Boolean) as Array<{ id: string, label: string }>;\n enumValues.sort((a, b) => a.label.localeCompare(b.label));\n return enumValues;\n}\n","import { FileType, Property, StringProperty } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".png\", \".webp\", \".gif\"];\nconst AUDIO_EXTENSIONS = [\".mp3\", \".ogg\", \".opus\", \".aac\"];\nconst VIDEO_EXTENSIONS = [\".avi\", \".mp4\"];\n\nconst 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])?)*$/;\n\n\nexport function buildStringProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n dataType: \"string\",\n\n };\n\n if (valuesResult) {\n\n const totalEntriesCount = valuesResult.values.length;\n const totalValues = Array.from(valuesResult.valuesCount.keys()).length;\n\n const config: Partial<StringProperty> = {};\n\n const probablyAURL = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n value.toString().startsWith(\"http\")).length > totalDocsCount / 3 * 2;\n if (probablyAURL) {\n config.url = true;\n }\n\n const probablyAnEmail = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n emailRegEx.test(value)).length > totalDocsCount / 3 * 2;\n if (probablyAnEmail) {\n config.email = true;\n }\n\n const probablyUserIds = valuesResult.values\n .filter((value) => typeof value === \"string\" && value.length === 28 && !value.includes(\" \"))\n .length > totalDocsCount / 3 * 2;\n if (probablyUserIds)\n config.readOnly = true;\n\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n totalValues < totalEntriesCount / 3\n ) {\n const enumValues = extractEnumFromValues(Array.from(valuesResult.valuesCount.keys()));\n\n if (Object.keys(enumValues).length > 1)\n config.enumValues = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enumValues) {\n const fileType = probableFileType(valuesResult, totalDocsCount);\n if (fileType) {\n config.storage = {\n acceptedFiles: [fileType as FileType],\n storagePath: findCommonInitialStringInPath(valuesResult) ?? \"/\"\n };\n }\n }\n\n if (Object.keys(config).length > 0)\n stringProperty = {\n ...stringProperty,\n ...config,\n editable: true\n };\n }\n\n return stringProperty;\n}\n\n// TODO: support returning multiple types\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): boolean | FileType {\n const probablyAnImage = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyAudio = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyVideo = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const fileType: boolean | FileType = probablyAnImage\n ? \"image/*\"\n : probablyAudio\n ? \"audio/*\"\n : probablyVideo ? \"video/*\" : false;\n return fileType;\n}\n","import { PropertyValidationSchema } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { InferencePropertyBuilderProps } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { Property } from \"@firecms/core\";\n\nexport function buildReferenceProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n dataType: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\",\n editable: true\n };\n\n return property;\n}\n","import {\n DataType,\n EnumValues,\n mergeDeep,\n Properties,\n Property,\n resolveEnumValues,\n StringProperty, toKebabCase,\n unslugify\n} from \"@firecms/core\";\nimport {\n InferencePropertyBuilderProps,\n TypesCount,\n TypesCountRecord,\n ValuesCountEntry,\n ValuesCountRecord\n} from \"./types\";\nimport { buildStringProperty } from \"./builders/string_property_builder\";\nimport { buildValidation } from \"./builders/validation_builder\";\nimport { buildReferenceProperty } from \"./builders/reference_property_builder\";\nimport { extractEnumFromValues } from \"./util\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(data: object[], getType: InferenceTypeBuilder): Promise<Properties> {\n const typesCount: TypesCountRecord = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n if (entry) {\n Object.entries(entry).forEach(([key, value]) => {\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n })\n }\n });\n }\n // console.log(util.inspect({ typesCount }, { showHidden: false, depth: null, colors: true }));\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(data: any[], property: Property, getType: InferenceTypeBuilder): Property {\n const typesCount = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n increaseTypeCount(property.dataType, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enumValues\" in property ? resolveEnumValues(property[\"enumValues\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enumValues: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\"inferred_prop\", data.length, property.dataType, typesCount, valuesCount[\"inferred_prop\"]);\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(properties: Properties<any>): string [] {\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (k === \"title\" || k === \"name\") return 3;\n if (k.includes(\"title\") || k.includes(\"name\")) return 2;\n if (k.includes(\"image\") || k.includes(\"picture\")) return 1;\n return 0;\n }\n\n const keys = Object.keys(properties);\n keys.sort(); // alphabetically\n keys.sort((a, b) => {\n return propOrder(b) - propOrder(a);\n });\n return keys;\n}\n\n/**\n * @param type\n * @param typesCount\n * @param fieldValue\n * @param getType\n */\nfunction increaseTypeCount(type: DataType, typesCount: TypesCount, fieldValue: any, getType: InferenceTypeBuilder) {\n if (type === \"map\") {\n if (fieldValue) {\n let mapTypesCount = typesCount[type];\n if (!mapTypesCount) {\n mapTypesCount = {};\n typesCount[type] = mapTypesCount;\n }\n Object.entries(fieldValue).forEach(([key, value]) => {\n increaseMapTypeCount(mapTypesCount as TypesCountRecord, key, value, getType);\n })\n }\n } else if (type === \"array\") {\n let arrayTypesCount = typesCount[type];\n if (!arrayTypesCount) {\n arrayTypesCount = {};\n typesCount[type] = arrayTypesCount;\n }\n if (fieldValue && Array.isArray(fieldValue) && fieldValue.length > 0) {\n const arrayType = getMostProbableTypeInArray(fieldValue, getType); // get type of first element\n if (!arrayTypesCount[arrayType]) (arrayTypesCount[arrayType] as number) = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else (typesCount[type] as number)++;\n }\n}\n\nfunction increaseMapTypeCount(\n typesCountRecord: TypesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) { // Check that fieldValue is not null or undefined before proceeding\n const type = getType(fieldValue);\n increaseTypeCount(type, typesCount, fieldValue, getType);\n }\n}\n\nfunction increaseValuesCount(\n typeValuesRecord: ValuesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n\n const dataType = getType(fieldValue);\n\n let valuesRecord: {\n values: any[];\n valuesCount: Map<any, number>;\n map?: ValuesCountRecord;\n } = typeValuesRecord[key];\n\n if (!valuesRecord) {\n valuesRecord = {\n values: [],\n valuesCount: new Map()\n };\n typeValuesRecord[key] = valuesRecord;\n }\n\n if (dataType === \"map\") {\n let mapValuesRecord: ValuesCountRecord | undefined = valuesRecord.map;\n if (!mapValuesRecord) {\n mapValuesRecord = {};\n valuesRecord.map = mapValuesRecord;\n }\n if (fieldValue)\n Object.entries(fieldValue).forEach(([key, value]) => increaseValuesCount(mapValuesRecord as ValuesCountRecord, key, value, getType))\n } else if (dataType === \"array\") {\n if (Array.isArray(fieldValue)) {\n fieldValue.forEach((value) => {\n valuesRecord.values.push(value);\n valuesRecord.valuesCount.set(value, (valuesRecord.valuesCount.get(value) ?? 0) + 1);\n })\n }\n } else {\n if (fieldValue) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\n }\n }\n\n}\n\nfunction getHighestTypesCount(typesCount: TypesCount): number {\n let highestCount = 0;\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue = 0;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n }\n });\n\n return highestCount;\n}\n\nfunction getHighestRecordCount(record: TypesCountRecord): number {\n return Object.entries(record)\n .map(([key, typesCount]) => getHighestTypesCount(typesCount))\n .reduce((a, b) => Math.max(a, b), 0);\n}\n\nfunction getMostProbableType(typesCount: TypesCount): DataType {\n let highestCount = -1;\n let probableType: DataType = \"string\"; //default\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n probableType = type as DataType;\n }\n });\n return probableType;\n}\n\nfunction buildPropertyFromCount(key: string, totalDocsCount: number, mostProbableType: DataType, typesCount: TypesCount, valuesResult?: ValuesCountEntry): Property {\n let title: string | undefined;\n\n if (key) {\n title = formatString(key.toLowerCase());\n }\n\n let result: Property | undefined = undefined;\n if (mostProbableType === \"map\") {\n\n const highVariability = checkTypesCountHighVariability(typesCount);\n if (highVariability) {\n result = {\n dataType: \"map\",\n name: title,\n keyValue: true,\n properties: {}\n };\n }\n const properties = buildPropertiesFromCount(totalDocsCount, typesCount.map as TypesCountRecord, valuesResult ? valuesResult.mapValues : undefined);\n result = {\n dataType: \"map\",\n name: title,\n properties\n };\n } else if (mostProbableType === \"array\") {\n const arrayTypesCount = typesCount.array as TypesCount;\n const arrayMostProbableType = getMostProbableType(arrayTypesCount);\n const of = buildPropertyFromCount(key, totalDocsCount, arrayMostProbableType, arrayTypesCount, valuesResult);\n result = {\n dataType: \"array\",\n name: title,\n of\n };\n }\n if (!result) {\n const propertyProps: InferencePropertyBuilderProps = {\n name: key,\n totalDocsCount,\n valuesResult\n };\n if (mostProbableType === \"string\") {\n result = buildStringProperty(propertyProps);\n } else if (mostProbableType === \"reference\") {\n result = buildReferenceProperty(propertyProps);\n } else {\n result = {\n dataType: mostProbableType\n } as Property;\n }\n\n if (title) {\n result.name = title;\n }\n\n const validation = buildValidation(propertyProps);\n if (validation) {\n result.validation = validation;\n }\n }\n\n return {\n ...result,\n editable: true\n };\n}\n\nfunction buildPropertiesFromCount(totalDocsCount: number, typesCountRecord: TypesCountRecord, valuesCountRecord?: ValuesCountRecord): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesCountRecord ? valuesCountRecord[key] : undefined);\n })\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\n // console.log(util.inspect({ type, value }, { showHidden: false, depth: null, colors: true }));\n if (typeof value === \"object\") {\n count = Math.max(count, countMaxDocumentsUnder(value as TypesCountRecord));\n } else {\n count = Math.max(count, value as number);\n }\n });\n return count;\n}\n\nfunction getMostProbableTypeInArray(array: any[], getType: InferenceTypeBuilder): DataType {\n let typesCount: TypesCount = {};\n array.forEach((value) => {\n increaseTypeCount(getType(value), typesCount, value, getType);\n });\n return getMostProbableType(typesCount);\n}\n\nfunction checkTypesCountHighVariability(typesCount: TypesCount) {\n const maxCount = countMaxDocumentsUnder(typesCount);\n let keysWithFewValues = 0;\n Object.entries(typesCount.map ?? {})\n .forEach(([key, value]) => {\n const count = countMaxDocumentsUnder(value);\n if (count < maxCount / 3) {\n keysWithFewValues++;\n }\n });\n return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;\n}\n\nfunction formatString(input: string): string {\n const normalized = input\n .replace(/[_\\-]+/g, \" \")\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .toLowerCase();\n\n // Split the normalized string into words\n const words = normalized.split(\" \");\n\n // Capitalize the first letter of each word and join them with a space\n const formatted = words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return formatted;\n}\n\n"],"names":["findCommonInitialStringInPath","valuesCount","getPath","value","DocumentReference","pathWithSlash","v","s","searchedPath","path","extractEnumFromValues","values","enumValues","unslugify","a","b","IMAGE_EXTENSIONS","AUDIO_EXTENSIONS","VIDEO_EXTENSIONS","emailRegEx","buildStringProperty","totalDocsCount","valuesResult","stringProperty","totalEntriesCount","totalValues","config","probablyAURL","probablyAnEmail","probablyUserIds","fileType","probableFileType","probablyAnImage","extension","probablyAudio","probablyVideo","buildValidation","buildReferenceProperty","buildEntityPropertiesFromData","data","getType","typesCount","entry","key","increaseMapTypeCount","increaseValuesCount","buildPropertiesFromCount","buildPropertyFromData","property","increaseTypeCount","resolveEnumValues","newEnumValues","generatedProperty","buildPropertyFromCount","mergeDeep","buildPropertiesOrder","properties","propOrder","k","keys","type","fieldValue","mapTypesCount","arrayTypesCount","arrayType","getMostProbableTypeInArray","typesCountRecord","typeValuesRecord","dataType","valuesRecord","mapValuesRecord","getHighestTypesCount","highestCount","count","countValue","getHighestRecordCount","record","getMostProbableType","probableType","mostProbableType","title","formatString","result","checkTypesCountHighVariability","arrayMostProbableType","of","propertyProps","validation","valuesCountRecord","res","countMaxDocumentsUnder","array","maxCount","keysWithFewValues","input","word"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/strings.ts","../src/util.ts","../src/builders/string_property_builder.ts","../src/builders/validation_builder.ts","../src/builders/reference_property_builder.ts","../src/collection_builder.ts"],"sourcesContent":["import { ValuesCountEntry } from \"./types\";\nimport { DocumentReference } from \"firebase/firestore\";\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any) {\n if (typeof value === \"string\") return value;\n else if (value instanceof DocumentReference) return value.path;\n else return undefined;\n }\n\n const strings: string[] = valuesCount.values.map((v) => getPath(v)).filter(v => !!v) as string[];\n const pathWithSlash = strings.find((s) => s.includes(\"/\"));\n if (!pathWithSlash)\n return undefined;\n\n const searchedPath = pathWithSlash.substr(0, pathWithSlash.lastIndexOf(\"/\"));\n\n const yep = valuesCount.values\n .filter((value) => {\n const path = getPath(value);\n if (!path) return false;\n return path.startsWith(searchedPath)\n }).length > valuesCount.values.length / 3 * 2;\n\n return yep ? searchedPath : undefined;\n\n}\n\nexport function removeInitialAndTrailingSlashes(s: string): string {\n return removeInitialSlash(removeTrailingSlash(s));\n}\n\nexport function removeInitialSlash(s: string) {\n if (s.startsWith(\"/\"))\n return s.slice(1);\n else return s;\n}\n\nexport function removeTrailingSlash(s: string) {\n if (s.endsWith(\"/\"))\n return s.slice(0, -1);\n else return s;\n}\n","import { unslugify } from \"@firecms/core\";\n\nexport function extractEnumFromValues(values: unknown[]) {\n if (!Array.isArray(values)) {\n return [];\n }\n const enumValues = values\n .map((value) => {\n if (typeof value === \"string\") {\n return ({ id: value, label: unslugify(value) });\n } else\n return null;\n }).filter(Boolean) as Array<{ id: string, label: string }>;\n enumValues.sort((a, b) => a.label.localeCompare(b.label));\n return enumValues;\n}\n","import { FileType, Property, StringProperty } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".png\", \".webp\", \".gif\"];\nconst AUDIO_EXTENSIONS = [\".mp3\", \".ogg\", \".opus\", \".aac\"];\nconst VIDEO_EXTENSIONS = [\".avi\", \".mp4\"];\n\nconst 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])?)*$/;\n\n\nexport function buildStringProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n dataType: \"string\",\n\n };\n\n if (valuesResult) {\n\n const totalEntriesCount = valuesResult.values.length;\n const totalValues = Array.from(valuesResult.valuesCount.keys()).length;\n\n const config: Partial<StringProperty> = {};\n\n const probablyAURL = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n value.toString().startsWith(\"http\")).length > totalDocsCount / 3 * 2;\n if (probablyAURL) {\n config.url = true;\n }\n\n const probablyAnEmail = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n emailRegEx.test(value)).length > totalDocsCount / 3 * 2;\n if (probablyAnEmail) {\n config.email = true;\n }\n\n const probablyUserIds = valuesResult.values\n .filter((value) => typeof value === \"string\" && value.length === 28 && !value.includes(\" \"))\n .length > totalDocsCount / 3 * 2;\n if (probablyUserIds)\n config.readOnly = true;\n\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n totalValues < totalEntriesCount / 3\n ) {\n const enumValues = extractEnumFromValues(Array.from(valuesResult.valuesCount.keys()));\n\n if (Object.keys(enumValues).length > 1)\n config.enumValues = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enumValues) {\n const fileType = probableFileType(valuesResult, totalDocsCount);\n if (fileType) {\n config.storage = {\n acceptedFiles: [fileType as FileType],\n storagePath: findCommonInitialStringInPath(valuesResult) ?? \"/\"\n };\n }\n }\n\n if (Object.keys(config).length > 0)\n stringProperty = {\n ...stringProperty,\n ...config,\n editable: true\n };\n }\n\n return stringProperty;\n}\n\n// TODO: support returning multiple types\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): boolean | FileType {\n const probablyAnImage = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyAudio = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyVideo = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const fileType: boolean | FileType = probablyAnImage\n ? \"image/*\"\n : probablyAudio\n ? \"audio/*\"\n : probablyVideo ? \"video/*\" : false;\n return fileType;\n}\n","import { PropertyValidationSchema } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { InferencePropertyBuilderProps } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { Property } from \"@firecms/core\";\n\nexport function buildReferenceProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n dataType: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\",\n editable: true\n };\n\n return property;\n}\n","import {\n DataType,\n EnumValues,\n mergeDeep,\n Properties,\n Property,\n resolveEnumValues,\n StringProperty\n} from \"@firecms/core\";\nimport {\n InferencePropertyBuilderProps,\n TypesCount,\n TypesCountRecord,\n ValuesCountEntry,\n ValuesCountRecord\n} from \"./types\";\nimport { buildStringProperty } from \"./builders/string_property_builder\";\nimport { buildValidation } from \"./builders/validation_builder\";\nimport { buildReferenceProperty } from \"./builders/reference_property_builder\";\nimport { extractEnumFromValues } from \"./util\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(data: object[], getType: InferenceTypeBuilder): Promise<Properties> {\n const typesCount: TypesCountRecord = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n if (entry) {\n Object.entries(entry).forEach(([key, value]) => {\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n })\n }\n });\n }\n // console.log(util.inspect({ typesCount }, { showHidden: false, depth: null, colors: true }));\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(data: any[], property: Property, getType: InferenceTypeBuilder): Property {\n const typesCount = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n increaseTypeCount(property.dataType, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enumValues\" in property ? resolveEnumValues(property[\"enumValues\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enumValues: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\"inferred_prop\", data.length, property.dataType, typesCount, valuesCount[\"inferred_prop\"]);\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(properties: Properties<any>): string [] {\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (k === \"title\" || k === \"name\") return 3;\n if (k.includes(\"title\") || k.includes(\"name\")) return 2;\n if (k.includes(\"image\") || k.includes(\"picture\")) return 1;\n return 0;\n }\n\n const keys = Object.keys(properties);\n keys.sort(); // alphabetically\n keys.sort((a, b) => {\n return propOrder(b) - propOrder(a);\n });\n return keys;\n}\n\n/**\n * @param type\n * @param typesCount\n * @param fieldValue\n * @param getType\n */\nfunction increaseTypeCount(type: DataType, typesCount: TypesCount, fieldValue: any, getType: InferenceTypeBuilder) {\n if (type === \"map\") {\n if (fieldValue) {\n let mapTypesCount = typesCount[type];\n if (!mapTypesCount) {\n mapTypesCount = {};\n typesCount[type] = mapTypesCount;\n }\n Object.entries(fieldValue).forEach(([key, value]) => {\n increaseMapTypeCount(mapTypesCount as TypesCountRecord, key, value, getType);\n })\n }\n } else if (type === \"array\") {\n let arrayTypesCount = typesCount[type];\n if (!arrayTypesCount) {\n arrayTypesCount = {};\n typesCount[type] = arrayTypesCount;\n }\n if (fieldValue && Array.isArray(fieldValue) && fieldValue.length > 0) {\n const arrayType = getMostProbableTypeInArray(fieldValue, getType); // get type of first element\n if (!arrayTypesCount[arrayType]) (arrayTypesCount[arrayType] as number) = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else (typesCount[type] as number)++;\n }\n}\n\nfunction increaseMapTypeCount(\n typesCountRecord: TypesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) { // Check that fieldValue is not null or undefined before proceeding\n const type = getType(fieldValue);\n increaseTypeCount(type, typesCount, fieldValue, getType);\n }\n}\n\nfunction increaseValuesCount(\n typeValuesRecord: ValuesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n\n const dataType = getType(fieldValue);\n\n let valuesRecord: {\n values: any[];\n valuesCount: Map<any, number>;\n map?: ValuesCountRecord;\n } = typeValuesRecord[key];\n\n if (!valuesRecord) {\n valuesRecord = {\n values: [],\n valuesCount: new Map()\n };\n typeValuesRecord[key] = valuesRecord;\n }\n\n if (dataType === \"map\") {\n let mapValuesRecord: ValuesCountRecord | undefined = valuesRecord.map;\n if (!mapValuesRecord) {\n mapValuesRecord = {};\n valuesRecord.map = mapValuesRecord;\n }\n if (fieldValue)\n Object.entries(fieldValue).forEach(([key, value]) => increaseValuesCount(mapValuesRecord as ValuesCountRecord, key, value, getType))\n } else if (dataType === \"array\") {\n if (Array.isArray(fieldValue)) {\n fieldValue.forEach((value) => {\n valuesRecord.values.push(value);\n valuesRecord.valuesCount.set(value, (valuesRecord.valuesCount.get(value) ?? 0) + 1);\n })\n }\n } else {\n if (fieldValue) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\n }\n }\n\n}\n\nfunction getHighestTypesCount(typesCount: TypesCount): number {\n let highestCount = 0;\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue = 0;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n }\n });\n\n return highestCount;\n}\n\nfunction getHighestRecordCount(record: TypesCountRecord): number {\n return Object.entries(record)\n .map(([key, typesCount]) => getHighestTypesCount(typesCount))\n .reduce((a, b) => Math.max(a, b), 0);\n}\n\nfunction getMostProbableType(typesCount: TypesCount): DataType {\n let highestCount = -1;\n let probableType: DataType = \"string\"; //default\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n probableType = type as DataType;\n }\n });\n return probableType;\n}\n\nfunction buildPropertyFromCount(key: string, totalDocsCount: number, mostProbableType: DataType, typesCount: TypesCount, valuesResult?: ValuesCountEntry): Property {\n let title: string | undefined;\n\n if (key) {\n title = formatString(key.toLowerCase());\n }\n\n let result: Property | undefined = undefined;\n if (mostProbableType === \"map\") {\n\n const highVariability = checkTypesCountHighVariability(typesCount);\n if (highVariability) {\n result = {\n dataType: \"map\",\n name: title,\n keyValue: true,\n properties: {}\n };\n }\n const properties = buildPropertiesFromCount(totalDocsCount, typesCount.map as TypesCountRecord, valuesResult ? valuesResult.mapValues : undefined);\n result = {\n dataType: \"map\",\n name: title,\n properties\n };\n } else if (mostProbableType === \"array\") {\n const arrayTypesCount = typesCount.array as TypesCount;\n const arrayMostProbableType = getMostProbableType(arrayTypesCount);\n const of = buildPropertyFromCount(key, totalDocsCount, arrayMostProbableType, arrayTypesCount, valuesResult);\n result = {\n dataType: \"array\",\n name: title,\n of\n };\n }\n if (!result) {\n const propertyProps: InferencePropertyBuilderProps = {\n name: key,\n totalDocsCount,\n valuesResult\n };\n if (mostProbableType === \"string\") {\n result = buildStringProperty(propertyProps);\n } else if (mostProbableType === \"reference\") {\n result = buildReferenceProperty(propertyProps);\n } else {\n result = {\n dataType: mostProbableType\n } as Property;\n }\n\n if (title) {\n result.name = title;\n }\n\n const validation = buildValidation(propertyProps);\n if (validation) {\n result.validation = validation;\n }\n }\n\n return {\n ...result,\n editable: true\n };\n}\n\nfunction buildPropertiesFromCount(totalDocsCount: number, typesCountRecord: TypesCountRecord, valuesCountRecord?: ValuesCountRecord): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesCountRecord ? valuesCountRecord[key] : undefined);\n })\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\n // console.log(util.inspect({ type, value }, { showHidden: false, depth: null, colors: true }));\n if (typeof value === \"object\") {\n count = Math.max(count, countMaxDocumentsUnder(value as TypesCountRecord));\n } else {\n count = Math.max(count, value as number);\n }\n });\n return count;\n}\n\nfunction getMostProbableTypeInArray(array: any[], getType: InferenceTypeBuilder): DataType {\n let typesCount: TypesCount = {};\n array.forEach((value) => {\n increaseTypeCount(getType(value), typesCount, value, getType);\n });\n return getMostProbableType(typesCount);\n}\n\nfunction checkTypesCountHighVariability(typesCount: TypesCount) {\n const maxCount = countMaxDocumentsUnder(typesCount);\n let keysWithFewValues = 0;\n Object.entries(typesCount.map ?? {})\n .forEach(([key, value]) => {\n const count = countMaxDocumentsUnder(value);\n if (count < maxCount / 3) {\n keysWithFewValues++;\n }\n });\n return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;\n}\n\nfunction formatString(input: string): string {\n const normalized = input\n .replace(/[_\\-]+/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n\n // Split the normalized string into words\n const words = normalized.split(\" \");\n\n // Capitalize the first letter of each word and join them with a space\n const formatted = words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return formatted;\n}\n\nexport function inferTypeFromValue(value: any): DataType {\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\") return \"map\";\n return \"string\";\n}\n\n"],"names":["findCommonInitialStringInPath","valuesCount","getPath","value","DocumentReference","pathWithSlash","v","s","searchedPath","path","extractEnumFromValues","values","enumValues","unslugify","a","b","IMAGE_EXTENSIONS","AUDIO_EXTENSIONS","VIDEO_EXTENSIONS","emailRegEx","buildStringProperty","totalDocsCount","valuesResult","stringProperty","totalEntriesCount","totalValues","config","probablyAURL","probablyAnEmail","probablyUserIds","fileType","probableFileType","probablyAnImage","extension","probablyAudio","probablyVideo","buildValidation","buildReferenceProperty","buildEntityPropertiesFromData","data","getType","typesCount","entry","key","increaseMapTypeCount","increaseValuesCount","buildPropertiesFromCount","buildPropertyFromData","property","increaseTypeCount","resolveEnumValues","newEnumValues","generatedProperty","buildPropertyFromCount","mergeDeep","buildPropertiesOrder","properties","propOrder","k","keys","type","fieldValue","mapTypesCount","arrayTypesCount","arrayType","getMostProbableTypeInArray","typesCountRecord","typeValuesRecord","dataType","valuesRecord","mapValuesRecord","getHighestTypesCount","highestCount","count","countValue","getHighestRecordCount","record","getMostProbableType","probableType","mostProbableType","title","formatString","result","checkTypesCountHighVariability","arrayMostProbableType","of","propertyProps","validation","valuesCountRecord","res","countMaxDocumentsUnder","array","maxCount","keysWithFewValues","input","word","inferTypeFromValue"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(u,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("@firecms/core"),require("firebase/firestore")):typeof define=="function"&&define.amd?define(["exports","@firecms/core","firebase/firestore"],l):(u=typeof globalThis<"u"?globalThis:u||self,l(u["FireCMS schema inference"]={},u.core,u.firestore))})(this,function(u,l,j){"use strict";function E(r){if(!r)return;function e(i){return typeof i=="string"?i:i instanceof j.DocumentReference?i.path:void 0}const s=r.values.map(i=>e(i)).filter(i=>!!i).find(i=>i.includes("/"));if(!s)return;const n=s.substr(0,s.lastIndexOf("/"));return r.values.filter(i=>{const a=e(i);return a?a.startsWith(n):!1}).length>r.values.length/3*2?n:void 0}function p(r){if(!Array.isArray(r))return[];const e=r.map(t=>typeof t=="string"?{id:t,label:l.unslugify(t)}:null).filter(Boolean);return e.sort((t,s)=>t.label.localeCompare(s.label)),e}const P=[".jpg",".png",".webp",".gif"],S=[".mp3",".ogg",".opus",".aac"],C=[".avi",".mp4"],F=/^[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])?)*$/;function I({totalDocsCount:r,valuesResult:e}){let t={dataType:"string"};if(e){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;i&&(o.url=!0);const a=e.values.filter(f=>typeof f=="string"&&F.test(f)).length>r/3*2;a&&(o.email=!0);const c=e.values.filter(f=>typeof f=="string"&&f.length===28&&!f.includes(" ")).length>r/3*2;if(c&&(o.readOnly=!0),!a&&!i&&!c&&!i&&n<s/3){const f=p(Array.from(e.valuesCount.keys()));Object.keys(f).length>1&&(o.enumValues=f)}if(!a&&!i&&!c&&!i&&!o.enumValues){const f=M(e,r);f&&(o.storage={acceptedFiles:[f],storagePath:E(e)??"/"})}Object.keys(o).length>0&&(t={...t,...o,editable:!0})}return t}function M(r,e){const t=r.values.filter(i=>typeof i=="string"&&P.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"&&C.some(a=>i.toString().endsWith(a))).length>e/3*2;return t?"image/*":s?"audio/*":n?"video/*":!1}function z({totalDocsCount:r,valuesResult:e}){if(e){const t=e.values.length;if(r===t)return{required:!0}}}function V({totalDocsCount:r,valuesResult:e}){return{dataType:"reference",path:E(e)??"!!!FIX_ME!!!",editable:!0}}async function _(r,e){const t={},s={};return r&&r.forEach(n=>{n&&Object.entries(n).forEach(([o,i])=>{A(t,o,i,e),h(s,o,i,e)})}),T(r.length,t,s)}function w(r,e,t){const s={},n={};r&&r.forEach(a=>{m(e.dataType,s,a,t),h(n,"inferred_prop",a,t)});const o="enumValues"in e?l.resolveEnumValues(e.enumValues):void 0;if(o){const a=p(Array.from(n.inferred_prop.valuesCount.keys()));return{...e,enumValues:[...a,...o]}}const i=b("inferred_prop",r.length,e.dataType,s,n.inferred_prop);return l.mergeDeep(i,e)}function x(r){function e(s){const n=s.toLowerCase();return n==="title"||n==="name"?3:n.includes("title")||n.includes("name")?2:n.includes("image")||n.includes("picture")?1:0}const t=Object.keys(r);return t.sort(),t.sort((s,n)=>e(n)-e(s)),t}function m(r,e,t,s){if(r==="map"){if(t){let n=e[r];n||(n={},e[r]=n),Object.entries(t).forEach(([o,i])=>{A(n,o,i,s)})}}else if(r==="array"){let n=e[r];if(n||(n={},e[r]=n),t&&Array.isArray(t)&&t.length>0){const o=Z(t,s);n[o]?n[o]++:n[o]=1}}else e[r]?e[r]++:e[r]=1}function A(r,e,t,s){let n=r[e];if(n||(n={},r[e]=n),t!=null){const o=s(t);m(o,n,t,s)}}function h(r,e,t,s){const n=s(t);let o=r[e];if(o||(o={values:[],valuesCount:new Map},r[e]=o),n==="map"){let i=o.map;i||(i={},o.map=i),t&&Object.entries(t).forEach(([a,c])=>h(i,a,c,s))}else n==="array"?Array.isArray(t)&&t.forEach(i=>{o.values.push(i),o.valuesCount.set(i,(o.valuesCount.get(i)??0)+1)}):t&&(o.values.push(t),o.valuesCount.set(t,(o.valuesCount.get(t)??0)+1))}function d(r){let e=0;return Object.entries(r).forEach(([t,s])=>{let n=0;t==="map"?n=O(s):t==="array"?n=d(s):n=s,n>e&&(e=n)}),e}function O(r){return Object.entries(r).map(([e,t])=>d(t)).reduce((e,t)=>Math.max(e,t),0)}function g(r){let e=-1,t="string";return Object.entries(r).forEach(([s,n])=>{let o;s==="map"?o=O(n):s==="array"?o=d(n):o=n,o>e&&(e=o,t=s)}),t}function b(r,e,t,s,n){let o;r&&(o=N(r.toLowerCase()));let i;if(t==="map"){W(s)&&(i={dataType:"map",name:o,keyValue:!0,properties:{}});const c=T(e,s.map,n?n.mapValues:void 0);i={dataType:"map",name:o,properties:c}}else if(t==="array"){const a=s.array,c=g(a),f=b(r,e,c,a,n);i={dataType:"array",name:o,of:f}}if(!i){const a={name:r,totalDocsCount:e,valuesResult:n};t==="string"?i=I(a):t==="reference"?i=V(a):i={dataType:t},o&&(i.name=o);const c=z(a);c&&(i.validation=c)}return{...i,editable:!0}}function T(r,e,t){const s={};return Object.entries(e).forEach(([n,o])=>{const i=g(o);s[n]=b(n,r,i,o,t?t[n]:void 0)}),s}function y(r){let e=0;return Object.entries(r).forEach(([t,s])=>{typeof s=="object"?e=Math.max(e,y(s)):e=Math.max(e,s)}),e}function Z(r,e){let t={};return r.forEach(s=>{m(e(s),t,s,e)}),g(t)}function W(r){const e=y(r);let t=0;return Object.entries(r.map??{}).forEach(([s,n])=>{y(n)<e/3&&t++}),t/Object.entries(r.map??{}).length>.5}function N(r){return r.replace(/[_\-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").toLowerCase().split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}u.buildEntityPropertiesFromData=_,u.buildPropertiesOrder=x,u.buildPropertyFromData=w,u.extractEnumFromValues=p,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
1
+ (function(c,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("@firecms/core"),require("firebase/firestore")):typeof define=="function"&&define.amd?define(["exports","@firecms/core","firebase/firestore"],l):(c=typeof globalThis<"u"?globalThis:c||self,l(c["FireCMS schema inference"]={},c.core,c.firestore))})(this,function(c,l,j){"use strict";function E(r){if(!r)return;function e(i){return typeof i=="string"?i:i instanceof j.DocumentReference?i.path:void 0}const s=r.values.map(i=>e(i)).filter(i=>!!i).find(i=>i.includes("/"));if(!s)return;const n=s.substr(0,s.lastIndexOf("/"));return r.values.filter(i=>{const a=e(i);return a?a.startsWith(n):!1}).length>r.values.length/3*2?n:void 0}function p(r){if(!Array.isArray(r))return[];const e=r.map(t=>typeof t=="string"?{id:t,label:l.unslugify(t)}:null).filter(Boolean);return e.sort((t,s)=>t.label.localeCompare(s.label)),e}const P=[".jpg",".png",".webp",".gif"],S=[".mp3",".ogg",".opus",".aac"],F=[".avi",".mp4"],C=/^[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])?)*$/;function I({totalDocsCount:r,valuesResult:e}){let t={dataType:"string"};if(e){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;i&&(o.url=!0);const a=e.values.filter(f=>typeof f=="string"&&C.test(f)).length>r/3*2;a&&(o.email=!0);const u=e.values.filter(f=>typeof f=="string"&&f.length===28&&!f.includes(" ")).length>r/3*2;if(u&&(o.readOnly=!0),!a&&!i&&!u&&!i&&n<s/3){const f=p(Array.from(e.valuesCount.keys()));Object.keys(f).length>1&&(o.enumValues=f)}if(!a&&!i&&!u&&!i&&!o.enumValues){const f=M(e,r);f&&(o.storage={acceptedFiles:[f],storagePath:E(e)??"/"})}Object.keys(o).length>0&&(t={...t,...o,editable:!0})}return t}function M(r,e){const t=r.values.filter(i=>typeof i=="string"&&P.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"&&F.some(a=>i.toString().endsWith(a))).length>e/3*2;return t?"image/*":s?"audio/*":n?"video/*":!1}function V({totalDocsCount:r,valuesResult:e}){if(e){const t=e.values.length;if(r===t)return{required:!0}}}function z({totalDocsCount:r,valuesResult:e}){return{dataType:"reference",path:E(e)??"!!!FIX_ME!!!",editable:!0}}async function _(r,e){const t={},s={};return r&&r.forEach(n=>{n&&Object.entries(n).forEach(([o,i])=>{A(t,o,i,e),h(s,o,i,e)})}),T(r.length,t,s)}function w(r,e,t){const s={},n={};r&&r.forEach(a=>{m(e.dataType,s,a,t),h(n,"inferred_prop",a,t)});const o="enumValues"in e?l.resolveEnumValues(e.enumValues):void 0;if(o){const a=p(Array.from(n.inferred_prop.valuesCount.keys()));return{...e,enumValues:[...a,...o]}}const i=y("inferred_prop",r.length,e.dataType,s,n.inferred_prop);return l.mergeDeep(i,e)}function Z(r){function e(s){const n=s.toLowerCase();return n==="title"||n==="name"?3:n.includes("title")||n.includes("name")?2:n.includes("image")||n.includes("picture")?1:0}const t=Object.keys(r);return t.sort(),t.sort((s,n)=>e(n)-e(s)),t}function m(r,e,t,s){if(r==="map"){if(t){let n=e[r];n||(n={},e[r]=n),Object.entries(t).forEach(([o,i])=>{A(n,o,i,s)})}}else if(r==="array"){let n=e[r];if(n||(n={},e[r]=n),t&&Array.isArray(t)&&t.length>0){const o=x(t,s);n[o]?n[o]++:n[o]=1}}else e[r]?e[r]++:e[r]=1}function A(r,e,t,s){let n=r[e];if(n||(n={},r[e]=n),t!=null){const o=s(t);m(o,n,t,s)}}function h(r,e,t,s){const n=s(t);let o=r[e];if(o||(o={values:[],valuesCount:new Map},r[e]=o),n==="map"){let i=o.map;i||(i={},o.map=i),t&&Object.entries(t).forEach(([a,u])=>h(i,a,u,s))}else n==="array"?Array.isArray(t)&&t.forEach(i=>{o.values.push(i),o.valuesCount.set(i,(o.valuesCount.get(i)??0)+1)}):t&&(o.values.push(t),o.valuesCount.set(t,(o.valuesCount.get(t)??0)+1))}function g(r){let e=0;return Object.entries(r).forEach(([t,s])=>{let n=0;t==="map"?n=O(s):t==="array"?n=g(s):n=s,n>e&&(e=n)}),e}function O(r){return Object.entries(r).map(([e,t])=>g(t)).reduce((e,t)=>Math.max(e,t),0)}function d(r){let e=-1,t="string";return Object.entries(r).forEach(([s,n])=>{let o;s==="map"?o=O(n):s==="array"?o=g(n):o=n,o>e&&(e=o,t=s)}),t}function y(r,e,t,s,n){let o;r&&(o=N(r.toLowerCase()));let i;if(t==="map"){W(s)&&(i={dataType:"map",name:o,keyValue:!0,properties:{}});const u=T(e,s.map,n?n.mapValues:void 0);i={dataType:"map",name:o,properties:u}}else if(t==="array"){const a=s.array,u=d(a),f=y(r,e,u,a,n);i={dataType:"array",name:o,of:f}}if(!i){const a={name:r,totalDocsCount:e,valuesResult:n};t==="string"?i=I(a):t==="reference"?i=z(a):i={dataType:t},o&&(i.name=o);const u=V(a);u&&(i.validation=u)}return{...i,editable:!0}}function T(r,e,t){const s={};return Object.entries(e).forEach(([n,o])=>{const i=d(o);s[n]=y(n,r,i,o,t?t[n]:void 0)}),s}function b(r){let e=0;return Object.entries(r).forEach(([t,s])=>{typeof s=="object"?e=Math.max(e,b(s)):e=Math.max(e,s)}),e}function x(r,e){let t={};return r.forEach(s=>{m(e(s),t,s,e)}),d(t)}function W(r){const e=b(r);let t=0;return Object.entries(r.map??{}).forEach(([s,n])=>{b(n)<e/3&&t++}),t/Object.entries(r.map??{}).length>.5}function N(r){return r.replace(/[_\-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").toLowerCase().split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function k(r){return typeof r=="string"?"string":typeof r=="number"?"number":typeof r=="boolean"?"boolean":Array.isArray(r)?"array":typeof r=="object"?"map":"string"}c.buildEntityPropertiesFromData=_,c.buildPropertiesOrder=Z,c.buildPropertyFromData=w,c.extractEnumFromValues=p,c.inferTypeFromValue=k,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/strings.ts","../src/util.ts","../src/builders/string_property_builder.ts","../src/builders/validation_builder.ts","../src/builders/reference_property_builder.ts","../src/collection_builder.ts"],"sourcesContent":["import { ValuesCountEntry } from \"./types\";\nimport { DocumentReference } from \"firebase/firestore\";\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any) {\n if (typeof value === \"string\") return value;\n else if (value instanceof DocumentReference) return value.path;\n else return undefined;\n }\n\n const strings: string[] = valuesCount.values.map((v) => getPath(v)).filter(v => !!v) as string[];\n const pathWithSlash = strings.find((s) => s.includes(\"/\"));\n if (!pathWithSlash)\n return undefined;\n\n const searchedPath = pathWithSlash.substr(0, pathWithSlash.lastIndexOf(\"/\"));\n\n const yep = valuesCount.values\n .filter((value) => {\n const path = getPath(value);\n if (!path) return false;\n return path.startsWith(searchedPath)\n }).length > valuesCount.values.length / 3 * 2;\n\n return yep ? searchedPath : undefined;\n\n}\n\nexport function removeInitialAndTrailingSlashes(s: string): string {\n return removeInitialSlash(removeTrailingSlash(s));\n}\n\nexport function removeInitialSlash(s: string) {\n if (s.startsWith(\"/\"))\n return s.slice(1);\n else return s;\n}\n\nexport function removeTrailingSlash(s: string) {\n if (s.endsWith(\"/\"))\n return s.slice(0, -1);\n else return s;\n}\n","import { unslugify } from \"@firecms/core\";\n\nexport function extractEnumFromValues(values: unknown[]) {\n if (!Array.isArray(values)) {\n return [];\n }\n const enumValues = values\n .map((value) => {\n if (typeof value === \"string\") {\n return ({ id: value, label: unslugify(value) });\n } else\n return null;\n }).filter(Boolean) as Array<{ id: string, label: string }>;\n enumValues.sort((a, b) => a.label.localeCompare(b.label));\n return enumValues;\n}\n","import { FileType, Property, StringProperty } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".png\", \".webp\", \".gif\"];\nconst AUDIO_EXTENSIONS = [\".mp3\", \".ogg\", \".opus\", \".aac\"];\nconst VIDEO_EXTENSIONS = [\".avi\", \".mp4\"];\n\nconst 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])?)*$/;\n\n\nexport function buildStringProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n dataType: \"string\",\n\n };\n\n if (valuesResult) {\n\n const totalEntriesCount = valuesResult.values.length;\n const totalValues = Array.from(valuesResult.valuesCount.keys()).length;\n\n const config: Partial<StringProperty> = {};\n\n const probablyAURL = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n value.toString().startsWith(\"http\")).length > totalDocsCount / 3 * 2;\n if (probablyAURL) {\n config.url = true;\n }\n\n const probablyAnEmail = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n emailRegEx.test(value)).length > totalDocsCount / 3 * 2;\n if (probablyAnEmail) {\n config.email = true;\n }\n\n const probablyUserIds = valuesResult.values\n .filter((value) => typeof value === \"string\" && value.length === 28 && !value.includes(\" \"))\n .length > totalDocsCount / 3 * 2;\n if (probablyUserIds)\n config.readOnly = true;\n\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n totalValues < totalEntriesCount / 3\n ) {\n const enumValues = extractEnumFromValues(Array.from(valuesResult.valuesCount.keys()));\n\n if (Object.keys(enumValues).length > 1)\n config.enumValues = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enumValues) {\n const fileType = probableFileType(valuesResult, totalDocsCount);\n if (fileType) {\n config.storage = {\n acceptedFiles: [fileType as FileType],\n storagePath: findCommonInitialStringInPath(valuesResult) ?? \"/\"\n };\n }\n }\n\n if (Object.keys(config).length > 0)\n stringProperty = {\n ...stringProperty,\n ...config,\n editable: true\n };\n }\n\n return stringProperty;\n}\n\n// TODO: support returning multiple types\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): boolean | FileType {\n const probablyAnImage = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyAudio = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyVideo = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const fileType: boolean | FileType = probablyAnImage\n ? \"image/*\"\n : probablyAudio\n ? \"audio/*\"\n : probablyVideo ? \"video/*\" : false;\n return fileType;\n}\n","import { PropertyValidationSchema } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { InferencePropertyBuilderProps } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { Property } from \"@firecms/core\";\n\nexport function buildReferenceProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n dataType: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\",\n editable: true\n };\n\n return property;\n}\n","import {\n DataType,\n EnumValues,\n mergeDeep,\n Properties,\n Property,\n resolveEnumValues,\n StringProperty, toKebabCase,\n unslugify\n} from \"@firecms/core\";\nimport {\n InferencePropertyBuilderProps,\n TypesCount,\n TypesCountRecord,\n ValuesCountEntry,\n ValuesCountRecord\n} from \"./types\";\nimport { buildStringProperty } from \"./builders/string_property_builder\";\nimport { buildValidation } from \"./builders/validation_builder\";\nimport { buildReferenceProperty } from \"./builders/reference_property_builder\";\nimport { extractEnumFromValues } from \"./util\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(data: object[], getType: InferenceTypeBuilder): Promise<Properties> {\n const typesCount: TypesCountRecord = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n if (entry) {\n Object.entries(entry).forEach(([key, value]) => {\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n })\n }\n });\n }\n // console.log(util.inspect({ typesCount }, { showHidden: false, depth: null, colors: true }));\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(data: any[], property: Property, getType: InferenceTypeBuilder): Property {\n const typesCount = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n increaseTypeCount(property.dataType, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enumValues\" in property ? resolveEnumValues(property[\"enumValues\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enumValues: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\"inferred_prop\", data.length, property.dataType, typesCount, valuesCount[\"inferred_prop\"]);\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(properties: Properties<any>): string [] {\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (k === \"title\" || k === \"name\") return 3;\n if (k.includes(\"title\") || k.includes(\"name\")) return 2;\n if (k.includes(\"image\") || k.includes(\"picture\")) return 1;\n return 0;\n }\n\n const keys = Object.keys(properties);\n keys.sort(); // alphabetically\n keys.sort((a, b) => {\n return propOrder(b) - propOrder(a);\n });\n return keys;\n}\n\n/**\n * @param type\n * @param typesCount\n * @param fieldValue\n * @param getType\n */\nfunction increaseTypeCount(type: DataType, typesCount: TypesCount, fieldValue: any, getType: InferenceTypeBuilder) {\n if (type === \"map\") {\n if (fieldValue) {\n let mapTypesCount = typesCount[type];\n if (!mapTypesCount) {\n mapTypesCount = {};\n typesCount[type] = mapTypesCount;\n }\n Object.entries(fieldValue).forEach(([key, value]) => {\n increaseMapTypeCount(mapTypesCount as TypesCountRecord, key, value, getType);\n })\n }\n } else if (type === \"array\") {\n let arrayTypesCount = typesCount[type];\n if (!arrayTypesCount) {\n arrayTypesCount = {};\n typesCount[type] = arrayTypesCount;\n }\n if (fieldValue && Array.isArray(fieldValue) && fieldValue.length > 0) {\n const arrayType = getMostProbableTypeInArray(fieldValue, getType); // get type of first element\n if (!arrayTypesCount[arrayType]) (arrayTypesCount[arrayType] as number) = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else (typesCount[type] as number)++;\n }\n}\n\nfunction increaseMapTypeCount(\n typesCountRecord: TypesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) { // Check that fieldValue is not null or undefined before proceeding\n const type = getType(fieldValue);\n increaseTypeCount(type, typesCount, fieldValue, getType);\n }\n}\n\nfunction increaseValuesCount(\n typeValuesRecord: ValuesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n\n const dataType = getType(fieldValue);\n\n let valuesRecord: {\n values: any[];\n valuesCount: Map<any, number>;\n map?: ValuesCountRecord;\n } = typeValuesRecord[key];\n\n if (!valuesRecord) {\n valuesRecord = {\n values: [],\n valuesCount: new Map()\n };\n typeValuesRecord[key] = valuesRecord;\n }\n\n if (dataType === \"map\") {\n let mapValuesRecord: ValuesCountRecord | undefined = valuesRecord.map;\n if (!mapValuesRecord) {\n mapValuesRecord = {};\n valuesRecord.map = mapValuesRecord;\n }\n if (fieldValue)\n Object.entries(fieldValue).forEach(([key, value]) => increaseValuesCount(mapValuesRecord as ValuesCountRecord, key, value, getType))\n } else if (dataType === \"array\") {\n if (Array.isArray(fieldValue)) {\n fieldValue.forEach((value) => {\n valuesRecord.values.push(value);\n valuesRecord.valuesCount.set(value, (valuesRecord.valuesCount.get(value) ?? 0) + 1);\n })\n }\n } else {\n if (fieldValue) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\n }\n }\n\n}\n\nfunction getHighestTypesCount(typesCount: TypesCount): number {\n let highestCount = 0;\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue = 0;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n }\n });\n\n return highestCount;\n}\n\nfunction getHighestRecordCount(record: TypesCountRecord): number {\n return Object.entries(record)\n .map(([key, typesCount]) => getHighestTypesCount(typesCount))\n .reduce((a, b) => Math.max(a, b), 0);\n}\n\nfunction getMostProbableType(typesCount: TypesCount): DataType {\n let highestCount = -1;\n let probableType: DataType = \"string\"; //default\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n probableType = type as DataType;\n }\n });\n return probableType;\n}\n\nfunction buildPropertyFromCount(key: string, totalDocsCount: number, mostProbableType: DataType, typesCount: TypesCount, valuesResult?: ValuesCountEntry): Property {\n let title: string | undefined;\n\n if (key) {\n title = formatString(key.toLowerCase());\n }\n\n let result: Property | undefined = undefined;\n if (mostProbableType === \"map\") {\n\n const highVariability = checkTypesCountHighVariability(typesCount);\n if (highVariability) {\n result = {\n dataType: \"map\",\n name: title,\n keyValue: true,\n properties: {}\n };\n }\n const properties = buildPropertiesFromCount(totalDocsCount, typesCount.map as TypesCountRecord, valuesResult ? valuesResult.mapValues : undefined);\n result = {\n dataType: \"map\",\n name: title,\n properties\n };\n } else if (mostProbableType === \"array\") {\n const arrayTypesCount = typesCount.array as TypesCount;\n const arrayMostProbableType = getMostProbableType(arrayTypesCount);\n const of = buildPropertyFromCount(key, totalDocsCount, arrayMostProbableType, arrayTypesCount, valuesResult);\n result = {\n dataType: \"array\",\n name: title,\n of\n };\n }\n if (!result) {\n const propertyProps: InferencePropertyBuilderProps = {\n name: key,\n totalDocsCount,\n valuesResult\n };\n if (mostProbableType === \"string\") {\n result = buildStringProperty(propertyProps);\n } else if (mostProbableType === \"reference\") {\n result = buildReferenceProperty(propertyProps);\n } else {\n result = {\n dataType: mostProbableType\n } as Property;\n }\n\n if (title) {\n result.name = title;\n }\n\n const validation = buildValidation(propertyProps);\n if (validation) {\n result.validation = validation;\n }\n }\n\n return {\n ...result,\n editable: true\n };\n}\n\nfunction buildPropertiesFromCount(totalDocsCount: number, typesCountRecord: TypesCountRecord, valuesCountRecord?: ValuesCountRecord): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesCountRecord ? valuesCountRecord[key] : undefined);\n })\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\n // console.log(util.inspect({ type, value }, { showHidden: false, depth: null, colors: true }));\n if (typeof value === \"object\") {\n count = Math.max(count, countMaxDocumentsUnder(value as TypesCountRecord));\n } else {\n count = Math.max(count, value as number);\n }\n });\n return count;\n}\n\nfunction getMostProbableTypeInArray(array: any[], getType: InferenceTypeBuilder): DataType {\n let typesCount: TypesCount = {};\n array.forEach((value) => {\n increaseTypeCount(getType(value), typesCount, value, getType);\n });\n return getMostProbableType(typesCount);\n}\n\nfunction checkTypesCountHighVariability(typesCount: TypesCount) {\n const maxCount = countMaxDocumentsUnder(typesCount);\n let keysWithFewValues = 0;\n Object.entries(typesCount.map ?? {})\n .forEach(([key, value]) => {\n const count = countMaxDocumentsUnder(value);\n if (count < maxCount / 3) {\n keysWithFewValues++;\n }\n });\n return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;\n}\n\nfunction formatString(input: string): string {\n const normalized = input\n .replace(/[_\\-]+/g, \" \")\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .toLowerCase();\n\n // Split the normalized string into words\n const words = normalized.split(\" \");\n\n // Capitalize the first letter of each word and join them with a space\n const formatted = words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return formatted;\n}\n\n"],"names":["findCommonInitialStringInPath","valuesCount","getPath","value","DocumentReference","pathWithSlash","v","s","searchedPath","path","extractEnumFromValues","values","enumValues","unslugify","a","b","IMAGE_EXTENSIONS","AUDIO_EXTENSIONS","VIDEO_EXTENSIONS","emailRegEx","buildStringProperty","totalDocsCount","valuesResult","stringProperty","totalEntriesCount","totalValues","config","probablyAURL","probablyAnEmail","probablyUserIds","fileType","probableFileType","probablyAnImage","extension","probablyAudio","probablyVideo","buildValidation","buildReferenceProperty","buildEntityPropertiesFromData","data","getType","typesCount","entry","key","increaseMapTypeCount","increaseValuesCount","buildPropertiesFromCount","buildPropertyFromData","property","increaseTypeCount","resolveEnumValues","newEnumValues","generatedProperty","buildPropertyFromCount","mergeDeep","buildPropertiesOrder","properties","propOrder","k","keys","type","fieldValue","mapTypesCount","arrayTypesCount","arrayType","getMostProbableTypeInArray","typesCountRecord","typeValuesRecord","dataType","valuesRecord","mapValuesRecord","getHighestTypesCount","highestCount","count","countValue","getHighestRecordCount","record","getMostProbableType","probableType","mostProbableType","title","formatString","result","checkTypesCountHighVariability","arrayMostProbableType","of","propertyProps","validation","valuesCountRecord","res","countMaxDocumentsUnder","array","maxCount","keysWithFewValues","input","word"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/strings.ts","../src/util.ts","../src/builders/string_property_builder.ts","../src/builders/validation_builder.ts","../src/builders/reference_property_builder.ts","../src/collection_builder.ts"],"sourcesContent":["import { ValuesCountEntry } from \"./types\";\nimport { DocumentReference } from \"firebase/firestore\";\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any) {\n if (typeof value === \"string\") return value;\n else if (value instanceof DocumentReference) return value.path;\n else return undefined;\n }\n\n const strings: string[] = valuesCount.values.map((v) => getPath(v)).filter(v => !!v) as string[];\n const pathWithSlash = strings.find((s) => s.includes(\"/\"));\n if (!pathWithSlash)\n return undefined;\n\n const searchedPath = pathWithSlash.substr(0, pathWithSlash.lastIndexOf(\"/\"));\n\n const yep = valuesCount.values\n .filter((value) => {\n const path = getPath(value);\n if (!path) return false;\n return path.startsWith(searchedPath)\n }).length > valuesCount.values.length / 3 * 2;\n\n return yep ? searchedPath : undefined;\n\n}\n\nexport function removeInitialAndTrailingSlashes(s: string): string {\n return removeInitialSlash(removeTrailingSlash(s));\n}\n\nexport function removeInitialSlash(s: string) {\n if (s.startsWith(\"/\"))\n return s.slice(1);\n else return s;\n}\n\nexport function removeTrailingSlash(s: string) {\n if (s.endsWith(\"/\"))\n return s.slice(0, -1);\n else return s;\n}\n","import { unslugify } from \"@firecms/core\";\n\nexport function extractEnumFromValues(values: unknown[]) {\n if (!Array.isArray(values)) {\n return [];\n }\n const enumValues = values\n .map((value) => {\n if (typeof value === \"string\") {\n return ({ id: value, label: unslugify(value) });\n } else\n return null;\n }).filter(Boolean) as Array<{ id: string, label: string }>;\n enumValues.sort((a, b) => a.label.localeCompare(b.label));\n return enumValues;\n}\n","import { FileType, Property, StringProperty } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".png\", \".webp\", \".gif\"];\nconst AUDIO_EXTENSIONS = [\".mp3\", \".ogg\", \".opus\", \".aac\"];\nconst VIDEO_EXTENSIONS = [\".avi\", \".mp4\"];\n\nconst 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])?)*$/;\n\n\nexport function buildStringProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n dataType: \"string\",\n\n };\n\n if (valuesResult) {\n\n const totalEntriesCount = valuesResult.values.length;\n const totalValues = Array.from(valuesResult.valuesCount.keys()).length;\n\n const config: Partial<StringProperty> = {};\n\n const probablyAURL = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n value.toString().startsWith(\"http\")).length > totalDocsCount / 3 * 2;\n if (probablyAURL) {\n config.url = true;\n }\n\n const probablyAnEmail = valuesResult.values\n .filter((value) => typeof value === \"string\" &&\n emailRegEx.test(value)).length > totalDocsCount / 3 * 2;\n if (probablyAnEmail) {\n config.email = true;\n }\n\n const probablyUserIds = valuesResult.values\n .filter((value) => typeof value === \"string\" && value.length === 28 && !value.includes(\" \"))\n .length > totalDocsCount / 3 * 2;\n if (probablyUserIds)\n config.readOnly = true;\n\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n totalValues < totalEntriesCount / 3\n ) {\n const enumValues = extractEnumFromValues(Array.from(valuesResult.valuesCount.keys()));\n\n if (Object.keys(enumValues).length > 1)\n config.enumValues = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enumValues) {\n const fileType = probableFileType(valuesResult, totalDocsCount);\n if (fileType) {\n config.storage = {\n acceptedFiles: [fileType as FileType],\n storagePath: findCommonInitialStringInPath(valuesResult) ?? \"/\"\n };\n }\n }\n\n if (Object.keys(config).length > 0)\n stringProperty = {\n ...stringProperty,\n ...config,\n editable: true\n };\n }\n\n return stringProperty;\n}\n\n// TODO: support returning multiple types\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): boolean | FileType {\n const probablyAnImage = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyAudio = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const probablyVideo = valuesCount.values\n .filter((value) => typeof value === \"string\" &&\n VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension))).length > totalDocsCount / 3 * 2;\n\n const fileType: boolean | FileType = probablyAnImage\n ? \"image/*\"\n : probablyAudio\n ? \"audio/*\"\n : probablyVideo ? \"video/*\" : false;\n return fileType;\n}\n","import { PropertyValidationSchema } from \"@firecms/core\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { InferencePropertyBuilderProps } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { Property } from \"@firecms/core\";\n\nexport function buildReferenceProperty({\n totalDocsCount,\n valuesResult\n }: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n dataType: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\",\n editable: true\n };\n\n return property;\n}\n","import {\n DataType,\n EnumValues,\n mergeDeep,\n Properties,\n Property,\n resolveEnumValues,\n StringProperty\n} from \"@firecms/core\";\nimport {\n InferencePropertyBuilderProps,\n TypesCount,\n TypesCountRecord,\n ValuesCountEntry,\n ValuesCountRecord\n} from \"./types\";\nimport { buildStringProperty } from \"./builders/string_property_builder\";\nimport { buildValidation } from \"./builders/validation_builder\";\nimport { buildReferenceProperty } from \"./builders/reference_property_builder\";\nimport { extractEnumFromValues } from \"./util\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(data: object[], getType: InferenceTypeBuilder): Promise<Properties> {\n const typesCount: TypesCountRecord = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n if (entry) {\n Object.entries(entry).forEach(([key, value]) => {\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n })\n }\n });\n }\n // console.log(util.inspect({ typesCount }, { showHidden: false, depth: null, colors: true }));\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(data: any[], property: Property, getType: InferenceTypeBuilder): Property {\n const typesCount = {};\n const valuesCount: ValuesCountRecord = {};\n if (data) {\n data.forEach((entry) => {\n increaseTypeCount(property.dataType, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enumValues\" in property ? resolveEnumValues(property[\"enumValues\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enumValues: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\"inferred_prop\", data.length, property.dataType, typesCount, valuesCount[\"inferred_prop\"]);\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(properties: Properties<any>): string [] {\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (k === \"title\" || k === \"name\") return 3;\n if (k.includes(\"title\") || k.includes(\"name\")) return 2;\n if (k.includes(\"image\") || k.includes(\"picture\")) return 1;\n return 0;\n }\n\n const keys = Object.keys(properties);\n keys.sort(); // alphabetically\n keys.sort((a, b) => {\n return propOrder(b) - propOrder(a);\n });\n return keys;\n}\n\n/**\n * @param type\n * @param typesCount\n * @param fieldValue\n * @param getType\n */\nfunction increaseTypeCount(type: DataType, typesCount: TypesCount, fieldValue: any, getType: InferenceTypeBuilder) {\n if (type === \"map\") {\n if (fieldValue) {\n let mapTypesCount = typesCount[type];\n if (!mapTypesCount) {\n mapTypesCount = {};\n typesCount[type] = mapTypesCount;\n }\n Object.entries(fieldValue).forEach(([key, value]) => {\n increaseMapTypeCount(mapTypesCount as TypesCountRecord, key, value, getType);\n })\n }\n } else if (type === \"array\") {\n let arrayTypesCount = typesCount[type];\n if (!arrayTypesCount) {\n arrayTypesCount = {};\n typesCount[type] = arrayTypesCount;\n }\n if (fieldValue && Array.isArray(fieldValue) && fieldValue.length > 0) {\n const arrayType = getMostProbableTypeInArray(fieldValue, getType); // get type of first element\n if (!arrayTypesCount[arrayType]) (arrayTypesCount[arrayType] as number) = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else (typesCount[type] as number)++;\n }\n}\n\nfunction increaseMapTypeCount(\n typesCountRecord: TypesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) { // Check that fieldValue is not null or undefined before proceeding\n const type = getType(fieldValue);\n increaseTypeCount(type, typesCount, fieldValue, getType);\n }\n}\n\nfunction increaseValuesCount(\n typeValuesRecord: ValuesCountRecord,\n key: string,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\n\n const dataType = getType(fieldValue);\n\n let valuesRecord: {\n values: any[];\n valuesCount: Map<any, number>;\n map?: ValuesCountRecord;\n } = typeValuesRecord[key];\n\n if (!valuesRecord) {\n valuesRecord = {\n values: [],\n valuesCount: new Map()\n };\n typeValuesRecord[key] = valuesRecord;\n }\n\n if (dataType === \"map\") {\n let mapValuesRecord: ValuesCountRecord | undefined = valuesRecord.map;\n if (!mapValuesRecord) {\n mapValuesRecord = {};\n valuesRecord.map = mapValuesRecord;\n }\n if (fieldValue)\n Object.entries(fieldValue).forEach(([key, value]) => increaseValuesCount(mapValuesRecord as ValuesCountRecord, key, value, getType))\n } else if (dataType === \"array\") {\n if (Array.isArray(fieldValue)) {\n fieldValue.forEach((value) => {\n valuesRecord.values.push(value);\n valuesRecord.valuesCount.set(value, (valuesRecord.valuesCount.get(value) ?? 0) + 1);\n })\n }\n } else {\n if (fieldValue) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\n }\n }\n\n}\n\nfunction getHighestTypesCount(typesCount: TypesCount): number {\n let highestCount = 0;\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue = 0;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n }\n });\n\n return highestCount;\n}\n\nfunction getHighestRecordCount(record: TypesCountRecord): number {\n return Object.entries(record)\n .map(([key, typesCount]) => getHighestTypesCount(typesCount))\n .reduce((a, b) => Math.max(a, b), 0);\n}\n\nfunction getMostProbableType(typesCount: TypesCount): DataType {\n let highestCount = -1;\n let probableType: DataType = \"string\"; //default\n Object.entries(typesCount).forEach(([type, count]) => {\n let countValue;\n if (type === \"map\") {\n countValue = getHighestRecordCount(count as TypesCountRecord);\n } else if (type === \"array\") {\n countValue = getHighestTypesCount(count as TypesCount);\n } else {\n countValue = count as number;\n }\n if (countValue > highestCount) {\n highestCount = countValue;\n probableType = type as DataType;\n }\n });\n return probableType;\n}\n\nfunction buildPropertyFromCount(key: string, totalDocsCount: number, mostProbableType: DataType, typesCount: TypesCount, valuesResult?: ValuesCountEntry): Property {\n let title: string | undefined;\n\n if (key) {\n title = formatString(key.toLowerCase());\n }\n\n let result: Property | undefined = undefined;\n if (mostProbableType === \"map\") {\n\n const highVariability = checkTypesCountHighVariability(typesCount);\n if (highVariability) {\n result = {\n dataType: \"map\",\n name: title,\n keyValue: true,\n properties: {}\n };\n }\n const properties = buildPropertiesFromCount(totalDocsCount, typesCount.map as TypesCountRecord, valuesResult ? valuesResult.mapValues : undefined);\n result = {\n dataType: \"map\",\n name: title,\n properties\n };\n } else if (mostProbableType === \"array\") {\n const arrayTypesCount = typesCount.array as TypesCount;\n const arrayMostProbableType = getMostProbableType(arrayTypesCount);\n const of = buildPropertyFromCount(key, totalDocsCount, arrayMostProbableType, arrayTypesCount, valuesResult);\n result = {\n dataType: \"array\",\n name: title,\n of\n };\n }\n if (!result) {\n const propertyProps: InferencePropertyBuilderProps = {\n name: key,\n totalDocsCount,\n valuesResult\n };\n if (mostProbableType === \"string\") {\n result = buildStringProperty(propertyProps);\n } else if (mostProbableType === \"reference\") {\n result = buildReferenceProperty(propertyProps);\n } else {\n result = {\n dataType: mostProbableType\n } as Property;\n }\n\n if (title) {\n result.name = title;\n }\n\n const validation = buildValidation(propertyProps);\n if (validation) {\n result.validation = validation;\n }\n }\n\n return {\n ...result,\n editable: true\n };\n}\n\nfunction buildPropertiesFromCount(totalDocsCount: number, typesCountRecord: TypesCountRecord, valuesCountRecord?: ValuesCountRecord): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesCountRecord ? valuesCountRecord[key] : undefined);\n })\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\n // console.log(util.inspect({ type, value }, { showHidden: false, depth: null, colors: true }));\n if (typeof value === \"object\") {\n count = Math.max(count, countMaxDocumentsUnder(value as TypesCountRecord));\n } else {\n count = Math.max(count, value as number);\n }\n });\n return count;\n}\n\nfunction getMostProbableTypeInArray(array: any[], getType: InferenceTypeBuilder): DataType {\n let typesCount: TypesCount = {};\n array.forEach((value) => {\n increaseTypeCount(getType(value), typesCount, value, getType);\n });\n return getMostProbableType(typesCount);\n}\n\nfunction checkTypesCountHighVariability(typesCount: TypesCount) {\n const maxCount = countMaxDocumentsUnder(typesCount);\n let keysWithFewValues = 0;\n Object.entries(typesCount.map ?? {})\n .forEach(([key, value]) => {\n const count = countMaxDocumentsUnder(value);\n if (count < maxCount / 3) {\n keysWithFewValues++;\n }\n });\n return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;\n}\n\nfunction formatString(input: string): string {\n const normalized = input\n .replace(/[_\\-]+/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .toLowerCase();\n\n // Split the normalized string into words\n const words = normalized.split(\" \");\n\n // Capitalize the first letter of each word and join them with a space\n const formatted = words\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return formatted;\n}\n\nexport function inferTypeFromValue(value: any): DataType {\n if (typeof value === \"string\") return \"string\";\n if (typeof value === \"number\") return \"number\";\n if (typeof value === \"boolean\") return \"boolean\";\n if (Array.isArray(value)) return \"array\";\n if (typeof value === \"object\") return \"map\";\n return \"string\";\n}\n\n"],"names":["findCommonInitialStringInPath","valuesCount","getPath","value","DocumentReference","pathWithSlash","v","s","searchedPath","path","extractEnumFromValues","values","enumValues","unslugify","a","b","IMAGE_EXTENSIONS","AUDIO_EXTENSIONS","VIDEO_EXTENSIONS","emailRegEx","buildStringProperty","totalDocsCount","valuesResult","stringProperty","totalEntriesCount","totalValues","config","probablyAURL","probablyAnEmail","probablyUserIds","fileType","probableFileType","probablyAnImage","extension","probablyAudio","probablyVideo","buildValidation","buildReferenceProperty","buildEntityPropertiesFromData","data","getType","typesCount","entry","key","increaseMapTypeCount","increaseValuesCount","buildPropertiesFromCount","buildPropertyFromData","property","increaseTypeCount","resolveEnumValues","newEnumValues","generatedProperty","buildPropertyFromCount","mergeDeep","buildPropertiesOrder","properties","propOrder","k","keys","type","fieldValue","mapTypesCount","arrayTypesCount","arrayType","getMostProbableTypeInArray","typesCountRecord","typeValuesRecord","dataType","valuesRecord","mapValuesRecord","getHighestTypesCount","highestCount","count","countValue","getHighestRecordCount","record","getMostProbableType","probableType","mostProbableType","title","formatString","result","checkTypesCountHighVariability","arrayMostProbableType","of","propertyProps","validation","valuesCountRecord","res","countMaxDocumentsUnder","array","maxCount","keysWithFewValues","input","word","inferTypeFromValue"],"mappings":"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"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.0.0-canary.42",
2
+ "version": "3.0.0-canary.43",
3
3
  "type": "module",
4
4
  "name": "@firecms/schema_inference",
5
5
  "access": "public",
@@ -8,10 +8,10 @@
8
8
  "types": "dist/index.d.ts",
9
9
  "source": "src/index.ts",
10
10
  "devDependencies": {
11
- "@firecms/core": "^3.0.0-canary.42",
12
- "@types/node": "^20.11.30",
13
- "typescript": "^5.4.2",
14
- "vite": "^5.2.3"
11
+ "@firecms/core": "^3.0.0-canary.43",
12
+ "@types/node": "^20.12.7",
13
+ "typescript": "^5.4.5",
14
+ "vite": "^5.2.9"
15
15
  },
16
16
  "exports": {
17
17
  ".": {
@@ -30,5 +30,5 @@
30
30
  "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
31
31
  "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
32
32
  },
33
- "gitHead": "d6a2f28e93d3c532dd6efacfccffb91383d5330e"
33
+ "gitHead": "fedcb0d43c504245dd76b702e4ab4479fa8592df"
34
34
  }
@@ -5,8 +5,7 @@ import {
5
5
  Properties,
6
6
  Property,
7
7
  resolveEnumValues,
8
- StringProperty, toKebabCase,
9
- unslugify
8
+ StringProperty
10
9
  } from "@firecms/core";
11
10
  import {
12
11
  InferencePropertyBuilderProps,
@@ -335,7 +334,7 @@ function checkTypesCountHighVariability(typesCount: TypesCount) {
335
334
  function formatString(input: string): string {
336
335
  const normalized = input
337
336
  .replace(/[_\-]+/g, " ")
338
- .replace(/([a-z])([A-Z])/g, '$1 $2')
337
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
339
338
  .toLowerCase();
340
339
 
341
340
  // Split the normalized string into words
@@ -349,3 +348,12 @@ function formatString(input: string): string {
349
348
  return formatted;
350
349
  }
351
350
 
351
+ export function inferTypeFromValue(value: any): DataType {
352
+ if (typeof value === "string") return "string";
353
+ if (typeof value === "number") return "number";
354
+ if (typeof value === "boolean") return "boolean";
355
+ if (Array.isArray(value)) return "array";
356
+ if (typeof value === "object") return "map";
357
+ return "string";
358
+ }
359
+