edge-mock
Version:
types for testing an developer edge applications
141 lines • 4.95 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EdgeKVNamespace = void 0;
// https://developers.cloudflare.com/workers/runtime-apis/kv
// TODO expiration
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const utils_1 = require("./utils");
class EdgeKVNamespace {
kv;
constructor() {
this.kv = new Map();
}
async get(key, options) {
options = options || {};
if (typeof options == 'string') {
options = { type: options };
}
const v = await this.getWithMetadata(key, options.type);
return v.value || null;
}
async getWithMetadata(key, type) {
const v = this.kv.get(key);
if (v == undefined) {
return { value: null, metadata: null };
}
return { value: prepare_value(v.value, type), metadata: v.metadata || {} };
}
async put(key, value, { metadata } = {}) {
let _value;
if (typeof value == 'string') {
_value = utils_1.encode(value).buffer;
}
else if (Buffer.isBuffer(value)) {
_value = value.buffer;
}
else if ('getReader' in value) {
const view = await utils_1.rsToArrayBufferView(value);
_value = view.buffer;
}
else {
_value = value;
}
this.kv.set(key, { value: _value, metadata });
}
async delete(key) {
this.kv.delete(key);
}
async list(options) {
options = options || {};
if (options.cursor) {
throw new Error('list cursors not yet implemented');
}
const prefix = options.prefix;
const limit = options.limit || 1000;
const keys = [];
for (const [name, value] of this.kv) {
if (!prefix || name.startsWith(prefix)) {
if (keys.length == limit) {
return { keys, list_complete: false, cursor: 'not-fully-implemented' };
}
// const {expiration, metadata} = value
const { metadata } = value;
const list_value = { name };
// if (expiration != undefined) {
// list_value.expiration = expiration
// }
if (metadata != undefined) {
list_value.metadata = metadata;
}
keys.push(list_value);
}
}
return { keys, list_complete: true };
}
async _add_files(directory, prepare_key) {
this._clear();
if (!prepare_key) {
const clean_dir = directory.replace(/\/+$/, '');
const replace_prefix = new RegExp(`^${utils_1.escape_regex(clean_dir)}\\/`);
prepare_key = (file_name) => file_name.replace(replace_prefix, '');
}
return await this._add_directory(directory, prepare_key);
}
async _add_directory(directory, prepare_key) {
if (!(await fs_1.default.promises.stat(directory)).isDirectory()) {
throw new Error(`"${directory}" is not a directory`);
}
const files = await fs_1.default.promises.readdir(directory);
let count = 0;
for (const file of files) {
const file_path = path_1.default.join(directory, file);
const stat = await fs_1.default.promises.stat(file_path);
if (stat.isFile()) {
const content = await fs_1.default.promises.readFile(file_path);
await this.put(prepare_key(file_path), content);
count += 1;
}
else if (stat.isDirectory()) {
count += await this._add_directory(file_path, prepare_key);
}
}
return count;
}
_manifestJson() {
const manifest = Object.fromEntries([...this.kv.keys()].map(k => [k, k]));
return JSON.stringify(manifest);
}
_clear() {
this.kv.clear();
}
async _putMany(kv) {
const promises = [];
for (const [k, v] of Object.entries(kv)) {
if (typeof v != 'string' && 'value' in v) {
promises.push(this.put(k, v.value, { metadata: v.metadata }));
}
else {
promises.push(this.put(k, v, undefined));
}
}
await Promise.all(promises);
}
}
exports.EdgeKVNamespace = EdgeKVNamespace;
function prepare_value(v, type) {
switch (type) {
case 'arrayBuffer':
return v;
case 'json':
return JSON.parse(utils_1.decode(v));
case 'stream':
return utils_1.rsFromArray([new Uint8Array(v)]);
default:
return utils_1.decode(v);
}
}
//# sourceMappingURL=kv_namespace.js.map