magicbell
Version:
MagicBell API wrapper
84 lines • 3.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeArgs = normalizeArgs;
const utils_js_1 = require("../lib/utils.js");
const options_js_1 = require("./options.js");
const queryParamValidators = {
archived: utils_js_1.isBoolean,
read: utils_js_1.isBoolean,
seen: utils_js_1.isBoolean,
category: utils_js_1.isString,
topic: utils_js_1.isString,
};
function isForcedQueryParams(object) {
if (!(0, utils_js_1.isObject)(object))
return false;
for (const key of Object.keys(object)) {
if (!queryParamValidators[key]?.(object[key]))
return false;
}
return true;
}
function getUrl(path, params, options = { encode: true }) {
return path.replace(/{([\s\S]+?)}/g, (_, $1) => options.encode ? encodeURIComponent(params[$1] || '') : params[$1] || '');
}
function extractUrlParams(path) {
const params = path.match(/{\w+}/g) || [];
return (params || []).map((param) => param.replace(/[{}]/g, ''));
}
/**
* Return the data argument from a list of arguments
*
* @param {object[]} args
* @returns {object}
*/
function getDataFromArgs(args) {
if (!(0, utils_js_1.isArray)(args) || !(0, utils_js_1.isObject)(args[0]))
return {};
if ((0, options_js_1.isOptionsHash)(args[0]))
return {};
return args.shift();
}
/**
* Return the options hash from a list of arguments
*/
function getOptionsFromArgs(args) {
if (!(0, utils_js_1.isArray)(args) || args.length === 0)
return {};
const arg = args[args.length - 1];
if (!(0, options_js_1.isOptionsHash)(arg))
return {};
return { ...args.pop() };
}
function normalizeArgs({ path, method, args, }) {
const argsCopy = [...args].filter((x) => x !== undefined);
const urlParams = extractUrlParams(path);
const urlData = urlParams.reduce((urlData, param) => {
const arg = argsCopy.shift();
if (typeof arg !== 'string') {
throw new Error(`MagicBell: Argument "${param}" must be a string, but got ${typeof arg}: ${JSON.stringify(arg)} (on API request to \`${method} ${path}\`)`);
}
urlData[param] = arg;
return urlData;
}, {});
// We don't encode atm because the backend doesn't support that in PUT /users/email:user@domain.com
const url = getUrl(path, urlData, { encode: false });
const dataFromArgs = getDataFromArgs(argsCopy);
const options = getOptionsFromArgs(argsCopy);
// Validate that there are no more args.
if (argsCopy.filter((x) => x != null).length) {
throw new Error(`MagicBell: Unknown arguments (${JSON.stringify(argsCopy)}). (on API request to \`${method} ${url}\`)`);
}
// Note, DELETE requests should have data in the params, but our `subscriptions.delete`
// endpoint reads it from the body. Other delete requests don't have data, so this seems
// to be the best solution for now.
let dataInQuery = method === 'GET'; // || method === 'DELETE';
// We have a few POST methods using query data instead of body data.
if (method === 'POST' && isForcedQueryParams(dataFromArgs)) {
dataInQuery = true;
}
const data = dataInQuery ? {} : dataFromArgs;
const params = dataInQuery ? dataFromArgs : {};
return { path: url, data, params, options };
}
//# sourceMappingURL=method.js.map