imagekit
Version:
Offical NodeJS SDK for ImageKit.io integration
163 lines (161 loc) • 7.01 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSignature = exports.encodeStringIfRequired = void 0;
/*
Helper Modules
*/
var url_1 = require("url");
var path_1 = __importDefault(require("path"));
var crypto_1 = __importDefault(require("crypto"));
/*
Utils
*/
var transformation_1 = __importDefault(require("../../utils/transformation"));
var urlFormatter_1 = __importDefault(require("../../utils/urlFormatter"));
/*
Variables
*/
var TRANSFORMATION_PARAMETER = "tr";
var SIGNATURE_PARAMETER = "ik-s";
var TIMESTAMP_PARAMETER = "ik-t";
var DEFAULT_TIMESTAMP = "9999999999";
//used to check if special char is present in string (you'll need to encode it to utf-8 if it does)
var hasMoreThanAscii = function (str) {
return str.split('').some(function (char) { return char.charCodeAt(0) > 127; });
};
var customEncodeURI = function (str) {
return str.includes("?") ? "".concat(encodeURI(str.split("?")[0]), "?").concat(str.split("?")[1]) : encodeURI(str);
};
var encodeStringIfRequired = function (str) {
return hasMoreThanAscii(str) ? customEncodeURI(str) : str;
};
exports.encodeStringIfRequired = encodeStringIfRequired;
var buildURL = function (opts) {
var isSrcParameterUsedForURL = false;
var urlObject;
if (opts.path) {
urlObject = new url_1.URL(opts.urlEndpoint);
}
else if (opts.src) {
isSrcParameterUsedForURL = true;
urlObject = new url_1.URL(opts.src);
}
else {
return "";
}
var queryParameters = new url_1.URLSearchParams(urlObject.search || "");
for (var i in opts.queryParameters) {
queryParameters.set(i, opts.queryParameters[i]);
}
//Create Transformation String
var transformationString = constructTransformationString(opts.transformation);
if (transformationString) {
//force that if src parameter is being used for URL construction then the transformation
//string should be added only as a query parameter
if (transformation_1.default.addAsQueryParameter(opts) || isSrcParameterUsedForURL) {
queryParameters.set(TRANSFORMATION_PARAMETER, transformationString);
urlObject.pathname = "".concat(urlObject.pathname).concat(opts.path || '');
}
else {
urlObject.pathname = path_1.default.posix.join(urlObject.pathname, [TRANSFORMATION_PARAMETER, transformationString].join(transformation_1.default.getChainTransformDelimiter()), opts.path || '');
}
}
else {
urlObject.pathname = "".concat(urlObject.pathname).concat(opts.path || '');
}
urlObject.host = urlFormatter_1.default.removeTrailingSlash(urlObject.host);
urlObject.pathname = urlFormatter_1.default.addLeadingSlash(urlObject.pathname);
urlObject.search = queryParameters.toString();
/*
Signature String and Timestamp
If the url is constructed using src parameter instead of path then we still replace the urlEndpoint we have
But the user is responsible for passing correct urlEndpoint value
Signature generation logic, let's assume:
urlEndpoint value = https://ik.imagekit.io/your_imagekit_id
expiryTimestamp 9999999999
1. Let the final URL construct e.g. https://ik.imagekit.io/your_imagekit_id/tr:w-400:rotate-91/sample/testing-file.jpg?param1=123
2. Now remove urlEndpoint from it i.e tr:w-400:rotate-91/sample/testing-file.jpg?param1=123
3. Append expiryTimestamp to above string and calcualte signature of this string i.e "tr:w-400:rotate-91/sample/testing-file.jpg?param1=1239999999999"
*/
var expiryTimestamp;
if (opts.signed === true) {
if (opts.expireSeconds) {
expiryTimestamp = getSignatureTimestamp(opts.expireSeconds);
}
else {
expiryTimestamp = DEFAULT_TIMESTAMP;
}
var intermediateURL = urlObject.href;
var urlSignature = getSignature({
privateKey: opts.privateKey,
url: intermediateURL,
urlEndpoint: opts.urlEndpoint,
expiryTimestamp: expiryTimestamp,
});
if (expiryTimestamp && expiryTimestamp != DEFAULT_TIMESTAMP) {
queryParameters.set(TIMESTAMP_PARAMETER, expiryTimestamp);
}
queryParameters.set(SIGNATURE_PARAMETER, urlSignature);
urlObject.search = queryParameters.toString();
}
return urlObject.href;
};
function constructTransformationString(inputTransformation) {
var transformation = inputTransformation;
if (!Array.isArray(transformation)) {
return "";
}
var parsedTransforms = [];
for (var i = 0, l = transformation.length; i < l; i++) {
var parsedTransformStep = [];
for (var key in transformation[i]) {
if (transformation[i][key] === undefined || transformation[i][key] === null)
continue;
var transformKey = transformation_1.default.getTransformKey(key);
if (!transformKey) {
transformKey = key;
}
if (transformation[i][key] === "-") {
parsedTransformStep.push(transformKey);
}
else if (key === "raw") {
parsedTransformStep.push(transformation[i][key]);
}
else {
var value = String(transformation[i][key]);
if (transformKey === "di") {
value = urlFormatter_1.default.removeTrailingSlash(urlFormatter_1.default.removeLeadingSlash(value));
if (value)
value = value.replace(/\//g, "@@");
}
parsedTransformStep.push([transformKey, value].join(transformation_1.default.getTransformKeyValueDelimiter()));
}
}
parsedTransforms.push(parsedTransformStep.join(transformation_1.default.getTransformDelimiter()));
}
return parsedTransforms.join(transformation_1.default.getChainTransformDelimiter());
}
function getSignatureTimestamp(seconds) {
if (!seconds)
return DEFAULT_TIMESTAMP;
var sec = parseInt(String(seconds), 10);
if (!sec)
return DEFAULT_TIMESTAMP;
var currentTimestamp = parseInt(String(new Date().getTime() / 1000), 10);
return String(currentTimestamp + sec);
}
function getSignature(opts) {
if (!opts.privateKey || !opts.url || !opts.urlEndpoint)
return "";
var stringToSign = opts.url.replace(urlFormatter_1.default.addTrailingSlash(opts.urlEndpoint), "") + opts.expiryTimestamp;
stringToSign = (0, exports.encodeStringIfRequired)(stringToSign);
return crypto_1.default.createHmac("sha1", opts.privateKey).update(stringToSign).digest("hex");
}
exports.getSignature = getSignature;
exports.default = {
buildURL: buildURL,
getSignature: getSignature,
};