knack-api
Version:
Knack API
346 lines (319 loc) • 11.7 kB
JavaScript
const { verifyUserToken } = require("./helpers/verifyUserToken");
const { showCustomModal } = require("./helpers/showCustomModal");
module.exports.knack_api = {
get: function (settings, ajaxAttemptsRemaining, combinedRecords) {
const { sceneKey, viewKey, recordId, filters, sort, retry, cb, isPublic, context } =
settings;
// if Knack user session has expired we want to show a warning and return without making a network req
if (!isPublic && !verifyUserToken()) {
showCustomModal(
"Session Expired",
"Your session has expired. To prevent network errors and ensure proper functionality, please log out and then log back in."
);
return Promise.reject("User token is invalid.");
}
this.data = {
records: new Promise((resolve, reject) => {
let rowsPerPage = settings.rowsPerPage;
let recordLimit = settings.recordLimit;
//handle retry upon failure
if (!retry) ajaxAttemptsRemaining = 3;
if (!combinedRecords) combinedRecords = {};
if (!settings.page) settings.page = 1;
if (!rowsPerPage || rowsPerPage > 1000) rowsPerPage = 1000;
let reqUrl = `https://api.knack.com/v1/pages/${sceneKey}/views/${viewKey}/records/`;
if (recordId) {
reqUrl += `${recordId}`;
}
if (filters) {
reqUrl += `?filters=${encodeURIComponent(JSON.stringify(filters))}`;
}
if (sort) {
if (Array.isArray(sort)) {
sort.forEach((value) => {
const field = value.field;
const order = value.order;
reqUrl.indexOf("?") == -1
? (reqUrl += `?sort_field=${field}&sort_order=${order}`)
: (reqUrl += `&sort_field=${field}&sort_order=${order}`);
});
} else {
reqUrl.indexOf("?") == -1
? (reqUrl += `?sort_field=${sort.field}&sort_order=${sort.order}`)
: (reqUrl += `&sort_field=${sort.field}&sort_order=${sort.order}`);
}
}
if (context) {
const [key, value] = Object.entries(context)[0];
if (key && value) {
reqUrl.indexOf("?") == -1
? (reqUrl += `?${key}=${value}`)
: (reqUrl += `&${key}=${value}`);
}
}
reqUrl.indexOf("?") == -1
? (reqUrl += `?page=${settings.page}&rows_per_page=${rowsPerPage}`)
: (reqUrl += `&page=${settings.page}&rows_per_page=${rowsPerPage}`);
console.log("Request URL: ", reqUrl);
Knack.$.ajax({
url: reqUrl,
type: "GET",
dataType: "json",
headers: {
"X-Knack-Application-Id": Knack.application_id,
"X-Knack-REST-API-KEY": "knack",
Authorization: Knack.getUserToken(),
"content-type": "application/json",
},
success: function (data) {
cb && cb(data);
if (
data &&
data.records &&
data.records.length > 0 &&
data.total_pages > 0
) {
if (settings.page < data.total_pages) {
combinedRecords.records
? combinedRecords.records.push(...data.records)
: (combinedRecords = data);
settings.page++;
if (recordLimit) {
if (combinedRecords.records.length >= recordLimit) {
if (combinedRecords.records.length > recordLimit)
combinedRecords.records = combinedRecords.records.slice(
0,
recordLimit
);
resolve(combinedRecords);
} else {
resolve(
module.exports.knack_api.get(
settings,
ajaxAttemptsRemaining,
combinedRecords
)
);
}
} else {
resolve(
module.exports.knack_api.get(
settings,
ajaxAttemptsRemaining,
combinedRecords
)
);
}
} else {
combinedRecords.records
? combinedRecords.records.push(...data.records)
: (combinedRecords = data);
if (recordLimit && combinedRecords.records.length > recordLimit)
combinedRecords.records = combinedRecords.records.slice(
0,
recordLimit
);
resolve(combinedRecords);
}
} else {
resolve(data);
}
},
error: function (err) {
if (ajaxAttemptsRemaining) {
ajaxAttemptsRemaining--;
settings.retry = true;
console.log(`Ajax get error: ${err}`);
console.log(`Attempts remaining: ${ajaxAttemptsRemaining}`);
resolve(
module.exports.knack_api.get(
settings,
ajaxAttemptsRemaining,
combinedRecords
)
);
} else {
reject(err);
}
},
});
})
.then((result) => {
this.data.result = result;
return this.data.result;
})
.catch((reason) => {
console.log(`Failure reason: ${reason}`);
}),
};
this.data.records.include = async (filterParam) => {
await this.data.records;
this.data.result.records.forEach((record) => {
for (let prop in record) {
if (filterParam.indexOf(prop) == -1) {
delete record[prop];
}
}
});
return this.data.result;
};
this.data.records.exclude = async (filterParam) => {
await this.data.records;
this.data.result.records.forEach((record) => {
for (let prop in record) {
if (filterParam.indexOf(prop) != -1) {
delete record[prop];
}
}
});
return this.data.result;
};
return this.data.records;
},
put: (settings, ajaxAttemptsRemaining) => {
const { sceneKey, viewKey, recordId, payload, retry, isPublic } = settings;
// if Knack user session has expired we want to show a warning and return without making a network req
if (!isPublic && !verifyUserToken()) {
showCustomModal(
"Session Expired",
"Your session has expired. To prevent network errors and ensure proper functionality, please log out and then log back in."
);
return Promise.reject("User token is invalid.");
}
return new Promise((resolve, reject) => {
//handle retry upon failure
if (!retry) ajaxAttemptsRemaining = 3;
let reqUrl = `https://api.knack.com/v1/pages/${sceneKey}/views/${viewKey}/records/`;
if (recordId) {
reqUrl += `${recordId}`;
}
console.log("Request URL: ", reqUrl);
Knack.$.ajax({
url: reqUrl,
type: "PUT",
dataType: "json",
headers: {
"X-Knack-Application-Id": Knack.application_id,
"X-Knack-REST-API-KEY": "knack",
Authorization: Knack.getUserToken(),
"content-type": "application/json",
},
data: JSON.stringify(payload),
success: function (data) {
resolve(data);
},
error: function (err) {
if (ajaxAttemptsRemaining) {
ajaxAttemptsRemaining--;
settings.retry = true;
console.log(`Ajax put error: ${err}`);
console.log(`Attempts remaining: ${ajaxAttemptsRemaining}`);
resolve(
module.exports.knack_api.put(settings, ajaxAttemptsRemaining)
);
} else {
reject(err);
}
},
});
}).catch((reason) => {
console.log(`Failure reason: ${reason}`);
});
},
post: (settings, ajaxAttemptsRemaining) => {
const { sceneKey, viewKey, payload, retry, isPublic } = settings;
// if Knack user session has expired we want to show a warning and return without making a network req
if (!isPublic && !verifyUserToken()) {
showCustomModal(
"Session Expired",
"Your session has expired. To prevent network errors and ensure proper functionality, please log out and then log back in."
);
return Promise.reject("User token is invalid.");
}
return new Promise((resolve, reject) => {
//handle retry upon failure
if (!retry) ajaxAttemptsRemaining = 3;
let reqUrl = `https://api.knack.com/v1/pages/${sceneKey}/views/${viewKey}/records/`;
console.log("Request URL: ", reqUrl);
Knack.$.ajax({
url: reqUrl,
type: "POST",
dataType: "json",
headers: {
"X-Knack-Application-Id": Knack.application_id,
"X-Knack-REST-API-KEY": "knack",
Authorization: Knack.getUserToken(),
"content-type": "application/json",
},
data: JSON.stringify(payload),
success: function (data) {
resolve(data);
},
error: function (err) {
if (ajaxAttemptsRemaining) {
ajaxAttemptsRemaining--;
settings.retry = true;
console.log(`Ajax post error: ${err}`);
console.log(`Attempts remaining: ${ajaxAttemptsRemaining}`);
resolve(
module.exports.knack_api.post(settings, ajaxAttemptsRemaining)
);
} else {
reject(err);
}
},
});
}).catch((reason) => {
console.log(`Failure reason: ${reason}`);
});
},
deletion: (settings, ajaxAttemptsRemaining) => {
// if Knack user session has expired we want to show a warning and return without making a network req
if (!verifyUserToken()) {
showCustomModal(
"Session Expired",
"Your session has expired. To prevent network errors and ensure proper functionality, please log out and then log back in."
);
return Promise.reject("User token is invalid.");
}
return new Promise((resolve, reject) => {
const { sceneKey, viewKey, recordId, retry } = settings;
//handle retry upon failure
if (!retry) ajaxAttemptsRemaining = 3;
let reqUrl = `https://api.knack.com/v1/pages/${sceneKey}/views/${viewKey}/records/`;
if (recordId) {
reqUrl += `${recordId}`;
}
console.log("Request URL: ", reqUrl);
Knack.$.ajax({
url: reqUrl,
type: "DELETE",
dataType: "json",
headers: {
"X-Knack-Application-Id": Knack.application_id,
"X-Knack-REST-API-KEY": "knack",
Authorization: Knack.getUserToken(),
"content-type": "application/json",
},
success: function (data) {
resolve(data);
},
error: function (err) {
if (ajaxAttemptsRemaining) {
ajaxAttemptsRemaining--;
settings.retry = true;
console.log(`Ajax delete error: ${err}`);
console.log(`Attempts remaining: ${ajaxAttemptsRemaining}`);
resolve(
module.exports.knack_api.deletion(settings, ajaxAttemptsRemaining)
);
} else {
reject(err);
}
},
});
}).catch((reason) => {
console.log(`Failure reason: ${reason}`);
});
},
};