@firecms/schema_inference 3.0.0-canary.247 → 3.0.0-canary.249

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.
@@ -8,26 +8,6 @@ export type DataType<T extends CMSType = CMSType> = T extends string ? "string"
8
8
  * @group Models
9
9
  */
10
10
  export type EntityStatus = "new" | "existing" | "copy";
11
- /**
12
- * Representation of an entity fetched from the datasource
13
- * @group Models
14
- */
15
- export interface Entity<M extends object = any> {
16
- /**
17
- * ID of the entity
18
- */
19
- id: string;
20
- /**
21
- * A string representing the path of the referenced document (relative
22
- * to the root of the database).
23
- */
24
- path: string;
25
- /**
26
- * Current values
27
- */
28
- values: EntityValues<M>;
29
- databaseId?: string;
30
- }
31
11
  /**
32
12
  * This type represents a record of key value pairs as described in an
33
13
  * entity collection.
@@ -265,6 +245,13 @@ export interface StringProperty extends BaseProperty<string> {
265
245
  * Add an icon to clear the value and set it to `null`. Defaults to `false`
266
246
  */
267
247
  clearable?: boolean;
248
+ /**
249
+ * You can use this property (a string) to behave as a reference to another
250
+ * collection. The stored value is the ID of the entity in the
251
+ * collection, and the `path` prop is used to
252
+ * define the collection this reference points to.
253
+ */
254
+ reference?: ReferenceProperty;
268
255
  }
