import _ from "lodash";
import sqlGenerator from "../../functions/dsql/sql/sql-generator";
import {
DsqlCrudQueryObject,
DsqlMethodCrudParam,
ServerQueryParam,
} from "../../types";
import deserializeQuery from "../deserialize-query";
import EJSON from "../ejson";
import numberfy from "../numberfy";
import dsqlCrud from "./crud";
export type APIDataCrudQuery = ServerQueryParam & {
page?: number;
};
export type CRUDResponseObject
= {
success: boolean;
payload?: P;
msg?: string;
error?: string;
queryObject?: ReturnType>;
};
export default async function dsqlMethodCrud<
T extends { [key: string]: any } = { [key: string]: any },
P extends { [key: string]: any } = { [key: string]: any }
>({
method,
tableName,
addUser,
user,
extraData,
transformData,
existingData,
body,
query,
targetId,
sanitize,
transformQuery,
debug,
}: DsqlMethodCrudParam): Promise> {
let result: CRUDResponseObject = {
success: false,
};
try {
let finalBody = body;
let finalQuery = deserializeQuery(query as any) as
| DsqlCrudQueryObject
| undefined;
let LIMIT = 10;
let PAGE = 1;
let OFFSET = (PAGE - 1) * LIMIT;
if (method == "GET") {
const newFinalQuery = _.cloneDeep(
finalQuery || ({} as DsqlCrudQueryObject)
);
Object.keys(newFinalQuery).forEach((key) => {
const value = newFinalQuery[key];
if (typeof value == "string" && value.match(/^\{|^\[/)) {
newFinalQuery[key] = EJSON.stringify(value);
}
if (value == "true") {
newFinalQuery[key] = true;
}
if (value == "false") {
newFinalQuery[key] = false;
}
});
if (newFinalQuery.limit) LIMIT = numberfy(newFinalQuery.limit);
if (newFinalQuery.page) PAGE = numberfy(newFinalQuery.page);
OFFSET = (PAGE - 1) * LIMIT;
finalQuery = newFinalQuery;
}
let finalData = finalBody
? ({
...finalBody,
...extraData,
} as T)
: ({} as T);
if (user?.id && addUser) {
finalData = {
...finalData,
[addUser.field]: String(user.id),
} as T;
}
if (transformData) {
if (debug) {
console.log("DEBUG:::transforming Data ...");
}
finalData = (await transformData({
data: finalData,
existingData: existingData,
user,
reqMethod: method,
})) as T;
}
if (transformQuery) {
if (debug) {
console.log("DEBUG:::transforming Query ...");
}
finalQuery = await transformQuery({
query: finalQuery || {},
user,
reqMethod: method,
});
}
if (debug) {
console.log("DEBUG:::finalQuery", finalQuery);
console.log("DEBUG:::finalData", finalData);
}
switch (method) {
case "GET":
const GET_RESULT = await dsqlCrud({
action: "get",
table: tableName,
query: {
...finalQuery,
query: {
...finalQuery?.query,
...(user?.id && addUser
? {
[addUser.field]: {
value: String(user.id),
},
}
: undefined),
},
limit: LIMIT,
offset: OFFSET,
} as any,
sanitize,
});
result = {
success: Boolean(GET_RESULT?.success),
payload: GET_RESULT?.payload,
msg: GET_RESULT?.msg,
error: GET_RESULT?.error,
queryObject: GET_RESULT?.queryObject,
};
break;
case "POST":
const POST_RESULT = await dsqlCrud({
action: "insert",
table: tableName,
data:
finalData && Object.keys(finalData)?.[0]
? finalData
: undefined,
sanitize,
});
result = {
success: Boolean(POST_RESULT?.success),
payload: POST_RESULT?.payload,
msg: POST_RESULT?.msg,
error: POST_RESULT?.error,
};
break;
case "PUT":
const PUT_RESULT = await dsqlCrud({
action: "update",
table: tableName,
data:
finalData && Object.keys(finalData)?.[0]
? finalData
: undefined,
targetId,
sanitize,
});
result = {
success: Boolean(PUT_RESULT?.success),
payload: PUT_RESULT?.payload,
msg: PUT_RESULT?.msg,
error: PUT_RESULT?.error,
};
break;
case "DELETE":
const DELETE_RESULT = await dsqlCrud({
action: "delete",
table: tableName,
targetId,
sanitize,
});
result = {
success: Boolean(DELETE_RESULT?.success),
payload: DELETE_RESULT?.payload,
msg: DELETE_RESULT?.msg,
error: DELETE_RESULT?.error,
};
break;
default:
break;
}
return result;
} catch (error) {
return result;
}
}