@lensjs/core 1.0.1 → 1.0.2
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/abstracts/adapter.cjs +8 -0
- package/dist/abstracts/adapter.d.cts +19 -0
- package/dist/abstracts/adapter.d.ts +19 -0
- package/dist/abstracts/adapter.js +8 -0
- package/dist/abstracts/store.cjs +7 -0
- package/dist/abstracts/store.d.cts +23 -0
- package/dist/abstracts/store.d.ts +23 -0
- package/dist/abstracts/store.js +7 -0
- package/dist/chunk-2HRVJRKV.cjs +10 -0
- package/dist/chunk-3R5QARPT.cjs +14 -0
- package/{src/watchers/request_watcher.ts → dist/chunk-4HLDYZJA.js} +18 -11
- package/dist/chunk-5PYQWLAZ.js +129 -0
- package/dist/chunk-75ZPJI57.cjs +9 -0
- package/dist/chunk-7EKM5HB5.cjs +1 -0
- package/dist/chunk-AUDSBNLF.cjs +122 -0
- package/dist/chunk-BFFOUTTE.cjs +32 -0
- package/dist/chunk-BL4Z6JFH.cjs +34 -0
- package/dist/chunk-CQ2Z4TCR.js +7 -0
- package/dist/chunk-EHOWCXZV.cjs +7 -0
- package/{src/utils/index.ts → dist/chunk-EJ5BW35V.js} +69 -86
- package/dist/chunk-EKG3FVLV.cjs +7 -0
- package/dist/chunk-FCMQ3WE3.cjs +129 -0
- package/dist/chunk-FKMBNWX4.js +7 -0
- package/dist/chunk-FLOVBBFU.js +10 -0
- package/dist/chunk-GI7SJDNQ.cjs +38 -0
- package/dist/chunk-IPMTMCFP.js +122 -0
- package/dist/chunk-JZ2JLQXL.cjs +87 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-QRZUNYF6.cjs +16 -0
- package/dist/chunk-RMZ4UAQ2.js +14 -0
- package/dist/chunk-SJXZARBJ.cjs +22 -0
- package/dist/chunk-TJDE6AZM.js +87 -0
- package/dist/chunk-TPUVRGYT.js +32 -0
- package/dist/chunk-UF5HFNMI.js +22 -0
- package/dist/chunk-VD5IMUWL.js +0 -0
- package/dist/chunk-WU6IZUEV.cjs +159 -0
- package/dist/chunk-XXYRWHSQ.js +0 -0
- package/dist/chunk-XYXPHWEI.js +16 -0
- package/dist/chunk-XZFXXD3A.cjs +1 -0
- package/dist/chunk-YC6T4XWI.js +38 -0
- package/dist/context/container.cjs +7 -0
- package/dist/context/container.d.cts +28 -0
- package/dist/context/container.d.ts +28 -0
- package/dist/context/container.js +7 -0
- package/dist/context/context.cjs +10 -0
- package/dist/context/context.d.cts +15 -0
- package/dist/context/context.d.ts +15 -0
- package/dist/context/context.js +10 -0
- package/dist/core/api_controller.cjs +10 -0
- package/dist/core/api_controller.d.cts +25 -0
- package/dist/core/api_controller.d.ts +25 -0
- package/dist/core/api_controller.js +10 -0
- package/dist/core/lens.cjs +15 -0
- package/dist/core/lens.d.cts +24 -0
- package/dist/core/lens.d.ts +24 -0
- package/dist/core/lens.js +15 -0
- package/dist/core/watcher.cjs +7 -0
- package/dist/core/watcher.d.cts +9 -0
- package/dist/core/watcher.d.ts +9 -0
- package/dist/core/watcher.js +7 -0
- package/dist/index-D0Vszdac.d.cts +49 -0
- package/dist/index-D0Vszdac.d.ts +49 -0
- package/dist/index.cjs +55 -0
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +55 -0
- package/dist/stores/better_sqlite.cjs +10 -0
- package/dist/stores/better_sqlite.d.cts +51 -0
- package/dist/stores/better_sqlite.d.ts +51 -0
- package/dist/stores/better_sqlite.js +10 -0
- package/dist/stores/index.cjs +11 -0
- package/dist/stores/index.d.cts +5 -0
- package/dist/stores/index.d.ts +5 -0
- package/dist/stores/index.js +11 -0
- package/dist/types/index.cjs +7 -0
- package/dist/types/index.d.cts +91 -0
- package/dist/types/index.d.ts +91 -0
- package/dist/types/index.js +7 -0
- package/dist/ui/assets/QueriesContainer-Bxr99HkT.js +2 -0
- package/dist/ui/assets/QueryDetailsContainer-BcbxQyxT.js +48 -0
- package/dist/ui/assets/QueryTable-Dx1MyXwe.js +1 -0
- package/dist/ui/assets/RequestDetails-B9rQn1tY.js +1 -0
- package/dist/ui/assets/RequestDetailsContainer-C0sOvaO2.js +2 -0
- package/dist/ui/assets/RequestsContainer-DYNNLt6S.js +2 -0
- package/dist/ui/assets/RequetsTable-BN-1fud-.js +1 -0
- package/dist/ui/assets/StatusCode-ByIHR7Pe.js +1 -0
- package/dist/ui/assets/TabbedDataViewer-CoLeLuBm.js +1 -0
- package/dist/ui/assets/Table-CXg4Wfwf.js +6 -0
- package/dist/ui/assets/date-BXZFS9Wq.js +1 -0
- package/dist/ui/assets/index-BPTSPdZM.css +1 -0
- package/dist/ui/assets/index-C3XpMOuU.js +114 -0
- package/dist/ui/assets/useLensApi-BlL4RwJa.js +1 -0
- package/dist/ui/assets/useLoadMore-BqF649Mm.js +1 -0
- package/dist/ui/assets/useQueries-Iwl8o-Xk.js +1 -0
- package/dist/ui/favicon.ico +0 -0
- package/dist/ui/index.html +14 -0
- package/dist/utils/event_emitter.cjs +11 -0
- package/dist/utils/event_emitter.d.cts +16 -0
- package/dist/utils/event_emitter.d.ts +16 -0
- package/dist/utils/event_emitter.js +11 -0
- package/dist/utils/index.cjs +31 -0
- package/dist/utils/index.d.cts +3 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +31 -0
- package/dist/watchers/index.cjs +16 -0
- package/dist/watchers/index.d.cts +5 -0
- package/dist/watchers/index.d.ts +5 -0
- package/dist/watchers/index.js +16 -0
- package/dist/watchers/query_watcher.cjs +11 -0
- package/dist/watchers/query_watcher.d.cts +10 -0
- package/dist/watchers/query_watcher.d.ts +10 -0
- package/dist/watchers/query_watcher.js +11 -0
- package/dist/watchers/request_watcher.cjs +11 -0
- package/dist/watchers/request_watcher.d.cts +10 -0
- package/dist/watchers/request_watcher.d.ts +10 -0
- package/dist/watchers/request_watcher.js +11 -0
- package/package.json +4 -1
- package/copy-front-build.cjs +0 -16
- package/src/abstracts/adapter.ts +0 -41
- package/src/abstracts/store.ts +0 -36
- package/src/context/container.ts +0 -67
- package/src/context/context.ts +0 -9
- package/src/core/api_controller.ts +0 -116
- package/src/core/lens.ts +0 -147
- package/src/core/watcher.ts +0 -6
- package/src/index.ts +0 -11
- package/src/stores/better_sqlite.ts +0 -176
- package/src/stores/index.ts +0 -1
- package/src/types/index.ts +0 -103
- package/src/ui/README.md +0 -69
- package/src/ui/bun.lock +0 -750
- package/src/ui/eslint.config.js +0 -27
- package/src/ui/index.html +0 -13
- package/src/ui/package-lock.json +0 -2953
- package/src/ui/package.json +0 -40
- package/src/ui/src/App.tsx +0 -40
- package/src/ui/src/components/DetailPanel.tsx +0 -70
- package/src/ui/src/components/JsonViewer.tsx +0 -232
- package/src/ui/src/components/LoadMore.tsx +0 -25
- package/src/ui/src/components/MethodBadge.tsx +0 -19
- package/src/ui/src/components/Modal.tsx +0 -48
- package/src/ui/src/components/StatusCode.tsx +0 -20
- package/src/ui/src/components/Table.tsx +0 -127
- package/src/ui/src/components/layout/DeleteButton.tsx +0 -60
- package/src/ui/src/components/layout/Footer.tsx +0 -12
- package/src/ui/src/components/layout/Header.tsx +0 -40
- package/src/ui/src/components/layout/Layout.tsx +0 -49
- package/src/ui/src/components/layout/LoadingScreen.tsx +0 -14
- package/src/ui/src/components/layout/Sidebar.tsx +0 -67
- package/src/ui/src/components/queryFormatters/MongoViewer.tsx +0 -92
- package/src/ui/src/components/queryFormatters/QueryViewer.tsx +0 -18
- package/src/ui/src/components/queryFormatters/SqlViewer.tsx +0 -105
- package/src/ui/src/components/table/NoData.tsx +0 -26
- package/src/ui/src/components/tabs/TabbedDataViewer.tsx +0 -77
- package/src/ui/src/containers/queries/QueriesContainer.tsx +0 -21
- package/src/ui/src/containers/queries/QueryDetailsContainer.tsx +0 -15
- package/src/ui/src/containers/requests/RequestDetailsContainer.tsx +0 -16
- package/src/ui/src/containers/requests/RequestsContainer.tsx +0 -22
- package/src/ui/src/hooks/useLensApi.ts +0 -92
- package/src/ui/src/hooks/useLoadMore.ts +0 -48
- package/src/ui/src/hooks/useQueries.ts +0 -58
- package/src/ui/src/hooks/useRequests.ts +0 -79
- package/src/ui/src/hooks/useTanstackApi.ts +0 -126
- package/src/ui/src/index.css +0 -78
- package/src/ui/src/interfaces/index.ts +0 -10
- package/src/ui/src/main.tsx +0 -33
- package/src/ui/src/router/Router.ts +0 -11
- package/src/ui/src/router/routes/Loading.tsx +0 -5
- package/src/ui/src/router/routes/index.tsx +0 -85
- package/src/ui/src/types/index.ts +0 -95
- package/src/ui/src/utils/api.ts +0 -7
- package/src/ui/src/utils/context.ts +0 -24
- package/src/ui/src/utils/date.ts +0 -36
- package/src/ui/src/views/queries/QueryDetails.tsx +0 -58
- package/src/ui/src/views/queries/QueryTable.tsx +0 -21
- package/src/ui/src/views/queries/columns.tsx +0 -83
- package/src/ui/src/views/requests/BasicRequestDetails.tsx +0 -82
- package/src/ui/src/views/requests/RequestDetails.tsx +0 -70
- package/src/ui/src/views/requests/RequetsTable.tsx +0 -19
- package/src/ui/src/views/requests/columns.tsx +0 -62
- package/src/ui/src/vite-env.d.ts +0 -1
- package/src/ui/tsconfig.app.json +0 -27
- package/src/ui/tsconfig.json +0 -7
- package/src/ui/tsconfig.node.json +0 -25
- package/src/ui/vite.config.ts +0 -9
- package/src/utils/event_emitter.ts +0 -13
- package/src/watchers/index.ts +0 -2
- package/src/watchers/query_watcher.ts +0 -15
- package/tests/core/lens.test.ts +0 -89
- package/tests/stores/better_sqlite.test.ts +0 -168
- package/tests/utils/index.test.ts +0 -182
- package/tests/watchers/query_watcher.test.ts +0 -35
- package/tests/watchers/request_watcher.test.ts +0 -59
- package/tsconfig.json +0 -3
- package/tsup.config.ts +0 -15
- package/vitest.config.ts +0 -9
- /package/{src/ui/public/favicon.ico → dist/ui/assets/favicon-D0UnoCWN.ico} +0 -0
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Link } from "react-router-dom";
|
|
2
|
-
import DetailPanel from "../../components/DetailPanel";
|
|
3
|
-
import TabbedDataViewer from "../../components/tabs/TabbedDataViewer";
|
|
4
|
-
import type { QueryEntry } from "../../types";
|
|
5
|
-
import { getRoutesPaths } from "../../router/routes";
|
|
6
|
-
import { useConfig } from "../../utils/context";
|
|
7
|
-
import { formatDateWithTimeAgo } from "../../utils/date";
|
|
8
|
-
import QueryViewer from "../../components/queryFormatters/QueryViewer";
|
|
9
|
-
|
|
10
|
-
export default function QueryDetails({ query }: { query: QueryEntry }) {
|
|
11
|
-
const detailItems = [
|
|
12
|
-
query.lens_entry_id && {
|
|
13
|
-
label: "Request",
|
|
14
|
-
value: (
|
|
15
|
-
<Link
|
|
16
|
-
to={`${getRoutesPaths(useConfig()).REQUESTS}/${query.lens_entry_id}`}
|
|
17
|
-
className="text-blue-600 hover:underline font-semibold"
|
|
18
|
-
>
|
|
19
|
-
View Request
|
|
20
|
-
</Link>
|
|
21
|
-
),
|
|
22
|
-
className: "text-gray-900 dark:text-gray-100",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
label: "Time",
|
|
26
|
-
value: <span>{formatDateWithTimeAgo(query.created_at)}</span>,
|
|
27
|
-
className: "text-gray-900 dark:text-gray-100",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
label: "Duration",
|
|
31
|
-
value: <span>{query.data.duration}</span>,
|
|
32
|
-
className: "text-gray-900 dark:text-gray-100",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
label: "Provider",
|
|
36
|
-
value: <span>{query.data.type}</span>,
|
|
37
|
-
className: "text-gray-900 dark:text-gray-100",
|
|
38
|
-
},
|
|
39
|
-
].filter((item) => !!item);
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<div className="flex flex-col gap-4">
|
|
43
|
-
{" "}
|
|
44
|
-
<DetailPanel title="Request Details" items={detailItems} />
|
|
45
|
-
<TabbedDataViewer
|
|
46
|
-
tabs={[
|
|
47
|
-
{
|
|
48
|
-
id: "query",
|
|
49
|
-
data: ["query"],
|
|
50
|
-
label: "Query",
|
|
51
|
-
content: <QueryViewer queryPayload={query.data} />,
|
|
52
|
-
},
|
|
53
|
-
]}
|
|
54
|
-
defaultActiveTab="query"
|
|
55
|
-
/>
|
|
56
|
-
</div>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { LoadMoreButton } from "../../components/LoadMore";
|
|
2
|
-
import Table from "../../components/Table";
|
|
3
|
-
import type { HasMoreType, QueryTableRow } from "../../types";
|
|
4
|
-
import getColumns from "./columns";
|
|
5
|
-
|
|
6
|
-
const QueriesTable = ({
|
|
7
|
-
hasMoreObject,
|
|
8
|
-
}: {
|
|
9
|
-
hasMoreObject: HasMoreType<QueryTableRow>;
|
|
10
|
-
}) => {
|
|
11
|
-
return (
|
|
12
|
-
<div className="w-full">
|
|
13
|
-
<div className="overflow-x-auto">
|
|
14
|
-
<Table columns={getColumns()} data={hasMoreObject.data} />
|
|
15
|
-
</div>
|
|
16
|
-
<LoadMoreButton paginatedPage={hasMoreObject} />
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default QueriesTable;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { CircleArrowRightIcon } from "lucide-react";
|
|
2
|
-
import type { JSX } from "react";
|
|
3
|
-
import { Link } from "react-router-dom";
|
|
4
|
-
import type { TableColumn } from "../../components/Table";
|
|
5
|
-
import { getRoutesPaths } from "../../router/routes";
|
|
6
|
-
import type { QueryTableRow } from "../../types";
|
|
7
|
-
import { useConfig } from "../../utils/context";
|
|
8
|
-
import { humanDifferentDate } from "../../utils/date";
|
|
9
|
-
|
|
10
|
-
function highlightSQL(query: string): JSX.Element {
|
|
11
|
-
return (
|
|
12
|
-
<span className="text-red-600 dark:text-red-400 font-mono">{query}</span>
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const getColumns = (): TableColumn<QueryTableRow>[] => {
|
|
17
|
-
const paths = getRoutesPaths(useConfig());
|
|
18
|
-
|
|
19
|
-
return [
|
|
20
|
-
{
|
|
21
|
-
name: "Query",
|
|
22
|
-
render: (row) => (
|
|
23
|
-
<div className="col-span-5">
|
|
24
|
-
<code
|
|
25
|
-
className="text-sm font-mono text-slate-800 dark:text-slate-300 leading-relaxed line-clamp-1"
|
|
26
|
-
title={row.data.query}
|
|
27
|
-
>
|
|
28
|
-
{highlightSQL(row.data.query)}
|
|
29
|
-
</code>
|
|
30
|
-
</div>
|
|
31
|
-
),
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: "Duration",
|
|
35
|
-
render: (row) => (
|
|
36
|
-
<div className="col-span-1 text-right">
|
|
37
|
-
<span className="text-sm text-slate-600 dark:text-slate-400 font-mono">
|
|
38
|
-
{row.data.duration}
|
|
39
|
-
</span>
|
|
40
|
-
</div>
|
|
41
|
-
),
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: "Provider",
|
|
45
|
-
render: (row) => {
|
|
46
|
-
return (
|
|
47
|
-
<div className="col-span-2 text-right">
|
|
48
|
-
<span className="text-sm text-slate-600 dark:text-slate-400 font-mono">
|
|
49
|
-
{row.data.type}
|
|
50
|
-
</span>
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
name: "Happened",
|
|
57
|
-
render: (row) => {
|
|
58
|
-
const { label, exact } = humanDifferentDate(row.data.createdAt);
|
|
59
|
-
return (
|
|
60
|
-
<span className="text-nowrap" title={exact}>
|
|
61
|
-
{label}
|
|
62
|
-
</span>
|
|
63
|
-
);
|
|
64
|
-
},
|
|
65
|
-
position: "end",
|
|
66
|
-
class: "min-w-32",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "Actions",
|
|
70
|
-
render: (row) => (
|
|
71
|
-
<Link
|
|
72
|
-
to={`${paths.QUERIES}/${row.id}`}
|
|
73
|
-
className="transition-colors duration-100 hover:text-white"
|
|
74
|
-
>
|
|
75
|
-
<CircleArrowRightIcon size={20} />
|
|
76
|
-
</Link>
|
|
77
|
-
),
|
|
78
|
-
position: "end",
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export default getColumns;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { useMemo } from "react";
|
|
2
|
-
import DetailPanel, { type DetailItem } from "../../components/DetailPanel";
|
|
3
|
-
import type { OneRequest } from "../../types";
|
|
4
|
-
import { formatDateWithTimeAgo} from "../../utils/date";
|
|
5
|
-
import MethodBadge from "../../components/MethodBadge";
|
|
6
|
-
import StatusCode from "../../components/StatusCode";
|
|
7
|
-
|
|
8
|
-
const BasicRequestDetails = ({ request }: { request: OneRequest }) => {
|
|
9
|
-
const formattedTime = useMemo(() => {
|
|
10
|
-
return formatDateWithTimeAgo(request?.data?.createdAt);
|
|
11
|
-
}, [request?.data?.createdAt]);
|
|
12
|
-
|
|
13
|
-
if (!request || !request.data) {
|
|
14
|
-
return (
|
|
15
|
-
<DetailPanel
|
|
16
|
-
title="Request Details"
|
|
17
|
-
items={[]}
|
|
18
|
-
emptyMessage="No request data available"
|
|
19
|
-
/>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const getHostname = () => {
|
|
24
|
-
return request?.data?.headers?.host || "Unknown";
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const detailItems = useMemo(
|
|
28
|
-
(): DetailItem[] => [
|
|
29
|
-
{
|
|
30
|
-
label: "Time",
|
|
31
|
-
value: formattedTime,
|
|
32
|
-
className: "text-gray-900 dark:text-gray-100",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
label: "Hostname",
|
|
36
|
-
value: getHostname(),
|
|
37
|
-
className: "text-gray-900 dark:text-gray-100 font-mono",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
label: "Method",
|
|
41
|
-
value: request.data.method ? (
|
|
42
|
-
<MethodBadge method={request.data.method} />
|
|
43
|
-
) : (
|
|
44
|
-
"Unknown"
|
|
45
|
-
),
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
label: "Request ID",
|
|
49
|
-
value: request.data.id || "N/A",
|
|
50
|
-
className: "text-gray-700 dark:text-gray-300 font-mono text-sm",
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
label: "Path",
|
|
54
|
-
value: request.data.path || "N/A",
|
|
55
|
-
className: "text-gray-900 dark:text-gray-100 font-mono",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
label: "Status",
|
|
59
|
-
value: request.data.status ? (
|
|
60
|
-
<StatusCode status={request.data.status} />
|
|
61
|
-
) : (
|
|
62
|
-
"N/A"
|
|
63
|
-
),
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
label: "Duration",
|
|
67
|
-
value: request.data.duration || "N/A",
|
|
68
|
-
className: "text-gray-900 dark:text-gray-100 font-medium",
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
label: "IP Address",
|
|
72
|
-
value: request.data.ip || "N/A",
|
|
73
|
-
className: "text-gray-900 dark:text-gray-100 font-mono",
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
[request.data, formattedTime],
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
return <DetailPanel title="Request Details" items={detailItems} />;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export default BasicRequestDetails;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import DetailPanel from "../../components/DetailPanel";
|
|
2
|
-
import TabbedDataViewer from "../../components/tabs/TabbedDataViewer";
|
|
3
|
-
import type { OneRequest } from "../../types";
|
|
4
|
-
import BasicRequestDetails from "./BasicRequestDetails";
|
|
5
|
-
|
|
6
|
-
const RequestDetails = ({ request }: { request: OneRequest }) => {
|
|
7
|
-
const dynamicTabs = [
|
|
8
|
-
{
|
|
9
|
-
id: "payload",
|
|
10
|
-
label: "Payload",
|
|
11
|
-
data: request.data.body,
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
id: "headers",
|
|
15
|
-
label: "Headers",
|
|
16
|
-
data: request.data.headers,
|
|
17
|
-
},
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
const responseTabs = [
|
|
21
|
-
{
|
|
22
|
-
id: "response-body",
|
|
23
|
-
label: "Body",
|
|
24
|
-
data: request.data.response.json,
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: "response-headers",
|
|
28
|
-
label: "Headers",
|
|
29
|
-
data: request.data.response.headers,
|
|
30
|
-
},
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<div className="flex flex-col gap-3">
|
|
35
|
-
<BasicRequestDetails request={request} />
|
|
36
|
-
{request.data.user && (
|
|
37
|
-
<DetailPanel
|
|
38
|
-
title="User"
|
|
39
|
-
items={[
|
|
40
|
-
{
|
|
41
|
-
label: "ID",
|
|
42
|
-
value: request?.data?.user?.id,
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
label: "Email",
|
|
46
|
-
value: request?.data?.user?.email,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
label: "Name",
|
|
50
|
-
value: request?.data?.user?.name,
|
|
51
|
-
},
|
|
52
|
-
]}
|
|
53
|
-
/>
|
|
54
|
-
)}
|
|
55
|
-
|
|
56
|
-
<TabbedDataViewer
|
|
57
|
-
tabs={dynamicTabs}
|
|
58
|
-
title="Request Data"
|
|
59
|
-
defaultActiveTab="payload"
|
|
60
|
-
/>
|
|
61
|
-
<TabbedDataViewer
|
|
62
|
-
tabs={responseTabs}
|
|
63
|
-
title="Response Data"
|
|
64
|
-
defaultActiveTab="response-body"
|
|
65
|
-
/>
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export default RequestDetails;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { LoadMoreButton } from "../../components/LoadMore";
|
|
2
|
-
import Table from "../../components/Table";
|
|
3
|
-
import type { HasMoreType, RequestTableRow } from "../../types";
|
|
4
|
-
import getColumns from "./columns";
|
|
5
|
-
|
|
6
|
-
const RequestTable = ({
|
|
7
|
-
hasMoreObject,
|
|
8
|
-
}: {
|
|
9
|
-
hasMoreObject: HasMoreType<RequestTableRow>;
|
|
10
|
-
}) => {
|
|
11
|
-
return (
|
|
12
|
-
<div>
|
|
13
|
-
<Table columns={getColumns()} data={hasMoreObject.data} />
|
|
14
|
-
<LoadMoreButton paginatedPage={hasMoreObject} />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default RequestTable;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { CircleArrowRightIcon } from "lucide-react";
|
|
2
|
-
import MethodBadge from "../../components/MethodBadge";
|
|
3
|
-
import StatusCode from "../../components/StatusCode";
|
|
4
|
-
import { getRoutesPaths } from "../../router/routes";
|
|
5
|
-
import type { RequestTableRow } from "../../types";
|
|
6
|
-
import { useConfig } from "../../utils/context";
|
|
7
|
-
import { humanDifferentDate } from "../../utils/date";
|
|
8
|
-
import type { TableColumn } from "../../components/Table";
|
|
9
|
-
import { Link } from "react-router-dom";
|
|
10
|
-
|
|
11
|
-
const getColumns = (): TableColumn<RequestTableRow>[] => {
|
|
12
|
-
const paths = getRoutesPaths(useConfig());
|
|
13
|
-
|
|
14
|
-
return [
|
|
15
|
-
{
|
|
16
|
-
name: "Verb",
|
|
17
|
-
render: (row) => <MethodBadge method={row.data.method} />,
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
name: "Path",
|
|
21
|
-
render: (row) => (
|
|
22
|
-
<Link
|
|
23
|
-
to={`${paths.REQUESTS}/${row.id}`}
|
|
24
|
-
className="line-clamp-2 max-w-80 min-w-40 text-base text-blue-600 dark:text-neutral-200 hover:underline"
|
|
25
|
-
>
|
|
26
|
-
{row.data.path}
|
|
27
|
-
</Link>
|
|
28
|
-
),
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: "Status",
|
|
32
|
-
render: (row) => <StatusCode status={row.data.status} />,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: "Duration",
|
|
36
|
-
value: (row) => row.data.duration,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: "Happened",
|
|
40
|
-
render: (row) => {
|
|
41
|
-
const { label, exact } = humanDifferentDate(row.data.createdAt);
|
|
42
|
-
return <span title={exact}>{label}</span>;
|
|
43
|
-
},
|
|
44
|
-
position: "end",
|
|
45
|
-
class: "min-w-32",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: "Actions",
|
|
49
|
-
render: (row) => (
|
|
50
|
-
<Link
|
|
51
|
-
to={`${paths.REQUESTS}/${row.id}`}
|
|
52
|
-
className="transition-colors duration-100 hover:text-white"
|
|
53
|
-
>
|
|
54
|
-
<CircleArrowRightIcon size={20} />
|
|
55
|
-
</Link>
|
|
56
|
-
),
|
|
57
|
-
position: "end",
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export default getColumns;
|
package/src/ui/src/vite-env.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
package/src/ui/tsconfig.app.json
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"useDefineForClassFields": true,
|
|
6
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"verbatimModuleSyntax": true,
|
|
14
|
-
"moduleDetection": "force",
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"jsx": "react-jsx",
|
|
17
|
-
|
|
18
|
-
/* Linting */
|
|
19
|
-
"strict": true,
|
|
20
|
-
"noUnusedLocals": true,
|
|
21
|
-
"noUnusedParameters": true,
|
|
22
|
-
"erasableSyntaxOnly": true,
|
|
23
|
-
"noFallthroughCasesInSwitch": true,
|
|
24
|
-
"noUncheckedSideEffectImports": true
|
|
25
|
-
},
|
|
26
|
-
"include": ["src"]
|
|
27
|
-
}
|
package/src/ui/tsconfig.json
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
-
"target": "ES2023",
|
|
5
|
-
"lib": ["ES2023"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
|
|
9
|
-
/* Bundler mode */
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"allowImportingTsExtensions": true,
|
|
12
|
-
"verbatimModuleSyntax": true,
|
|
13
|
-
"moduleDetection": "force",
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
|
|
16
|
-
/* Linting */
|
|
17
|
-
"strict": true,
|
|
18
|
-
"noUnusedLocals": true,
|
|
19
|
-
"noUnusedParameters": true,
|
|
20
|
-
"erasableSyntaxOnly": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true,
|
|
22
|
-
"noUncheckedSideEffectImports": true
|
|
23
|
-
},
|
|
24
|
-
"include": ["vite.config.ts"]
|
|
25
|
-
}
|
package/src/ui/vite.config.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AsyncResource } from "node:async_hooks";
|
|
2
|
-
import { QueryEntry } from "../types";
|
|
3
|
-
import Emittery from "emittery";
|
|
4
|
-
|
|
5
|
-
interface CoreEvents {
|
|
6
|
-
query: { query: QueryEntry["data"] };
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const createEmittery = <T extends Record<string, any>>() => {
|
|
10
|
-
return new Emittery<T>();
|
|
11
|
-
};
|
|
12
|
-
export const lensResource = new AsyncResource("lens-emitter");
|
|
13
|
-
export const lensEmitter = new Emittery<CoreEvents>();
|
package/src/watchers/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { getStore } from "../context/context";
|
|
2
|
-
import Watcher from "../core/watcher";
|
|
3
|
-
import { WatcherTypeEnum, type QueryEntry } from "../types/index";
|
|
4
|
-
|
|
5
|
-
export default class QueryWatcher extends Watcher {
|
|
6
|
-
name = WatcherTypeEnum.QUERY;
|
|
7
|
-
|
|
8
|
-
async log(entry: QueryEntry) {
|
|
9
|
-
await getStore().save({
|
|
10
|
-
type: this.name,
|
|
11
|
-
data: entry.data,
|
|
12
|
-
requestId: entry.requestId ?? "",
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
package/tests/core/lens.test.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import Lens from '../../src/core/lens';
|
|
3
|
-
import Store from '../../src/abstracts/store';
|
|
4
|
-
import Adapter from '../../src/abstracts/adapter';
|
|
5
|
-
import Watcher from '../../src/core/watcher';
|
|
6
|
-
import { WatcherTypeEnum } from '../../src/types';
|
|
7
|
-
|
|
8
|
-
// Mock implementations
|
|
9
|
-
class MockStore extends Store {
|
|
10
|
-
initialize = vi.fn();
|
|
11
|
-
save = vi.fn();
|
|
12
|
-
getAllRequests = vi.fn();
|
|
13
|
-
getAllQueries = vi.fn();
|
|
14
|
-
allByRequestId = vi.fn();
|
|
15
|
-
find = vi.fn();
|
|
16
|
-
truncate = vi.fn();
|
|
17
|
-
paginate = vi.fn();
|
|
18
|
-
count = vi.fn();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class MockAdapter extends Adapter {
|
|
22
|
-
setup = vi.fn();
|
|
23
|
-
registerRoutes = vi.fn();
|
|
24
|
-
serveUI = vi.fn();
|
|
25
|
-
override setWatchers = vi.fn().mockReturnThis();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
class MockWatcher extends Watcher {
|
|
29
|
-
name = WatcherTypeEnum.QUERY;
|
|
30
|
-
log = vi.fn();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe('Lens', () => {
|
|
34
|
-
let mockStore: MockStore;
|
|
35
|
-
let mockAdapter: MockAdapter;
|
|
36
|
-
let mockWatcher: MockWatcher;
|
|
37
|
-
|
|
38
|
-
beforeEach(() => {
|
|
39
|
-
mockStore = new MockStore();
|
|
40
|
-
mockAdapter = new MockAdapter();
|
|
41
|
-
mockWatcher = new MockWatcher();
|
|
42
|
-
|
|
43
|
-
// Reset static properties of Lens
|
|
44
|
-
Lens['watchers'].clear();
|
|
45
|
-
Lens['store'] = undefined as any;
|
|
46
|
-
Lens['adapter'] = undefined as any;
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('should set and get a store', async () => {
|
|
50
|
-
Lens.setStore(mockStore);
|
|
51
|
-
const store = await Lens.getStore();
|
|
52
|
-
expect(store).toBe(mockStore);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should set and get an adapter', () => {
|
|
56
|
-
Lens.setAdapter(mockAdapter);
|
|
57
|
-
const adapter = Lens.getAdapter();
|
|
58
|
-
expect(adapter).toBe(mockAdapter);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should throw an error if adapter is not set', () => {
|
|
62
|
-
expect(() => Lens.getAdapter()).toThrow('No adapter has been set');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should add a watcher', () => {
|
|
66
|
-
Lens.watch(mockWatcher);
|
|
67
|
-
expect(Lens['watchers'].get(WatcherTypeEnum.QUERY)).toBe(mockWatcher);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should start and configure the adapter', async () => {
|
|
71
|
-
Lens.setStore(mockStore);
|
|
72
|
-
Lens.setAdapter(mockAdapter);
|
|
73
|
-
Lens.watch(mockWatcher);
|
|
74
|
-
|
|
75
|
-
await Lens.start({ basePath: 'test', appName: 'TestApp', enabled: true });
|
|
76
|
-
|
|
77
|
-
expect(mockAdapter.setWatchers).toHaveBeenCalledWith([mockWatcher]);
|
|
78
|
-
expect(mockAdapter.setup).toHaveBeenCalled();
|
|
79
|
-
expect(mockAdapter.registerRoutes).toHaveBeenCalled();
|
|
80
|
-
expect(mockAdapter.serveUI).toHaveBeenCalled();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should not start if not enabled', async () => {
|
|
84
|
-
Lens.setAdapter(mockAdapter);
|
|
85
|
-
await Lens.start({ basePath: 'test', appName: 'TestApp', enabled: false });
|
|
86
|
-
|
|
87
|
-
expect(mockAdapter.setup).not.toHaveBeenCalled();
|
|
88
|
-
});
|
|
89
|
-
});
|