refine-apito
Version:
A data provider for Refine that connects to Apito - a headless CMS and backend builder.
936 lines (932 loc) • 37.7 kB
JavaScript
import { Client, cacheExchange, fetchExchange, gql } from '@urql/core';
import 'inflection';
// src/provider.ts
function splitCamelPieces(piece) {
const spaced = piece.replace(/([a-z0-9])([A-Z])/g, "$1 $2");
return spaced.split(/\s+/).filter(Boolean).map((s) => s.replace(/[^a-zA-Z0-9]/g, "").toLowerCase()).filter(Boolean);
}
function camelFromCanonical(canonical) {
const parts = canonical.split("_").filter(Boolean);
return parts.map(
(p, i) => i === 0 ? p.toLowerCase() : p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()
).join("");
}
function pascalFromCanonical(canonical) {
return canonical.split("_").filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join("");
}
function pascalFromAnyModelId(modelId) {
if (!modelId) return "";
if (modelId.includes("_")) return pascalFromCanonical(modelId);
const segs = splitCamelPieces(modelId);
return segs.map((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()).join("");
}
function listGraphQLTypeName(modelId) {
return `${pascalFromAnyModelId(apitoSingularResourceName(modelId))}List`;
}
function apitoGraphQLComposedTypeName(modelId, suffix) {
const singular = apitoSingularResourceName(modelId);
const suf = suffix.replace(/^_/, "").split("_").filter(Boolean);
const modelSegs = singular.includes("_") ? singular.split("_").filter(Boolean) : splitCamelPieces(singular).map((s) => s.toLowerCase());
const extra = suf.flatMap(
(chunk) => splitCamelPieces(chunk).map((x) => x.toLowerCase())
);
const all = [...modelSegs, ...extra];
return all.map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join("_");
}
function apitoSingularResourceName(name) {
let t = name.trim();
if (t.endsWith("ListCount")) t = t.slice(0, -"ListCount".length);
else if (t.endsWith("List")) t = t.slice(0, -"List".length);
t = t.trim();
if (!t) return "";
if (t.includes("_")) {
return camelFromCanonical(t);
}
const segs = splitCamelPieces(t);
if (segs.length === 0) return t.toLowerCase();
return segs.map(
(s, i) => i === 0 ? s.toLowerCase() : s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()
).join("");
}
var apitoModelName = apitoSingularResourceName;
function apitoMultipleResourceName(name) {
return `${apitoSingularResourceName(name)}List`;
}
function apitoGraphqlConnectionFieldFromMetaKey(key) {
const k = key.trim();
if (!k) return k;
if (k.includes("_")) {
return apitoSingularResourceName(k);
}
if (/List$/i.test(k) && !/ListCount$/i.test(k)) {
return k.charAt(0).toLowerCase() + k.slice(1);
}
return apitoSingularResourceName(k);
}
function apitoListGraphQLTypeName(resource) {
return listGraphQLTypeName(resource);
}
function apitoSingularGraphQLTypeName(resource) {
return pascalFromAnyModelId(apitoSingularResourceName(resource));
}
function apitoStoredSnakeModelId(resource) {
const singular = apitoSingularResourceName(resource);
if (singular.includes("_")) return singular;
return splitCamelPieces(singular).join("_");
}
function apitoConnectionFilterConditionType(resource) {
return `${apitoStoredSnakeModelId(resource)}_Connection_Filter_Condition`.toUpperCase();
}
function apitoWhereRelationFilterConditionType(resource) {
return `${apitoStoredSnakeModelId(resource)}_Where_Relation_Filter_Condition`.toUpperCase();
}
function apitoWhereInputType(resource) {
return `${listGraphQLTypeName(resource)}_Input_Where_Payload`.toUpperCase();
}
function apitoSortInputType(resource) {
return `${listGraphQLTypeName(resource)}_Input_Sort_Payload`.toUpperCase();
}
function apitoListKeyConditionType(resource) {
return `${listGraphQLTypeName(resource)}_Key_Condition`.toUpperCase();
}
function apitoListCountKeyConditionType(resource) {
return `${apitoGraphQLComposedTypeName(resource, "List_Count")}_Key_Condition`.toUpperCase();
}
function apitoListCountWhereInputType(resource) {
return `${apitoGraphQLComposedTypeName(resource, "List_Count")}_Input_Where_Payload`.toUpperCase();
}
function formatApitoConnectionSubselections(connectionFields, aliasFields = {}) {
return Object.keys(connectionFields).map((key) => {
const selection = connectionFields[key];
const rawTarget = aliasFields[key];
const hasExplicitAlias = rawTarget !== void 0 && rawTarget !== null && String(rawTarget).trim() !== "";
const targetField = apitoGraphqlConnectionFieldFromMetaKey(
hasExplicitAlias ? String(rawTarget).trim() : key
);
if (hasExplicitAlias) {
const responseKey = key;
if (responseKey === targetField) {
return `${targetField} { ${selection} }`;
}
return `${responseKey}: ${targetField} { ${selection} }`;
}
return `${targetField} { ${selection} }`;
}).join("\n");
}
function buildApitoCreateMutation(resource, fields) {
const id = apitoSingularResourceName(resource);
const pascal = pascalFromAnyModelId(id);
const payload = apitoGraphQLComposedTypeName(id, "Create_Payload");
const rel = apitoGraphQLComposedTypeName(id, "Relation_Connect_Payload");
return ` mutation Create${pascal}($payload: ${payload}!, $connect: ${rel}) {
create${pascal}(payload: $payload, connect: $connect, status: published) {
id
data {
${fields.join("\n")}
}
meta {
created_at
status
updated_at
}
}
}`;
}
// src/provider.ts
var UNSAFE_DYNAMIC_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
function isSafeDynamicKey(key) {
return typeof key === "string" && key.length > 0 && !UNSAFE_DYNAMIC_KEYS.has(key);
}
var handleGraphQLError = (error, onTokenExpired) => {
if (!error) {
return {
message: "Unknown error occurred",
statusCode: 500
};
}
if (error.networkError) {
const statusCode = error.networkError.statusCode || error.networkError.status;
if (statusCode === 403 || statusCode === 401) {
console.log("Token expired (403/401), triggering logout...");
onTokenExpired == null ? void 0 : onTokenExpired();
return {
message: "Token expired. Please login again.",
statusCode: 403
};
}
return {
message: `Network error: ${error.networkError.message}`,
statusCode: statusCode || 503
// Service Unavailable
};
}
if (error.graphQLErrors && error.graphQLErrors.length > 0) {
const hasAuthError = error.graphQLErrors.some(
(err) => err.message.toLowerCase().includes("unauthorized") || err.message.toLowerCase().includes("forbidden") || err.message.toLowerCase().includes("token") || err.message.toLowerCase().includes("authentication") || err.message.toLowerCase().includes("authorization")
);
if (hasAuthError) {
console.log(
"Authentication error detected in GraphQL, triggering logout..."
);
onTokenExpired == null ? void 0 : onTokenExpired();
return {
message: "Authentication failed. Please login again.",
statusCode: 403
};
}
const errorMessages = error.graphQLErrors.map((err) => err.message).join(", ");
return {
message: errorMessages,
statusCode: 400
// Bad Request for GraphQL validation errors
};
}
return {
message: error.message || "An error occurred during the GraphQL operation",
statusCode: 400
};
};
var apitoDataProvider = (apiUrl, token, onTokenExpired) => {
const client = new Client({
url: apiUrl,
exchanges: [cacheExchange, fetchExchange],
fetchOptions: () => ({
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
}),
preferGetMethod: false
});
return {
getApiUrl: () => apiUrl,
getApiClient: () => {
return new Client({
url: apiUrl,
exchanges: [cacheExchange, fetchExchange],
fetchOptions: () => ({
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
}),
preferGetMethod: false
});
},
getToken: () => token,
async getList(params) {
var _a, _b, _c, _d;
try {
const { resource, filters, sorters, pagination, meta } = params;
const connectionFields = (meta == null ? void 0 : meta.connectionFields) || {};
const aliasFields = (meta == null ? void 0 : meta.aliasFields) || {};
const reverseLookup = (meta == null ? void 0 : meta.reverseLookup) || {};
let data = [];
let total = 0;
let query = null;
let variables = null;
if (meta == null ? void 0 : meta.gqlQuery) {
query = meta.gqlQuery;
variables = meta.variables;
const queryKey = meta.queryKey || resource;
const response = await client.query(query, variables).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
const queryResponse = (_a = response == null ? void 0 : response.data) == null ? void 0 : _a[queryKey];
const responseData = Array.isArray(queryResponse) ? queryResponse : [];
const responseTotal = responseData.length ?? 0;
return {
data: responseData,
total: responseTotal
};
} else {
const fields = (meta == null ? void 0 : meta.fields) || ["id"];
const listPascal = apitoListGraphQLTypeName(resource);
const pluralResource = listPascal;
const processFilter = (filter) => {
const { field, operator, value } = filter;
if (operator === "eq" && Array.isArray(value)) {
const nestedCondition = /* @__PURE__ */ Object.create(null);
value.forEach((condition) => {
const {
field: subField,
operator: subOperator,
value: subValue
} = condition;
if (subField && subOperator && subValue !== void 0 && isSafeDynamicKey(subField) && isSafeDynamicKey(subOperator)) {
if (!nestedCondition[subField]) {
nestedCondition[subField] = /* @__PURE__ */ Object.create(null);
}
nestedCondition[subField][subOperator] = subValue;
}
});
if (!isSafeDynamicKey(field)) {
return {};
}
return { [field]: nestedCondition };
}
if (operator === "or" && Array.isArray(value)) {
const orConditions = /* @__PURE__ */ Object.create(null);
value.forEach((condition) => {
const { field: field2, operator: operator2, value: value2 } = condition;
if (field2 && operator2 && value2 !== void 0) {
const adjustedField = field2.startsWith("data.") ? field2.replace("data.", "") : field2;
if (isSafeDynamicKey(adjustedField) && isSafeDynamicKey(operator2)) {
orConditions[adjustedField] = { [operator2]: value2 };
}
}
});
return { OR: orConditions };
}
if (operator === "and" && Array.isArray(value)) {
const andConditions = /* @__PURE__ */ Object.create(null);
value.forEach((condition) => {
const { field: field2, operator: operator2, value: value2 } = condition;
if (field2 && operator2 && value2 !== void 0) {
const adjustedField = field2.startsWith("data.") ? field2.replace("data.", "") : field2;
if (isSafeDynamicKey(adjustedField) && isSafeDynamicKey(operator2)) {
andConditions[adjustedField] = { [operator2]: value2 };
}
}
});
return { AND: andConditions };
}
if (field === "_key") {
const keyOp = operator || "eq";
if (!isSafeDynamicKey(keyOp)) {
return {};
}
return { _key: { [keyOp]: value } };
}
if (field && field.includes("relation.")) {
const relationPath = field.replace("relation.", "").split(".");
if (!relationPath.length || !relationPath.every(isSafeDynamicKey)) {
return {};
}
const relationCondition = /* @__PURE__ */ Object.create(null);
let current = relationCondition;
for (let i = 0; i < relationPath.length - 1; i++) {
const part = relationPath[i];
if (!current[part]) {
current[part] = /* @__PURE__ */ Object.create(null);
}
current = current[part];
}
const lastPart = relationPath[relationPath.length - 1];
if (operator && value !== void 0 && isSafeDynamicKey(lastPart) && isSafeDynamicKey(operator)) {
current[lastPart] = { [operator]: value };
}
return { relation: relationCondition };
}
if (operator && value !== void 0 && typeof field === "string") {
const adjustedField = field.startsWith("data.") ? field.replace("data.", "") : field;
if (isSafeDynamicKey(adjustedField) && isSafeDynamicKey(operator)) {
return { [adjustedField]: { [operator]: value } };
}
}
return {};
};
let _key = null;
let relationWhere = null;
let where = {};
if (filters && filters.length > 0) {
filters.forEach((filter) => {
const processed = processFilter(filter);
if (processed._key) {
_key = processed._key;
} else if (processed.relation) {
if (!relationWhere) {
relationWhere = {};
}
Object.assign(relationWhere, processed.relation);
} else if (processed.OR) {
where.OR = processed.OR;
} else if (processed.AND) {
where.AND = processed.AND;
} else {
Object.assign(where, processed);
}
});
}
const hasKey = _key !== null;
const hasRelationWhere = relationWhere !== null;
const queryVariables = [
hasKey ? `$_key: ${apitoListKeyConditionType(resource)}` : null,
`$connection: ${apitoConnectionFilterConditionType(resource)}`,
`$where: ${apitoWhereInputType(resource)}`,
hasRelationWhere ? `$relationWhere: ${apitoWhereRelationFilterConditionType(resource)}` : null,
hasKey ? `$_keyCount: ${apitoListCountKeyConditionType(resource)}` : null,
`$whereCount: ${apitoListCountWhereInputType(resource)}`,
hasRelationWhere ? `$relationWhereCount: ${apitoWhereRelationFilterConditionType(resource)}` : null,
`$sort: ${apitoSortInputType(resource)}`,
`$page: Int`,
`$limit: Int`,
`$local: LOCAL_TYPE_ENUM`
].filter(Boolean).join("\n");
const queryArguments = [
hasKey ? "_key: $_key" : null,
"connection: $connection",
"where: $where",
hasRelationWhere ? "relation: $relationWhere" : null,
"sort: $sort",
"page: $page",
"limit: $limit",
"local: $local"
].filter(Boolean).join(", ");
const countArguments = [
hasKey ? "_key: $_keyCount" : null,
"connection: $connection",
"where: $whereCount",
hasRelationWhere ? "relation: $relationWhereCount" : null,
"page: $page",
"limit: $limit"
].filter(Boolean).join(", ");
query = gql`
query Get${pluralResource}(
${queryVariables}
) {
${apitoMultipleResourceName(resource)}(${queryArguments}) {
id
data {
${fields.join("\n")}
}
${formatApitoConnectionSubselections(connectionFields, aliasFields)}
meta {
created_at
status
updated_at
}
}
${apitoMultipleResourceName(resource)}Count(${countArguments}) {
total
}
}
`;
variables = {
...hasKey && { _key },
connection: reverseLookup || {},
where: where || {},
...hasRelationWhere && { relationWhere },
whereCount: where || {},
...hasKey && { _keyCount: _key },
...hasRelationWhere && { relationWhereCount: relationWhere },
sort: sorters == null ? void 0 : sorters.reduce((acc, sorter) => {
const { field, order } = sorter;
if (field && order) {
acc[field] = order.toUpperCase();
}
return acc;
}, {}),
page: (pagination == null ? void 0 : pagination.currentPage) || 1,
limit: (pagination == null ? void 0 : pagination.pageSize) || 10
};
const response = await client.query(query, variables).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
const listRoot = apitoMultipleResourceName(resource);
data = ((_b = response == null ? void 0 : response.data) == null ? void 0 : _b[listRoot]) ?? [];
total = "total" in (((_c = response == null ? void 0 : response.data) == null ? void 0 : _c[`${listRoot}Count`]) || {}) ? ((_d = response == null ? void 0 : response.data) == null ? void 0 : _d[`${listRoot}Count`]).total : 0;
}
return {
data,
total
};
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || "Failed to fetch list data",
statusCode: 500
};
return Promise.reject(httpError);
}
},
async getOne(params) {
var _a;
try {
const { resource, id, meta } = params;
const fields = (meta == null ? void 0 : meta.fields) || ["id"];
const connectionFields = (meta == null ? void 0 : meta.connectionFields) || {};
const aliasFields = (meta == null ? void 0 : meta.aliasFields) || {};
const singularField = apitoModelName(resource);
const singularPascal = apitoSingularGraphQLTypeName(resource);
const query = gql`
query Get${singularPascal}($id: String!) {
${singularField}(_id: $id) {
id
data {
${fields.join("\n")}
}
${formatApitoConnectionSubselections(connectionFields, aliasFields)}
meta {
created_at
status
updated_at
}
}
}
`;
const response = await client.query(query, { id }).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
const data = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a[singularField]) ?? {};
return {
data
};
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to fetch ${params.resource} with id ${params.id}`,
statusCode: 500
};
return Promise.reject(httpError);
}
},
async create(params) {
var _a, _b, _c;
try {
const { resource, variables, meta } = params;
let query = null;
let _variables = null;
if (meta == null ? void 0 : meta.gqlMutation) {
query = meta.gqlMutation;
if (variables) {
_variables = variables;
} else {
_variables = meta.variables;
}
const response = await client.mutation(query, _variables).toPromise();
if (response.error) {
return Promise.reject(handleGraphQLError(response.error));
}
return {
data: ((_b = (_a = response == null ? void 0 : response.data) == null ? void 0 : _a[`create${apitoSingularGraphQLTypeName(resource)}`]) == null ? void 0 : _b.data) ?? {}
};
} else {
try {
const { resource: resource2, variables: variables2, meta: meta2 } = params;
const fields = (meta2 == null ? void 0 : meta2.fields) || ["id"];
const name = apitoSingularGraphQLTypeName(resource2);
const query2 = gql(buildApitoCreateMutation(resource2, fields));
const variableData = variables2;
const response = await client.mutation(query2, {
payload: variableData.data,
connect: variableData.connect
}).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
const data = ((_c = response == null ? void 0 : response.data) == null ? void 0 : _c[`create${name}`]) ?? {};
return { data };
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to create ${params.resource}`,
statusCode: 500
};
return Promise.reject(httpError);
}
}
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to create ${params.resource}`,
statusCode: 500
};
return Promise.reject(httpError);
}
},
async createMany(params) {
var _a;
try {
const { resource, variables, meta } = params;
const fields = (meta == null ? void 0 : meta.fields) || ["id"];
const listPascal = apitoListGraphQLTypeName(resource);
const upsertPayloadType = apitoGraphQLComposedTypeName(
resource,
"List_Upsert_Payload"
);
const listConnectType = apitoGraphQLComposedTypeName(
resource,
"Relation_Connect_Payload"
);
const mutation = gql`
mutation Upsert${listPascal}($payloads: [${upsertPayloadType}!]!, $connect: ${listConnectType}) {
upsert${listPascal}(payloads: $payloads, connect: $connect, status: published) {
id
data {
${fields.join("\n")}
}
meta {
created_at
status
updated_at
}
}
}
`;
const variableData = Array.isArray(variables) ? variables.filter(
(item) => item !== null && item !== void 0 && (typeof item !== "object" || Object.keys(item).length > 0)
) : variables;
const response = await client.mutation(mutation, {
payloads: variableData
//connect: variableData.connect,
}).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
const data = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a[`upsert${listPascal}`]) ?? [];
return { data };
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to create multiple ${params.resource} records`,
statusCode: 500
};
return Promise.reject(httpError);
}
},
async update({ resource, id, variables, meta }) {
var _a, _b, _c, _d;
try {
let query = null;
let _variables = null;
if (meta == null ? void 0 : meta.gqlMutation) {
query = meta.gqlMutation;
if (variables) {
_variables = variables;
} else {
_variables = meta.variables;
}
const response = await client.mutation(query, _variables).toPromise();
if (response.error) {
return Promise.reject(handleGraphQLError(response.error));
}
return {
data: ((_b = (_a = response == null ? void 0 : response.data) == null ? void 0 : _a[`update${apitoSingularGraphQLTypeName(resource)}`]) == null ? void 0 : _b.data) ?? {}
};
} else {
const fields = (meta == null ? void 0 : meta.fields) || ["id"];
const deltaUpdate = (meta == null ? void 0 : meta.deltaUpdate) || false;
const includeRelations = (meta == null ? void 0 : meta.relation) !== false;
const name = apitoSingularGraphQLTypeName(resource);
const updatePayload = apitoGraphQLComposedTypeName(resource, "Update_Payload");
const relConn = apitoGraphQLComposedTypeName(
resource,
"Relation_Connect_Payload"
);
const relDis = apitoGraphQLComposedTypeName(
resource,
"Relation_Disconnect_Payload"
);
const relationVarDefs = includeRelations ? `,
$connect: ${relConn},
$disconnect: ${relDis}` : "";
const relationArgs = includeRelations ? `, connect: $connect, disconnect: $disconnect` : "";
query = gql`
mutation Update${name}(
$id: String!,
$deltaUpdate: Boolean,
$payload: ${updatePayload}!${relationVarDefs}
) {
update${name}(_id: $id, deltaUpdate: $deltaUpdate, payload: $payload${relationArgs}, status: published) {
id
data {
${fields.join("\n")}
}
meta {
created_at
status
updated_at
}
}
}
`;
_variables = {
id,
deltaUpdate,
payload: variables.data
};
if (includeRelations) {
_variables.connect = variables.connect;
_variables.disconnect = variables.disconnect;
}
const response = await client.mutation(query, _variables).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
return {
data: ((_d = (_c = response == null ? void 0 : response.data) == null ? void 0 : _c[`update${name}`]) == null ? void 0 : _d.data) ?? {}
};
}
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to update ${resource} with id ${id}`,
statusCode: 500
};
return Promise.reject(httpError);
}
},
async deleteOne({ resource, id }) {
var _a, _b, _c;
try {
const name = apitoSingularGraphQLTypeName(resource);
const query = gql`
mutation Delete${name}($ids: [String]!) {
delete${name}(_ids: $ids) {
response
}
}
`;
const response = await client.mutation(query, { ids: [id] }).toPromise();
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
if (((_a = response.data) == null ? void 0 : _a.errors) && Array.isArray(response.data.errors)) {
const errorMessages = response.data.errors.map((err) => err.message).join(", ");
const httpError = {
message: errorMessages,
statusCode: 400
};
return Promise.reject(httpError);
}
return {
data: ((_c = (_b = response == null ? void 0 : response.data) == null ? void 0 : _b[`delete${name}`]) == null ? void 0 : _c.data) ?? {}
};
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || `Failed to delete ${resource} with id ${id}`,
statusCode: 500
};
return Promise.reject(httpError);
}
},
async custom(params) {
var _a, _b, _c, _d;
try {
const query = (_a = params == null ? void 0 : params.meta) == null ? void 0 : _a.gqlQuery;
const mutation = (_b = params == null ? void 0 : params.meta) == null ? void 0 : _b.gqlMutation;
let variables = (_c = params == null ? void 0 : params.meta) == null ? void 0 : _c.gqlVariables;
if (query && mutation) {
const httpError = {
message: "Query and mutation cannot both be provided for custom operation",
statusCode: 400
};
return Promise.reject(httpError);
}
if (!query && !mutation) {
const httpError = {
message: "Query or mutation is required for custom operation",
statusCode: 400
};
return Promise.reject(httpError);
}
const { filters } = params;
const where = filters == null ? void 0 : filters.reduce(
(acc, filter) => {
const { field, operator, value } = filter;
if (operator && value !== void 0) {
const adjustedField = field.startsWith("data.") ? field.replace("data.", "") : field;
acc[adjustedField] = { [operator || "eq"]: value };
}
return acc;
},
{}
);
if (where) {
variables = {
...variables,
where: where || {}
};
}
if ((variables == null ? void 0 : variables.payloads) && typeof variables.payloads === "object" && !Array.isArray(variables.payloads)) {
variables = {
...variables,
payloads: Object.values(variables.payloads)
};
}
let response = null;
if (query) {
response = await client.query(query, variables).toPromise();
} else if (mutation) {
response = await client.mutation(mutation, variables).toPromise();
} else {
throw new Error("No query or mutation provided");
}
if (response.error) {
return Promise.reject(
handleGraphQLError(response.error, onTokenExpired)
);
}
if (((_d = response.data) == null ? void 0 : _d.errors) && Array.isArray(response.data.errors)) {
const errorMessages = response.data.errors.map((err) => err.message).join(", ");
const httpError = {
message: errorMessages,
statusCode: 400
};
return Promise.reject(httpError);
}
return {
data: response == null ? void 0 : response.data
};
} catch (error) {
if (error.statusCode !== void 0) {
return Promise.reject(error);
}
const httpError = {
message: (error == null ? void 0 : error.message) || "Failed to execute custom operation",
statusCode: 500
};
return Promise.reject(httpError);
}
}
};
};
var provider_default = apitoDataProvider;
// src/debugProvider.ts
var debugApitoDataProvider = (apiUrl, token) => {
const provider = provider_default(apiUrl, token);
return {
...provider,
// Utility methods
getApiUrl: () => {
console.log("[Apito Debug] getApiUrl called");
return provider.getApiUrl();
},
getApiClient: () => {
console.log("[Apito Debug] getApiClient called");
return provider.getApiClient();
},
getToken: () => {
console.log("[Apito Debug] getToken called");
return provider.getToken();
},
// Data provider methods
getList: async (params) => {
console.log("[Apito Debug] getList called with params:", JSON.stringify(params, null, 2));
try {
const result = await provider.getList(params);
console.log("[Apito Debug] getList result:", JSON.stringify({
total: result.total,
data: result.data.length > 0 ? `${result.data.length} items` : "empty array"
}, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] getList error:", error);
throw error;
}
},
getOne: async (params) => {
console.log("[Apito Debug] getOne called with params:", JSON.stringify(params, null, 2));
try {
const result = await provider.getOne(params);
console.log("[Apito Debug] getOne result:", JSON.stringify({
id: result.data.id
}, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] getOne error:", error);
throw error;
}
},
create: async (params) => {
console.log("[Apito Debug] create called with params:", JSON.stringify(params, null, 2));
try {
const result = await provider.create(params);
console.log("[Apito Debug] create result:", JSON.stringify({
id: result.data.id
}, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] create error:", error);
throw error;
}
},
createMany: async (params) => {
console.log("[Apito Debug] createMany called with params:", JSON.stringify(params, null, 2));
try {
const createManyFn = provider.createMany;
const result = await createManyFn(params);
console.log("[Apito Debug] createMany result:", JSON.stringify({
count: Array.isArray(result.data) ? result.data.length : 0
}, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] createMany error:", error);
throw error;
}
},
update: async (params) => {
console.log("[Apito Debug] update called with params:", JSON.stringify(params, null, 2));
try {
const result = await provider.update(params);
console.log("[Apito Debug] update result:", JSON.stringify(result, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] update error:", error);
throw error;
}
},
deleteOne: async (params) => {
console.log("[Apito Debug] deleteOne called with params:", JSON.stringify(params, null, 2));
try {
const result = await provider.deleteOne(params);
console.log("[Apito Debug] deleteOne result:", JSON.stringify(result, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] deleteOne error:", error);
throw error;
}
},
custom: async (params) => {
console.log("[Apito Debug] custom called with params:", JSON.stringify(params, null, 2));
try {
const customFn = provider.custom;
const result = await customFn(params);
console.log("[Apito Debug] custom result:", JSON.stringify(result, null, 2));
return result;
} catch (error) {
console.error("[Apito Debug] custom error:", error);
throw error;
}
}
};
};
var debugProvider_default = debugApitoDataProvider;
export { provider_default as apitoDataProvider, debugProvider_default as debugApitoDataProvider };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map