@firecms/schema_inference 3.0.0-tw4.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.es.js CHANGED
@@ -31,6 +31,15 @@ function extractEnumFromValues(values) {
31
31
  enumValues.sort((a, b) => a.label.localeCompare(b.label));
32
32
  return enumValues;
33
33
  }
34
+ function prettifyIdentifier(input) {
35
+ if (!input) return "";
36
+ let text = input;
37
+ text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
38
+ text = text.replace(/[_-]+/g, " ");
39
+ const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
40
+ console.log("Prettified identifier:", { input, s });
41
+ return s;
42
+ }
34
43
  function unslugify(slug) {
35
44
  if (!slug) return "";
36
45
  if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
@@ -351,7 +360,7 @@ function getMostProbableType(typesCount) {
351
360
  function buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesResult) {
352
361
  let title;
353
362
  if (key) {
354
- title = formatString(key.toLowerCase());
363
+ title = prettifyIdentifier(key);
355
364
  }
356
365
  let result = void 0;
357
366
  if (mostProbableType === "map") {
@@ -460,12 +469,6 @@ function checkTypesCountHighVariability(typesCount) {
460
469
  });
461
470
  return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;
462
471
  }
463
- function formatString(input) {
464
- const normalized = input.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
465
- const words = normalized.split(" ");
466
- const formatted = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
467
- return formatted;
468
- }
469
472
  function inferTypeFromValue(value) {
470
473
  if (value === null || value === void 0) return "string";
471
474
  if (typeof value === "string") return "string";
@@ -483,6 +486,7 @@ export {
483
486
  inferTypeFromValue,
484
487
  isObject,
485
488
  mergeDeep,
489
+ prettifyIdentifier,
486
490
  resolveEnumValues,
487
491
  unslugify
488
492
  };
@@ -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.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<any>> {\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<any> {\n const res: Properties<any> = {};\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\n\nexport function prettifyIdentifier(input: string) {\n if (!input) return \"\";\n\n let text = input;\n\n // 1. Handle camelCase and Acronyms\n // Group 1 ($1 $2): Lowercase followed by Uppercase (e.g., imageURL -> image URL)\n // Group 2 ($3 $4): Uppercase followed by Uppercase+lowercase (e.g., XMLParser -> XML Parser)\n text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, \"$1$3 $2$4\");\n\n // 2. Replace hyphens/underscores with spaces\n text = text.replace(/[_-]+/g, \" \");\n\n // 3. Capitalize first letter of each word (Title Case)\n const s = text\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n console.log(\"Prettified identifier:\", { input,s });\n return s;\n}\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, prettifyIdentifier, 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<any>> {\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 = prettifyIdentifier(key);\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<any> {\n const res: Properties<any> = {};\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\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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"}
@@ -35,6 +35,15 @@
35
35
  enumValues.sort((a, b) => a.label.localeCompare(b.label));
36
36
  return enumValues;
37
37
  }
38
+ function prettifyIdentifier(input) {
39
+ if (!input) return "";
40
+ let text = input;
41
+ text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
42
+ text = text.replace(/[_-]+/g, " ");
43
+ const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
44
+ console.log("Prettified identifier:", { input, s });
45
+ return s;
46
+ }
38
47
  function unslugify(slug) {
39
48
  if (!slug) return "";
40
49
  if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
@@ -355,7 +364,7 @@
355
364
  function buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesResult) {
356
365
  let title;
357
366
  if (key) {
358
- title = formatString(key.toLowerCase());
367
+ title = prettifyIdentifier(key);
359
368
  }
360
369
  let result = void 0;
361
370
  if (mostProbableType === "map") {
@@ -464,12 +473,6 @@
464
473
  });
465
474
  return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;
466
475
  }
467
- function formatString(input) {
468
- const normalized = input.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
469
- const words = normalized.split(" ");
470
- const formatted = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
471
- return formatted;
472
- }
473
476
  function inferTypeFromValue(value) {
474
477
  if (value === null || value === void 0) return "string";
475
478
  if (typeof value === "string") return "string";
@@ -486,6 +489,7 @@
486
489
  exports2.inferTypeFromValue = inferTypeFromValue;
487
490
  exports2.isObject = isObject;
488
491
  exports2.mergeDeep = mergeDeep;
492
+ exports2.prettifyIdentifier = prettifyIdentifier;
489
493
  exports2.resolveEnumValues = resolveEnumValues;
490
494
  exports2.unslugify = unslugify;
491
495
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
@@ -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.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<any>> {\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<any> {\n const res: Properties<any> = {};\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\n\nexport function prettifyIdentifier(input: string) {\n if (!input) return \"\";\n\n let text = input;\n\n // 1. Handle camelCase and Acronyms\n // Group 1 ($1 $2): Lowercase followed by Uppercase (e.g., imageURL -> image URL)\n // Group 2 ($3 $4): Uppercase followed by Uppercase+lowercase (e.g., XMLParser -> XML Parser)\n text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, \"$1$3 $2$4\");\n\n // 2. Replace hyphens/underscores with spaces\n text = text.replace(/[_-]+/g, \" \");\n\n // 3. Capitalize first letter of each word (Title Case)\n const s = text\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n console.log(\"Prettified identifier:\", { input,s });\n return s;\n}\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, prettifyIdentifier, 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<any>> {\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 = prettifyIdentifier(key);\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<any> {\n const res: Properties<any> = {};\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\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/dist/util.d.ts CHANGED
@@ -3,6 +3,7 @@ export declare function extractEnumFromValues(values: unknown[]): {
3
3
  id: string;
4
4
  label: string;
5
5
  }[];
6
+ export declare function prettifyIdentifier(input: string): string;
6
7
  export declare function unslugify(slug?: string): string;
7
8
  export declare function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined;
8
9
  export declare function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined?: boolean): T & U;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.0.0-tw4.2",
2
+ "version": "3.0.0",
3
3
  "type": "module",
4
4
  "name": "@firecms/schema_inference",
5
5
  "access": "public",
@@ -29,7 +29,7 @@
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": "1292c52536d1485a6dd0803de81e05448cb0a36e",
32
+ "gitHead": "d106a7fde537c4330ae4ba5471c74d4536dea710",
33
33
  "dependencies": {
34
34
  "axios": "1.13.2",
35
35
  "vite-plugin-static-copy": "3.1.4"
@@ -8,7 +8,7 @@ import {
8
8
  import { buildStringProperty } from "./builders/string_property_builder";
9
9
  import { buildValidation } from "./builders/validation_builder";
10
10
  import { buildReferenceProperty } from "./builders/reference_property_builder";
11
- import { extractEnumFromValues, mergeDeep, resolveEnumValues } from "./util";
11
+ import { extractEnumFromValues, mergeDeep, prettifyIdentifier, resolveEnumValues } from "./util";
12
12
  import { DataType, EnumValues, Properties, Property, StringProperty } from "./cms_types";
13
13
 
14
14
  export type InferenceTypeBuilder = (value: any) => DataType;
@@ -268,7 +268,7 @@ function buildPropertyFromCount(
268
268
  let title: string | undefined;
269
269
 
270
270
  if (key) {
271
- title = formatString(key.toLowerCase());
271
+ title = prettifyIdentifier(key);
272
272
  }
273
273
 
274
274
  let result: Property | undefined = undefined;
@@ -395,22 +395,6 @@ function checkTypesCountHighVariability(typesCount: TypesCount) {
395
395
  return keysWithFewValues / Object.entries(typesCount.map ?? {}).length > 0.5;
396
396
  }
397
397
 
398
- function formatString(input: string): string {
399
- const normalized = input
400
- .replace(/[_-]+/g, " ")
401
- .replace(/([a-z])([A-Z])/g, "$1 $2")
402
- .toLowerCase();
403
-
404
- // Split the normalized string into words
405
- const words = normalized.split(" ");
406
-
407
- // Capitalize the first letter of each word and join them with a space
408
- const formatted = words
409
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
410
- .join(" ");
411
-
412
- return formatted;
413
- }
414
398
 
415
399
  export function inferTypeFromValue(value: any): DataType {
416
400
  if (value === null || value === undefined) return "string";
package/src/util.ts CHANGED
@@ -15,6 +15,29 @@ export function extractEnumFromValues(values: unknown[]) {
15
15
  return enumValues;
16
16
  }
17
17
 
18
+
19
+ export function prettifyIdentifier(input: string) {
20
+ if (!input) return "";
21
+
22
+ let text = input;
23
+
24
+ // 1. Handle camelCase and Acronyms
25
+ // Group 1 ($1 $2): Lowercase followed by Uppercase (e.g., imageURL -> image URL)
26
+ // Group 2 ($3 $4): Uppercase followed by Uppercase+lowercase (e.g., XMLParser -> XML Parser)
27
+ text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
28
+
29
+ // 2. Replace hyphens/underscores with spaces
30
+ text = text.replace(/[_-]+/g, " ");
31
+
32
+ // 3. Capitalize first letter of each word (Title Case)
33
+ const s = text
34
+ .trim()
35
+ .replace(/\b\w/g, (char) => char.toUpperCase());
36
+ console.log("Prettified identifier:", { input,s });
37
+ return s;
38
+ }
39
+
40
+
18
41
  export function unslugify(slug?: string): string {
19
42
  if (!slug) return "";
20
43
  if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {