mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-10-13 23:38:45 +01:00
complete proxy with instructions
This commit is contained in:
parent
e489a66ae2
commit
e3055b121f
@ -1,23 +1,112 @@
|
||||
const { assert } = require("console");
|
||||
const express = require("express");
|
||||
const { createProxyMiddleware } = require("http-proxy-middleware");
|
||||
const { inspect } = require("util");
|
||||
|
||||
const conf = {};
|
||||
conf.PORT = process.env.EXPLORER_PORT || 1234;
|
||||
conf.AZURE_TENANT_ID = process.env.AZURE_TENANT_ID || "72f988bf-86f1-41af-91ab-2d7cd011db47";
|
||||
conf.EMULATOR_ENDPOINT = process.env.EMULATOR_ENDPOINT || "https://localhost:8081/";
|
||||
conf.LOG_LEVEL = process.env.LOG_LEVEL || "info";
|
||||
conf.EMULATOR_ENDPOINT = process.env.EMULATOR_ENDPOINT || "http://127.0.0.1:8081";
|
||||
conf.ENDPOINT_DISCOVERY_ENABLED = (process.env.ENDPOINT_DISCOVERY_ENABLED || "false").toLowerCase() === "true";
|
||||
|
||||
const LOG_NUM = levelToNumber(conf.LOG_LEVEL);
|
||||
function log(level, msg, color) {
|
||||
if (levelToNumber(level) >= LOG_NUM) {
|
||||
console.log(`${colorToCode(color)}[${level || "debug"}]${msg}\x1b[0m`);
|
||||
}
|
||||
}
|
||||
|
||||
function debug(msg, color) {
|
||||
log("debug", msg, color);
|
||||
}
|
||||
|
||||
function info(msg, color) {
|
||||
log("info", msg, color);
|
||||
}
|
||||
|
||||
function warn(msg, color) {
|
||||
log("warn", msg, color || "yellow");
|
||||
}
|
||||
|
||||
function err(msg, color) {
|
||||
log("error", msg, color || "red");
|
||||
}
|
||||
|
||||
function levelToNumber(level) {
|
||||
switch (level) {
|
||||
case "debug":
|
||||
return 0;
|
||||
case "info":
|
||||
return 1;
|
||||
case "warn":
|
||||
return 2;
|
||||
case "error":
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function colorToCode(color) {
|
||||
switch (color) {
|
||||
case "red":
|
||||
return "\x1b[31m";
|
||||
case "green":
|
||||
return "\x1b[32m";
|
||||
case "blue":
|
||||
return "\x1b[34m";
|
||||
case "yellow":
|
||||
return "\x1b[33m";
|
||||
default:
|
||||
return "\x1b[0m";
|
||||
}
|
||||
}
|
||||
|
||||
function statusToColor(status) {
|
||||
if (status < 300) {
|
||||
return "green";
|
||||
} else if (status < 400) {
|
||||
return "blue";
|
||||
} else {
|
||||
return "red";
|
||||
}
|
||||
}
|
||||
|
||||
const testEndpoint = () => {
|
||||
fetch(conf.EMULATOR_ENDPOINT)
|
||||
.then(async (res) => {
|
||||
const body = await res.json();
|
||||
info("[EMU] Emulator is accessible");
|
||||
})
|
||||
.catch((err) => {
|
||||
err("[EMU] Emulator is not accessible");
|
||||
err(`[EMU] ${inspect(err)}`);
|
||||
});
|
||||
};
|
||||
|
||||
testEndpoint();
|
||||
|
||||
const app = express();
|
||||
|
||||
app.all("*", (req, res, next) => {
|
||||
const start = new Date();
|
||||
app.use((err, req, res, next) => {
|
||||
err(`[APP] ${inspect(err)}`);
|
||||
res.status(500).json({ error: err.message });
|
||||
});
|
||||
|
||||
app.use((req, res, next) => {
|
||||
req.startTime = new Date();
|
||||
req.requestId = Math.random().toString(36).substring(7);
|
||||
res.append("Access-Control-Allow-Origin", "*");
|
||||
res.append("Access-Control-Allow-Credentials", "true");
|
||||
res.append("Access-Control-Max-Age", "3600");
|
||||
res.append("Access-Control-Allow-Headers", "*");
|
||||
res.append("Access-Control-Allow-Methods", "*");
|
||||
next();
|
||||
const ms = new Date() - start;
|
||||
console.log(`[${req.method}] ${req.url} -> ${res.statusCode} [${ms}ms]`);
|
||||
const ms = new Date() - req.startTime;
|
||||
(res.statusCode < 400 ? debug : err)(
|
||||
`[APP][${req.requestId}][${req.method}][${res.statusCode}][${ms}ms] ${req.url}`,
|
||||
statusToColor(res.statusCode),
|
||||
);
|
||||
});
|
||||
|
||||
app.get("/_ready", (_, res) => {
|
||||
@ -28,60 +117,44 @@ app.get("/_ready", (_, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.get("config.json", (_, res) => {
|
||||
res.json({ EMULATOR_ENDPOINT: conf.EMULATOR_ENDPOINT });
|
||||
});
|
||||
|
||||
const bypass = (req, res) => {
|
||||
if (req.method === "OPTIONS") {
|
||||
res.statusCode = 200;
|
||||
res.send();
|
||||
}
|
||||
const appConf = {
|
||||
PROXY_PATH: "/proxy",
|
||||
EMULATOR_ENDPOINT: conf.EMULATOR_ENDPOINT,
|
||||
};
|
||||
|
||||
const apiProxy = createProxyMiddleware({
|
||||
target: "https://main.documentdb.ext.azure.com",
|
||||
changeOrigin: true,
|
||||
logLevel: "debug",
|
||||
app.get("/config.json", (_, res) => {
|
||||
res.status(200).json(appConf).end();
|
||||
});
|
||||
|
||||
app.use("/api", bypass, apiProxy);
|
||||
|
||||
const proxyProxy = createProxyMiddleware({
|
||||
target: "https://main.documentdb.ext.azure.com",
|
||||
target: "https://cdb-ms-mpac-pbe.cosmos.azure.com",
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
logLevel: "debug",
|
||||
logLevel: conf.LOG_LEVEL,
|
||||
pathRewrite: { "^/proxy": "" },
|
||||
router: (req) => {
|
||||
if (conf.ENDPOINT_DISCOVERY_ENABLED) {
|
||||
let newTarget = req.headers["x-ms-proxy-target"];
|
||||
return newTarget;
|
||||
} else {
|
||||
return conf.EMULATOR_ENDPOINT;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
app.use("/proxy", proxyProxy);
|
||||
|
||||
const explorerProxy = createProxyMiddleware({
|
||||
target: conf.EMULATOR_ENDPOINT,
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
logLevel: "debug",
|
||||
});
|
||||
const unsupported = (req, res) => {
|
||||
res.status(404).send("Unexpected operation. Please create issue.");
|
||||
};
|
||||
|
||||
app.use("/_explorer", explorerProxy);
|
||||
app.use("/explorerProxy", explorerProxy);
|
||||
|
||||
const tenantProxy = createProxyMiddleware({
|
||||
target: "https://login.microsoftonline.com/",
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
logLevel: "debug",
|
||||
});
|
||||
|
||||
app.use(`/${conf.AZURE_TENANT_ID}`, tenantProxy);
|
||||
// TODO: andersonc - I don't believe these are needed for emulator, should confirm and remove.
|
||||
app.use("/api", unsupported);
|
||||
app.use("/_explorer", unsupported);
|
||||
app.use("/explorerProxy", unsupported);
|
||||
app.use(`/${conf.AZURE_TENANT_ID}`, unsupported);
|
||||
|
||||
app.use(express.static("dist"));
|
||||
|
||||
console.log(`Expecting emulator on [${conf.EMULATOR_ENDPOINT}]`);
|
||||
console.log(`Listening on [${conf.PORT}]`);
|
||||
info(`[EMU] Expecting emulator on [${conf.EMULATOR_ENDPOINT}]`);
|
||||
info(`[APP] Listening on [${conf.PORT}]`);
|
||||
app.listen(conf.PORT);
|
||||
|
@ -0,0 +1 @@
|
||||
require('./index.js');
|
@ -3,7 +3,8 @@
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
"start": "node main.js",
|
||||
"pack": "cd ../.. && npm run build:proxy && cd utils/local-proxy"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
39
utils/local-proxy/readme.md
Normal file
39
utils/local-proxy/readme.md
Normal file
@ -0,0 +1,39 @@
|
||||
# local-proxy
|
||||
|
||||
Lightweight host for Cosmos Explorer
|
||||
|
||||
## Quickstart
|
||||
|
||||
1. Pre-req - install packages for root project (`cd ../.. && npm ci && cd utils/local-proxy`)
|
||||
2. Install - install packages for local-proxy (`npm ci`)
|
||||
3. Pack - `npm run pack` - builds and packs Cosmos Explorer and copies files into project
|
||||
4. Start - `npm start` - starts the proxy
|
||||
|
||||
```bash
|
||||
cd ../..
|
||||
npm ci
|
||||
cd utils/local-proxy
|
||||
npm ci
|
||||
npm run pack
|
||||
npm start
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All config is current set via environment variables
|
||||
|
||||
| Name | Options (Default) | Description |
|
||||
| ---------------------------- | ----------------------------------------- | ------------------------------------------------------------ |
|
||||
| `PORT` | number (`1234`) | The port on which the proxy runs. |
|
||||
| `LOG_LEVEL` | `debug`, `info`, `warn`, `error` (`info`) | The logging level for the proxy. |
|
||||
| `EMULATOR_ENDPOINT` | string (`http://localhost:8081`) | The endpoint for the emulator which will be proxied. |
|
||||
| `ENDPOINT_DISCOVERY_ENABLED` | boolean (`false`) | Determine whether the proxy will rewrite the endpoint or not |
|
||||
|
||||
## Dependenies
|
||||
|
||||
Node.js v20+
|
||||
npm (optional)
|
||||
|
||||
## Deployment
|
||||
|
||||
Copy the entire local-proxy directory to wherever you'd like. If you have npm, you can use `npm start`, else `node main.js`
|
Loading…
x
Reference in New Issue
Block a user