@lensjs/core 2.0.0 → 2.1.1
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/README.md +69 -0
- package/dist/abstracts/store.cjs +13 -0
- package/dist/abstracts/store.d.cts +6 -3
- package/dist/abstracts/store.d.ts +6 -3
- package/dist/abstracts/store.js +13 -0
- package/dist/core/api_controller.cjs +22 -1
- package/dist/core/api_controller.d.cts +4 -2
- package/dist/core/api_controller.d.ts +4 -2
- package/dist/core/api_controller.js +22 -1
- package/dist/core/lens.cjs +52 -4
- package/dist/core/lens.js +52 -4
- package/dist/exception-3AZsPtAg.d.ts +52 -0
- package/dist/exception-C69UCHPk.d.cts +52 -0
- package/dist/index.cjs +207 -29
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +204 -29
- package/dist/stores/better_sqlite.cjs +19 -3
- package/dist/stores/better_sqlite.d.cts +9 -1
- package/dist/stores/better_sqlite.d.ts +9 -1
- package/dist/stores/better_sqlite.js +19 -3
- package/dist/stores/index.cjs +19 -3
- package/dist/stores/index.js +19 -3
- package/dist/types/index.cjs +1 -0
- package/dist/types/index.d.cts +26 -2
- package/dist/types/index.d.ts +26 -2
- package/dist/types/index.js +1 -0
- package/dist/ui/assets/{CacheActionBadge-3jjmNjC6.js → CacheActionBadge-CK7JdKoE.js} +1 -1
- package/dist/ui/assets/CacheEntriesTable-C5HcgCZI.js +1 -0
- package/dist/ui/assets/CacheEntryContainer-C0no2_6_.js +2 -0
- package/dist/ui/assets/{CacheEntryDetails-CHt_pNTk.js → CacheEntryDetails-D9Xy7d9u.js} +1 -1
- package/dist/ui/assets/CacheEntryDetailsContainer-BcwliP55.js +2 -0
- package/dist/ui/assets/ExceptionContainer-CQalcd8x.js +2 -0
- package/dist/ui/assets/ExceptionDetails-BbIFoM7M.js +16 -0
- package/dist/ui/assets/ExceptionDetailsContainer-fajmF7id.js +2 -0
- package/dist/ui/assets/ExceptionTable-DY3mmGT4.js +1 -0
- package/dist/ui/assets/{LoadMore-DHOrhPsi.js → LoadMore-CJh7FLbl.js} +1 -1
- package/dist/ui/assets/QueriesContainer-DWTsKzEk.js +2 -0
- package/dist/ui/assets/{QueryDetailsContainer-eoLkgEjj.js → QueryDetailsContainer-7CA9a5de.js} +7 -7
- package/dist/ui/assets/{QueryTable-BXSzT-Cm.js → QueryTable-pn7Ayura.js} +1 -1
- package/dist/ui/assets/RequestDetails-CYSM4og8.js +1 -0
- package/dist/ui/assets/{RequestDetailsContainer-BaH6fUK7.js → RequestDetailsContainer-BECT0XJh.js} +2 -2
- package/dist/ui/assets/RequestsContainer-DLkjpX67.js +2 -0
- package/dist/ui/assets/{RequetsTable-B51VXisk.js → RequetsTable-Cgas07Fe.js} +1 -1
- package/dist/ui/assets/{StatusCode-DVhX11V3.js → StatusCode-C5lihzKZ.js} +1 -1
- package/dist/ui/assets/TabbedDataViewer-BUMQ0QVm.js +1 -0
- package/dist/ui/assets/{Table-D1Kpw7PA.js → Table-BesHc4Lc.js} +1 -1
- package/dist/ui/assets/columns-C1CwS8yE.js +1 -0
- package/dist/ui/assets/{columns-jYfhBxOM.js → columns-CULxhcpY.js} +1 -1
- package/dist/ui/assets/{columns-BIDLCW64.js → columns-gYFQU5qH.js} +1 -1
- package/dist/ui/assets/index-B2QCOgug.css +1 -0
- package/dist/ui/assets/{index-CpP2Ap5X.js → index-BRRKsoNv.js} +1 -1
- package/dist/ui/assets/{index-BdvbrZNf.js → index-PEcJ5nx0.js} +26 -21
- package/dist/ui/assets/{useCacheEntries-vuHEIj6E.js → useCacheEntries-jbGe2CRY.js} +1 -1
- package/dist/ui/assets/useExceptions-uYUhAW-J.js +1 -0
- package/dist/ui/assets/useLensApi-BsDmB7vx.js +1 -0
- package/dist/ui/assets/{useLoadMore-twYxPJ-d.js → useLoadMore-sLsrekV5.js} +1 -1
- package/dist/ui/assets/{useQueries-BYFLoUQR.js → useQueries-DJE91mYq.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/utils/async_context.cjs +113 -0
- package/dist/utils/async_context.d.cts +6 -1
- package/dist/utils/async_context.d.ts +6 -1
- package/dist/utils/async_context.js +102 -0
- package/dist/utils/exception.cjs +130 -0
- package/dist/utils/exception.d.cts +3 -0
- package/dist/utils/exception.d.ts +3 -0
- package/dist/utils/exception.js +91 -0
- package/dist/utils/index.cjs +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/watchers/cache_watcher.cjs +12 -16
- package/dist/watchers/cache_watcher.js +12 -16
- package/dist/watchers/exception_watcher.cjs +108 -0
- package/dist/watchers/exception_watcher.d.cts +10 -0
- package/dist/watchers/exception_watcher.d.ts +10 -0
- package/dist/watchers/exception_watcher.js +75 -0
- package/dist/watchers/index.cjs +53 -16
- package/dist/watchers/index.d.cts +1 -0
- package/dist/watchers/index.d.ts +1 -0
- package/dist/watchers/index.js +42 -16
- package/package.json +8 -6
- package/dist/ui/assets/CacheEntriesTable-DPLre6br.js +0 -1
- package/dist/ui/assets/CacheEntryContainer-WN6LkoCR.js +0 -2
- package/dist/ui/assets/CacheEntryDetailsContainer-BhquSApO.js +0 -2
- package/dist/ui/assets/QueriesContainer-Cl6rq4dH.js +0 -2
- package/dist/ui/assets/RequestDetails-CIB7_XWh.js +0 -1
- package/dist/ui/assets/RequestsContainer-DLS17BWP.js +0 -2
- package/dist/ui/assets/TabbedDataViewer-CNSEhc6h.js +0 -1
- package/dist/ui/assets/index-C04tuZDI.css +0 -1
- package/dist/ui/assets/useLensApi-Bzmx8hps.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @lensjs/core
|
|
2
|
+
|
|
3
|
+
The core library for Lens, providing the fundamental architecture for monitoring and debugging applications. It defines the abstract concepts of adapters, stores, and watchers, along with utilities for event emission, asynchronous context management, and SQL formatting. This package also includes the embedded UI for the Lens dashboard.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
* **`Lens` class**: The central class for initializing Lens, setting up adapters and watchers, and starting the monitoring process.
|
|
8
|
+
* **`LensAdapter` (abstract class)**: Defines the interface for integrating Lens with different application frameworks (e.g., Express, Adonis). It handles route registration and UI serving.
|
|
9
|
+
* **`LensStore` (abstract class)**: Defines the interface for data storage, allowing Lens to persist and retrieve captured events (requests, queries, cache entries). Includes methods for saving, retrieving, and truncating data.
|
|
10
|
+
* **`LensWatcher` (abstract class)**: Defines the interface for capturing specific types of events within an application.
|
|
11
|
+
* **Concrete Watchers**:
|
|
12
|
+
* `RequestWatcher`: Captures and logs details of incoming HTTP requests.
|
|
13
|
+
* `QueryWatcher`: Captures and logs database queries.
|
|
14
|
+
* `CacheWatcher`: Captures and logs cache interactions.
|
|
15
|
+
* `ExceptionWatcher`: Captures and logs exceptions and errors.
|
|
16
|
+
* **`ApiController`**: Provides the API endpoints for the Lens UI to fetch monitoring data.
|
|
17
|
+
* **`lensEmitter`**: A global event emitter for internal communication between different parts of Lens.
|
|
18
|
+
* **`lensContext`**: Utilizes `AsyncLocalStorage` for managing asynchronous context, primarily to associate events with a specific request ID.
|
|
19
|
+
* **`lensUtils`**: A collection of utility functions, including:
|
|
20
|
+
* `generateRandomUuid`: Generates unique IDs.
|
|
21
|
+
* `interpolateQuery`: Interpolates SQL query placeholders with actual values.
|
|
22
|
+
* `formatSqlQuery`: Formats SQL queries for readability.
|
|
23
|
+
* `getMeta`: Provides `__filename` and `__dirname` in both CommonJS and ESM environments.
|
|
24
|
+
* `isStaticFile`, `stripBeforeAssetsPath`: Utilities for handling static file paths.
|
|
25
|
+
* `prepareIgnoredPaths`, `shouldIgnoreCurrentPath`: Logic for path-based filtering.
|
|
26
|
+
* `prettyHrTime`: Formats high-resolution time differences.
|
|
27
|
+
* **`BetterSqliteStore`**: A concrete implementation of `LensStore` using Better SQLite for data persistence.
|
|
28
|
+
* **Embedded UI**: Includes a built-in web interface for visualizing captured application data.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add @lensjs/core
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage Example (Conceptual - typically used via framework adapters)
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { Lens, RequestWatcher, QueryWatcher, CacheWatcher } from '@lensjs/core';
|
|
40
|
+
import { BetterSqliteStore } from '@lensjs/core/stores';
|
|
41
|
+
// Assuming you have a custom adapter for your framework
|
|
42
|
+
import MyFrameworkAdapter from './my-framework-adapter';
|
|
43
|
+
|
|
44
|
+
async function bootstrapLens(appInstance: any) {
|
|
45
|
+
const store = new BetterSqliteStore();
|
|
46
|
+
await store.initialize();
|
|
47
|
+
|
|
48
|
+
const adapter = new MyFrameworkAdapter({ app: appInstance });
|
|
49
|
+
|
|
50
|
+
await Lens.setStore(store)
|
|
51
|
+
.setAdapter(adapter)
|
|
52
|
+
.setWatchers([
|
|
53
|
+
new RequestWatcher(),
|
|
54
|
+
new QueryWatcher(),
|
|
55
|
+
new CacheWatcher(),
|
|
56
|
+
new ExceptionWatcher(),
|
|
57
|
+
])
|
|
58
|
+
.start({
|
|
59
|
+
appName: 'My Application',
|
|
60
|
+
enabled: process.env.NODE_ENV !== 'production',
|
|
61
|
+
basePath: 'lens-dashboard', // UI will be served at /lens-dashboard
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
console.log('Lens core initialized.');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// In your application's main entry point:
|
|
68
|
+
// bootstrapLens(yourFrameworkAppInstance);
|
|
69
|
+
```
|
package/dist/abstracts/store.cjs
CHANGED
|
@@ -24,6 +24,9 @@ __export(store_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(store_exports);
|
|
26
26
|
var Store = class {
|
|
27
|
+
getAllExceptions(_paginationParams) {
|
|
28
|
+
return this.defaultMinimalPaginate();
|
|
29
|
+
}
|
|
27
30
|
stringifyData(data) {
|
|
28
31
|
if (typeof data === "string") {
|
|
29
32
|
return data;
|
|
@@ -34,4 +37,14 @@ var Store = class {
|
|
|
34
37
|
console.error(`Failed to stringify lens data: ${e}`);
|
|
35
38
|
}
|
|
36
39
|
}
|
|
40
|
+
defaultMinimalPaginate() {
|
|
41
|
+
return Promise.resolve({
|
|
42
|
+
data: [],
|
|
43
|
+
meta: {
|
|
44
|
+
currentPage: 0,
|
|
45
|
+
lastPage: 0,
|
|
46
|
+
total: 0
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
37
50
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WatcherTypeEnum, PaginationParams, Paginator, LensEntry } from '../types/index.cjs';
|
|
2
2
|
import 'sql-formatter';
|
|
3
3
|
|
|
4
|
+
type MinimalPaginatePromise = Promise<Paginator<Omit<LensEntry, "data">[]>>;
|
|
4
5
|
declare abstract class Store {
|
|
5
6
|
abstract initialize(): Promise<void>;
|
|
6
7
|
abstract save(entry: {
|
|
@@ -11,15 +12,17 @@ declare abstract class Store {
|
|
|
11
12
|
timestamp?: string;
|
|
12
13
|
requestId?: string;
|
|
13
14
|
}): Promise<void>;
|
|
14
|
-
abstract getAllRequests(paginationParams: PaginationParams):
|
|
15
|
+
abstract getAllRequests(paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
15
16
|
abstract getAllQueries(paginationParams: PaginationParams): Promise<Paginator<LensEntry[]>>;
|
|
16
|
-
abstract
|
|
17
|
-
abstract
|
|
17
|
+
abstract getAllCacheEntries(paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
18
|
+
abstract allByRequestId(requestId: string, type: WatcherTypeEnum, includeFullData?: boolean): Promise<LensEntry[]>;
|
|
18
19
|
abstract find(type: WatcherTypeEnum, id: string): Promise<LensEntry | null>;
|
|
19
20
|
abstract truncate(): Promise<void>;
|
|
20
21
|
abstract paginate<T>(type: WatcherTypeEnum, pagination: PaginationParams): Promise<Paginator<T>>;
|
|
21
22
|
abstract count(type: WatcherTypeEnum): Promise<number>;
|
|
23
|
+
getAllExceptions(_paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
22
24
|
protected stringifyData(data: Record<string, any> | string): string | undefined;
|
|
25
|
+
protected defaultMinimalPaginate(): MinimalPaginatePromise;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
export { Store as default };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WatcherTypeEnum, PaginationParams, Paginator, LensEntry } from '../types/index.js';
|
|
2
2
|
import 'sql-formatter';
|
|
3
3
|
|
|
4
|
+
type MinimalPaginatePromise = Promise<Paginator<Omit<LensEntry, "data">[]>>;
|
|
4
5
|
declare abstract class Store {
|
|
5
6
|
abstract initialize(): Promise<void>;
|
|
6
7
|
abstract save(entry: {
|
|
@@ -11,15 +12,17 @@ declare abstract class Store {
|
|
|
11
12
|
timestamp?: string;
|
|
12
13
|
requestId?: string;
|
|
13
14
|
}): Promise<void>;
|
|
14
|
-
abstract getAllRequests(paginationParams: PaginationParams):
|
|
15
|
+
abstract getAllRequests(paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
15
16
|
abstract getAllQueries(paginationParams: PaginationParams): Promise<Paginator<LensEntry[]>>;
|
|
16
|
-
abstract
|
|
17
|
-
abstract
|
|
17
|
+
abstract getAllCacheEntries(paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
18
|
+
abstract allByRequestId(requestId: string, type: WatcherTypeEnum, includeFullData?: boolean): Promise<LensEntry[]>;
|
|
18
19
|
abstract find(type: WatcherTypeEnum, id: string): Promise<LensEntry | null>;
|
|
19
20
|
abstract truncate(): Promise<void>;
|
|
20
21
|
abstract paginate<T>(type: WatcherTypeEnum, pagination: PaginationParams): Promise<Paginator<T>>;
|
|
21
22
|
abstract count(type: WatcherTypeEnum): Promise<number>;
|
|
23
|
+
getAllExceptions(_paginationParams: PaginationParams): MinimalPaginatePromise;
|
|
22
24
|
protected stringifyData(data: Record<string, any> | string): string | undefined;
|
|
25
|
+
protected defaultMinimalPaginate(): MinimalPaginatePromise;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
export { Store as default };
|
package/dist/abstracts/store.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/abstracts/store.ts
|
|
2
2
|
var Store = class {
|
|
3
|
+
getAllExceptions(_paginationParams) {
|
|
4
|
+
return this.defaultMinimalPaginate();
|
|
5
|
+
}
|
|
3
6
|
stringifyData(data) {
|
|
4
7
|
if (typeof data === "string") {
|
|
5
8
|
return data;
|
|
@@ -10,6 +13,16 @@ var Store = class {
|
|
|
10
13
|
console.error(`Failed to stringify lens data: ${e}`);
|
|
11
14
|
}
|
|
12
15
|
}
|
|
16
|
+
defaultMinimalPaginate() {
|
|
17
|
+
return Promise.resolve({
|
|
18
|
+
data: [],
|
|
19
|
+
meta: {
|
|
20
|
+
currentPage: 0,
|
|
21
|
+
lastPage: 0,
|
|
22
|
+
total: 0
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
13
26
|
};
|
|
14
27
|
export {
|
|
15
28
|
Store as default
|
|
@@ -87,10 +87,16 @@ var ApiController = class {
|
|
|
87
87
|
request.id,
|
|
88
88
|
"cache" /* CACHE */
|
|
89
89
|
);
|
|
90
|
+
const exceptions = await getStore().allByRequestId(
|
|
91
|
+
request.id,
|
|
92
|
+
"exception" /* EXCEPTION */,
|
|
93
|
+
false
|
|
94
|
+
);
|
|
90
95
|
return this.resourceResponse({
|
|
91
96
|
request,
|
|
92
97
|
queries,
|
|
93
|
-
cacheEntries
|
|
98
|
+
cacheEntries,
|
|
99
|
+
exceptions
|
|
94
100
|
});
|
|
95
101
|
}
|
|
96
102
|
static async getQueries({
|
|
@@ -122,6 +128,21 @@ var ApiController = class {
|
|
|
122
128
|
}
|
|
123
129
|
return this.resourceResponse(cacheEntry);
|
|
124
130
|
}
|
|
131
|
+
static async getExceptions({ qs }) {
|
|
132
|
+
return this.paginatedResponse(
|
|
133
|
+
await getStore().getAllExceptions(this.extractPaginationParams(qs))
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
static async getException({ params }) {
|
|
137
|
+
const exception = await getStore().find(
|
|
138
|
+
"exception" /* EXCEPTION */,
|
|
139
|
+
params.id
|
|
140
|
+
);
|
|
141
|
+
if (!exception) {
|
|
142
|
+
return this.notFoundResponse();
|
|
143
|
+
}
|
|
144
|
+
return this.resourceResponse(exception);
|
|
145
|
+
}
|
|
125
146
|
static async truncate() {
|
|
126
147
|
await getStore().truncate();
|
|
127
148
|
return this.baseResponse({}, 200, "All entries cleared");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RouteDefinitionHandler, ApiResponse, LensEntry } from '../types/index.cjs';
|
|
1
|
+
import { RouteDefinitionHandler, ApiResponse, LensEntry, Paginator } from '../types/index.cjs';
|
|
2
2
|
import 'sql-formatter';
|
|
3
3
|
|
|
4
4
|
declare class ApiController {
|
|
@@ -8,6 +8,8 @@ declare class ApiController {
|
|
|
8
8
|
static getQuery({ params, }: RouteDefinitionHandler): Promise<ApiResponse<LensEntry>>;
|
|
9
9
|
static getCacheEntries({ qs }: RouteDefinitionHandler): Promise<ApiResponse<Omit<LensEntry, "data">[]>>;
|
|
10
10
|
static getCacheEntry({ params }: RouteDefinitionHandler): Promise<ApiResponse<Object>>;
|
|
11
|
+
static getExceptions({ qs }: RouteDefinitionHandler): Promise<ApiResponse<Omit<LensEntry, "data">[]>>;
|
|
12
|
+
static getException({ params }: RouteDefinitionHandler): Promise<ApiResponse<Object>>;
|
|
11
13
|
static truncate(): Promise<ApiResponse<{}>>;
|
|
12
14
|
static fetchUiConfig(): {
|
|
13
15
|
appName: string;
|
|
@@ -20,7 +22,7 @@ declare class ApiController {
|
|
|
20
22
|
private static extractPaginationParams;
|
|
21
23
|
private static resourceResponse;
|
|
22
24
|
private static notFoundResponse;
|
|
23
|
-
|
|
25
|
+
static paginatedResponse<T extends Object>(data: Paginator<T>): ApiResponse<T>;
|
|
24
26
|
private static baseResponse;
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RouteDefinitionHandler, ApiResponse, LensEntry } from '../types/index.js';
|
|
1
|
+
import { RouteDefinitionHandler, ApiResponse, LensEntry, Paginator } from '../types/index.js';
|
|
2
2
|
import 'sql-formatter';
|
|
3
3
|
|
|
4
4
|
declare class ApiController {
|
|
@@ -8,6 +8,8 @@ declare class ApiController {
|
|
|
8
8
|
static getQuery({ params, }: RouteDefinitionHandler): Promise<ApiResponse<LensEntry>>;
|
|
9
9
|
static getCacheEntries({ qs }: RouteDefinitionHandler): Promise<ApiResponse<Omit<LensEntry, "data">[]>>;
|
|
10
10
|
static getCacheEntry({ params }: RouteDefinitionHandler): Promise<ApiResponse<Object>>;
|
|
11
|
+
static getExceptions({ qs }: RouteDefinitionHandler): Promise<ApiResponse<Omit<LensEntry, "data">[]>>;
|
|
12
|
+
static getException({ params }: RouteDefinitionHandler): Promise<ApiResponse<Object>>;
|
|
11
13
|
static truncate(): Promise<ApiResponse<{}>>;
|
|
12
14
|
static fetchUiConfig(): {
|
|
13
15
|
appName: string;
|
|
@@ -20,7 +22,7 @@ declare class ApiController {
|
|
|
20
22
|
private static extractPaginationParams;
|
|
21
23
|
private static resourceResponse;
|
|
22
24
|
private static notFoundResponse;
|
|
23
|
-
|
|
25
|
+
static paginatedResponse<T extends Object>(data: Paginator<T>): ApiResponse<T>;
|
|
24
26
|
private static baseResponse;
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -61,10 +61,16 @@ var ApiController = class {
|
|
|
61
61
|
request.id,
|
|
62
62
|
"cache" /* CACHE */
|
|
63
63
|
);
|
|
64
|
+
const exceptions = await getStore().allByRequestId(
|
|
65
|
+
request.id,
|
|
66
|
+
"exception" /* EXCEPTION */,
|
|
67
|
+
false
|
|
68
|
+
);
|
|
64
69
|
return this.resourceResponse({
|
|
65
70
|
request,
|
|
66
71
|
queries,
|
|
67
|
-
cacheEntries
|
|
72
|
+
cacheEntries,
|
|
73
|
+
exceptions
|
|
68
74
|
});
|
|
69
75
|
}
|
|
70
76
|
static async getQueries({
|
|
@@ -96,6 +102,21 @@ var ApiController = class {
|
|
|
96
102
|
}
|
|
97
103
|
return this.resourceResponse(cacheEntry);
|
|
98
104
|
}
|
|
105
|
+
static async getExceptions({ qs }) {
|
|
106
|
+
return this.paginatedResponse(
|
|
107
|
+
await getStore().getAllExceptions(this.extractPaginationParams(qs))
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
static async getException({ params }) {
|
|
111
|
+
const exception = await getStore().find(
|
|
112
|
+
"exception" /* EXCEPTION */,
|
|
113
|
+
params.id
|
|
114
|
+
);
|
|
115
|
+
if (!exception) {
|
|
116
|
+
return this.notFoundResponse();
|
|
117
|
+
}
|
|
118
|
+
return this.resourceResponse(exception);
|
|
119
|
+
}
|
|
99
120
|
static async truncate() {
|
|
100
121
|
await getStore().truncate();
|
|
101
122
|
return this.baseResponse({}, 200, "All entries cleared");
|
package/dist/core/lens.cjs
CHANGED
|
@@ -97,10 +97,16 @@ var ApiController = class {
|
|
|
97
97
|
request.id,
|
|
98
98
|
"cache" /* CACHE */
|
|
99
99
|
);
|
|
100
|
+
const exceptions = await getStore().allByRequestId(
|
|
101
|
+
request.id,
|
|
102
|
+
"exception" /* EXCEPTION */,
|
|
103
|
+
false
|
|
104
|
+
);
|
|
100
105
|
return this.resourceResponse({
|
|
101
106
|
request,
|
|
102
107
|
queries,
|
|
103
|
-
cacheEntries
|
|
108
|
+
cacheEntries,
|
|
109
|
+
exceptions
|
|
104
110
|
});
|
|
105
111
|
}
|
|
106
112
|
static async getQueries({
|
|
@@ -132,6 +138,21 @@ var ApiController = class {
|
|
|
132
138
|
}
|
|
133
139
|
return this.resourceResponse(cacheEntry);
|
|
134
140
|
}
|
|
141
|
+
static async getExceptions({ qs }) {
|
|
142
|
+
return this.paginatedResponse(
|
|
143
|
+
await getStore().getAllExceptions(this.extractPaginationParams(qs))
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
static async getException({ params }) {
|
|
147
|
+
const exception = await getStore().find(
|
|
148
|
+
"exception" /* EXCEPTION */,
|
|
149
|
+
params.id
|
|
150
|
+
);
|
|
151
|
+
if (!exception) {
|
|
152
|
+
return this.notFoundResponse();
|
|
153
|
+
}
|
|
154
|
+
return this.resourceResponse(exception);
|
|
155
|
+
}
|
|
135
156
|
static async truncate() {
|
|
136
157
|
await getStore().truncate();
|
|
137
158
|
return this.baseResponse({}, 200, "All entries cleared");
|
|
@@ -183,6 +204,9 @@ var path2 = __toESM(require("path"), 1);
|
|
|
183
204
|
|
|
184
205
|
// src/abstracts/store.ts
|
|
185
206
|
var Store = class {
|
|
207
|
+
getAllExceptions(_paginationParams) {
|
|
208
|
+
return this.defaultMinimalPaginate();
|
|
209
|
+
}
|
|
186
210
|
stringifyData(data) {
|
|
187
211
|
if (typeof data === "string") {
|
|
188
212
|
return data;
|
|
@@ -193,6 +217,16 @@ var Store = class {
|
|
|
193
217
|
console.error(`Failed to stringify lens data: ${e}`);
|
|
194
218
|
}
|
|
195
219
|
}
|
|
220
|
+
defaultMinimalPaginate() {
|
|
221
|
+
return Promise.resolve({
|
|
222
|
+
data: [],
|
|
223
|
+
meta: {
|
|
224
|
+
currentPage: 0,
|
|
225
|
+
lastPage: 0,
|
|
226
|
+
total: 0
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
196
230
|
};
|
|
197
231
|
|
|
198
232
|
// src/stores/better_sqlite.ts
|
|
@@ -231,11 +265,14 @@ var BetterSqliteStore = class extends Store {
|
|
|
231
265
|
async getAllCacheEntries(pagination) {
|
|
232
266
|
return await this.paginate("cache" /* CACHE */, pagination);
|
|
233
267
|
}
|
|
234
|
-
async
|
|
268
|
+
async getAllExceptions(pagination) {
|
|
269
|
+
return await this.paginate("exception" /* EXCEPTION */, pagination, false);
|
|
270
|
+
}
|
|
271
|
+
async allByRequestId(requestId, type, includeFullData = true) {
|
|
235
272
|
const rows = this.connection.prepare(
|
|
236
|
-
`${this.getSelectedColumns()} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
|
|
273
|
+
`${this.getSelectedColumns(includeFullData)} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
|
|
237
274
|
).all({ type, requestId });
|
|
238
|
-
return this.mapRows(rows);
|
|
275
|
+
return this.mapRows(rows, includeFullData);
|
|
239
276
|
}
|
|
240
277
|
async paginate(type, { page, perPage }, includeFullData = true) {
|
|
241
278
|
const offset = (page - 1) * perPage;
|
|
@@ -397,6 +434,7 @@ var Lens = class {
|
|
|
397
434
|
requests: `/${config.basePath}/api/requests`,
|
|
398
435
|
queries: `/${config.basePath}/api/queries`,
|
|
399
436
|
cache: `/${config.basePath}/api/cache`,
|
|
437
|
+
exceptions: `/${config.basePath}/api/exceptions`,
|
|
400
438
|
truncate: `/${config.basePath}/api/truncate`
|
|
401
439
|
}
|
|
402
440
|
};
|
|
@@ -439,6 +477,16 @@ var Lens = class {
|
|
|
439
477
|
path: `${basePath}/api/cache/:id`,
|
|
440
478
|
handler: async (data) => await ApiController.getCacheEntry(data)
|
|
441
479
|
},
|
|
480
|
+
{
|
|
481
|
+
method: "GET",
|
|
482
|
+
path: `${basePath}/api/exceptions`,
|
|
483
|
+
handler: async (data) => await ApiController.getExceptions(data)
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
method: "GET",
|
|
487
|
+
path: `${basePath}/api/exceptions/:id`,
|
|
488
|
+
handler: async (data) => await ApiController.getException(data)
|
|
489
|
+
},
|
|
442
490
|
{
|
|
443
491
|
method: "DELETE",
|
|
444
492
|
path: `${basePath}/api/truncate`,
|
package/dist/core/lens.js
CHANGED
|
@@ -61,10 +61,16 @@ var ApiController = class {
|
|
|
61
61
|
request.id,
|
|
62
62
|
"cache" /* CACHE */
|
|
63
63
|
);
|
|
64
|
+
const exceptions = await getStore().allByRequestId(
|
|
65
|
+
request.id,
|
|
66
|
+
"exception" /* EXCEPTION */,
|
|
67
|
+
false
|
|
68
|
+
);
|
|
64
69
|
return this.resourceResponse({
|
|
65
70
|
request,
|
|
66
71
|
queries,
|
|
67
|
-
cacheEntries
|
|
72
|
+
cacheEntries,
|
|
73
|
+
exceptions
|
|
68
74
|
});
|
|
69
75
|
}
|
|
70
76
|
static async getQueries({
|
|
@@ -96,6 +102,21 @@ var ApiController = class {
|
|
|
96
102
|
}
|
|
97
103
|
return this.resourceResponse(cacheEntry);
|
|
98
104
|
}
|
|
105
|
+
static async getExceptions({ qs }) {
|
|
106
|
+
return this.paginatedResponse(
|
|
107
|
+
await getStore().getAllExceptions(this.extractPaginationParams(qs))
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
static async getException({ params }) {
|
|
111
|
+
const exception = await getStore().find(
|
|
112
|
+
"exception" /* EXCEPTION */,
|
|
113
|
+
params.id
|
|
114
|
+
);
|
|
115
|
+
if (!exception) {
|
|
116
|
+
return this.notFoundResponse();
|
|
117
|
+
}
|
|
118
|
+
return this.resourceResponse(exception);
|
|
119
|
+
}
|
|
99
120
|
static async truncate() {
|
|
100
121
|
await getStore().truncate();
|
|
101
122
|
return this.baseResponse({}, 200, "All entries cleared");
|
|
@@ -147,6 +168,9 @@ import * as path2 from "path";
|
|
|
147
168
|
|
|
148
169
|
// src/abstracts/store.ts
|
|
149
170
|
var Store = class {
|
|
171
|
+
getAllExceptions(_paginationParams) {
|
|
172
|
+
return this.defaultMinimalPaginate();
|
|
173
|
+
}
|
|
150
174
|
stringifyData(data) {
|
|
151
175
|
if (typeof data === "string") {
|
|
152
176
|
return data;
|
|
@@ -157,6 +181,16 @@ var Store = class {
|
|
|
157
181
|
console.error(`Failed to stringify lens data: ${e}`);
|
|
158
182
|
}
|
|
159
183
|
}
|
|
184
|
+
defaultMinimalPaginate() {
|
|
185
|
+
return Promise.resolve({
|
|
186
|
+
data: [],
|
|
187
|
+
meta: {
|
|
188
|
+
currentPage: 0,
|
|
189
|
+
lastPage: 0,
|
|
190
|
+
total: 0
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
160
194
|
};
|
|
161
195
|
|
|
162
196
|
// src/stores/better_sqlite.ts
|
|
@@ -195,11 +229,14 @@ var BetterSqliteStore = class extends Store {
|
|
|
195
229
|
async getAllCacheEntries(pagination) {
|
|
196
230
|
return await this.paginate("cache" /* CACHE */, pagination);
|
|
197
231
|
}
|
|
198
|
-
async
|
|
232
|
+
async getAllExceptions(pagination) {
|
|
233
|
+
return await this.paginate("exception" /* EXCEPTION */, pagination, false);
|
|
234
|
+
}
|
|
235
|
+
async allByRequestId(requestId, type, includeFullData = true) {
|
|
199
236
|
const rows = this.connection.prepare(
|
|
200
|
-
`${this.getSelectedColumns()} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
|
|
237
|
+
`${this.getSelectedColumns(includeFullData)} FROM ${TABLE_NAME} WHERE type = $type AND lens_entry_id = $requestId ORDER BY created_at DESC`
|
|
201
238
|
).all({ type, requestId });
|
|
202
|
-
return this.mapRows(rows);
|
|
239
|
+
return this.mapRows(rows, includeFullData);
|
|
203
240
|
}
|
|
204
241
|
async paginate(type, { page, perPage }, includeFullData = true) {
|
|
205
242
|
const offset = (page - 1) * perPage;
|
|
@@ -360,6 +397,7 @@ var Lens = class {
|
|
|
360
397
|
requests: `/${config.basePath}/api/requests`,
|
|
361
398
|
queries: `/${config.basePath}/api/queries`,
|
|
362
399
|
cache: `/${config.basePath}/api/cache`,
|
|
400
|
+
exceptions: `/${config.basePath}/api/exceptions`,
|
|
363
401
|
truncate: `/${config.basePath}/api/truncate`
|
|
364
402
|
}
|
|
365
403
|
};
|
|
@@ -402,6 +440,16 @@ var Lens = class {
|
|
|
402
440
|
path: `${basePath}/api/cache/:id`,
|
|
403
441
|
handler: async (data) => await ApiController.getCacheEntry(data)
|
|
404
442
|
},
|
|
443
|
+
{
|
|
444
|
+
method: "GET",
|
|
445
|
+
path: `${basePath}/api/exceptions`,
|
|
446
|
+
handler: async (data) => await ApiController.getExceptions(data)
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
method: "GET",
|
|
450
|
+
path: `${basePath}/api/exceptions/:id`,
|
|
451
|
+
handler: async (data) => await ApiController.getException(data)
|
|
452
|
+
},
|
|
405
453
|
{
|
|
406
454
|
method: "DELETE",
|
|
407
455
|
path: `${basePath}/api/truncate`,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ExceptionEntry } from './types/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Clean a raw stack trace string, removing internal Node.js frames.
|
|
5
|
+
*/
|
|
6
|
+
declare function cleanStack(stack?: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Extract file information from the top frame of a stack trace.
|
|
9
|
+
*/
|
|
10
|
+
declare function getFileInfo(stack?: string): {
|
|
11
|
+
file: string;
|
|
12
|
+
line: number;
|
|
13
|
+
column: number;
|
|
14
|
+
function: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Parse a stack trace into an array of structured frames.
|
|
18
|
+
*/
|
|
19
|
+
declare function getStackTrace(stack?: string): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Extract surrounding code lines (context) from a file where the error occurred.
|
|
22
|
+
*/
|
|
23
|
+
declare function extractCodeFrame({ file, line, column, contextLines, }: {
|
|
24
|
+
file: string;
|
|
25
|
+
line: number;
|
|
26
|
+
column: number;
|
|
27
|
+
contextLines?: number;
|
|
28
|
+
}): {
|
|
29
|
+
file: string;
|
|
30
|
+
line: number;
|
|
31
|
+
column: number;
|
|
32
|
+
context: {
|
|
33
|
+
pre: string[];
|
|
34
|
+
error: string;
|
|
35
|
+
post: string[];
|
|
36
|
+
};
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* Construct a normalized error object with metadata, stack trace, and code frame.
|
|
40
|
+
*/
|
|
41
|
+
declare function constructErrorObject(err: Error): ExceptionEntry;
|
|
42
|
+
|
|
43
|
+
declare const exception_cleanStack: typeof cleanStack;
|
|
44
|
+
declare const exception_constructErrorObject: typeof constructErrorObject;
|
|
45
|
+
declare const exception_extractCodeFrame: typeof extractCodeFrame;
|
|
46
|
+
declare const exception_getFileInfo: typeof getFileInfo;
|
|
47
|
+
declare const exception_getStackTrace: typeof getStackTrace;
|
|
48
|
+
declare namespace exception {
|
|
49
|
+
export { exception_cleanStack as cleanStack, exception_constructErrorObject as constructErrorObject, exception_extractCodeFrame as extractCodeFrame, exception_getFileInfo as getFileInfo, exception_getStackTrace as getStackTrace };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { getStackTrace as a, extractCodeFrame as b, cleanStack as c, constructErrorObject as d, exception as e, getFileInfo as g };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ExceptionEntry } from './types/index.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Clean a raw stack trace string, removing internal Node.js frames.
|
|
5
|
+
*/
|
|
6
|
+
declare function cleanStack(stack?: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Extract file information from the top frame of a stack trace.
|
|
9
|
+
*/
|
|
10
|
+
declare function getFileInfo(stack?: string): {
|
|
11
|
+
file: string;
|
|
12
|
+
line: number;
|
|
13
|
+
column: number;
|
|
14
|
+
function: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Parse a stack trace into an array of structured frames.
|
|
18
|
+
*/
|
|
19
|
+
declare function getStackTrace(stack?: string): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Extract surrounding code lines (context) from a file where the error occurred.
|
|
22
|
+
*/
|
|
23
|
+
declare function extractCodeFrame({ file, line, column, contextLines, }: {
|
|
24
|
+
file: string;
|
|
25
|
+
line: number;
|
|
26
|
+
column: number;
|
|
27
|
+
contextLines?: number;
|
|
28
|
+
}): {
|
|
29
|
+
file: string;
|
|
30
|
+
line: number;
|
|
31
|
+
column: number;
|
|
32
|
+
context: {
|
|
33
|
+
pre: string[];
|
|
34
|
+
error: string;
|
|
35
|
+
post: string[];
|
|
36
|
+
};
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* Construct a normalized error object with metadata, stack trace, and code frame.
|
|
40
|
+
*/
|
|
41
|
+
declare function constructErrorObject(err: Error): ExceptionEntry;
|
|
42
|
+
|
|
43
|
+
declare const exception_cleanStack: typeof cleanStack;
|
|
44
|
+
declare const exception_constructErrorObject: typeof constructErrorObject;
|
|
45
|
+
declare const exception_extractCodeFrame: typeof extractCodeFrame;
|
|
46
|
+
declare const exception_getFileInfo: typeof getFileInfo;
|
|
47
|
+
declare const exception_getStackTrace: typeof getStackTrace;
|
|
48
|
+
declare namespace exception {
|
|
49
|
+
export { exception_cleanStack as cleanStack, exception_constructErrorObject as constructErrorObject, exception_extractCodeFrame as extractCodeFrame, exception_getFileInfo as getFileInfo, exception_getStackTrace as getStackTrace };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { getStackTrace as a, extractCodeFrame as b, cleanStack as c, constructErrorObject as d, exception as e, getFileInfo as g };
|