@vestig/next 0.5.0 → 0.8.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.
- package/README.md +1 -1
- package/dist/__tests__/mocks/next-server.d.ts.map +1 -1
- package/dist/__tests__/mocks/next-server.js.map +1 -1
- package/dist/client/error-boundary.d.ts +80 -0
- package/dist/client/error-boundary.d.ts.map +1 -0
- package/dist/client/error-boundary.js +182 -0
- package/dist/client/error-boundary.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/transport.d.ts +42 -0
- package/dist/client/transport.d.ts.map +1 -1
- package/dist/client/transport.js +143 -2
- package/dist/client/transport.js.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -1
- package/dist/db/drizzle.d.ts +115 -0
- package/dist/db/drizzle.d.ts.map +1 -0
- package/dist/db/drizzle.js +174 -0
- package/dist/db/drizzle.js.map +1 -0
- package/dist/db/index.d.ts +49 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +51 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/prisma.d.ts +114 -0
- package/dist/db/prisma.d.ts.map +1 -0
- package/dist/db/prisma.js +144 -0
- package/dist/db/prisma.js.map +1 -0
- package/dist/db/query-logger.d.ts +30 -0
- package/dist/db/query-logger.d.ts.map +1 -0
- package/dist/db/query-logger.js +169 -0
- package/dist/db/query-logger.js.map +1 -0
- package/dist/db/types.d.ts +102 -0
- package/dist/db/types.d.ts.map +1 -0
- package/dist/db/types.js +28 -0
- package/dist/db/types.js.map +1 -0
- package/dist/dev/api/index.d.ts +13 -0
- package/dist/dev/api/index.d.ts.map +1 -0
- package/dist/dev/api/index.js +13 -0
- package/dist/dev/api/index.js.map +1 -0
- package/dist/dev/api/logs-stream.d.ts +119 -0
- package/dist/dev/api/logs-stream.d.ts.map +1 -0
- package/dist/dev/api/logs-stream.js +156 -0
- package/dist/dev/api/logs-stream.js.map +1 -0
- package/dist/dev/filters.d.ts +17 -0
- package/dist/dev/filters.d.ts.map +1 -0
- package/dist/dev/filters.js +96 -0
- package/dist/dev/filters.js.map +1 -0
- package/dist/dev/hooks/use-logs.d.ts +53 -0
- package/dist/dev/hooks/use-logs.d.ts.map +1 -0
- package/dist/dev/hooks/use-logs.js +205 -0
- package/dist/dev/hooks/use-logs.js.map +1 -0
- package/dist/dev/index.d.ts +35 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +41 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/dev/log-entry.d.ts +12 -0
- package/dist/dev/log-entry.d.ts.map +1 -0
- package/dist/dev/log-entry.js +152 -0
- package/dist/dev/log-entry.js.map +1 -0
- package/dist/dev/log-viewer.d.ts +11 -0
- package/dist/dev/log-viewer.d.ts.map +1 -0
- package/dist/dev/log-viewer.js +49 -0
- package/dist/dev/log-viewer.js.map +1 -0
- package/dist/dev/metrics-card.d.ts +18 -0
- package/dist/dev/metrics-card.d.ts.map +1 -0
- package/dist/dev/metrics-card.js +75 -0
- package/dist/dev/metrics-card.js.map +1 -0
- package/dist/dev/metrics-histogram.d.ts +12 -0
- package/dist/dev/metrics-histogram.d.ts.map +1 -0
- package/dist/dev/metrics-histogram.js +69 -0
- package/dist/dev/metrics-histogram.js.map +1 -0
- package/dist/dev/metrics-panel.d.ts +10 -0
- package/dist/dev/metrics-panel.d.ts.map +1 -0
- package/dist/dev/metrics-panel.js +84 -0
- package/dist/dev/metrics-panel.js.map +1 -0
- package/dist/dev/overlay.d.ts +55 -0
- package/dist/dev/overlay.d.ts.map +1 -0
- package/dist/dev/overlay.js +204 -0
- package/dist/dev/overlay.js.map +1 -0
- package/dist/dev/store.d.ts +186 -0
- package/dist/dev/store.d.ts.map +1 -0
- package/dist/dev/store.js +214 -0
- package/dist/dev/store.js.map +1 -0
- package/dist/error/boundary.d.ts +36 -0
- package/dist/error/boundary.d.ts.map +1 -0
- package/dist/error/boundary.js +263 -0
- package/dist/error/boundary.js.map +1 -0
- package/dist/error/breadcrumbs.d.ts +95 -0
- package/dist/error/breadcrumbs.d.ts.map +1 -0
- package/dist/error/breadcrumbs.js +273 -0
- package/dist/error/breadcrumbs.js.map +1 -0
- package/dist/error/fingerprint.d.ts +42 -0
- package/dist/error/fingerprint.d.ts.map +1 -0
- package/dist/error/fingerprint.js +135 -0
- package/dist/error/fingerprint.js.map +1 -0
- package/dist/error/index.d.ts +52 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +56 -0
- package/dist/error/index.js.map +1 -0
- package/dist/error/stack-parser.d.ts +43 -0
- package/dist/error/stack-parser.d.ts.map +1 -0
- package/dist/error/stack-parser.js +166 -0
- package/dist/error/stack-parser.js.map +1 -0
- package/dist/error/types.d.ts +152 -0
- package/dist/error/types.d.ts.map +1 -0
- package/dist/error/types.js +10 -0
- package/dist/error/types.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/metrics/hooks/use-route-metrics.d.ts +91 -0
- package/dist/metrics/hooks/use-route-metrics.d.ts.map +1 -0
- package/dist/metrics/hooks/use-route-metrics.js +216 -0
- package/dist/metrics/hooks/use-route-metrics.js.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts +70 -0
- package/dist/metrics/hooks/use-web-vitals.d.ts.map +1 -0
- package/dist/metrics/hooks/use-web-vitals.js +146 -0
- package/dist/metrics/hooks/use-web-vitals.js.map +1 -0
- package/dist/metrics/index.d.ts +51 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +56 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/reporter.d.ts +87 -0
- package/dist/metrics/reporter.d.ts.map +1 -0
- package/dist/metrics/reporter.js +178 -0
- package/dist/metrics/reporter.js.map +1 -0
- package/dist/metrics/store.d.ts +34 -0
- package/dist/metrics/store.d.ts.map +1 -0
- package/dist/metrics/store.js +172 -0
- package/dist/metrics/store.js.map +1 -0
- package/dist/metrics/thresholds.d.ts +84 -0
- package/dist/metrics/thresholds.d.ts.map +1 -0
- package/dist/metrics/thresholds.js +148 -0
- package/dist/metrics/thresholds.js.map +1 -0
- package/dist/metrics/types.d.ts +211 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +10 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/metrics/web-vitals.d.ts +72 -0
- package/dist/metrics/web-vitals.d.ts.map +1 -0
- package/dist/metrics/web-vitals.js +89 -0
- package/dist/metrics/web-vitals.js.map +1 -0
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +51 -37
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-handler.js +61 -40
- package/dist/server/route-handler.js.map +1 -1
- package/dist/server/server-action.d.ts.map +1 -1
- package/dist/server/server-action.js +54 -33
- package/dist/server/server-action.js.map +1 -1
- package/dist/types.d.ts +6 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +28 -6
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Integration
|
|
3
|
+
*
|
|
4
|
+
* Provides logging middleware and utilities for Prisma ORM.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // lib/db.ts
|
|
9
|
+
* import { PrismaClient } from '@prisma/client'
|
|
10
|
+
* import { withVestigPrisma } from '@vestig/next/db'
|
|
11
|
+
*
|
|
12
|
+
* const prisma = withVestigPrisma(new PrismaClient())
|
|
13
|
+
* export { prisma }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
import { createQueryLogEntry, logQuery, mergeConfig } from './query-logger';
|
|
19
|
+
/**
|
|
20
|
+
* Create a query event handler for Prisma
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const prisma = new PrismaClient({
|
|
25
|
+
* log: [{ emit: 'event', level: 'query' }],
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* prisma.$on('query', createPrismaQueryHandler({
|
|
29
|
+
* logger: myLogger,
|
|
30
|
+
* slowQueryThreshold: 200,
|
|
31
|
+
* }))
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function createPrismaQueryHandler(options = {}) {
|
|
35
|
+
const config = mergeConfig(options);
|
|
36
|
+
const logger = options.logger;
|
|
37
|
+
return (event) => {
|
|
38
|
+
// Parse params from JSON string
|
|
39
|
+
let params;
|
|
40
|
+
try {
|
|
41
|
+
params = JSON.parse(event.params);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
params = undefined;
|
|
45
|
+
}
|
|
46
|
+
const entry = createQueryLogEntry(event.query, params, event.duration, config);
|
|
47
|
+
if (logger) {
|
|
48
|
+
const nsLogger = logger.child(config.namespace);
|
|
49
|
+
logQuery(nsLogger, entry, config);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// Fallback to console
|
|
53
|
+
if (entry.isSlow) {
|
|
54
|
+
console.warn(`[${config.namespace}] Slow query:`, entry.query, `(${entry.duration}ms)`);
|
|
55
|
+
}
|
|
56
|
+
else if (config.logLevel === 'all') {
|
|
57
|
+
console.debug(`[${config.namespace}]`, entry.query, `(${entry.duration}ms)`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Wrap a Prisma Client with Vestig logging
|
|
64
|
+
*
|
|
65
|
+
* This is the recommended way to add logging to Prisma.
|
|
66
|
+
* It automatically configures query events and adds logging.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* import { PrismaClient } from '@prisma/client'
|
|
71
|
+
* import { withVestigPrisma } from '@vestig/next/db'
|
|
72
|
+
* import { createLogger } from 'vestig'
|
|
73
|
+
*
|
|
74
|
+
* const logger = createLogger({ namespace: 'app' })
|
|
75
|
+
*
|
|
76
|
+
* export const prisma = withVestigPrisma(
|
|
77
|
+
* new PrismaClient({
|
|
78
|
+
* log: [
|
|
79
|
+
* { emit: 'event', level: 'query' },
|
|
80
|
+
* { emit: 'event', level: 'error' },
|
|
81
|
+
* { emit: 'event', level: 'warn' },
|
|
82
|
+
* ],
|
|
83
|
+
* }),
|
|
84
|
+
* {
|
|
85
|
+
* logger,
|
|
86
|
+
* slowQueryThreshold: 100,
|
|
87
|
+
* }
|
|
88
|
+
* )
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @param prisma - Prisma Client instance (must have query event logging enabled)
|
|
92
|
+
* @param options - Logging options
|
|
93
|
+
* @returns The same Prisma Client with logging attached
|
|
94
|
+
*/
|
|
95
|
+
export function withVestigPrisma(prisma, options = {}) {
|
|
96
|
+
const config = mergeConfig(options);
|
|
97
|
+
const logger = options.logger;
|
|
98
|
+
// Subscribe to query events
|
|
99
|
+
prisma.$on('query', createPrismaQueryHandler(options));
|
|
100
|
+
// Subscribe to error events
|
|
101
|
+
prisma.$on('error', (e) => {
|
|
102
|
+
if (logger) {
|
|
103
|
+
logger.child(config.namespace).error('Prisma error', { message: e.message });
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
console.error(`[${config.namespace}] Prisma error:`, e.message);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
// Subscribe to warn events
|
|
110
|
+
prisma.$on('warn', (e) => {
|
|
111
|
+
if (logger) {
|
|
112
|
+
logger.child(config.namespace).warn('Prisma warning', { message: e.message });
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.warn(`[${config.namespace}] Prisma warning:`, e.message);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return prisma;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create Prisma log configuration for use with PrismaClient constructor
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* import { PrismaClient } from '@prisma/client'
|
|
126
|
+
* import { createPrismaLogConfig } from '@vestig/next/db'
|
|
127
|
+
*
|
|
128
|
+
* const prisma = new PrismaClient({
|
|
129
|
+
* log: createPrismaLogConfig(),
|
|
130
|
+
* })
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export function createPrismaLogConfig(options) {
|
|
134
|
+
const config = [
|
|
135
|
+
{ emit: 'event', level: 'query' },
|
|
136
|
+
{ emit: 'event', level: 'error' },
|
|
137
|
+
{ emit: 'event', level: 'warn' },
|
|
138
|
+
];
|
|
139
|
+
if (options?.includeInfo) {
|
|
140
|
+
config.push({ emit: 'event', level: 'info' });
|
|
141
|
+
}
|
|
142
|
+
return config;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/db/prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Logger Core
|
|
3
|
+
*
|
|
4
|
+
* Core utilities for database query logging shared by
|
|
5
|
+
* Prisma and Drizzle integrations.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import type { Logger } from 'vestig';
|
|
10
|
+
import type { DbLoggerConfig, QueryLogEntry } from './types';
|
|
11
|
+
/**
|
|
12
|
+
* Format duration for logging
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatDuration(ms: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Create a query log entry
|
|
17
|
+
*/
|
|
18
|
+
export declare function createQueryLogEntry(query: string, params: unknown[] | undefined, duration: number, config: Required<DbLoggerConfig>, context?: {
|
|
19
|
+
requestId?: string;
|
|
20
|
+
traceId?: string;
|
|
21
|
+
}): QueryLogEntry;
|
|
22
|
+
/**
|
|
23
|
+
* Log a query with the provided logger
|
|
24
|
+
*/
|
|
25
|
+
export declare function logQuery(logger: Logger, entry: QueryLogEntry, config: Required<DbLoggerConfig>): void;
|
|
26
|
+
/**
|
|
27
|
+
* Merge config with defaults
|
|
28
|
+
*/
|
|
29
|
+
export declare function mergeConfig(config?: DbLoggerConfig): Required<DbLoggerConfig>;
|
|
30
|
+
//# sourceMappingURL=query-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-logger.d.ts","sourceRoot":"","sources":["../../src/db/query-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAmG5D;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,EAChC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,aAAa,CAgBf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAC9B,IAAI,CA6BN;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC,CAE7E"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Logger Core
|
|
3
|
+
*
|
|
4
|
+
* Core utilities for database query logging shared by
|
|
5
|
+
* Prisma and Drizzle integrations.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
import { isSensitiveParam } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
enabled: process.env.NODE_ENV === 'development',
|
|
15
|
+
slowQueryThreshold: 100,
|
|
16
|
+
logLevel: process.env.NODE_ENV === 'development' ? 'all' : 'slow',
|
|
17
|
+
sanitizeParams: true,
|
|
18
|
+
maxQueryLength: 1000,
|
|
19
|
+
namespace: 'db',
|
|
20
|
+
onQuery: () => { },
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Create a unique query ID
|
|
24
|
+
*/
|
|
25
|
+
function createQueryId() {
|
|
26
|
+
return `q_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 5)}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Detect SQL operation type from query
|
|
30
|
+
*/
|
|
31
|
+
function detectOperation(query) {
|
|
32
|
+
const trimmed = query.trim().toUpperCase();
|
|
33
|
+
if (trimmed.startsWith('SELECT'))
|
|
34
|
+
return 'SELECT';
|
|
35
|
+
if (trimmed.startsWith('INSERT'))
|
|
36
|
+
return 'INSERT';
|
|
37
|
+
if (trimmed.startsWith('UPDATE'))
|
|
38
|
+
return 'UPDATE';
|
|
39
|
+
if (trimmed.startsWith('DELETE'))
|
|
40
|
+
return 'DELETE';
|
|
41
|
+
return 'OTHER';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract table name from query (best effort)
|
|
45
|
+
*/
|
|
46
|
+
function extractTableName(query) {
|
|
47
|
+
const patterns = [
|
|
48
|
+
/FROM\s+["'`]?(\w+)["'`]?/i,
|
|
49
|
+
/INTO\s+["'`]?(\w+)["'`]?/i,
|
|
50
|
+
/UPDATE\s+["'`]?(\w+)["'`]?/i,
|
|
51
|
+
/DELETE\s+FROM\s+["'`]?(\w+)["'`]?/i,
|
|
52
|
+
];
|
|
53
|
+
for (const pattern of patterns) {
|
|
54
|
+
const match = pattern.exec(query);
|
|
55
|
+
if (match?.[1]) {
|
|
56
|
+
return match[1];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Sanitize query parameters to hide sensitive data
|
|
63
|
+
*/
|
|
64
|
+
function sanitizeParams(params, query) {
|
|
65
|
+
return params.map((param, index) => {
|
|
66
|
+
// Check if this position might be a sensitive field
|
|
67
|
+
const queryLower = query.toLowerCase();
|
|
68
|
+
const sensitiveFields = ['password', 'secret', 'token', 'key', 'credit', 'ssn'];
|
|
69
|
+
for (const field of sensitiveFields) {
|
|
70
|
+
if (queryLower.includes(field)) {
|
|
71
|
+
// If query contains sensitive field names, redact string params
|
|
72
|
+
if (typeof param === 'string' && param.length > 0) {
|
|
73
|
+
return '[REDACTED]';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// For objects, check property names
|
|
78
|
+
if (typeof param === 'object' && param !== null) {
|
|
79
|
+
const sanitized = {};
|
|
80
|
+
for (const [key, value] of Object.entries(param)) {
|
|
81
|
+
if (isSensitiveParam(key)) {
|
|
82
|
+
sanitized[key] = '[REDACTED]';
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
sanitized[key] = value;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return sanitized;
|
|
89
|
+
}
|
|
90
|
+
return param;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Truncate query if too long
|
|
95
|
+
*/
|
|
96
|
+
function truncateQuery(query, maxLength) {
|
|
97
|
+
if (query.length <= maxLength)
|
|
98
|
+
return query;
|
|
99
|
+
return query.slice(0, maxLength) + '... [truncated]';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Format duration for logging
|
|
103
|
+
*/
|
|
104
|
+
export function formatDuration(ms) {
|
|
105
|
+
if (ms < 1)
|
|
106
|
+
return `${(ms * 1000).toFixed(0)}μs`;
|
|
107
|
+
if (ms < 1000)
|
|
108
|
+
return `${ms.toFixed(2)}ms`;
|
|
109
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create a query log entry
|
|
113
|
+
*/
|
|
114
|
+
export function createQueryLogEntry(query, params, duration, config, context) {
|
|
115
|
+
const operation = detectOperation(query);
|
|
116
|
+
const table = extractTableName(query);
|
|
117
|
+
const isSlow = duration >= config.slowQueryThreshold;
|
|
118
|
+
return {
|
|
119
|
+
id: createQueryId(),
|
|
120
|
+
timestamp: new Date().toISOString(),
|
|
121
|
+
query: truncateQuery(query, config.maxQueryLength),
|
|
122
|
+
params: params && config.sanitizeParams ? sanitizeParams(params, query) : params,
|
|
123
|
+
duration,
|
|
124
|
+
isSlow,
|
|
125
|
+
operation,
|
|
126
|
+
table,
|
|
127
|
+
context,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Log a query with the provided logger
|
|
132
|
+
*/
|
|
133
|
+
export function logQuery(logger, entry, config) {
|
|
134
|
+
// Check if we should log
|
|
135
|
+
if (!config.enabled)
|
|
136
|
+
return;
|
|
137
|
+
if (config.logLevel === 'none')
|
|
138
|
+
return;
|
|
139
|
+
if (config.logLevel === 'slow' && !entry.isSlow)
|
|
140
|
+
return;
|
|
141
|
+
const metadata = {
|
|
142
|
+
query: entry.query,
|
|
143
|
+
duration: formatDuration(entry.duration),
|
|
144
|
+
durationMs: entry.duration,
|
|
145
|
+
operation: entry.operation,
|
|
146
|
+
...(entry.table && { table: entry.table }),
|
|
147
|
+
...(entry.params && { params: entry.params }),
|
|
148
|
+
...(entry.context?.requestId && { requestId: entry.context.requestId }),
|
|
149
|
+
...(entry.isSlow && { slow: true }),
|
|
150
|
+
};
|
|
151
|
+
const message = entry.isSlow
|
|
152
|
+
? `Slow query: ${entry.operation}${entry.table ? ` ${entry.table}` : ''} (${formatDuration(entry.duration)})`
|
|
153
|
+
: `${entry.operation}${entry.table ? ` ${entry.table}` : ''} (${formatDuration(entry.duration)})`;
|
|
154
|
+
if (entry.isSlow) {
|
|
155
|
+
logger.warn(message, metadata);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
logger.debug(message, metadata);
|
|
159
|
+
}
|
|
160
|
+
// Call custom callback
|
|
161
|
+
config.onQuery(entry);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Merge config with defaults
|
|
165
|
+
*/
|
|
166
|
+
export function mergeConfig(config) {
|
|
167
|
+
return { ...DEFAULT_CONFIG, ...config };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=query-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-logger.js","sourceRoot":"","sources":["../../src/db/query-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Logging Types
|
|
3
|
+
*
|
|
4
|
+
* Types for database query logging with Prisma and Drizzle.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Query log entry
|
|
10
|
+
*/
|
|
11
|
+
export interface QueryLogEntry {
|
|
12
|
+
/** Unique query ID */
|
|
13
|
+
id: string;
|
|
14
|
+
/** ISO timestamp */
|
|
15
|
+
timestamp: string;
|
|
16
|
+
/** SQL query (sanitized) */
|
|
17
|
+
query: string;
|
|
18
|
+
/** Query parameters (sanitized) */
|
|
19
|
+
params?: unknown[];
|
|
20
|
+
/** Duration in milliseconds */
|
|
21
|
+
duration: number;
|
|
22
|
+
/** Whether query was slow (exceeded threshold) */
|
|
23
|
+
isSlow: boolean;
|
|
24
|
+
/** Database operation type */
|
|
25
|
+
operation: 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'OTHER';
|
|
26
|
+
/** Table/model name if detectable */
|
|
27
|
+
table?: string;
|
|
28
|
+
/** Request context if available */
|
|
29
|
+
context?: {
|
|
30
|
+
requestId?: string;
|
|
31
|
+
traceId?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for database logging
|
|
36
|
+
*/
|
|
37
|
+
export interface DbLoggerConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Enable query logging
|
|
40
|
+
* @default true in development
|
|
41
|
+
*/
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Slow query threshold in milliseconds
|
|
45
|
+
* @default 100
|
|
46
|
+
*/
|
|
47
|
+
slowQueryThreshold?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Log all queries or only slow ones
|
|
50
|
+
* @default 'all' in dev, 'slow' in prod
|
|
51
|
+
*/
|
|
52
|
+
logLevel?: 'all' | 'slow' | 'none';
|
|
53
|
+
/**
|
|
54
|
+
* Sanitize query parameters (hide sensitive data)
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
sanitizeParams?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Maximum query length to log
|
|
60
|
+
* @default 1000
|
|
61
|
+
*/
|
|
62
|
+
maxQueryLength?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Custom logger namespace
|
|
65
|
+
* @default 'db'
|
|
66
|
+
*/
|
|
67
|
+
namespace?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Callback when query is logged
|
|
70
|
+
*/
|
|
71
|
+
onQuery?: (entry: QueryLogEntry) => void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Prisma log event types
|
|
75
|
+
*/
|
|
76
|
+
export type PrismaLogEvent = {
|
|
77
|
+
timestamp: Date;
|
|
78
|
+
message: string;
|
|
79
|
+
target: string;
|
|
80
|
+
};
|
|
81
|
+
export type PrismaQueryEvent = {
|
|
82
|
+
timestamp: Date;
|
|
83
|
+
query: string;
|
|
84
|
+
params: string;
|
|
85
|
+
duration: number;
|
|
86
|
+
target: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Drizzle logger interface
|
|
90
|
+
*/
|
|
91
|
+
export interface DrizzleLogger {
|
|
92
|
+
logQuery(query: string, params: unknown[]): void;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Sensitive parameter patterns to sanitize
|
|
96
|
+
*/
|
|
97
|
+
export declare const SENSITIVE_PATTERNS: RegExp[];
|
|
98
|
+
/**
|
|
99
|
+
* Check if a parameter name is sensitive
|
|
100
|
+
*/
|
|
101
|
+
export declare function isSensitiveParam(name: string): boolean;
|
|
102
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,sBAAsB;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,8BAA8B;IAC9B,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC9D,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mCAAmC;IACnC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,IAAI,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,SAAS,EAAE,IAAI,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAChD;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,UAU9B,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
|
package/dist/db/types.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Logging Types
|
|
3
|
+
*
|
|
4
|
+
* Types for database query logging with Prisma and Drizzle.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Sensitive parameter patterns to sanitize
|
|
10
|
+
*/
|
|
11
|
+
export const SENSITIVE_PATTERNS = [
|
|
12
|
+
/password/i,
|
|
13
|
+
/secret/i,
|
|
14
|
+
/token/i,
|
|
15
|
+
/api_key/i,
|
|
16
|
+
/apikey/i,
|
|
17
|
+
/credit_card/i,
|
|
18
|
+
/creditcard/i,
|
|
19
|
+
/ssn/i,
|
|
20
|
+
/social_security/i,
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Check if a parameter name is sensitive
|
|
24
|
+
*/
|
|
25
|
+
export function isSensitiveParam(name) {
|
|
26
|
+
return SENSITIVE_PATTERNS.some((pattern) => pattern.test(name));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/db/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6FH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IACjC,WAAW;IACX,SAAS;IACT,QAAQ;IACR,UAAU;IACV,SAAS;IACT,cAAc;IACd,aAAa;IACb,MAAM;IACN,kBAAkB;CAClB,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;AAChE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side utilities for Vestig Dev Overlay
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* // app/api/vestig/logs/route.ts
|
|
7
|
+
* import { createLogStreamHandler } from '@vestig/next/dev/api'
|
|
8
|
+
*
|
|
9
|
+
* export const GET = createLogStreamHandler()
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export { createLogStreamHandler, createDevTransport, devLogEmitter, type SSELogEntry, } from './logs-stream';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dev/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACN,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,KAAK,WAAW,GAChB,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side utilities for Vestig Dev Overlay
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* // app/api/vestig/logs/route.ts
|
|
7
|
+
* import { createLogStreamHandler } from '@vestig/next/dev/api'
|
|
8
|
+
*
|
|
9
|
+
* export const GET = createLogStreamHandler()
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export { createLogStreamHandler, createDevTransport, devLogEmitter, } from './logs-stream';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dev/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACN,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,GAEb,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSE Endpoint Helper for Vestig Dev Overlay
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for creating a Server-Sent Events
|
|
5
|
+
* endpoint that streams logs to the Dev Overlay in real-time.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // app/api/vestig/logs/route.ts
|
|
10
|
+
* import { createLogStreamHandler, devLogEmitter } from '@vestig/next/dev/api'
|
|
11
|
+
*
|
|
12
|
+
* export const GET = createLogStreamHandler()
|
|
13
|
+
*
|
|
14
|
+
* // In your middleware or logger setup
|
|
15
|
+
* devLogEmitter.emit({
|
|
16
|
+
* timestamp: new Date().toISOString(),
|
|
17
|
+
* level: 'info',
|
|
18
|
+
* message: 'Hello from server',
|
|
19
|
+
* namespace: 'api',
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { LogLevel } from 'vestig';
|
|
24
|
+
/**
|
|
25
|
+
* Log entry for SSE streaming
|
|
26
|
+
*/
|
|
27
|
+
export interface SSELogEntry {
|
|
28
|
+
timestamp: string;
|
|
29
|
+
level: LogLevel;
|
|
30
|
+
message: string;
|
|
31
|
+
namespace?: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
context?: Record<string, unknown>;
|
|
34
|
+
error?: {
|
|
35
|
+
name: string;
|
|
36
|
+
message: string;
|
|
37
|
+
stack?: string;
|
|
38
|
+
};
|
|
39
|
+
duration?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Simple event emitter for logs
|
|
43
|
+
*/
|
|
44
|
+
type LogListener = (entry: SSELogEntry) => void;
|
|
45
|
+
declare class DevLogEmitter {
|
|
46
|
+
private listeners;
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to log events
|
|
49
|
+
*/
|
|
50
|
+
subscribe(listener: LogListener): () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Emit a log entry to all subscribers
|
|
53
|
+
*/
|
|
54
|
+
emit(entry: SSELogEntry): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get count of active listeners
|
|
57
|
+
*/
|
|
58
|
+
get listenerCount(): number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Singleton log emitter instance
|
|
62
|
+
*/
|
|
63
|
+
export declare const devLogEmitter: DevLogEmitter;
|
|
64
|
+
/**
|
|
65
|
+
* Create an SSE response for streaming logs
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // app/api/vestig/logs/route.ts
|
|
70
|
+
* import { createLogStreamHandler } from '@vestig/next/dev/api'
|
|
71
|
+
*
|
|
72
|
+
* export const GET = createLogStreamHandler()
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function createLogStreamHandler(options?: {
|
|
76
|
+
/**
|
|
77
|
+
* Send a ping every N milliseconds to keep connection alive
|
|
78
|
+
* @default 30000
|
|
79
|
+
*/
|
|
80
|
+
pingInterval?: number;
|
|
81
|
+
}): () => Promise<Response>;
|
|
82
|
+
/**
|
|
83
|
+
* Create a vestig transport that streams logs to Dev Overlay
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* import { createLogger } from 'vestig'
|
|
88
|
+
* import { createDevTransport } from '@vestig/next/dev/api'
|
|
89
|
+
*
|
|
90
|
+
* const logger = createLogger({
|
|
91
|
+
* // Only add dev transport in development
|
|
92
|
+
* transports: process.env.NODE_ENV === 'development'
|
|
93
|
+
* ? [createDevTransport()]
|
|
94
|
+
* : [],
|
|
95
|
+
* })
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function createDevTransport(): {
|
|
99
|
+
name: string;
|
|
100
|
+
config: {
|
|
101
|
+
name: string;
|
|
102
|
+
enabled: boolean;
|
|
103
|
+
};
|
|
104
|
+
log(entry: {
|
|
105
|
+
timestamp: string;
|
|
106
|
+
level: LogLevel;
|
|
107
|
+
message: string;
|
|
108
|
+
namespace?: string;
|
|
109
|
+
metadata?: Record<string, unknown>;
|
|
110
|
+
context?: Record<string, unknown>;
|
|
111
|
+
error?: {
|
|
112
|
+
name: string;
|
|
113
|
+
message: string;
|
|
114
|
+
stack?: string;
|
|
115
|
+
};
|
|
116
|
+
}): void;
|
|
117
|
+
};
|
|
118
|
+
export {};
|
|
119
|
+
//# sourceMappingURL=logs-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs-stream.d.ts","sourceRoot":"","sources":["../../../src/dev/api/logs-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,KAAK,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;IACD,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;AAE/C,cAAM,aAAa;IAClB,OAAO,CAAC,SAAS,CAAyB;IAE1C;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,IAAI;IAK5C;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAU9B;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;CACD;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,eAAsB,CAAA;AAEhD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB,SAGiC,OAAO,CAAC,QAAQ,CAAC,CAoDlD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB;;;;;;eAQrB;QACV,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,QAAQ,CAAA;QACf,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,KAAK,CAAC,EAAE;YACP,IAAI,EAAE,MAAM,CAAA;YACZ,OAAO,EAAE,MAAM,CAAA;YACf,KAAK,CAAC,EAAE,MAAM,CAAA;SACd,CAAA;KACD,GAAG,IAAI;EAYT"}
|