@tbd54566975/dwn-proxy-js
Version:
Bidirectional proxy between DWM's <> RESTful
307 lines (299 loc) • 10.5 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b ||= {})
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __forAwait = (obj, it, method) => {
it = obj[Symbol.asyncIterator];
method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((resolve, reject, done) => {
arg = fn.call(obj, arg);
done = arg.done;
return Promise.resolve(arg.value).then((value) => resolve({ value, done }), reject);
}));
return it ? it.call(obj) : (obj = obj[Symbol.iterator](), it = {}, method("next"), method("return"), it);
};
// src/main.ts
var main_exports = {};
__export(main_exports, {
DwnHttpClient: () => DwnHttpClient,
DwnHttpServer: () => DwnHttpServer,
DwnProxy: () => DwnProxy,
createRequest: () => createRequest,
createResponse: () => createResponse,
parseRequest: () => parseRequest,
parseResponse: () => parseResponse,
readReq: () => readReq
});
module.exports = __toCommonJS(main_exports);
// src/dwn-http-client.ts
var import_dids = require("@tbd54566975/dids");
// src/dwn-json-rpc.ts
var parseRequest = (req) => {
return req.params;
};
var createRequest = (target, message) => {
return {
jsonrpc: "2.0",
id: "",
// TODO
method: "dwn.processMessage",
params: {
target,
message
}
};
};
var parseResponse = (res) => {
return res.result;
};
var createResponse = (res) => {
return {
jsonrpc: "2.0",
id: "",
result: {
reply: res.reply
}
};
};
// src/dwn-http-client.ts
var _resolveEndpoint;
var DwnHttpClient = class {
constructor() {
// TODO did resolver cache member variable
__privateAdd(this, _resolveEndpoint, async (did) => {
var _a;
const doc = (await new import_dids.DidIonApi().resolve(did)).didDocument;
if (!doc)
throw new Error();
const service = (_a = doc.service) == null ? void 0 : _a.find((x) => x.type === "DecentralizedWebNode");
if (!service)
throw new Error();
return service.serviceEndpoint.nodes[0];
});
this.send = async (target, message, payload) => {
const endpoint = await __privateGet(this, _resolveEndpoint).call(this, target);
const fetchOpts = {
method: "POST",
headers: {
"dwn-request": JSON.stringify(createRequest(target, message))
}
};
if (payload) {
fetchOpts.headers["content-type"] = "application/octet-stream";
fetchOpts["body"] = payload;
}
const res = await fetch(endpoint, fetchOpts);
let dwnResponse;
if (res.headers.has("dwn-response"))
dwnResponse = parseResponse(JSON.parse(res.headers.get("dwn-response")));
else
dwnResponse = parseResponse(JSON.parse(await res.text()));
return dwnResponse;
};
}
};
_resolveEndpoint = new WeakMap();
// src/dwn-http-server.ts
var import_express = __toESM(require("express"), 1);
var import_cors = __toESM(require("cors"), 1);
var readReq = async (req) => {
let chunks = "";
try {
for (var iter = __forAwait(req), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
const chunk = temp.value;
chunks += chunk;
}
} catch (temp) {
error = [temp];
} finally {
try {
more && (temp = iter.return) && await temp.call(iter);
} finally {
if (error)
throw error[0];
}
}
if (chunks)
return JSON.parse(chunks);
};
var _options;
var DwnHttpServer = class {
constructor(options) {
__privateAdd(this, _options, void 0);
this.listen = (port, callback) => this.api.listen(port, callback);
__privateSet(this, _options, options);
this.api = (0, import_express.default)();
this.api.use((0, import_cors.default)({ exposedHeaders: "dwn-response" }));
this.api.get("/health", (_, res) => res.json({ ok: true }));
this.api.get("/", (_req, res) => {
res.setHeader("content-type", "text/plain");
return res.send("please use a web5 client, for example: https://github.com/TBD54566975/web5-js ");
});
this.api.post("/", async (req, res) => {
try {
let dwnRequest;
try {
dwnRequest = parseRequest(JSON.parse(req.headers["dwn-request"]));
if (!dwnRequest.payload) {
const contentLength = req.headers["content-length"];
const transferEncoding = req.headers["transfer-encoding"];
const requestDataStream = parseInt(contentLength) > 0 || transferEncoding !== void 0 ? req : void 0;
dwnRequest.payload = requestDataStream;
}
} catch (err) {
console.error("Failed to parse client request", err);
res.status(400).end(err.message);
return;
}
const dwnResponse = __privateGet(this, _options).handler ? await __privateGet(this, _options).handler(dwnRequest) : void 0;
if (!dwnResponse) {
const reply = await __privateGet(this, _options).dwn.processMessage(dwnRequest.target, dwnRequest.message, dwnRequest.payload);
res.json(reply);
} else if (dwnResponse.payload) {
res.setHeader("content-type", "application/octet-stream");
res.setHeader("dwn-response", JSON.stringify(createResponse(dwnResponse)));
dwnResponse.payload.pipe(res);
} else {
res.json(createResponse(dwnResponse));
}
} catch (err) {
console.error("Failed to process message", err);
res.status(500).end(err.message);
return;
}
});
}
};
_options = new WeakMap();
// src/dwn-did.ts
var import_dids2 = require("@tbd54566975/dids");
var generateDidState = async (endpoint) => {
const didState = await new import_dids2.DidIonApi().create({
services: [{
id: "dwn",
type: "DecentralizedWebNode",
serviceEndpoint: {
nodes: [endpoint]
}
}]
});
console.log(`Created DID & hosting service endpoint at ${endpoint}`);
console.log(didState.id);
const { keys } = didState;
const [key] = keys;
const { privateKeyJwk } = key;
const kidFragment = privateKeyJwk.kid || key.id;
const kid = `${didState.id}#${kidFragment}`;
return __spreadProps(__spreadValues({}, didState), {
signatureInput: {
privateJwk: privateKeyJwk,
protectedHeader: { alg: privateKeyJwk.crv, kid }
}
});
};
// src/dwn-proxy.ts
var import_dwn_sdk_js = require("@tbd54566975/dwn-sdk-js");
var _handlers, _inbound;
var DwnProxy = class {
constructor(options) {
__privateAdd(this, _handlers, []);
__privateAdd(this, _inbound, async (request) => {
for (const { match, handler } of __privateGet(this, _handlers)) {
const isMatch = match(request);
if (isMatch) {
if (request.payload)
request.payload = await readReq(request.payload);
return await handler(request);
}
}
throw new Error("Unable to find middleware");
});
this.addHandler = (match, handler) => __privateGet(this, _handlers).push({ match, handler });
this.options = options;
}
async listen(port) {
var _a;
if (!this.options.didState)
this.options.didState = await generateDidState((_a = this.options.serviceEndpoint) != null ? _a : `http://0.0.0.0:${port}`);
this.dwn = await import_dwn_sdk_js.Dwn.create();
this.server = new DwnHttpServer({
dwn: this.dwn,
handler: __privateGet(this, _inbound)
});
this.server.listen(port, () => {
console.log(`server listening on port ${port}`);
});
this.client = new DwnHttpClient();
}
};
_handlers = new WeakMap();
_inbound = new WeakMap();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DwnHttpClient,
DwnHttpServer,
DwnProxy,
createRequest,
createResponse,
parseRequest,
parseResponse,
readReq
});
//# sourceMappingURL=main.cjs.map