knack-object-api
Version:
Object based api calls in Knack
124 lines (101 loc) • 3.26 kB
text/typescript
import axios from "axios";
import dotenv from "dotenv";
import factory from "../factory";
import { getSettings } from "../types";
import { generateRequestId, handleError, wait } from "../helpers";
dotenv.config();
declare let process: any;
let axiosInstance = axios.create({
headers: {
"X-Knack-Application-Id": process.env.KNACK_APP_ID,
"X-Knack-REST-API-Key": process.env.KNACK_API_KEY,
},
});
const get = async (settings: getSettings): Promise<any> => {
const {
objectKey,
recordId,
filters,
sort,
debug,
attempts,
rowsPerPage,
format,
host,
} = settings;
if (!settings.requestId) settings.requestId = generateRequestId(8);
const requestId = settings.requestId;
let state = factory.getState(requestId);
if (!state) state = factory.initialize(requestId);
// if a number of attempts was sent in, this will set the number of retries to the attempts. If not, it will set the number of retries to the default 3
// if it has failed before, it won't update the number of attempts again so that it will decrease properly
const hasFailed = state.failed;
hasFailed && attempts && factory.setAttempts(requestId, attempts);
// initial page to 1
if (!settings.page) settings.page = state.page;
settings.method = "get";
const rows_per_page = rowsPerPage
? factory.setRowsPerPage(requestId, rowsPerPage)
: state.rowsPerPage;
factory.setObjectKey(requestId, objectKey);
recordId && factory.setRecordId(requestId, recordId);
filters &&
factory.addAddition(
requestId,
`filters=${encodeURIComponent(JSON.stringify(filters))}`
);
factory.addAddition(
requestId,
`page=${settings.page}&rows_per_page=${rows_per_page}`
);
if (format) {
factory.addAddition(requestId, `format=${format}`);
}
if (sort) {
// sort can be sent in as a single object or array of objects for multiple sorting
// if it is an array, it will be done after records are retrieved in combine records
if (!Array.isArray(sort)) {
factory.addAddition(
requestId,
`sort_field=${sort.field}&sort_order=${sort.order}`
);
}
}
// if client sends in settings.debug as true, this will tell them the request url
if (debug)
console.warn(
"Request ID:",
requestId,
"Request URL:",
factory.getUrl(requestId, host)
);
try {
axiosInstance.defaults.headers.get["Content-Type"] = "application/json";
const response = await axiosInstance.get(factory.getUrl(requestId, host));
const returnResponse: any = await factory.combineRecords(
requestId,
settings,
response.data
);
if (returnResponse?.retry) {
return await get(returnResponse.settings);
}
return returnResponse;
} catch (error) {
const errorRsp: any = handleError(factory, requestId, error);
if (errorRsp?.retry) {
const waitTime = factory.incrementWaitTime(requestId);
settings.debug &&
console.warn(
"Request ID:",
requestId,
`Waiting ${waitTime} milliseconds`
);
await wait(waitTime);
return await get(settings);
}
factory.remove(requestId);
return errorRsp;
}
};
export default get;