@gameye/sdk
Version:
Node.js SDK for Gameye
114 lines • 4.17 kB
JavaScript
import * as http from "http";
import * as Koa from "koa";
import * as route from "koa-route";
export class ApiTestServer {
constructor(config = {}) {
this.koaServer = new Koa();
this.httpServer = http.createServer();
this.socketPool = new Set();
this.patchListenerPool = new Set();
this.config = Object.freeze(Object.assign({}, ApiTestServer.defaultConfig, config));
this.initializeHttpServer();
this.initializeMiddleware();
}
static async create(config = {}) {
const instance = new this(config);
await instance.initialize();
return instance;
}
getEndpoint() {
const address = this.httpServer.address();
if (!address)
throw new Error("no address!");
if (typeof address === "string")
return address;
return `http://localhost:${address.port}`;
}
emitPatches(patches) {
const { patchListenerPool } = this;
patchListenerPool.forEach(listener => listener(patches));
}
async destroy() {
const { httpServer, socketPool } = this;
await new Promise(resolve => {
const maybeResolve = () => {
if (socketPool.size === 0)
resolve();
};
socketPool.forEach(socket => {
socket.once("close", maybeResolve);
socket.destroy();
});
maybeResolve();
});
await new Promise((resolve, reject) => {
httpServer.close((err) => {
if (err)
reject(err);
else
resolve();
});
});
}
initializeMiddleware() {
const { token, keepAliveInterval } = this.config;
const { koaServer } = this;
koaServer.use((context, next) => {
if (context.request.header.authorization !== `Bearer ${token}`) {
return context.throw(403);
}
return next();
});
koaServer.use(route.post("/action/*", context => {
context.status = 204;
}));
koaServer.use(route.get("/fetch/*", async (context) => {
switch (context.request.accepts("application/json", "application/x-ndjson")) {
case "application/json": {
context.type = "application/json";
context.status = 200;
context.body = {};
break;
}
case "application/x-ndjson": {
const { req, res } = context;
context.type = "application/x-ndjson";
context.status = 200;
context.flushHeaders();
const patchListener = (patches) => {
res.write(JSON.stringify(patches));
res.write("\n");
};
this.patchListenerPool.add(patchListener);
const keepAliveIntervalHandle = setInterval(() => {
res.write("\n");
}, keepAliveInterval);
await new Promise(resolve => {
req.on("close", resolve);
});
clearInterval(keepAliveIntervalHandle);
this.patchListenerPool.delete(patchListener);
await new Promise(resolve => res.end(resolve));
break;
}
}
}));
}
initializeHttpServer() {
const { httpServer, koaServer, socketPool } = this;
httpServer.on("request", koaServer.callback());
httpServer.on("connection", socket => {
socketPool.add(socket);
socket.once("close", () => socketPool.delete(socket));
});
}
async initialize() {
const { httpServer } = this;
await new Promise(resolve => httpServer.listen({ port: 0 }, resolve));
}
}
ApiTestServer.defaultConfig = Object.freeze({
token: "super-secret",
keepAliveInterval: 1300,
});
//# sourceMappingURL=api.js.map