UNPKG

@sagi.io/workers-kv

Version:

Cloudflare Workers KV API for Node.js

123 lines (121 loc) 5.47 kB
"use strict"; 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;