elysia-vision 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ declare const VISION_CALL_EVENT_NAME = "vision-call";
2
+ declare const VISION_REQUEST_ID_HEADER = "vision-request-id";
3
+ declare const VISION_PATHS: string[];
4
+ declare const HEADERS_TO_REMOVE: string[];
5
+
6
+ export { HEADERS_TO_REMOVE, VISION_CALL_EVENT_NAME, VISION_PATHS, VISION_REQUEST_ID_HEADER };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/constants.ts
21
+ var constants_exports = {};
22
+ __export(constants_exports, {
23
+ HEADERS_TO_REMOVE: () => HEADERS_TO_REMOVE,
24
+ VISION_CALL_EVENT_NAME: () => VISION_CALL_EVENT_NAME,
25
+ VISION_PATHS: () => VISION_PATHS,
26
+ VISION_REQUEST_ID_HEADER: () => VISION_REQUEST_ID_HEADER
27
+ });
28
+ module.exports = __toCommonJS(constants_exports);
29
+ var VISION_CALL_EVENT_NAME = "vision-call";
30
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
31
+ var VISION_PATHS = ["/vision", "/.well-known"];
32
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ HEADERS_TO_REMOVE,
36
+ VISION_CALL_EVENT_NAME,
37
+ VISION_PATHS,
38
+ VISION_REQUEST_ID_HEADER
39
+ });
@@ -0,0 +1,42 @@
1
+ import { Elysia } from 'elysia';
2
+
3
+ declare const vision: () => Elysia<"", {
4
+ decorator: {};
5
+ store: {};
6
+ derive: {};
7
+ resolve: {};
8
+ }, {
9
+ typebox: {};
10
+ error: {};
11
+ }, {
12
+ schema: {};
13
+ standaloneSchema: {};
14
+ macro: {};
15
+ macroFn: {};
16
+ parser: {};
17
+ response: {};
18
+ }, {
19
+ vision: {
20
+ subscribe: {
21
+ body: unknown;
22
+ params: {};
23
+ query: unknown;
24
+ headers: unknown;
25
+ response: {};
26
+ };
27
+ };
28
+ }, {
29
+ derive: {};
30
+ resolve: {};
31
+ schema: {};
32
+ standaloneSchema: {};
33
+ response: {};
34
+ }, {
35
+ derive: {};
36
+ resolve: {};
37
+ schema: {};
38
+ standaloneSchema: {};
39
+ response: {};
40
+ }> | null;
41
+
42
+ export { vision as default };
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ default: () => index_default
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+ var import_elysia = require("elysia");
27
+
28
+ // src/constants.ts
29
+ var VISION_CALL_EVENT_NAME = "vision-call";
30
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
31
+ var VISION_PATHS = ["/vision", "/.well-known"];
32
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
33
+
34
+ // src/utils.ts
35
+ var sanitizeHeaders = (headers) => {
36
+ return Object.fromEntries(
37
+ Object.entries(headers).filter(([key]) => !HEADERS_TO_REMOVE.includes(key)).map(([key, value]) => [
38
+ key,
39
+ Array.isArray(value) ? value.join(", ") : value
40
+ ])
41
+ );
42
+ };
43
+
44
+ // src/index.ts
45
+ var vision = () => {
46
+ if (process.env.NODE_ENV === "production") {
47
+ return null;
48
+ }
49
+ const clients = /* @__PURE__ */ new Set();
50
+ const calls = /* @__PURE__ */ new Map();
51
+ const emit = (eventName, data) => {
52
+ const payload = {
53
+ event: eventName,
54
+ payload: data
55
+ };
56
+ for (const ws of clients) {
57
+ try {
58
+ ws.send(payload);
59
+ } catch {
60
+ }
61
+ }
62
+ };
63
+ const app = new import_elysia.Elysia({
64
+ name: "elysia-vision"
65
+ }).onRequest(async ({ request, set }) => {
66
+ const clonedRequest = request.clone();
67
+ const url = new URL(clonedRequest.url);
68
+ if (VISION_PATHS.some((path) => url.pathname.startsWith(path))) {
69
+ return;
70
+ }
71
+ const visionRequestId = Bun.randomUUIDv7();
72
+ set.headers[VISION_REQUEST_ID_HEADER] = visionRequestId;
73
+ const visionRequest = {
74
+ method: clonedRequest.method,
75
+ path: url.pathname + url.search,
76
+ timestamp: Date.now(),
77
+ body: clonedRequest.body ? JSON.stringify(await clonedRequest.body.json()) : null,
78
+ headers: sanitizeHeaders(set.headers)
79
+ };
80
+ const visionCall = {
81
+ request: visionRequest,
82
+ response: null,
83
+ id: visionRequestId
84
+ };
85
+ calls.set(visionRequestId, visionCall);
86
+ emit(VISION_CALL_EVENT_NAME, visionCall);
87
+ }).onAfterResponse(({ responseValue, set }) => {
88
+ const visionRequestId = set.headers[VISION_REQUEST_ID_HEADER];
89
+ if (!visionRequestId || visionRequestId === "") return;
90
+ const visionResponse = {
91
+ body: responseValue ? JSON.stringify(responseValue) : null,
92
+ status: set.status,
93
+ timestamp: Date.now(),
94
+ headers: sanitizeHeaders(set.headers)
95
+ };
96
+ const call = calls.get(visionRequestId);
97
+ if (!call) return;
98
+ call.response = visionResponse;
99
+ calls.set(visionRequestId, call);
100
+ emit(VISION_CALL_EVENT_NAME, call);
101
+ }).ws("/vision", {
102
+ open: (ws) => {
103
+ clients.add(ws);
104
+ },
105
+ close: (ws) => {
106
+ clients.delete(ws);
107
+ }
108
+ }).as("global");
109
+ return app;
110
+ };
111
+ var index_default = vision;
@@ -0,0 +1,24 @@
1
+ type _INTERNAL_VisionWebSocketPayload<T> = {
2
+ event: string;
3
+ payload: T;
4
+ };
5
+ type VisionRequest = {
6
+ method: string;
7
+ path: string;
8
+ timestamp: number;
9
+ body: string | null;
10
+ headers: Record<string, string | number>;
11
+ };
12
+ type VisionResponse = {
13
+ timestamp: number;
14
+ body: string | null;
15
+ status: number;
16
+ headers: Record<string, string | number>;
17
+ };
18
+ type VisionCall = {
19
+ id: string;
20
+ request: VisionRequest;
21
+ response: VisionResponse | null;
22
+ };
23
+
24
+ export type { VisionCall, VisionRequest, VisionResponse, _INTERNAL_VisionWebSocketPayload };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
@@ -0,0 +1,5 @@
1
+ import { HTTPHeaders } from 'elysia';
2
+
3
+ declare const sanitizeHeaders: (headers: HTTPHeaders) => Record<string, string | number>;
4
+
5
+ export { sanitizeHeaders };
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ sanitizeHeaders: () => sanitizeHeaders
24
+ });
25
+ module.exports = __toCommonJS(utils_exports);
26
+
27
+ // src/constants.ts
28
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
29
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
30
+
31
+ // src/utils.ts
32
+ var sanitizeHeaders = (headers) => {
33
+ return Object.fromEntries(
34
+ Object.entries(headers).filter(([key]) => !HEADERS_TO_REMOVE.includes(key)).map(([key, value]) => [
35
+ key,
36
+ Array.isArray(value) ? value.join(", ") : value
37
+ ])
38
+ );
39
+ };
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ sanitizeHeaders
43
+ });
@@ -0,0 +1,6 @@
1
+ declare const VISION_CALL_EVENT_NAME = "vision-call";
2
+ declare const VISION_REQUEST_ID_HEADER = "vision-request-id";
3
+ declare const VISION_PATHS: string[];
4
+ declare const HEADERS_TO_REMOVE: string[];
5
+
6
+ export { HEADERS_TO_REMOVE, VISION_CALL_EVENT_NAME, VISION_PATHS, VISION_REQUEST_ID_HEADER };
@@ -0,0 +1,11 @@
1
+ // src/constants.ts
2
+ var VISION_CALL_EVENT_NAME = "vision-call";
3
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
4
+ var VISION_PATHS = ["/vision", "/.well-known"];
5
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
6
+ export {
7
+ HEADERS_TO_REMOVE,
8
+ VISION_CALL_EVENT_NAME,
9
+ VISION_PATHS,
10
+ VISION_REQUEST_ID_HEADER
11
+ };
@@ -0,0 +1,42 @@
1
+ import { Elysia } from 'elysia';
2
+
3
+ declare const vision: () => Elysia<"", {
4
+ decorator: {};
5
+ store: {};
6
+ derive: {};
7
+ resolve: {};
8
+ }, {
9
+ typebox: {};
10
+ error: {};
11
+ }, {
12
+ schema: {};
13
+ standaloneSchema: {};
14
+ macro: {};
15
+ macroFn: {};
16
+ parser: {};
17
+ response: {};
18
+ }, {
19
+ vision: {
20
+ subscribe: {
21
+ body: unknown;
22
+ params: {};
23
+ query: unknown;
24
+ headers: unknown;
25
+ response: {};
26
+ };
27
+ };
28
+ }, {
29
+ derive: {};
30
+ resolve: {};
31
+ schema: {};
32
+ standaloneSchema: {};
33
+ response: {};
34
+ }, {
35
+ derive: {};
36
+ resolve: {};
37
+ schema: {};
38
+ standaloneSchema: {};
39
+ response: {};
40
+ }> | null;
41
+
42
+ export { vision as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,90 @@
1
+ // src/index.ts
2
+ import { Elysia } from "elysia";
3
+
4
+ // src/constants.ts
5
+ var VISION_CALL_EVENT_NAME = "vision-call";
6
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
7
+ var VISION_PATHS = ["/vision", "/.well-known"];
8
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
9
+
10
+ // src/utils.ts
11
+ var sanitizeHeaders = (headers) => {
12
+ return Object.fromEntries(
13
+ Object.entries(headers).filter(([key]) => !HEADERS_TO_REMOVE.includes(key)).map(([key, value]) => [
14
+ key,
15
+ Array.isArray(value) ? value.join(", ") : value
16
+ ])
17
+ );
18
+ };
19
+
20
+ // src/index.ts
21
+ var vision = () => {
22
+ if (process.env.NODE_ENV === "production") {
23
+ return null;
24
+ }
25
+ const clients = /* @__PURE__ */ new Set();
26
+ const calls = /* @__PURE__ */ new Map();
27
+ const emit = (eventName, data) => {
28
+ const payload = {
29
+ event: eventName,
30
+ payload: data
31
+ };
32
+ for (const ws of clients) {
33
+ try {
34
+ ws.send(payload);
35
+ } catch {
36
+ }
37
+ }
38
+ };
39
+ const app = new Elysia({
40
+ name: "elysia-vision"
41
+ }).onRequest(async ({ request, set }) => {
42
+ const clonedRequest = request.clone();
43
+ const url = new URL(clonedRequest.url);
44
+ if (VISION_PATHS.some((path) => url.pathname.startsWith(path))) {
45
+ return;
46
+ }
47
+ const visionRequestId = Bun.randomUUIDv7();
48
+ set.headers[VISION_REQUEST_ID_HEADER] = visionRequestId;
49
+ const visionRequest = {
50
+ method: clonedRequest.method,
51
+ path: url.pathname + url.search,
52
+ timestamp: Date.now(),
53
+ body: clonedRequest.body ? JSON.stringify(await clonedRequest.body.json()) : null,
54
+ headers: sanitizeHeaders(set.headers)
55
+ };
56
+ const visionCall = {
57
+ request: visionRequest,
58
+ response: null,
59
+ id: visionRequestId
60
+ };
61
+ calls.set(visionRequestId, visionCall);
62
+ emit(VISION_CALL_EVENT_NAME, visionCall);
63
+ }).onAfterResponse(({ responseValue, set }) => {
64
+ const visionRequestId = set.headers[VISION_REQUEST_ID_HEADER];
65
+ if (!visionRequestId || visionRequestId === "") return;
66
+ const visionResponse = {
67
+ body: responseValue ? JSON.stringify(responseValue) : null,
68
+ status: set.status,
69
+ timestamp: Date.now(),
70
+ headers: sanitizeHeaders(set.headers)
71
+ };
72
+ const call = calls.get(visionRequestId);
73
+ if (!call) return;
74
+ call.response = visionResponse;
75
+ calls.set(visionRequestId, call);
76
+ emit(VISION_CALL_EVENT_NAME, call);
77
+ }).ws("/vision", {
78
+ open: (ws) => {
79
+ clients.add(ws);
80
+ },
81
+ close: (ws) => {
82
+ clients.delete(ws);
83
+ }
84
+ }).as("global");
85
+ return app;
86
+ };
87
+ var index_default = vision;
88
+ export {
89
+ index_default as default
90
+ };
@@ -0,0 +1,24 @@
1
+ type _INTERNAL_VisionWebSocketPayload<T> = {
2
+ event: string;
3
+ payload: T;
4
+ };
5
+ type VisionRequest = {
6
+ method: string;
7
+ path: string;
8
+ timestamp: number;
9
+ body: string | null;
10
+ headers: Record<string, string | number>;
11
+ };
12
+ type VisionResponse = {
13
+ timestamp: number;
14
+ body: string | null;
15
+ status: number;
16
+ headers: Record<string, string | number>;
17
+ };
18
+ type VisionCall = {
19
+ id: string;
20
+ request: VisionRequest;
21
+ response: VisionResponse | null;
22
+ };
23
+
24
+ export type { VisionCall, VisionRequest, VisionResponse, _INTERNAL_VisionWebSocketPayload };
package/dist/types.mjs ADDED
File without changes
@@ -0,0 +1,5 @@
1
+ import { HTTPHeaders } from 'elysia';
2
+
3
+ declare const sanitizeHeaders: (headers: HTTPHeaders) => Record<string, string | number>;
4
+
5
+ export { sanitizeHeaders };
package/dist/utils.mjs ADDED
@@ -0,0 +1,16 @@
1
+ // src/constants.ts
2
+ var VISION_REQUEST_ID_HEADER = "vision-request-id";
3
+ var HEADERS_TO_REMOVE = [VISION_REQUEST_ID_HEADER];
4
+
5
+ // src/utils.ts
6
+ var sanitizeHeaders = (headers) => {
7
+ return Object.fromEntries(
8
+ Object.entries(headers).filter(([key]) => !HEADERS_TO_REMOVE.includes(key)).map(([key, value]) => [
9
+ key,
10
+ Array.isArray(value) ? value.join(", ") : value
11
+ ])
12
+ );
13
+ };
14
+ export {
15
+ sanitizeHeaders
16
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "elysia-vision",
3
+ "version": "0.1.0",
4
+ "description": "Plugin for Elysia that monitors your API requests in real-time through a web dashboard.",
5
+ "exports": {
6
+ "./package.json": "./package.json",
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/cjs/index.js"
11
+ }
12
+ },
13
+ "main": "./dist/cjs/index.js",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/index.d.ts",
16
+ "author": {
17
+ "name": "rouret",
18
+ "url": "https://github.com/rouret"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/rouret/elysia-vision"
23
+ },
24
+ "homepage": "https://github.com/rouret/elysia-vision",
25
+ "keywords": [
26
+ "elysia",
27
+ "vision"
28
+ ],
29
+ "license": "MIT",
30
+ "scripts": {
31
+ "test": "bun test",
32
+ "dev": "bun --hot test/local.ts",
33
+ "release": "bun --hot test/release.ts",
34
+ "fakeClient": "bun test/fakeClient.ts",
35
+ "build": "bun build.ts"
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "README.md"
40
+ ],
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "devDependencies": {
45
+ "@types/bun": "^1.3.5",
46
+ "elysia": "^1.4.19",
47
+ "tsup": "^8.5.1",
48
+ "typescript": "^5.9.3"
49
+ },
50
+ "peerDependencies": {
51
+ "elysia": ">= 1.4.0"
52
+ }
53
+ }