diff --git a/frontend-web-free/src/api/krowSDK.js b/frontend-web-free/src/api/krowSDK.js index 93a31ed3..454db78a 100644 --- a/frontend-web-free/src/api/krowSDK.js +++ b/frontend-web-free/src/api/krowSDK.js @@ -373,6 +373,24 @@ const toCamel = (value) => { return value; }; +// --- Helper to convert camelCase to snake_case recursively --- +const toSnake = (value) => { + if (Array.isArray(value)) { + return value.map(toSnake); + } + if (value && typeof value === "object") { + return Object.entries(value).reduce((acc, [key, val]) => { + const snakeKey = key + .replace(/([A-Z])/g, "_$1") + .toLowerCase(); + acc[snakeKey] = toSnake(val); + return acc; + }, {}); + } + return value; +}; + + Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => { entitiesModule[entityName] = { @@ -392,102 +410,91 @@ Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => { `Data Connect operation "${ops.list}" not found for entity "${entityName}".` ); } - - //return fn(dataConnect); - /*let variables; - const maybeVars = params[0]; - - if (maybeVars && typeof maybeVars === 'object' && !Array.isArray(maybeVars)) { - variables = maybeVars; + + let sort; + let limit; + let baseVariables; // por si algún list usa variables (como Team) + + if (args.length === 1) { + const [a0] = args; + if (typeof a0 === "string") { + // list('-created_date') + sort = a0; + } else if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { + // list({ ...vars }) -> reservado para queries que acepten variables + baseVariables = a0; + } + } else if (args.length === 2) { + const [a0, a1] = args; + if (typeof a0 === "string" && typeof a1 === "number") { + // list('-created_date', 50) + sort = a0; + limit = a1; + } else if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { + // list({ ...vars }, '-created_date') + baseVariables = a0; + if (typeof a1 === "string") sort = a1; + } + } else if (args.length >= 3) { + const [a0, a1, a2] = args; + if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { + // list({ ...vars }, '-created_date', 50) + baseVariables = a0; + if (typeof a1 === "string") sort = a1; + if (typeof a2 === "number") limit = a2; + } + } + + // COMMENT FIX: variables que realmente se mandan a DataConnect + let variables = baseVariables; + + // COMMENT FIX: caso especial para Team, que SÍ tiene orderBy/limit en el query + if (entityName === "Team") { + variables = variables || {}; + if (sort) { + const desc = sort.startsWith("-"); + variables.orderByCreatedDate = desc ? "DESC" : "ASC"; + } + if (typeof limit === "number") { + variables.limit = limit; + } } const res = await fn(dataConnect, variables); - return normalizeResultToArray(res); - */ + let items = normalizeResultToArray(res); - let sort; - let limit; - let baseVariables; // por si algún list usa variables (como Team) + // COMMENT FIX: para entidades que NO tienen orderBy/limit en el query, + // aplicamos sort/limit en el front como fallback. + if (entityName !== "Team" && sort) { + const desc = sort.startsWith("-"); + const field = desc ? sort.slice(1) : sort; // '-created_date' -> 'created_date' - if (args.length === 1) { - const [a0] = args; - if (typeof a0 === "string") { - // list('-created_date') - sort = a0; - } else if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { - // list({ ...vars }) -> reservado para queries que acepten variables - baseVariables = a0; - } - } else if (args.length === 2) { - const [a0, a1] = args; - if (typeof a0 === "string" && typeof a1 === "number") { - // list('-created_date', 50) - sort = a0; - limit = a1; - } else if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { - // list({ ...vars }, '-created_date') - baseVariables = a0; - if (typeof a1 === "string") sort = a1; - } - } else if (args.length >= 3) { - const [a0, a1, a2] = args; - if (a0 && typeof a0 === "object" && !Array.isArray(a0)) { - // list({ ...vars }, '-created_date', 50) - baseVariables = a0; - if (typeof a1 === "string") sort = a1; - if (typeof a2 === "number") limit = a2; - } - } + items = items.slice().sort((a, b) => { + const av = a?.[field]; + const bv = b?.[field]; - // COMMENT FIX: variables que realmente se mandan a DataConnect - let variables = baseVariables; + if (av == null && bv == null) return 0; + if (av == null) return 1; + if (bv == null) return -1; - // COMMENT FIX: caso especial para Team, que SÍ tiene orderBy/limit en el query - if (entityName === "Team") { - variables = variables || {}; - if (sort) { - const desc = sort.startsWith("-"); - variables.orderByCreatedDate = desc ? "DESC" : "ASC"; - } - if (typeof limit === "number") { - variables.limit = limit; - } - } + const da = new Date(av); + const db = new Date(bv); + if (!isNaN(da) && !isNaN(db)) { + return desc ? db - da : da - db; + } - const res = await fn(dataConnect, variables); - let items = normalizeResultToArray(res); - - // COMMENT FIX: para entidades que NO tienen orderBy/limit en el query, - // aplicamos sort/limit en el front como fallback. - if (entityName !== "Team" && sort) { - const desc = sort.startsWith("-"); - const field = desc ? sort.slice(1) : sort; // '-created_date' -> 'created_date' - - items = items.slice().sort((a, b) => { - const av = a?.[field]; - const bv = b?.[field]; - - if (av == null && bv == null) return 0; - if (av == null) return 1; - if (bv == null) return -1; - - const da = new Date(av); - const db = new Date(bv); - if (!isNaN(da) && !isNaN(db)) { - return desc ? db - da : da - db; + if (av < bv) return desc ? 1 : -1; + if (av > bv) return desc ? -1 : 1; + return 0; + }); } - if (av < bv) return desc ? 1 : -1; - if (av > bv) return desc ? -1 : 1; - return 0; - }); - } - - if (entityName !== "Team" && typeof limit === "number") { - items = items.slice(0, limit); - } - - return items; + if (entityName !== "Team" && typeof limit === "number") { + items = items.slice(0, limit); + } + //console.log(items) + //return items; + return items.map(toSnake); }, }), @@ -501,14 +508,6 @@ Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => { ); } - /*const { data } = params ?? {}; - if (!data) { - throw new Error( - `${entityName}.create expects a payload like { data: { ...fields } }` - ); - } - - return fn(dataConnect, data);*/ if (!params || typeof params !== 'object') { throw new Error( `${entityName}.create expects an object with the fields to insert` @@ -546,13 +545,16 @@ Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => { throw new Error(`${entityName}.get expects an object of variables (e.g. { id })`); } - return fn(dataConnect, params); + //return fn(dataConnect, params); + const result = await fn(dataConnect, params); + return toSnake(result); + }, }), //update ...(ops.update && { - update: async (params) => { + update: async (id,params) => { const fn = dcSdk[ops.update]; if (typeof fn !== 'function') { throw new Error( @@ -566,7 +568,8 @@ Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => { ); } - const { id, data } = params; + //const { id, data } = params; + let data = params; if (!id) { throw new Error(`${entityName}.update requires an "id" field`);