269
256
  /**
270
257
  * @group Entity properties
package/dist/index.es.js CHANGED
@@ -2,8 +2,9 @@ function findCommonInitialStringInPath(valuesCount) {
2
2
  if (!valuesCount) return void 0;
3
3
  function getPath(value) {
4
4
  if (typeof value === "string") return value;
5
- else if (value?.type === "document" && value.path) return value.path;
6
- else return void 0;
5
+ else if (value.path) return value.path;
6
+ console.warn("findCommonInitialStringInPath: value is not a string or document with path", value);
7
+ return void 0;
7
8
  }
8
9
  const strings = valuesCount.values.map((v) => getPath(v)).filter((v) => !!v);
9
10
  const pathWithSlash = strings.find((s) => s.includes("/"));
@@ -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\";\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?.type === \"document\" && value.path) 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 { EnumValueConfig, EnumValues } from \"./cms_types\";\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\nexport function unslugify(slug?: string): string {\n if (!slug) return \"\";\n if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n const result = slug.replace(/[-_]/g, \" \");\n return result.replace(/\\w\\S*/g, function (txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n if (typeof input === \"object\") {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else {\n return undefined;\n }\n}\n\nexport function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined: boolean = false): T & U {\n const targetIsObject = isObject(target);\n const output = targetIsObject ? { ...target } : target;\n if (targetIsObject && isObject(source)) {\n Object.keys(source).forEach(key => {\n const sourceElement = source[key];\n // Skip undefined values when ignoreUndefined is true\n if (ignoreUndefined && sourceElement === undefined) {\n return;\n }\n if (sourceElement instanceof Date) {\n // Assign a new Date instance with the same time value\n Object.assign(output, { [key]: new Date(sourceElement.getTime()) });\n } else if (isObject(sourceElement)) {\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else\n (output as any)[key] = mergeDeep((target as any)[key], sourceElement);\n } else {\n Object.assign(output, { [key]: sourceElement });\n }\n });\n }\n return output as T;\n}\n\nexport function isObject(item: any) {\n return item && typeof item === \"object\" && !Array.isArray(item);\n}\n\n\n","import { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"../cms_types\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\", \".webp\", \".gif\", \".avif\"];\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\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 { InferencePropertyBuilderProps } from \"../types\";\nimport { PropertyValidationSchema } from \"../cms_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 \"../cms_types\";\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 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, mergeDeep, resolveEnumValues } from \"./util\";\nimport { DataType, EnumValues, Properties, Property, StringProperty } from \"./cms_types\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(\n data: object[],\n getType: InferenceTypeBuilder\n): 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n });\n }\n });\n }\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(\n data: any[],\n property: Property,\n getType: InferenceTypeBuilder\n): 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(\n \"inferred_prop\",\n data.length,\n property.dataType,\n typesCount,\n valuesCount[\"inferred_prop\"]\n );\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(\n properties: Properties,\n propertiesOrder?: string[],\n priorityKeys?: string[]\n): string[] {\n const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());\n\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (lowerCasePriorityKeys.includes(k)) return 4;\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 = propertiesOrder ?? 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(\n type: DataType,\n typesCount: TypesCount,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\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);\n if (arrayType === \"map\") {\n let mapTypesCount = arrayTypesCount[arrayType];\n if (!mapTypesCount) {\n mapTypesCount = {};\n }\n fieldValue.forEach((value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) { // Ensure value is an object for Object.entries\n Object.entries(value).forEach(([key, v]) =>\n increaseMapTypeCount(mapTypesCount, key, v, getType)\n );\n }\n });\n arrayTypesCount[arrayType] = mapTypesCount;\n } else {\n if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) {\n // 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\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(([subKey, value]) =>\n increaseValuesCount(mapValuesRecord as ValuesCountRecord, subKey, value, getType)\n );\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 !== null && fieldValue !== undefined) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\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(\n key: string,\n totalDocsCount: number,\n mostProbableType: DataType,\n typesCount: TypesCount,\n valuesResult?: ValuesCountEntry\n): 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 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(\n totalDocsCount,\n typesCount.map as TypesCountRecord,\n valuesResult ? valuesResult.mapValues : undefined\n );\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(\n key,\n totalDocsCount,\n arrayMostProbableType,\n arrayTypesCount,\n valuesResult\n );\n result = {\n dataType: \"array\",\n name: title,\n of\n };\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(\n totalDocsCount: number,\n typesCountRecord: TypesCountRecord,\n valuesCountRecord?: ValuesCountRecord\n): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(\n key,\n totalDocsCount,\n mostProbableType,\n typesCount,\n valuesCountRecord ? valuesCountRecord[key] : undefined\n );\n });\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\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(\n array: any[],\n getType: InferenceTypeBuilder\n): DataType {\n const 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 ?? {}).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 (value === null || value === undefined) return \"string\";\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"],"names":[],"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\";\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.path) return value.path;\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n 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 { EnumValueConfig, EnumValues } from \"./cms_types\";\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\nexport function unslugify(slug?: string): string {\n if (!slug) return \"\";\n if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n const result = slug.replace(/[-_]/g, \" \");\n return result.replace(/\\w\\S*/g, function (txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n if (typeof input === \"object\") {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else {\n return undefined;\n }\n}\n\nexport function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined: boolean = false): T & U {\n const targetIsObject = isObject(target);\n const output = targetIsObject ? { ...target } : target;\n if (targetIsObject && isObject(source)) {\n Object.keys(source).forEach(key => {\n const sourceElement = source[key];\n // Skip undefined values when ignoreUndefined is true\n if (ignoreUndefined && sourceElement === undefined) {\n return;\n }\n if (sourceElement instanceof Date) {\n // Assign a new Date instance with the same time value\n Object.assign(output, { [key]: new Date(sourceElement.getTime()) });\n } else if (isObject(sourceElement)) {\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else\n (output as any)[key] = mergeDeep((target as any)[key], sourceElement);\n } else {\n Object.assign(output, { [key]: sourceElement });\n }\n });\n }\n return output as T;\n}\n\nexport function isObject(item: any) {\n return item && typeof item === \"object\" && !Array.isArray(item);\n}\n\n\n","import { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"../cms_types\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\", \".webp\", \".gif\", \".avif\"];\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\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 { InferencePropertyBuilderProps } from \"../types\";\nimport { PropertyValidationSchema } from \"../cms_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 \"../cms_types\";\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 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, mergeDeep, resolveEnumValues } from \"./util\";\nimport { DataType, EnumValues, Properties, Property, StringProperty } from \"./cms_types\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(\n data: object[],\n getType: InferenceTypeBuilder\n): 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n });\n }\n });\n }\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(\n data: any[],\n property: Property,\n getType: InferenceTypeBuilder\n): 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(\n \"inferred_prop\",\n data.length,\n property.dataType,\n typesCount,\n valuesCount[\"inferred_prop\"]\n );\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(\n properties: Properties,\n propertiesOrder?: string[],\n priorityKeys?: string[]\n): string[] {\n const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());\n\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (lowerCasePriorityKeys.includes(k)) return 4;\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 = propertiesOrder ?? 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(\n type: DataType,\n typesCount: TypesCount,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\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);\n if (arrayType === \"map\") {\n let mapTypesCount = arrayTypesCount[arrayType];\n if (!mapTypesCount) {\n mapTypesCount = {};\n }\n fieldValue.forEach((value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) { // Ensure value is an object for Object.entries\n Object.entries(value).forEach(([key, v]) =>\n increaseMapTypeCount(mapTypesCount, key, v, getType)\n );\n }\n });\n arrayTypesCount[arrayType] = mapTypesCount;\n } else {\n if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) {\n // 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\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(([subKey, value]) =>\n increaseValuesCount(mapValuesRecord as ValuesCountRecord, subKey, value, getType)\n );\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 !== null && fieldValue !== undefined) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\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(\n key: string,\n totalDocsCount: number,\n mostProbableType: DataType,\n typesCount: TypesCount,\n valuesResult?: ValuesCountEntry\n): 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 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(\n totalDocsCount,\n typesCount.map as TypesCountRecord,\n valuesResult ? valuesResult.mapValues : undefined\n );\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(\n key,\n totalDocsCount,\n arrayMostProbableType,\n arrayTypesCount,\n valuesResult\n );\n result = {\n dataType: \"array\",\n name: title,\n of\n };\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(\n totalDocsCount: number,\n typesCountRecord: TypesCountRecord,\n valuesCountRecord?: ValuesCountRecord\n): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(\n key,\n totalDocsCount,\n mostProbableType,\n typesCount,\n valuesCountRecord ? valuesCountRecord[key] : undefined\n );\n });\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\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(\n array: any[],\n getType: InferenceTypeBuilder\n): DataType {\n const 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 ?? {}).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 (value === null || value === undefined) return \"string\";\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"],"names":[],"mappings":"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"}
@@ -6,8 +6,9 @@
6
6
  if (!valuesCount) return void 0;
