@lensjs/express 1.0.7 → 1.0.10

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.
package/dist/adapter.cjs CHANGED
@@ -26,6 +26,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/adapter.ts
29
31
  var adapter_exports = {};
30
32
  __export(adapter_exports, {
31
33
  default: () => ExpressAdapter
@@ -33,8 +35,10 @@ __export(adapter_exports, {
33
35
  module.exports = __toCommonJS(adapter_exports);
34
36
  var import_core = require("@lensjs/core");
35
37
  var path = __toESM(require("path"), 1);
36
- var import_express2 = __toESM(require("express"), 1);
37
- class ExpressAdapter extends import_core.LensAdapter {
38
+ var import_node_fs = __toESM(require("fs"), 1);
39
+ var import_express = __toESM(require("express"), 1);
40
+ var import_date = require("@lensjs/date");
41
+ var ExpressAdapter = class extends import_core.LensAdapter {
38
42
  app;
39
43
  config;
40
44
  constructor({ app }) {
@@ -72,7 +76,7 @@ class ExpressAdapter extends import_core.LensAdapter {
72
76
  });
73
77
  }
74
78
  serveUI(uiPath, spaRoute, _dataToInject) {
75
- this.app.use(this.normalizePath(spaRoute), import_express2.default.static(uiPath));
79
+ this.app.use(this.normalizePath(spaRoute), import_express.default.static(uiPath));
76
80
  this.app.get(
77
81
  this.normalizePath(`${spaRoute}/favicon.svg`),
78
82
  (_, res) => res.sendFile(path.join(uiPath, "favicon.svg"))
@@ -94,7 +98,7 @@ class ExpressAdapter extends import_core.LensAdapter {
94
98
  const queryPayload = {
95
99
  query: query.query,
96
100
  duration: query.duration || "0 ms",
97
- createdAt: query.createdAt || import_core.lensUtils.sqlDateTime(),
101
+ createdAt: query.createdAt || (0, import_date.sqlDateTime)(),
98
102
  type: query.type
99
103
  };
100
104
  await watcher?.log({
@@ -124,8 +128,29 @@ class ExpressAdapter extends import_core.LensAdapter {
124
128
  return originalJson(body);
125
129
  };
126
130
  res.send = function(body) {
127
- res._body = body;
128
- return originalSend(body);
131
+ let safeBody;
132
+ try {
133
+ if (!body) {
134
+ safeBody = "Purged By Lens";
135
+ } else if (typeof body === "object" && !Buffer.isBuffer(body)) {
136
+ safeBody = body;
137
+ } else if (typeof body === "string") {
138
+ const filePath = path.resolve(body);
139
+ if (import_node_fs.default.existsSync(filePath)) {
140
+ safeBody = "Purged By Lens";
141
+ } else {
142
+ safeBody = body;
143
+ }
144
+ } else if (Buffer.isBuffer(body)) {
145
+ safeBody = "Purged By Lens";
146
+ } else {
147
+ safeBody = "Purged By Lens";
148
+ }
149
+ } catch {
150
+ safeBody = "Purged By Lens";
151
+ }
152
+ res._body = safeBody;
153
+ return originalSend(safeBody);
129
154
  };
130
155
  }
131
156
  async finalizeRequestLog(req, res, requestWatcher, start) {
@@ -141,7 +166,7 @@ class ExpressAdapter extends import_core.LensAdapter {
141
166
  body: req.body ?? {},
142
167
  status: res.statusCode,
143
168
  ip: req.socket?.remoteAddress ?? "",
144
- createdAt: import_core.lensUtils.nowISO()
169
+ createdAt: (0, import_date.nowISO)()
145
170
  },
146
171
  response: {
147
172
  json: res._body ?? null,
@@ -157,4 +182,4 @@ class ExpressAdapter extends import_core.LensAdapter {
157
182
  normalizePath(pathStr) {
158
183
  return pathStr.startsWith("/") ? pathStr : `/${pathStr}`;
159
184
  }
160
- }
185
+ };
package/dist/adapter.js CHANGED
@@ -1,11 +1,14 @@
1
+ // src/adapter.ts
1
2
  import {
2
3
  LensAdapter,
3
4
  lensUtils,
4
5
  WatcherTypeEnum
5
6
  } from "@lensjs/core";
6
7
  import * as path from "path";
8
+ import fs from "fs";
7
9
  import express from "express";
8
- class ExpressAdapter extends LensAdapter {
10
+ import { nowISO, sqlDateTime } from "@lensjs/date";
11
+ var ExpressAdapter = class extends LensAdapter {
9
12
  app;
10
13
  config;
11
14
  constructor({ app }) {
@@ -65,7 +68,7 @@ class ExpressAdapter extends LensAdapter {
65
68
  const queryPayload = {
66
69
  query: query.query,
67
70
  duration: query.duration || "0 ms",
68
- createdAt: query.createdAt || lensUtils.sqlDateTime(),
71
+ createdAt: query.createdAt || sqlDateTime(),
69
72
  type: query.type
70
73
  };
71
74
  await watcher?.log({
@@ -95,8 +98,29 @@ class ExpressAdapter extends LensAdapter {
95
98
  return originalJson(body);
96
99
  };
97
100
  res.send = function(body) {
98
- res._body = body;
99
- return originalSend(body);
101
+ let safeBody;
102
+ try {
103
+ if (!body) {
104
+ safeBody = "Purged By Lens";
105
+ } else if (typeof body === "object" && !Buffer.isBuffer(body)) {
106
+ safeBody = body;
107
+ } else if (typeof body === "string") {
108
+ const filePath = path.resolve(body);
109
+ if (fs.existsSync(filePath)) {
110
+ safeBody = "Purged By Lens";
111
+ } else {
112
+ safeBody = body;
113
+ }
114
+ } else if (Buffer.isBuffer(body)) {
115
+ safeBody = "Purged By Lens";
116
+ } else {
117
+ safeBody = "Purged By Lens";
118
+ }
119
+ } catch {
120
+ safeBody = "Purged By Lens";
121
+ }
122
+ res._body = safeBody;
123
+ return originalSend(safeBody);
100
124
  };
101
125
  }
102
126
  async finalizeRequestLog(req, res, requestWatcher, start) {
@@ -112,7 +136,7 @@ class ExpressAdapter extends LensAdapter {
112
136
  body: req.body ?? {},
113
137
  status: res.statusCode,
114
138
  ip: req.socket?.remoteAddress ?? "",
115
- createdAt: lensUtils.nowISO()
139
+ createdAt: nowISO()
116
140
  },
117
141
  response: {
118
142
  json: res._body ?? null,
@@ -128,7 +152,7 @@ class ExpressAdapter extends LensAdapter {
128
152
  normalizePath(pathStr) {
129
153
  return pathStr.startsWith("/") ? pathStr : `/${pathStr}`;
130
154
  }
131
- }
155
+ };
132
156
  export {
133
157
  ExpressAdapter as default
134
158
  };
package/dist/index.cjs CHANGED
@@ -26,14 +26,169 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
29
31
  var index_exports = {};
30
32
  __export(index_exports, {
31
33
  lens: () => lens
32
34
  });
33
35
  module.exports = __toCommonJS(index_exports);
36
+ var import_core2 = require("@lensjs/core");
37
+
38
+ // src/adapter.ts
34
39
  var import_core = require("@lensjs/core");
35
- var import_adapter = __toESM(require("./adapter"), 1);
36
- const defaultConfig = {
40
+ var path = __toESM(require("path"), 1);
41
+ var import_node_fs = __toESM(require("fs"), 1);
42
+ var import_express = __toESM(require("express"), 1);
43
+ var import_date = require("@lensjs/date");
44
+ var ExpressAdapter = class extends import_core.LensAdapter {
45
+ app;
46
+ config;
47
+ constructor({ app }) {
48
+ super();
49
+ this.app = app;
50
+ }
51
+ setConfig(config) {
52
+ this.config = config;
53
+ return this;
54
+ }
55
+ setup() {
56
+ for (const watcher of this.getWatchers()) {
57
+ switch (watcher.name) {
58
+ case import_core.WatcherTypeEnum.REQUEST:
59
+ this.watchRequests(watcher);
60
+ break;
61
+ case import_core.WatcherTypeEnum.QUERY:
62
+ void this.watchQueries(watcher);
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ registerRoutes(routes) {
68
+ routes.forEach((route) => {
69
+ this.app[route.method.toLowerCase()](
70
+ this.normalizePath(route.path),
71
+ async (req, res) => {
72
+ const result = await route.handler({
73
+ params: req.params,
74
+ qs: req.query
75
+ });
76
+ return res.json(result);
77
+ }
78
+ );
79
+ });
80
+ }
81
+ serveUI(uiPath, spaRoute, _dataToInject) {
82
+ this.app.use(this.normalizePath(spaRoute), import_express.default.static(uiPath));
83
+ this.app.get(
84
+ this.normalizePath(`${spaRoute}/favicon.svg`),
85
+ (_, res) => res.sendFile(path.join(uiPath, "favicon.svg"))
86
+ );
87
+ this.app.get(new RegExp(`^/${spaRoute}(?!/api)(/.*)?$`), (req, res) => {
88
+ if (import_core.lensUtils.isStaticFile(req.path.split("/"))) {
89
+ return res.download(
90
+ path.join(uiPath, import_core.lensUtils.stripBeforeAssetsPath(req.path))
91
+ );
92
+ }
93
+ return res.sendFile(path.join(uiPath, "index.html"));
94
+ });
95
+ }
96
+ async watchQueries(watcher) {
97
+ if (!this.config.queryWatcher.enabled) return;
98
+ const handler = this.config.queryWatcher.handler;
99
+ await handler({
100
+ onQuery: async (query) => {
101
+ const queryPayload = {
102
+ query: query.query,
103
+ duration: query.duration || "0 ms",
104
+ createdAt: query.createdAt || (0, import_date.sqlDateTime)(),
105
+ type: query.type
106
+ };
107
+ await watcher?.log({
108
+ data: queryPayload
109
+ });
110
+ }
111
+ });
112
+ }
113
+ watchRequests(requestWatcher) {
114
+ if (!this.config.requestWatcherEnabled) return;
115
+ this.app.use((req, res, next) => {
116
+ if (this.shouldIgnorePath(req.path)) return next();
117
+ const start = process.hrtime();
118
+ this.patchResponseMethods(res);
119
+ res.on("finish", async () => {
120
+ await this.finalizeRequestLog(req, res, requestWatcher, start);
121
+ });
122
+ next();
123
+ });
124
+ }
125
+ patchResponseMethods(res) {
126
+ const originalJson = res.json.bind(res);
127
+ const originalSend = res.send.bind(res);
128
+ res._body = void 0;
129
+ res.json = function(body) {
130
+ res._body = body;
131
+ return originalJson(body);
132
+ };
133
+ res.send = function(body) {
134
+ let safeBody;
135
+ try {
136
+ if (!body) {
137
+ safeBody = "Purged By Lens";
138
+ } else if (typeof body === "object" && !Buffer.isBuffer(body)) {
139
+ safeBody = body;
140
+ } else if (typeof body === "string") {
141
+ const filePath = path.resolve(body);
142
+ if (import_node_fs.default.existsSync(filePath)) {
143
+ safeBody = "Purged By Lens";
144
+ } else {
145
+ safeBody = body;
146
+ }
147
+ } else if (Buffer.isBuffer(body)) {
148
+ safeBody = "Purged By Lens";
149
+ } else {
150
+ safeBody = "Purged By Lens";
151
+ }
152
+ } catch {
153
+ safeBody = "Purged By Lens";
154
+ }
155
+ res._body = safeBody;
156
+ return originalSend(safeBody);
157
+ };
158
+ }
159
+ async finalizeRequestLog(req, res, requestWatcher, start) {
160
+ try {
161
+ const duration = import_core.lensUtils.prettyHrTime(process.hrtime(start));
162
+ const logPayload = {
163
+ request: {
164
+ id: import_core.lensUtils.generateRandomUuid(),
165
+ method: req.method,
166
+ duration,
167
+ path: req.originalUrl,
168
+ headers: req.headers,
169
+ body: req.body ?? {},
170
+ status: res.statusCode,
171
+ ip: req.socket?.remoteAddress ?? "",
172
+ createdAt: (0, import_date.nowISO)()
173
+ },
174
+ response: {
175
+ json: res._body ?? null,
176
+ headers: res.getHeaders?.()
177
+ },
178
+ user: await this.config.isAuthenticated?.(req) ? await this.config.getUser?.(req) : null
179
+ };
180
+ await requestWatcher.log(logPayload);
181
+ } catch (err) {
182
+ console.error("Error finalizing request log:", err);
183
+ }
184
+ }
185
+ normalizePath(pathStr) {
186
+ return pathStr.startsWith("/") ? pathStr : `/${pathStr}`;
187
+ }
188
+ };
189
+
190
+ // src/index.ts
191
+ var defaultConfig = {
37
192
  appName: "Lens",
38
193
  enabled: true,
39
194
  path: "/lens",
@@ -41,25 +196,25 @@ const defaultConfig = {
41
196
  onlyPaths: [],
42
197
  requestWatcherEnabled: true
43
198
  };
44
- const lens = async (config) => {
45
- const adapter = new import_adapter.default({ app: config.app });
199
+ var lens = async (config) => {
200
+ const adapter = new ExpressAdapter({ app: config.app });
46
201
  const watchers = [];
47
202
  const mergedConfig = {
48
203
  ...config,
49
204
  ...defaultConfig
50
205
  };
51
206
  if (mergedConfig.requestWatcherEnabled) {
52
- watchers.push(new import_core.RequestWatcher());
207
+ watchers.push(new import_core2.RequestWatcher());
53
208
  }
54
209
  if (mergedConfig.queryWatcher?.enabled) {
55
- watchers.push(new import_core.QueryWatcher());
210
+ watchers.push(new import_core2.QueryWatcher());
56
211
  }
57
- const { ignoredPaths, normalizedPath } = import_core.lensUtils.prepareIgnoredPaths(
212
+ const { ignoredPaths, normalizedPath } = import_core2.lensUtils.prepareIgnoredPaths(
58
213
  mergedConfig.path,
59
214
  mergedConfig.ignoredPaths
60
215
  );
61
216
  adapter.setConfig(mergedConfig).setIgnoredPaths(ignoredPaths).setOnlyPaths(mergedConfig.onlyPaths);
62
- await import_core.Lens.setAdapter(adapter).setWatchers(watchers).start({
217
+ await import_core2.Lens.setAdapter(adapter).setWatchers(watchers).start({
63
218
  appName: mergedConfig.appName,
64
219
  enabled: mergedConfig.enabled,
65
220
  basePath: normalizedPath
package/dist/index.js CHANGED
@@ -1,11 +1,169 @@
1
+ // src/index.ts
1
2
  import {
2
3
  Lens,
4
+ lensUtils as lensUtils2,
5
+ QueryWatcher as QueryWatcher2,
6
+ RequestWatcher as RequestWatcher2
7
+ } from "@lensjs/core";
8
+
9
+ // src/adapter.ts
10
+ import {
11
+ LensAdapter,
3
12
  lensUtils,
4
- QueryWatcher,
5
- RequestWatcher
13
+ WatcherTypeEnum
6
14
  } from "@lensjs/core";
7
- import ExpressAdapter from "./adapter";
8
- const defaultConfig = {
15
+ import * as path from "path";
16
+ import fs from "fs";
17
+ import express from "express";
18
+ import { nowISO, sqlDateTime } from "@lensjs/date";
19
+ var ExpressAdapter = class extends LensAdapter {
20
+ app;
21
+ config;
22
+ constructor({ app }) {
23
+ super();
24
+ this.app = app;
25
+ }
26
+ setConfig(config) {
27
+ this.config = config;
28
+ return this;
29
+ }
30
+ setup() {
31
+ for (const watcher of this.getWatchers()) {
32
+ switch (watcher.name) {
33
+ case WatcherTypeEnum.REQUEST:
34
+ this.watchRequests(watcher);
35
+ break;
36
+ case WatcherTypeEnum.QUERY:
37
+ void this.watchQueries(watcher);
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ registerRoutes(routes) {
43
+ routes.forEach((route) => {
44
+ this.app[route.method.toLowerCase()](
45
+ this.normalizePath(route.path),
46
+ async (req, res) => {
47
+ const result = await route.handler({
48
+ params: req.params,
49
+ qs: req.query
50
+ });
51
+ return res.json(result);
52
+ }
53
+ );
54
+ });
55
+ }
56
+ serveUI(uiPath, spaRoute, _dataToInject) {
57
+ this.app.use(this.normalizePath(spaRoute), express.static(uiPath));
58
+ this.app.get(
59
+ this.normalizePath(`${spaRoute}/favicon.svg`),
60
+ (_, res) => res.sendFile(path.join(uiPath, "favicon.svg"))
61
+ );
62
+ this.app.get(new RegExp(`^/${spaRoute}(?!/api)(/.*)?$`), (req, res) => {
63
+ if (lensUtils.isStaticFile(req.path.split("/"))) {
64
+ return res.download(
65
+ path.join(uiPath, lensUtils.stripBeforeAssetsPath(req.path))
66
+ );
67
+ }
68
+ return res.sendFile(path.join(uiPath, "index.html"));
69
+ });
70
+ }
71
+ async watchQueries(watcher) {
72
+ if (!this.config.queryWatcher.enabled) return;
73
+ const handler = this.config.queryWatcher.handler;
74
+ await handler({
75
+ onQuery: async (query) => {
76
+ const queryPayload = {
77
+ query: query.query,
78
+ duration: query.duration || "0 ms",
79
+ createdAt: query.createdAt || sqlDateTime(),
80
+ type: query.type
81
+ };
82
+ await watcher?.log({
83
+ data: queryPayload
84
+ });
85
+ }
86
+ });
87
+ }
88
+ watchRequests(requestWatcher) {
89
+ if (!this.config.requestWatcherEnabled) return;
90
+ this.app.use((req, res, next) => {
91
+ if (this.shouldIgnorePath(req.path)) return next();
92
+ const start = process.hrtime();
93
+ this.patchResponseMethods(res);
94
+ res.on("finish", async () => {
95
+ await this.finalizeRequestLog(req, res, requestWatcher, start);
96
+ });
97
+ next();
98
+ });
99
+ }
100
+ patchResponseMethods(res) {
101
+ const originalJson = res.json.bind(res);
102
+ const originalSend = res.send.bind(res);
103
+ res._body = void 0;
104
+ res.json = function(body) {
105
+ res._body = body;
106
+ return originalJson(body);
107
+ };
108
+ res.send = function(body) {
109
+ let safeBody;
110
+ try {
111
+ if (!body) {
112
+ safeBody = "Purged By Lens";
113
+ } else if (typeof body === "object" && !Buffer.isBuffer(body)) {
114
+ safeBody = body;
115
+ } else if (typeof body === "string") {
116
+ const filePath = path.resolve(body);
117
+ if (fs.existsSync(filePath)) {
118
+ safeBody = "Purged By Lens";
119
+ } else {
120
+ safeBody = body;
121
+ }
122
+ } else if (Buffer.isBuffer(body)) {
123
+ safeBody = "Purged By Lens";
124
+ } else {
125
+ safeBody = "Purged By Lens";
126
+ }
127
+ } catch {
128
+ safeBody = "Purged By Lens";
129
+ }
130
+ res._body = safeBody;
131
+ return originalSend(safeBody);
132
+ };
133
+ }
134
+ async finalizeRequestLog(req, res, requestWatcher, start) {
135
+ try {
136
+ const duration = lensUtils.prettyHrTime(process.hrtime(start));
137
+ const logPayload = {
138
+ request: {
139
+ id: lensUtils.generateRandomUuid(),
140
+ method: req.method,
141
+ duration,
142
+ path: req.originalUrl,
143
+ headers: req.headers,
144
+ body: req.body ?? {},
145
+ status: res.statusCode,
146
+ ip: req.socket?.remoteAddress ?? "",
147
+ createdAt: nowISO()
148
+ },
149
+ response: {
150
+ json: res._body ?? null,
151
+ headers: res.getHeaders?.()
152
+ },
153
+ user: await this.config.isAuthenticated?.(req) ? await this.config.getUser?.(req) : null
154
+ };
155
+ await requestWatcher.log(logPayload);
156
+ } catch (err) {
157
+ console.error("Error finalizing request log:", err);
158
+ }
159
+ }
160
+ normalizePath(pathStr) {
161
+ return pathStr.startsWith("/") ? pathStr : `/${pathStr}`;
162
+ }
163
+ };
164
+
165
+ // src/index.ts
166
+ var defaultConfig = {
9
167
  appName: "Lens",
10
168
  enabled: true,
11
169
  path: "/lens",
@@ -13,7 +171,7 @@ const defaultConfig = {
13
171
  onlyPaths: [],
14
172
  requestWatcherEnabled: true
15
173
  };
16
- const lens = async (config) => {
174
+ var lens = async (config) => {
17
175
  const adapter = new ExpressAdapter({ app: config.app });
18
176
  const watchers = [];
19
177
  const mergedConfig = {
@@ -21,12 +179,12 @@ const lens = async (config) => {
21
179
  ...defaultConfig
22
180
  };
23
181
  if (mergedConfig.requestWatcherEnabled) {
24
- watchers.push(new RequestWatcher());
182
+ watchers.push(new RequestWatcher2());
25
183
  }
26
184
  if (mergedConfig.queryWatcher?.enabled) {
27
- watchers.push(new QueryWatcher());
185
+ watchers.push(new QueryWatcher2());
28
186
  }
29
- const { ignoredPaths, normalizedPath } = lensUtils.prepareIgnoredPaths(
187
+ const { ignoredPaths, normalizedPath } = lensUtils2.prepareIgnoredPaths(
30
188
  mergedConfig.path,
31
189
  mergedConfig.ignoredPaths
32
190
  );
@@ -12,5 +12,7 @@ var __copyProps = (to, from, except, desc) => {
12
12
  return to;
13
13
  };
14
14
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/index.ts
15
17
  var types_exports = {};
16
18
  module.exports = __toCommonJS(types_exports);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lensjs/express",
3
- "version": "1.0.7",
4
- "description": "Express adapter for Lens",
3
+ "version": "1.0.10",
4
+ "description": "Express adapter for LensJs",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "type": "module",
@@ -17,19 +17,17 @@
17
17
  "files": [
18
18
  "dist"
19
19
  ],
20
- "scripts": {
21
- "build": "tsup --clean"
22
- },
23
20
  "dependencies": {
24
21
  "express": "^5.1.0",
25
- "utf-8-validate": "^6.0.5"
22
+ "@lensjs/date": "1.0.10",
23
+ "@lensjs/watchers": "1.0.10",
24
+ "@lensjs/typescript-config": "1.0.10",
25
+ "@lensjs/core": "1.0.10"
26
26
  },
27
- "trustedDependencies": [
28
- "utf-8-validate"
29
- ],
30
27
  "devDependencies": {
31
- "@lensjs/core": "1.0.4",
32
28
  "@types/express": "^5.0.3"
33
29
  },
34
- "gitHead": "a229fde5700970ec290ff31f1e3b7d84cc56d325"
35
- }
30
+ "scripts": {
31
+ "build": "tsup --clean"
32
+ }
33
+ }