@sagi.io/workers-kv
Version:
Cloudflare Workers KV API for Node.js
123 lines (121 loc) • 5.47 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.responseBodyResolver = exports.removeUndefineds = exports.isString = exports.httpsReq = exports.httpsAgent = exports.getQueryString = exports.getPathWithQueryString = exports.getNamespaceId = exports.getAuthHeaders = exports.checkMultipleKeysLength = exports.checkLimit = exports.checkKeys = exports.checkKeyValueMap = exports.checkKeyValue = exports.checkKey = exports.MIN_KEYS_LIMIT = exports.MIN_EXPIRATION_TTL_SECONDS = exports.MAX_VALUE_LENGTH = exports.MAX_MULTIPLE_KEYS_LENGTH = exports.MAX_KEY_LENGTH = exports.MAX_KEYS_LIMIT = exports.ERROR_PREFIX = void 0;
var _https = _interopRequireDefault(require("https"));
var _querystring = _interopRequireDefault(require("querystring"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
//const workersKvDebug = require('debug')('workers-kv-debug');
const MAX_KEYS_LIMIT = exports.MAX_KEYS_LIMIT = 1000;
const MIN_KEYS_LIMIT = exports.MIN_KEYS_LIMIT = 10;
const MAX_KEY_LENGTH = exports.MAX_KEY_LENGTH = 512;
const MAX_VALUE_LENGTH = exports.MAX_VALUE_LENGTH = 10 * 1024 * 1024;
const MIN_EXPIRATION_TTL_SECONDS = exports.MIN_EXPIRATION_TTL_SECONDS = 60;
const MAX_MULTIPLE_KEYS_LENGTH = exports.MAX_MULTIPLE_KEYS_LENGTH = 10000;
const ERROR_PREFIX = exports.ERROR_PREFIX = '@sagi.io/workers-kv';
const httpsAgent = exports.httpsAgent = new _https.default.Agent({
keepAlive: true
});
const httpsReq = (options, reqBody = '') => new Promise((resolve, reject) => {
options.agent = httpsAgent;
const req = _https.default.request(options, res => {
const {
headers
} = res;
//workersKvDebug({ headers });
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => responseBodyResolver(resolve)(headers, data));
});
req.on('error', e => reject(e));
!!reqBody && req.write(reqBody);
req.end();
});
exports.httpsReq = httpsReq;
const responseBodyResolver = resolve => (headers, data) => {
const contentType = headers['content-type'];
if (contentType.includes('text/plain')) {
resolve(data);
} else if (contentType.includes('application/json')) {
resolve(JSON.parse(data));
} else if (contentType.includes('application/octet-stream')) {
resolve(data);
} else {
throw new Error(`${ERROR_PREFIX} only JSON, octet-stream or plain text content types are expected. Received content-type: ${contentType}.`);
}
};
exports.responseBodyResolver = responseBodyResolver;
const removeUndefineds = obj => JSON.parse(JSON.stringify(obj));
exports.removeUndefineds = removeUndefineds;
const getQueryString = obj => _querystring.default.stringify(removeUndefineds(obj));
exports.getQueryString = getQueryString;
const getPathWithQueryString = (path, qs) => path + (qs ? `?${qs}` : '');
exports.getPathWithQueryString = getPathWithQueryString;
const checkLimit = limit => {
if (limit < MIN_KEYS_LIMIT || limit > MAX_KEYS_LIMIT) {
throw new Error(`${ERROR_PREFIX}: limit should be between ${MIN_KEYS_LIMIT} and ${MAX_KEYS_LIMIT}. Given limit: ${limit}.`);
}
};
exports.checkLimit = checkLimit;
const isString = x => typeof x === 'string' || x && Object.prototype.toString.call(x) === '[object String]';
exports.isString = isString;
const checkKey = key => {
if (!key || !isString(key) || key.length > MAX_KEY_LENGTH) {
throw new Error(`${ERROR_PREFIX}: Key length should be less than ${MAX_KEY_LENGTH}. `);
}
};
exports.checkKey = checkKey;
const checkKeyValue = (key, value) => {
checkKey(key);
if (!value || !isString(value) || value.length > MAX_VALUE_LENGTH) {
throw new Error(`${ERROR_PREFIX}: Value length should be less than ${MAX_VALUE_LENGTH}.`);
}
};
exports.checkKeyValue = checkKeyValue;
const checkMultipleKeysLength = (method, length) => {
if (length > MAX_MULTIPLE_KEYS_LENGTH) {
throw new Error(`${ERROR_PREFIX}: method ${method} must be provided a container with at most ${MAX_MULTIPLE_KEYS_LENGTH} items.`);
}
};
exports.checkMultipleKeysLength = checkMultipleKeysLength;
const checkKeyValueMap = keyValueMap => {
const entries = keyValueMap ? Object.entries(keyValueMap) : [];
if (!entries.length) {
throw new Error(`${ERROR_PREFIX}: keyValueMap must be an object thats maps string keys to string values.`);
}
checkMultipleKeysLength('checkKeyValue', entries.length);
entries.forEach(([k, v]) => checkKeyValue(k, v));
};
exports.checkKeyValueMap = checkKeyValueMap;
const checkKeys = keys => {
if (!keys || !Array.isArray(keys) || !keys.length) {
throw new Error(`${ERROR_PREFIX}: keys must be an array of strings (key names).`);
}
checkMultipleKeysLength('checkKeys', keys.length);
keys.forEach(checkKey);
};
exports.checkKeys = checkKeys;
const getNamespaceId = (baseInputs, namespaceId) => {
const nsId = namespaceId || baseInputs.namespaceId;
if (!nsId) {
throw new Error(`${ERROR_PREFIX}: namepspaceId wasn't provided to either WorkersKV or the specific method.`);
}
return nsId;
};
exports.getNamespaceId = getNamespaceId;
const getAuthHeaders = (cfEmail, cfAuthKey, cfAuthToken) => {
if (cfAuthToken) {
return {
Authorization: `Bearer ${cfAuthToken}`
};
}
if (cfEmail && cfAuthKey) {
return {
'X-Auth-Email': cfEmail,
'X-Auth-Key': cfAuthKey
};
}
throw new Error(`${ERROR_PREFIX}: Either cfAuthToken or cfEmail and cfAuthKey must be provided`);
};
exports.getAuthHeaders = getAuthHeaders;