7
7
  function getPath(value) {
8
8
  if (typeof value === "string") return value;
9
- else if (value?.type === "document" && value.path) return value.path;
10
- else return void 0;
9
+ else if (value.path) return value.path;
10
+ console.warn("findCommonInitialStringInPath: value is not a string or document with path", value);
11
+ return void 0;
11
12
  }
12
13
  const strings = valuesCount.values.map((v) => getPath(v)).filter((v) => !!v);
13
14
  const pathWithSlash = strings.find((s) => s.includes("/"));
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.cjs","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\";\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?.type === \"document\" && value.path) 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 { EnumValueConfig, EnumValues } from \"./cms_types\";\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\nexport function unslugify(slug?: string): string {\n if (!slug) return \"\";\n if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n const result = slug.replace(/[-_]/g, \" \");\n return result.replace(/\\w\\S*/g, function (txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n if (typeof input === \"object\") {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else {\n return undefined;\n }\n}\n\nexport function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined: boolean = false): T & U {\n const targetIsObject = isObject(target);\n const output = targetIsObject ? { ...target } : target;\n if (targetIsObject && isObject(source)) {\n Object.keys(source).forEach(key => {\n const sourceElement = source[key];\n // Skip undefined values when ignoreUndefined is true\n if (ignoreUndefined && sourceElement === undefined) {\n return;\n }\n if (sourceElement instanceof Date) {\n // Assign a new Date instance with the same time value\n Object.assign(output, { [key]: new Date(sourceElement.getTime()) });\n } else if (isObject(sourceElement)) {\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else\n (output as any)[key] = mergeDeep((target as any)[key], sourceElement);\n } else {\n Object.assign(output, { [key]: sourceElement });\n }\n });\n }\n return output as T;\n}\n\nexport function isObject(item: any) {\n return item && typeof item === \"object\" && !Array.isArray(item);\n}\n\n\n","import { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"../cms_types\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\", \".webp\", \".gif\", \".avif\"];\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\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 { InferencePropertyBuilderProps } from \"../types\";\nimport { PropertyValidationSchema } from \"../cms_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 \"../cms_types\";\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 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, mergeDeep, resolveEnumValues } from \"./util\";\nimport { DataType, EnumValues, Properties, Property, StringProperty } from \"./cms_types\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(\n data: object[],\n getType: InferenceTypeBuilder\n): 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n });\n }\n });\n }\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(\n data: any[],\n property: Property,\n getType: InferenceTypeBuilder\n): 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(\n \"inferred_prop\",\n data.length,\n property.dataType,\n typesCount,\n valuesCount[\"inferred_prop\"]\n );\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(\n properties: Properties,\n propertiesOrder?: string[],\n priorityKeys?: string[]\n): string[] {\n const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());\n\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (lowerCasePriorityKeys.includes(k)) return 4;\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 = propertiesOrder ?? 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(\n type: DataType,\n typesCount: TypesCount,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\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);\n if (arrayType === \"map\") {\n let mapTypesCount = arrayTypesCount[arrayType];\n if (!mapTypesCount) {\n mapTypesCount = {};\n }\n fieldValue.forEach((value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) { // Ensure value is an object for Object.entries\n Object.entries(value).forEach(([key, v]) =>\n increaseMapTypeCount(mapTypesCount, key, v, getType)\n );\n }\n });\n arrayTypesCount[arrayType] = mapTypesCount;\n } else {\n if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) {\n // 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\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(([subKey, value]) =>\n increaseValuesCount(mapValuesRecord as ValuesCountRecord, subKey, value, getType)\n );\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 !== null && fieldValue !== undefined) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\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(\n key: string,\n totalDocsCount: number,\n mostProbableType: DataType,\n typesCount: TypesCount,\n valuesResult?: ValuesCountEntry\n): 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 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(\n totalDocsCount,\n typesCount.map as TypesCountRecord,\n valuesResult ? valuesResult.mapValues : undefined\n );\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(\n key,\n totalDocsCount,\n arrayMostProbableType,\n arrayTypesCount,\n valuesResult\n );\n result = {\n dataType: \"array\",\n name: title,\n of\n };\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(\n totalDocsCount: number,\n typesCountRecord: TypesCountRecord,\n valuesCountRecord?: ValuesCountRecord\n): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(\n key,\n totalDocsCount,\n mostProbableType,\n typesCount,\n valuesCountRecord ? valuesCountRecord[key] : undefined\n );\n });\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\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(\n array: any[],\n getType: InferenceTypeBuilder\n): DataType {\n const 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 ?? {}).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 (value === null || value === undefined) return \"string\";\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"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.cjs","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\";\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.path) return value.path;\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n 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 { EnumValueConfig, EnumValues } from \"./cms_types\";\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\nexport function unslugify(slug?: string): string {\n if (!slug) return \"\";\n if (slug.includes(\"-\") || slug.includes(\"_\") || !slug.includes(\" \")) {\n const result = slug.replace(/[-_]/g, \" \");\n return result.replace(/\\w\\S*/g, function (txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n if (typeof input === \"object\") {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else {\n return undefined;\n }\n}\n\nexport function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined: boolean = false): T & U {\n const targetIsObject = isObject(target);\n const output = targetIsObject ? { ...target } : target;\n if (targetIsObject && isObject(source)) {\n Object.keys(source).forEach(key => {\n const sourceElement = source[key];\n // Skip undefined values when ignoreUndefined is true\n if (ignoreUndefined && sourceElement === undefined) {\n return;\n }\n if (sourceElement instanceof Date) {\n // Assign a new Date instance with the same time value\n Object.assign(output, { [key]: new Date(sourceElement.getTime()) });\n } else if (isObject(sourceElement)) {\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else\n (output as any)[key] = mergeDeep((target as any)[key], sourceElement);\n } else {\n Object.assign(output, { [key]: sourceElement });\n }\n });\n }\n return output as T;\n}\n\nexport function isObject(item: any) {\n return item && typeof item === \"object\" && !Array.isArray(item);\n}\n\n\n","import { InferencePropertyBuilderProps, ValuesCountEntry } from \"../types\";\nimport { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"../cms_types\";\n\nconst IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\", \".webp\", \".gif\", \".avif\"];\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\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 { InferencePropertyBuilderProps } from \"../types\";\nimport { PropertyValidationSchema } from \"../cms_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 \"../cms_types\";\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 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, mergeDeep, resolveEnumValues } from \"./util\";\nimport { DataType, EnumValues, Properties, Property, StringProperty } from \"./cms_types\";\n\nexport type InferenceTypeBuilder = (value: any) => DataType;\n\nexport async function buildEntityPropertiesFromData(\n data: object[],\n getType: InferenceTypeBuilder\n): 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n increaseMapTypeCount(typesCount, key, value, getType);\n increaseValuesCount(valuesCount, key, value, getType);\n });\n }\n });\n }\n return buildPropertiesFromCount(data.length, typesCount, valuesCount);\n}\n\nexport function buildPropertyFromData(\n data: any[],\n property: Property,\n getType: InferenceTypeBuilder\n): 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(\n \"inferred_prop\",\n data.length,\n property.dataType,\n typesCount,\n valuesCount[\"inferred_prop\"]\n );\n return mergeDeep(generatedProperty, property);\n}\n\nexport function buildPropertiesOrder(\n properties: Properties,\n propertiesOrder?: string[],\n priorityKeys?: string[]\n): string[] {\n const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());\n\n function propOrder(s: string) {\n const k = s.toLowerCase();\n if (lowerCasePriorityKeys.includes(k)) return 4;\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 = propertiesOrder ?? 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(\n type: DataType,\n typesCount: TypesCount,\n fieldValue: any,\n getType: InferenceTypeBuilder\n) {\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);\n if (arrayType === \"map\") {\n let mapTypesCount = arrayTypesCount[arrayType];\n if (!mapTypesCount) {\n mapTypesCount = {};\n }\n fieldValue.forEach((value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) { // Ensure value is an object for Object.entries\n Object.entries(value).forEach(([key, v]) =>\n increaseMapTypeCount(mapTypesCount, key, v, getType)\n );\n }\n });\n arrayTypesCount[arrayType] = mapTypesCount;\n } else {\n if (!arrayTypesCount[arrayType]) arrayTypesCount[arrayType] = 1;\n else (arrayTypesCount[arrayType] as number)++;\n }\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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\n\n let typesCount: TypesCount = typesCountRecord[key];\n if (!typesCount) {\n typesCount = {};\n typesCountRecord[key] = typesCount;\n }\n\n if (fieldValue != null) {\n // 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 if (key.startsWith(\"_\")) return; // Ignore properties starting with _\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(([subKey, value]) =>\n increaseValuesCount(mapValuesRecord as ValuesCountRecord, subKey, value, getType)\n );\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 !== null && fieldValue !== undefined) {\n valuesRecord.values.push(fieldValue);\n valuesRecord.valuesCount.set(fieldValue, (valuesRecord.valuesCount.get(fieldValue) ?? 0) + 1);\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(\n key: string,\n totalDocsCount: number,\n mostProbableType: DataType,\n typesCount: TypesCount,\n valuesResult?: ValuesCountEntry\n): 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 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(\n totalDocsCount,\n typesCount.map as TypesCountRecord,\n valuesResult ? valuesResult.mapValues : undefined\n );\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(\n key,\n totalDocsCount,\n arrayMostProbableType,\n arrayTypesCount,\n valuesResult\n );\n result = {\n dataType: \"array\",\n name: title,\n of\n };\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(\n totalDocsCount: number,\n typesCountRecord: TypesCountRecord,\n valuesCountRecord?: ValuesCountRecord\n): Properties {\n const res: Properties = {};\n Object.entries(typesCountRecord).forEach(([key, typesCount]) => {\n const mostProbableType = getMostProbableType(typesCount);\n res[key] = buildPropertyFromCount(\n key,\n totalDocsCount,\n mostProbableType,\n typesCount,\n valuesCountRecord ? valuesCountRecord[key] : undefined\n );\n });\n return res;\n}\n\nfunction countMaxDocumentsUnder(typesCount: TypesCount) {\n let count = 0;\n Object.entries(typesCount).forEach(([type, value]) => {\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(\n array: any[],\n getType: InferenceTypeBuilder\n): DataType {\n const 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 ?? {}).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 (value === null || value === undefined) return \"string\";\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"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.0.0-canary.247",
2
+ "version": "3.0.0-canary.249",
3
3
  "type": "module",
