@rebasepro/schema-inference 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e
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 +9 -63
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.cjs +29 -70
- package/dist/index.umd.cjs.map +1 -1
- package/dist/util.d.ts +5 -5
- package/package.json +36 -35
- package/src/builders/string_property_builder.ts +2 -2
- package/src/strings.ts +2 -1
- package/src/test_schemas/test_schema.ts +3 -1
- package/src/util.ts +8 -80
package/dist/index.es.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { unslugify, mergeDeep, prettifyIdentifier } from "@rebasepro/utils";
|
|
2
|
+
import { isObject, isPlainObject, mergeDeep as mergeDeep2, prettifyIdentifier as prettifyIdentifier2, unslugify as unslugify2 } from "@rebasepro/utils";
|
|
1
3
|
function parseReferenceString(value) {
|
|
2
4
|
if (!value) return null;
|
|
3
5
|
let database = void 0;
|
|
@@ -13,7 +15,10 @@ function parseReferenceString(value) {
|
|
|
13
15
|
return null;
|
|
14
16
|
}
|
|
15
17
|
const path = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
16
|
-
return {
|
|
18
|
+
return {
|
|
19
|
+
path,
|
|
20
|
+
database
|
|
21
|
+
};
|
|
17
22
|
}
|
|
18
23
|
function looksLikeReference(value) {
|
|
19
24
|
if (typeof value !== "string") return false;
|
|
@@ -79,29 +84,6 @@ function extractEnumFromValues(values) {
|
|
|
79
84
|
enumValues.sort((a, b) => a.label.localeCompare(b.label));
|
|
80
85
|
return enumValues;
|
|
81
86
|
}
|
|
82
|
-
function prettifyIdentifier(input) {
|
|
83
|
-
if (!input) return "";
|
|
84
|
-
let text = input;
|
|
85
|
-
text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
|
|
86
|
-
text = text.replace(/[_-]+/g, " ");
|
|
87
|
-
const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
88
|
-
console.log("Prettified identifier:", {
|
|
89
|
-
input,
|
|
90
|
-
s
|
|
91
|
-
});
|
|
92
|
-
return s;
|
|
93
|
-
}
|
|
94
|
-
function unslugify(slug) {
|
|
95
|
-
if (!slug) return "";
|
|
96
|
-
if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
|
|
97
|
-
const result = slug.replace(/[-_]/g, " ");
|
|
98
|
-
return result.replace(/\w\S*/g, function(txt) {
|
|
99
|
-
return txt.charAt(0).toUpperCase() + txt.substring(1);
|
|
100
|
-
}).trim();
|
|
101
|
-
} else {
|
|
102
|
-
return slug.trim();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
87
|
function resolveEnumValues(input) {
|
|
106
88
|
if (Array.isArray(input)) {
|
|
107
89
|
return input;
|
|
@@ -114,42 +96,6 @@ function resolveEnumValues(input) {
|
|
|
114
96
|
return void 0;
|
|
115
97
|
}
|
|
116
98
|
}
|
|
117
|
-
function mergeDeep(target, source, ignoreUndefined = false) {
|
|
118
|
-
const targetIsObject = isObject(target);
|
|
119
|
-
const output = targetIsObject ? { ...target } : target;
|
|
120
|
-
if (targetIsObject && isObject(source)) {
|
|
121
|
-
Object.keys(source).forEach((key) => {
|
|
122
|
-
const sourceElement = source[key];
|
|
123
|
-
if (ignoreUndefined && sourceElement === void 0) {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
if (sourceElement instanceof Date) {
|
|
127
|
-
Object.assign(output, { [key]: new Date(sourceElement.getTime()) });
|
|
128
|
-
} else if (isPlainObject(sourceElement)) {
|
|
129
|
-
if (!(key in target))
|
|
130
|
-
Object.assign(output, { [key]: sourceElement });
|
|
131
|
-
else if (isPlainObject(target[key]))
|
|
132
|
-
output[key] = mergeDeep(target[key], sourceElement);
|
|
133
|
-
else
|
|
134
|
-
Object.assign(output, { [key]: sourceElement });
|
|
135
|
-
} else if (isObject(sourceElement)) {
|
|
136
|
-
Object.assign(output, { [key]: sourceElement });
|
|
137
|
-
} else {
|
|
138
|
-
Object.assign(output, { [key]: sourceElement });
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
return output;
|
|
143
|
-
}
|
|
144
|
-
function isObject(item) {
|
|
145
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
146
|
-
}
|
|
147
|
-
function isPlainObject(obj) {
|
|
148
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
return Object.getPrototypeOf(obj) === Object.prototype;
|
|
152
|
-
}
|
|
153
99
|
const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".avif"];
|
|
154
100
|
const AUDIO_EXTENSIONS = [".mp3", ".ogg", ".opus", ".aac"];
|
|
155
101
|
const VIDEO_EXTENSIONS = [".avi", ".mp4"];
|
|
@@ -565,13 +511,13 @@ export {
|
|
|
565
511
|
isObject,
|
|
566
512
|
isPlainObject,
|
|
567
513
|
looksLikeReference,
|
|
568
|
-
mergeDeep,
|
|
514
|
+
mergeDeep2 as mergeDeep,
|
|
569
515
|
parseReferenceString,
|
|
570
|
-
prettifyIdentifier,
|
|
516
|
+
prettifyIdentifier2 as prettifyIdentifier,
|
|
571
517
|
removeInitialAndTrailingSlashes,
|
|
572
518
|
removeInitialSlash,
|
|
573
519
|
removeTrailingSlash,
|
|
574
520
|
resolveEnumValues,
|
|
575
|
-
unslugify
|
|
521
|
+
unslugify2 as unslugify
|
|
576
522
|
};
|
|
577
523
|
//# sourceMappingURL=index.es.js.map
|
package/dist/index.es.js.map
CHANGED
|
@@ -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\n/**\n * Parse a reference string value which can be in the format:\n * - Simple: \"path/entityId\"\n * - With database: \"database_name:::path/entityId\"\n * Returns the path and database (undefined if not specified or if \"(default)\")\n */\nexport function parseReferenceString(value: string): { path: string; database?: string } | null {\n if (!value) return null;\n\n let database: string | undefined = undefined;\n let fullPath = value;\n\n // Parse the new format: database_name:::path/entityId\n if (value.includes(\":::\")) {\n const [dbName, pathPart] = value.split(\":::\");\n if (dbName && dbName !== \"(default)\") {\n database = dbName;\n }\n fullPath = pathPart;\n }\n\n // Check if it looks like a path (contains at least one slash)\n if (!fullPath || !fullPath.includes(\"/\")) {\n return null;\n }\n\n // Extract the collection path (everything before the last slash)\n const path = fullPath.substring(0, fullPath.lastIndexOf(\"/\"));\n\n return { path, database };\n}\n\n/**\n * Check if a string value looks like a reference\n */\nexport function looksLikeReference(value: any): boolean {\n if (typeof value !== \"string\") return false;\n return parseReferenceString(value) !== null;\n}\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any): string | undefined {\n let pathString: string | undefined;\n\n if (typeof value === \"string\") {\n pathString = value;\n } else if (value.slug) {\n pathString = value.slug;\n } else {\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n return undefined;\n }\n\n if (!pathString) return undefined;\n\n // Parse the new format: database_name:::path/entityId\n // Extract just the path portion for comparison\n if (pathString.includes(\":::\")) {\n const [, pathPart] = pathString.split(\":::\");\n pathString = pathPart;\n }\n\n return pathString;\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.substring(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 \"@rebasepro/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 ({\n id: value,\n label: unslugify(value)\n });\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 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:\", {\n input,\n s\n });\n return s;\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.substring(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n // Check Array.isArray first since typeof [] === \"object\" is true in JavaScript\n if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else if (typeof input === \"object\" && input !== null) {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\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 (isPlainObject(sourceElement)) {\n // Only recursively merge plain objects, not class instances\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else if (isPlainObject((target as Record<string, unknown>)[key]))\n (output as Record<string, unknown>)[key] = mergeDeep((target as Record<string, unknown>)[key] as Record<string, unknown>, sourceElement);\n else\n Object.assign(output, { [key]: sourceElement });\n } else if (isObject(sourceElement)) {\n // For class instances (EntityReference, GeoPoint, etc.), assign directly to preserve prototype\n Object.assign(output, { [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\nexport function isPlainObject(obj: any) {\n if (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) {\n return false;\n }\n return Object.getPrototypeOf(obj) === Object.prototype;\n}\n\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../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 name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n name: name ?? \"\",\n type: \"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.enum = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enum) {\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 } as StringProperty;\n }\n\n return stringProperty;\n}\n\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): false | FileType[] {\n const isImage = (value: string) => IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isAudio = (value: string) => AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isVideo = (value: string) => VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n\n const stringValues = valuesCount.values.filter((v): v is string => typeof v === \"string\");\n \n let imageCount = 0;\n let audioCount = 0;\n let videoCount = 0;\n\n for (const value of stringValues) {\n if (isImage(value)) imageCount++;\n else if (isAudio(value)) audioCount++;\n else if (isVideo(value)) videoCount++;\n }\n\n const totalMediaCount = imageCount + audioCount + videoCount;\n if (totalMediaCount > (totalDocsCount * 2) / 3) {\n const fileTypes: FileType[] = [];\n if (imageCount > 0) fileTypes.push(\"image/*\");\n if (audioCount > 0) fileTypes.push(\"audio/*\");\n if (videoCount > 0) fileTypes.push(\"video/*\");\n return fileTypes.length > 0 ? fileTypes : false;\n }\n\n return false;\n}\n","import { PropertyValidationSchema } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { InferencePropertyBuilderProps } from \"../types\";\nimport { Property } from \"@rebasepro/types\";\n\nexport function buildReferenceProperty({\n name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n name: name ?? \"\",\n type: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\"\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 \"@rebasepro/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.type, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enum\" in property ? resolveEnumValues(property[\"enum\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enum: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\n \"inferred_prop\",\n data.length,\n property.type,\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] = Number(arrayTypesCount[arrayType]) + 1;\n }\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else typesCount[type] = Number(typesCount[type]) + 1;\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 type = 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 (type === \"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 (type === \"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 = Number(count);\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 = Number(count);\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"array\",\n name: title ?? key ?? \"\",\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 type: 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 result;\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, Number(value));\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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"}
|
|
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\n/**\n * Parse a reference string value which can be in the format:\n * - Simple: \"path/entityId\"\n * - With database: \"database_name:::path/entityId\"\n * Returns the path and database (undefined if not specified or if \"(default)\")\n */\nexport function parseReferenceString(value: string): { path: string; database?: string } | null {\n if (!value) return null;\n\n let database: string | undefined = undefined;\n let fullPath = value;\n\n // Parse the new format: database_name:::path/entityId\n if (value.includes(\":::\")) {\n const [dbName, pathPart] = value.split(\":::\");\n if (dbName && dbName !== \"(default)\") {\n database = dbName;\n }\n fullPath = pathPart;\n }\n\n // Check if it looks like a path (contains at least one slash)\n if (!fullPath || !fullPath.includes(\"/\")) {\n return null;\n }\n\n // Extract the collection path (everything before the last slash)\n const path = fullPath.substring(0, fullPath.lastIndexOf(\"/\"));\n\n return { path,\ndatabase };\n}\n\n/**\n * Check if a string value looks like a reference\n */\nexport function looksLikeReference(value: any): boolean {\n if (typeof value !== \"string\") return false;\n return parseReferenceString(value) !== null;\n}\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any): string | undefined {\n let pathString: string | undefined;\n\n if (typeof value === \"string\") {\n pathString = value;\n } else if (value.slug) {\n pathString = value.slug;\n } else {\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n return undefined;\n }\n\n if (!pathString) return undefined;\n\n // Parse the new format: database_name:::path/entityId\n // Extract just the path portion for comparison\n if (pathString.includes(\":::\")) {\n const [, pathPart] = pathString.split(\":::\");\n pathString = pathPart;\n }\n\n return pathString;\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.substring(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 \"@rebasepro/types\";\nimport { unslugify } from \"@rebasepro/utils\";\n\n// Canonical utility functions — single source of truth in @rebasepro/utils\nexport { unslugify, prettifyIdentifier, isObject, isPlainObject, mergeDeep } from \"@rebasepro/utils\";\n\n/**\n * Extract enum values from a list of sample values.\n * This is schema-inference-specific logic (not a general utility).\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 ({\n id: value,\n label: unslugify(value)\n });\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 resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n // Check Array.isArray first since typeof [] === \"object\" is true in JavaScript\n if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else if (typeof input === \"object\" && input !== null) {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else {\n return undefined;\n }\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../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 name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n name: name ?? \"\",\n type: \"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.enum = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enum) {\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 } as StringProperty;\n }\n\n return stringProperty;\n}\n\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): false | FileType[] {\n const isImage = (value: string) => IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isAudio = (value: string) => AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isVideo = (value: string) => VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n\n const stringValues = valuesCount.values.filter((v): v is string => typeof v === \"string\");\n\n let imageCount = 0;\n let audioCount = 0;\n let videoCount = 0;\n\n for (const value of stringValues) {\n if (isImage(value)) imageCount++;\n else if (isAudio(value)) audioCount++;\n else if (isVideo(value)) videoCount++;\n }\n\n const totalMediaCount = imageCount + audioCount + videoCount;\n if (totalMediaCount > (totalDocsCount * 2) / 3) {\n const fileTypes: FileType[] = [];\n if (imageCount > 0) fileTypes.push(\"image/*\");\n if (audioCount > 0) fileTypes.push(\"audio/*\");\n if (videoCount > 0) fileTypes.push(\"video/*\");\n return fileTypes.length > 0 ? fileTypes : false;\n }\n\n return false;\n}\n","import { PropertyValidationSchema } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { InferencePropertyBuilderProps } from \"../types\";\nimport { Property } from \"@rebasepro/types\";\n\nexport function buildReferenceProperty({\n name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n name: name ?? \"\",\n type: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\"\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 \"@rebasepro/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.type, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enum\" in property ? resolveEnumValues(property[\"enum\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enum: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\n \"inferred_prop\",\n data.length,\n property.type,\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] = Number(arrayTypesCount[arrayType]) + 1;\n }\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else typesCount[type] = Number(typesCount[type]) + 1;\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 type = 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 (type === \"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 (type === \"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 = Number(count);\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 = Number(count);\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"array\",\n name: title ?? key ?? \"\",\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 type: 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 result;\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, Number(value));\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/index.umd.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["Rebase schema inference"] = {}));
|
|
3
|
-
})(this, (function(exports2) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@rebasepro/utils")) : typeof define === "function" && define.amd ? define(["exports", "@rebasepro/utils"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["Rebase schema inference"] = {}, global.utils));
|
|
3
|
+
})(this, (function(exports2, utils) {
|
|
4
4
|
"use strict";
|
|
5
5
|
function parseReferenceString(value) {
|
|
6
6
|
if (!value) return null;
|
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
19
19
|
const path = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
20
|
-
return {
|
|
20
|
+
return {
|
|
21
|
+
path,
|
|
22
|
+
database
|
|
23
|
+
};
|
|
21
24
|
}
|
|
22
25
|
function looksLikeReference(value) {
|
|
23
26
|
if (typeof value !== "string") return false;
|
|
@@ -75,7 +78,7 @@
|
|
|
75
78
|
if (typeof value === "string") {
|
|
76
79
|
return {
|
|
77
80
|
id: value,
|
|
78
|
-
label: unslugify(value)
|
|
81
|
+
label: utils.unslugify(value)
|
|
79
82
|
};
|
|
80
83
|
} else
|
|
81
84
|
return null;
|
|
@@ -83,29 +86,6 @@
|
|
|
83
86
|
enumValues.sort((a, b) => a.label.localeCompare(b.label));
|
|
84
87
|
return enumValues;
|
|
85
88
|
}
|
|
86
|
-
function prettifyIdentifier(input) {
|
|
87
|
-
if (!input) return "";
|
|
88
|
-
let text = input;
|
|
89
|
-
text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
|
|
90
|
-
text = text.replace(/[_-]+/g, " ");
|
|
91
|
-
const s = text.trim().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
92
|
-
console.log("Prettified identifier:", {
|
|
93
|
-
input,
|
|
94
|
-
s
|
|
95
|
-
});
|
|
96
|
-
return s;
|
|
97
|
-
}
|
|
98
|
-
function unslugify(slug) {
|
|
99
|
-
if (!slug) return "";
|
|
100
|
-
if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
|
|
101
|
-
const result = slug.replace(/[-_]/g, " ");
|
|
102
|
-
return result.replace(/\w\S*/g, function(txt) {
|
|
103
|
-
return txt.charAt(0).toUpperCase() + txt.substring(1);
|
|
104
|
-
}).trim();
|
|
105
|
-
} else {
|
|
106
|
-
return slug.trim();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
89
|
function resolveEnumValues(input) {
|
|
110
90
|
if (Array.isArray(input)) {
|
|
111
91
|
return input;
|
|
@@ -118,42 +98,6 @@
|
|
|
118
98
|
return void 0;
|
|
119
99
|
}
|
|
120
100
|
}
|
|
121
|
-
function mergeDeep(target, source, ignoreUndefined = false) {
|
|
122
|
-
const targetIsObject = isObject(target);
|
|
123
|
-
const output = targetIsObject ? { ...target } : target;
|
|
124
|
-
if (targetIsObject && isObject(source)) {
|
|
125
|
-
Object.keys(source).forEach((key) => {
|
|
126
|
-
const sourceElement = source[key];
|
|
127
|
-
if (ignoreUndefined && sourceElement === void 0) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
if (sourceElement instanceof Date) {
|
|
131
|
-
Object.assign(output, { [key]: new Date(sourceElement.getTime()) });
|
|
132
|
-
} else if (isPlainObject(sourceElement)) {
|
|
133
|
-
if (!(key in target))
|
|
134
|
-
Object.assign(output, { [key]: sourceElement });
|
|
135
|
-
else if (isPlainObject(target[key]))
|
|
136
|
-
output[key] = mergeDeep(target[key], sourceElement);
|
|
137
|
-
else
|
|
138
|
-
Object.assign(output, { [key]: sourceElement });
|
|
139
|
-
} else if (isObject(sourceElement)) {
|
|
140
|
-
Object.assign(output, { [key]: sourceElement });
|
|
141
|
-
} else {
|
|
142
|
-
Object.assign(output, { [key]: sourceElement });
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
return output;
|
|
147
|
-
}
|
|
148
|
-
function isObject(item) {
|
|
149
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
150
|
-
}
|
|
151
|
-
function isPlainObject(obj) {
|
|
152
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
return Object.getPrototypeOf(obj) === Object.prototype;
|
|
156
|
-
}
|
|
157
101
|
const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".avif"];
|
|
158
102
|
const AUDIO_EXTENSIONS = [".mp3", ".ogg", ".opus", ".aac"];
|
|
159
103
|
const VIDEO_EXTENSIONS = [".avi", ".mp4"];
|
|
@@ -292,7 +236,7 @@
|
|
|
292
236
|
typesCount,
|
|
293
237
|
valuesCount["inferred_prop"]
|
|
294
238
|
);
|
|
295
|
-
return mergeDeep(generatedProperty, property);
|
|
239
|
+
return utils.mergeDeep(generatedProperty, property);
|
|
296
240
|
}
|
|
297
241
|
function buildPropertiesOrder(properties, propertiesOrder, priorityKeys) {
|
|
298
242
|
const lowerCasePriorityKeys = (priorityKeys ?? []).map((key) => key.toLowerCase());
|
|
@@ -443,7 +387,7 @@
|
|
|
443
387
|
function buildPropertyFromCount(key, totalDocsCount, mostProbableType, typesCount, valuesResult) {
|
|
444
388
|
let title;
|
|
445
389
|
if (key) {
|
|
446
|
-
title = prettifyIdentifier(key);
|
|
390
|
+
title = utils.prettifyIdentifier(key);
|
|
447
391
|
}
|
|
448
392
|
let result = void 0;
|
|
449
393
|
if (mostProbableType === "map") {
|
|
@@ -559,23 +503,38 @@
|
|
|
559
503
|
if (typeof value === "object") return "map";
|
|
560
504
|
return "string";
|
|
561
505
|
}
|
|
506
|
+
Object.defineProperty(exports2, "isObject", {
|
|
507
|
+
enumerable: true,
|
|
508
|
+
get: () => utils.isObject
|
|
509
|
+
});
|
|
510
|
+
Object.defineProperty(exports2, "isPlainObject", {
|
|
511
|
+
enumerable: true,
|
|
512
|
+
get: () => utils.isPlainObject
|
|
513
|
+
});
|
|
514
|
+
Object.defineProperty(exports2, "mergeDeep", {
|
|
515
|
+
enumerable: true,
|
|
516
|
+
get: () => utils.mergeDeep
|
|
517
|
+
});
|
|
518
|
+
Object.defineProperty(exports2, "prettifyIdentifier", {
|
|
519
|
+
enumerable: true,
|
|
520
|
+
get: () => utils.prettifyIdentifier
|
|
521
|
+
});
|
|
522
|
+
Object.defineProperty(exports2, "unslugify", {
|
|
523
|
+
enumerable: true,
|
|
524
|
+
get: () => utils.unslugify
|
|
525
|
+
});
|
|
562
526
|
exports2.buildEntityPropertiesFromData = buildEntityPropertiesFromData;
|
|
563
527
|
exports2.buildPropertiesOrder = buildPropertiesOrder;
|
|
564
528
|
exports2.buildPropertyFromData = buildPropertyFromData;
|
|
565
529
|
exports2.extractEnumFromValues = extractEnumFromValues;
|
|
566
530
|
exports2.findCommonInitialStringInPath = findCommonInitialStringInPath;
|
|
567
531
|
exports2.inferTypeFromValue = inferTypeFromValue;
|
|
568
|
-
exports2.isObject = isObject;
|
|
569
|
-
exports2.isPlainObject = isPlainObject;
|
|
570
532
|
exports2.looksLikeReference = looksLikeReference;
|
|
571
|
-
exports2.mergeDeep = mergeDeep;
|
|
572
533
|
exports2.parseReferenceString = parseReferenceString;
|
|
573
|
-
exports2.prettifyIdentifier = prettifyIdentifier;
|
|
574
534
|
exports2.removeInitialAndTrailingSlashes = removeInitialAndTrailingSlashes;
|
|
575
535
|
exports2.removeInitialSlash = removeInitialSlash;
|
|
576
536
|
exports2.removeTrailingSlash = removeTrailingSlash;
|
|
577
537
|
exports2.resolveEnumValues = resolveEnumValues;
|
|
578
|
-
exports2.unslugify = unslugify;
|
|
579
538
|
Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
|
|
580
539
|
}));
|
|
581
540
|
//# sourceMappingURL=index.umd.cjs.map
|
package/dist/index.umd.cjs.map
CHANGED
|
@@ -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\n/**\n * Parse a reference string value which can be in the format:\n * - Simple: \"path/entityId\"\n * - With database: \"database_name:::path/entityId\"\n * Returns the path and database (undefined if not specified or if \"(default)\")\n */\nexport function parseReferenceString(value: string): { path: string; database?: string } | null {\n if (!value) return null;\n\n let database: string | undefined = undefined;\n let fullPath = value;\n\n // Parse the new format: database_name:::path/entityId\n if (value.includes(\":::\")) {\n const [dbName, pathPart] = value.split(\":::\");\n if (dbName && dbName !== \"(default)\") {\n database = dbName;\n }\n fullPath = pathPart;\n }\n\n // Check if it looks like a path (contains at least one slash)\n if (!fullPath || !fullPath.includes(\"/\")) {\n return null;\n }\n\n // Extract the collection path (everything before the last slash)\n const path = fullPath.substring(0, fullPath.lastIndexOf(\"/\"));\n\n return { path, database };\n}\n\n/**\n * Check if a string value looks like a reference\n */\nexport function looksLikeReference(value: any): boolean {\n if (typeof value !== \"string\") return false;\n return parseReferenceString(value) !== null;\n}\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any): string | undefined {\n let pathString: string | undefined;\n\n if (typeof value === \"string\") {\n pathString = value;\n } else if (value.slug) {\n pathString = value.slug;\n } else {\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n return undefined;\n }\n\n if (!pathString) return undefined;\n\n // Parse the new format: database_name:::path/entityId\n // Extract just the path portion for comparison\n if (pathString.includes(\":::\")) {\n const [, pathPart] = pathString.split(\":::\");\n pathString = pathPart;\n }\n\n return pathString;\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.substring(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 \"@rebasepro/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 ({\n id: value,\n label: unslugify(value)\n });\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 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:\", {\n input,\n s\n });\n return s;\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.substring(1);\n }).trim();\n } else {\n return slug.trim();\n }\n}\n\nexport function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n // Check Array.isArray first since typeof [] === \"object\" is true in JavaScript\n if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else if (typeof input === \"object\" && input !== null) {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\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 (isPlainObject(sourceElement)) {\n // Only recursively merge plain objects, not class instances\n if (!(key in target))\n Object.assign(output, { [key]: sourceElement });\n else if (isPlainObject((target as Record<string, unknown>)[key]))\n (output as Record<string, unknown>)[key] = mergeDeep((target as Record<string, unknown>)[key] as Record<string, unknown>, sourceElement);\n else\n Object.assign(output, { [key]: sourceElement });\n } else if (isObject(sourceElement)) {\n // For class instances (EntityReference, GeoPoint, etc.), assign directly to preserve prototype\n Object.assign(output, { [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\nexport function isPlainObject(obj: any) {\n if (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) {\n return false;\n }\n return Object.getPrototypeOf(obj) === Object.prototype;\n}\n\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../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 name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n name: name ?? \"\",\n type: \"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.enum = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enum) {\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 } as StringProperty;\n }\n\n return stringProperty;\n}\n\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): false | FileType[] {\n const isImage = (value: string) => IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isAudio = (value: string) => AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isVideo = (value: string) => VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n\n const stringValues = valuesCount.values.filter((v): v is string => typeof v === \"string\");\n \n let imageCount = 0;\n let audioCount = 0;\n let videoCount = 0;\n\n for (const value of stringValues) {\n if (isImage(value)) imageCount++;\n else if (isAudio(value)) audioCount++;\n else if (isVideo(value)) videoCount++;\n }\n\n const totalMediaCount = imageCount + audioCount + videoCount;\n if (totalMediaCount > (totalDocsCount * 2) / 3) {\n const fileTypes: FileType[] = [];\n if (imageCount > 0) fileTypes.push(\"image/*\");\n if (audioCount > 0) fileTypes.push(\"audio/*\");\n if (videoCount > 0) fileTypes.push(\"video/*\");\n return fileTypes.length > 0 ? fileTypes : false;\n }\n\n return false;\n}\n","import { PropertyValidationSchema } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { InferencePropertyBuilderProps } from \"../types\";\nimport { Property } from \"@rebasepro/types\";\n\nexport function buildReferenceProperty({\n name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n name: name ?? \"\",\n type: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\"\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 \"@rebasepro/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.type, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enum\" in property ? resolveEnumValues(property[\"enum\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enum: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\n \"inferred_prop\",\n data.length,\n property.type,\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] = Number(arrayTypesCount[arrayType]) + 1;\n }\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else typesCount[type] = Number(typesCount[type]) + 1;\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 type = 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 (type === \"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 (type === \"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 = Number(count);\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 = Number(count);\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"array\",\n name: title ?? key ?? \"\",\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 type: 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 result;\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, Number(value));\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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"}
|
|
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\n/**\n * Parse a reference string value which can be in the format:\n * - Simple: \"path/entityId\"\n * - With database: \"database_name:::path/entityId\"\n * Returns the path and database (undefined if not specified or if \"(default)\")\n */\nexport function parseReferenceString(value: string): { path: string; database?: string } | null {\n if (!value) return null;\n\n let database: string | undefined = undefined;\n let fullPath = value;\n\n // Parse the new format: database_name:::path/entityId\n if (value.includes(\":::\")) {\n const [dbName, pathPart] = value.split(\":::\");\n if (dbName && dbName !== \"(default)\") {\n database = dbName;\n }\n fullPath = pathPart;\n }\n\n // Check if it looks like a path (contains at least one slash)\n if (!fullPath || !fullPath.includes(\"/\")) {\n return null;\n }\n\n // Extract the collection path (everything before the last slash)\n const path = fullPath.substring(0, fullPath.lastIndexOf(\"/\"));\n\n return { path,\ndatabase };\n}\n\n/**\n * Check if a string value looks like a reference\n */\nexport function looksLikeReference(value: any): boolean {\n if (typeof value !== \"string\") return false;\n return parseReferenceString(value) !== null;\n}\n\nexport function findCommonInitialStringInPath(valuesCount?: ValuesCountEntry) {\n\n if (!valuesCount) return undefined;\n\n function getPath(value: any): string | undefined {\n let pathString: string | undefined;\n\n if (typeof value === \"string\") {\n pathString = value;\n } else if (value.slug) {\n pathString = value.slug;\n } else {\n console.warn(\"findCommonInitialStringInPath: value is not a string or document with path\", value);\n return undefined;\n }\n\n if (!pathString) return undefined;\n\n // Parse the new format: database_name:::path/entityId\n // Extract just the path portion for comparison\n if (pathString.includes(\":::\")) {\n const [, pathPart] = pathString.split(\":::\");\n pathString = pathPart;\n }\n\n return pathString;\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.substring(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 \"@rebasepro/types\";\nimport { unslugify } from \"@rebasepro/utils\";\n\n// Canonical utility functions — single source of truth in @rebasepro/utils\nexport { unslugify, prettifyIdentifier, isObject, isPlainObject, mergeDeep } from \"@rebasepro/utils\";\n\n/**\n * Extract enum values from a list of sample values.\n * This is schema-inference-specific logic (not a general utility).\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 ({\n id: value,\n label: unslugify(value)\n });\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 resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {\n // Check Array.isArray first since typeof [] === \"object\" is true in JavaScript\n if (Array.isArray(input)) {\n return input as EnumValueConfig[];\n } else if (typeof input === \"object\" && input !== null) {\n return Object.entries(input).map(([id, value]) =>\n (typeof value === \"string\"\n ? {\n id,\n label: value\n }\n : value));\n } else {\n return undefined;\n }\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { extractEnumFromValues } from \"../util\";\nimport { FileType, Property, StringProperty } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps, ValuesCountEntry } from \"../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 name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n let stringProperty: Property = {\n name: name ?? \"\",\n type: \"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.enum = enumValues;\n }\n\n // regular string\n if (!probablyAnEmail &&\n !probablyAURL &&\n !probablyUserIds &&\n !probablyAURL &&\n !config.enum) {\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 } as StringProperty;\n }\n\n return stringProperty;\n}\n\nfunction probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number): false | FileType[] {\n const isImage = (value: string) => IMAGE_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isAudio = (value: string) => AUDIO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n const isVideo = (value: string) => VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));\n\n const stringValues = valuesCount.values.filter((v): v is string => typeof v === \"string\");\n\n let imageCount = 0;\n let audioCount = 0;\n let videoCount = 0;\n\n for (const value of stringValues) {\n if (isImage(value)) imageCount++;\n else if (isAudio(value)) audioCount++;\n else if (isVideo(value)) videoCount++;\n }\n\n const totalMediaCount = imageCount + audioCount + videoCount;\n if (totalMediaCount > (totalDocsCount * 2) / 3) {\n const fileTypes: FileType[] = [];\n if (imageCount > 0) fileTypes.push(\"image/*\");\n if (audioCount > 0) fileTypes.push(\"audio/*\");\n if (videoCount > 0) fileTypes.push(\"video/*\");\n return fileTypes.length > 0 ? fileTypes : false;\n }\n\n return false;\n}\n","import { PropertyValidationSchema } from \"@rebasepro/types\";\nimport { InferencePropertyBuilderProps } from \"../types\";\n\nexport function buildValidation({\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): PropertyValidationSchema | undefined {\n\n if (valuesResult) {\n const totalEntriesCount = valuesResult.values.length;\n if (totalDocsCount === totalEntriesCount)\n return {\n required: true\n }\n }\n\n return undefined;\n}\n","import { findCommonInitialStringInPath } from \"../strings\";\nimport { InferencePropertyBuilderProps } from \"../types\";\nimport { Property } from \"@rebasepro/types\";\n\nexport function buildReferenceProperty({\n name,\n totalDocsCount,\n valuesResult\n}: InferencePropertyBuilderProps): Property {\n\n const property: Property = {\n name: name ?? \"\",\n type: \"reference\",\n path: findCommonInitialStringInPath(valuesResult) ?? \"!!!FIX_ME!!!\"\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 \"@rebasepro/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.type, typesCount, entry, getType);\n increaseValuesCount(valuesCount, \"inferred_prop\", entry, getType);\n });\n }\n const enumValues = \"enum\" in property ? resolveEnumValues(property[\"enum\"] as EnumValues) : undefined;\n if (enumValues) {\n const newEnumValues = extractEnumFromValues(Array.from(valuesCount[\"inferred_prop\"].valuesCount.keys()));\n return {\n ...property,\n enum: [...newEnumValues, ...enumValues]\n } as StringProperty;\n }\n const generatedProperty = buildPropertyFromCount(\n \"inferred_prop\",\n data.length,\n property.type,\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] = Number(arrayTypesCount[arrayType]) + 1;\n }\n }\n } else {\n if (!typesCount[type]) typesCount[type] = 1;\n else typesCount[type] = Number(typesCount[type]) + 1;\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 type = 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 (type === \"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 (type === \"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 = Number(count);\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 = Number(count);\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"map\",\n name: title ?? key ?? \"\",\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 type: \"array\",\n name: title ?? key ?? \"\",\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 type: 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 result;\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, Number(value));\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":["unslugify","mergeDeep","prettifyIdentifier"],"mappings":"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"}
|
package/dist/util.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { EnumValueConfig, EnumValues } from "@rebasepro/types";
|
|
2
|
+
export { unslugify, prettifyIdentifier, isObject, isPlainObject, mergeDeep } from "@rebasepro/utils";
|
|
3
|
+
/**
|
|
4
|
+
* Extract enum values from a list of sample values.
|
|
5
|
+
* This is schema-inference-specific logic (not a general utility).
|
|
6
|
+
*/
|
|
2
7
|
export declare function extractEnumFromValues(values: unknown[]): {
|
|
3
8
|
id: string;
|
|
4
9
|
label: string;
|
|
5
10
|
}[];
|
|
6
|
-
export declare function prettifyIdentifier(input: string): string;
|
|
7
|
-
export declare function unslugify(slug?: string): string;
|
|
8
11
|
export declare function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined;
|
|
9
|
-
export declare function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined?: boolean): T & U;
|
|
10
|
-
export declare function isObject(item: any): any;
|
|
11
|
-
export declare function isPlainObject(obj: any): boolean;
|
package/package.json
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@rebasepro/schema-inference",
|
|
3
|
+
"version": "0.0.1-canary.ca2cb6e",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/index.umd.cjs",
|
|
9
|
+
"module": "./dist/index.es.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"source": "src/index.ts",
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@types/node": "^20.17.14",
|
|
14
|
+
"typescript": "^5.9.3",
|
|
15
|
+
"vite": "^7.2.4",
|
|
16
|
+
"@rebasepro/types": "0.0.1-canary.ca2cb6e",
|
|
17
|
+
"@rebasepro/utils": "0.0.1-canary.ca2cb6e"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"development": "./src/index.ts",
|
|
23
|
+
"import": "./dist/index.es.js",
|
|
24
|
+
"require": "./dist/index.umd.cjs"
|
|
7
25
|
},
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"development": "./src/index.ts",
|
|
22
|
-
"import": "./dist/index.es.js",
|
|
23
|
-
"require": "./dist/index.umd.cjs"
|
|
24
|
-
},
|
|
25
|
-
"./package.json": "./package.json"
|
|
26
|
-
},
|
|
27
|
-
"files": [
|
|
28
|
-
"dist",
|
|
29
|
-
"src"
|
|
30
|
-
],
|
|
31
|
-
"scripts": {
|
|
32
|
-
"dev": "vite",
|
|
33
|
-
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
34
|
-
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
|
|
35
|
-
},
|
|
36
|
-
"gitHead": "71bcef3c51a458cd054f7924cc18efbbe515dcc8"
|
|
37
|
-
}
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"src"
|
|
31
|
+
],
|
|
32
|
+
"gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"dev": "vite",
|
|
35
|
+
"build": "vite build && tsc --emitDeclarationOnly -p tsconfig.prod.json",
|
|
36
|
+
"clean": "rm -rf dist && find ./src -name '*.js' -type f | xargs rm -f"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -17,7 +17,7 @@ export function buildStringProperty({
|
|
|
17
17
|
|
|
18
18
|
let stringProperty: Property = {
|
|
19
19
|
name: name ?? "",
|
|
20
|
-
type: "string"
|
|
20
|
+
type: "string"
|
|
21
21
|
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -91,7 +91,7 @@ function probableFileType(valuesCount: ValuesCountEntry, totalDocsCount: number)
|
|
|
91
91
|
const isVideo = (value: string) => VIDEO_EXTENSIONS.some((extension) => value.toString().endsWith(extension));
|
|
92
92
|
|
|
93
93
|
const stringValues = valuesCount.values.filter((v): v is string => typeof v === "string");
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
let imageCount = 0;
|
|
96
96
|
let audioCount = 0;
|
|
97
97
|
let videoCount = 0;
|
package/src/strings.ts
CHANGED
|
@@ -29,7 +29,8 @@ export function parseReferenceString(value: string): { path: string; database?:
|
|
|
29
29
|
// Extract the collection path (everything before the last slash)
|
|
30
30
|
const path = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
31
31
|
|
|
32
|
-
return { path,
|
|
32
|
+
return { path,
|
|
33
|
+
database };
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
/**
|
|
@@ -12,7 +12,9 @@ import * as util from "util";
|
|
|
12
12
|
import { DataType } from "@rebasepro/types";
|
|
13
13
|
|
|
14
14
|
buildEntityPropertiesFromData(usage, getType)
|
|
15
|
-
.then((res) => console.log(util.inspect(res, { showHidden: false,
|
|
15
|
+
.then((res) => console.log(util.inspect(res, { showHidden: false,
|
|
16
|
+
depth: null,
|
|
17
|
+
colors: true })));
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
function getType(value: any): DataType {
|
package/src/util.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { EnumValueConfig, EnumValues } from "@rebasepro/types";
|
|
2
|
+
import { unslugify } from "@rebasepro/utils";
|
|
2
3
|
|
|
4
|
+
// Canonical utility functions — single source of truth in @rebasepro/utils
|
|
5
|
+
export { unslugify, prettifyIdentifier, isObject, isPlainObject, mergeDeep } from "@rebasepro/utils";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extract enum values from a list of sample values.
|
|
9
|
+
* This is schema-inference-specific logic (not a general utility).
|
|
10
|
+
*/
|
|
3
11
|
export function extractEnumFromValues(values: unknown[]) {
|
|
4
12
|
if (!Array.isArray(values)) {
|
|
5
13
|
return [];
|
|
@@ -18,42 +26,6 @@ export function extractEnumFromValues(values: unknown[]) {
|
|
|
18
26
|
return enumValues;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
|
-
export function prettifyIdentifier(input: string) {
|
|
22
|
-
if (!input) return "";
|
|
23
|
-
|
|
24
|
-
let text = input;
|
|
25
|
-
|
|
26
|
-
// 1. Handle camelCase and Acronyms
|
|
27
|
-
// Group 1 ($1 $2): Lowercase followed by Uppercase (e.g., imageURL -> image URL)
|
|
28
|
-
// Group 2 ($3 $4): Uppercase followed by Uppercase+lowercase (e.g., XMLParser -> XML Parser)
|
|
29
|
-
text = text.replace(/([a-z])([A-Z])|([A-Z])([A-Z][a-z])/g, "$1$3 $2$4");
|
|
30
|
-
|
|
31
|
-
// 2. Replace hyphens/underscores with spaces
|
|
32
|
-
text = text.replace(/[_-]+/g, " ");
|
|
33
|
-
|
|
34
|
-
// 3. Capitalize first letter of each word (Title Case)
|
|
35
|
-
const s = text
|
|
36
|
-
.trim()
|
|
37
|
-
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
38
|
-
console.log("Prettified identifier:", {
|
|
39
|
-
input,
|
|
40
|
-
s
|
|
41
|
-
});
|
|
42
|
-
return s;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function unslugify(slug?: string): string {
|
|
46
|
-
if (!slug) return "";
|
|
47
|
-
if (slug.includes("-") || slug.includes("_") || !slug.includes(" ")) {
|
|
48
|
-
const result = slug.replace(/[-_]/g, " ");
|
|
49
|
-
return result.replace(/\w\S*/g, function (txt) {
|
|
50
|
-
return txt.charAt(0).toUpperCase() + txt.substring(1);
|
|
51
|
-
}).trim();
|
|
52
|
-
} else {
|
|
53
|
-
return slug.trim();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
29
|
export function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefined {
|
|
58
30
|
// Check Array.isArray first since typeof [] === "object" is true in JavaScript
|
|
59
31
|
if (Array.isArray(input)) {
|
|
@@ -70,47 +42,3 @@ export function resolveEnumValues(input: EnumValues): EnumValueConfig[] | undefi
|
|
|
70
42
|
return undefined;
|
|
71
43
|
}
|
|
72
44
|
}
|
|
73
|
-
|
|
74
|
-
export function mergeDeep<T extends Record<any, any>, U extends Record<any, any>>(target: T, source: U, ignoreUndefined: boolean = false): T & U {
|
|
75
|
-
const targetIsObject = isObject(target);
|
|
76
|
-
const output = targetIsObject ? { ...target } : target;
|
|
77
|
-
if (targetIsObject && isObject(source)) {
|
|
78
|
-
Object.keys(source).forEach(key => {
|
|
79
|
-
const sourceElement = source[key];
|
|
80
|
-
// Skip undefined values when ignoreUndefined is true
|
|
81
|
-
if (ignoreUndefined && sourceElement === undefined) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (sourceElement instanceof Date) {
|
|
85
|
-
// Assign a new Date instance with the same time value
|
|
86
|
-
Object.assign(output, { [key]: new Date(sourceElement.getTime()) });
|
|
87
|
-
} else if (isPlainObject(sourceElement)) {
|
|
88
|
-
// Only recursively merge plain objects, not class instances
|
|
89
|
-
if (!(key in target))
|
|
90
|
-
Object.assign(output, { [key]: sourceElement });
|
|
91
|
-
else if (isPlainObject((target as Record<string, unknown>)[key]))
|
|
92
|
-
(output as Record<string, unknown>)[key] = mergeDeep((target as Record<string, unknown>)[key] as Record<string, unknown>, sourceElement);
|
|
93
|
-
else
|
|
94
|
-
Object.assign(output, { [key]: sourceElement });
|
|
95
|
-
} else if (isObject(sourceElement)) {
|
|
96
|
-
// For class instances (EntityReference, GeoPoint, etc.), assign directly to preserve prototype
|
|
97
|
-
Object.assign(output, { [key]: sourceElement });
|
|
98
|
-
} else {
|
|
99
|
-
Object.assign(output, { [key]: sourceElement });
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return output as T;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function isObject(item: any) {
|
|
107
|
-
return item && typeof item === "object" && !Array.isArray(item);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function isPlainObject(obj: any) {
|
|
111
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
return Object.getPrototypeOf(obj) === Object.prototype;
|
|
115
|
-
}
|
|
116
|
-
|