4
4
  "name": "@firecms/schema_inference",
5
5
  "access": "public",
@@ -29,5 +29,5 @@
29
29
  "build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
30
30
  "clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
31
31
  },
32
- "gitHead": "1383c05197c9ef33c04ee394c6455bb18e03bc94"
32
+ "gitHead": "5a61d7000af7d369373142087ee99792178a2c6f"
33
33
  }
package/src/cms_types.ts CHANGED
@@ -28,31 +28,6 @@ export type DataType<T extends CMSType = CMSType> =
28
28
  */
29
29
  export type EntityStatus = "new" | "existing" | "copy";
30
30
 
31
- /**
32
- * Representation of an entity fetched from the datasource
33
- * @group Models
34
- */
35
- export interface Entity<M extends object = any> {
36
-
37
- /**
38
- * ID of the entity
39
- */
40
- id: string;
41
-
42
- /**
43
- * A string representing the path of the referenced document (relative
44
- * to the root of the database).
45
- */
46
- path: string;
47
-
48
- /**
49
- * Current values
50
- */
51
- values: EntityValues<M>;
52
-
53
- databaseId?: string;
54
- }
55
-
56
31
  /**
57
32
  * This type represents a record of key value pairs as described in an
58
33
  * entity collection.
@@ -361,6 +336,14 @@ export interface StringProperty extends BaseProperty<string> {
361
336
  * Add an icon to clear the value and set it to `null`. Defaults to `false`
362
337
  */
363
338
  clearable?: boolean;
339
+
340
+ /**
341
+ * You can use this property (a string) to behave as a reference to another
342
+ * collection. The stored value is the ID of the entity in the
343
+ * collection, and the `path` prop is used to
344
+ * define the collection this reference points to.
345
+ */
346
+ reference?: ReferenceProperty;
364
347
  }
365
348
 
366
349
  /**
package/src/strings.ts CHANGED
@@ -6,8 +6,9 @@ export function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {
6
6
 
7
7
  function getPath(value: any) {
8
8
  if (typeof value === "string") return value;
9
- else if (value?.type === "document" && value.path) return value.path;
10
- else return undefined;
9
+ else if (value.path) return value.path;
10
+ console.warn("findCommonInitialStringInPath: value is not a string or document with path", value);
11
+ return undefined;
11
12
  }
12
13
 
13
14
  const strings: string[] = valuesCount.values.map((v) => getPath(v)).filter(v => !!v) as string[];