@maydotinc/q-studio 0.1.0 → 0.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/dist/{core/index.js → chunk-L36RXNVW.js} +2072 -2185
- package/dist/chunk-L36RXNVW.js.map +1 -0
- package/dist/{core/index.d.ts → core.d.ts} +4 -435
- package/dist/core.js +25 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/{express/index.js → index.js} +6 -5
- package/dist/index.js.map +1 -0
- package/dist/types-DhcUr9Xm.d.ts +377 -0
- package/package.json +21 -18
- package/dist/core/index.js.map +0 -1
- package/dist/express/index.d.ts +0 -38
- package/dist/express/index.js.map +0 -1
- /package/dist/{core/ui → ui}/assets/favicon.ico +0 -0
- /package/dist/{core/ui → ui}/assets/index.css +0 -0
- /package/dist/{core/ui → ui}/assets/index.js +0 -0
- /package/dist/{core/ui → ui}/index.html +0 -0
|
@@ -1,379 +1,6 @@
|
|
|
1
|
-
import { Queue
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Job status types matching BullMQ states
|
|
6
|
-
*/
|
|
7
|
-
type JobStatus = "waiting" | "active" | "completed" | "failed" | "delayed" | "paused" | "unknown";
|
|
8
|
-
/**
|
|
9
|
-
* Group/folder of related BullMQ queues.
|
|
10
|
-
*/
|
|
11
|
-
interface QueueGroup {
|
|
12
|
-
name: string;
|
|
13
|
-
queues: Queue[];
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Configuration options for Workbench
|
|
17
|
-
*/
|
|
18
|
-
interface WorkbenchOptions {
|
|
19
|
-
/** BullMQ Queue instances to display */
|
|
20
|
-
queues?: Queue[];
|
|
21
|
-
/** Named groups/folders of BullMQ Queue instances to display together */
|
|
22
|
-
queueGroups?: QueueGroup[];
|
|
23
|
-
/** Alias for queueGroups */
|
|
24
|
-
groups?: QueueGroup[];
|
|
25
|
-
/** Redis connection for auto-discovery of queues */
|
|
26
|
-
redis?: string | RedisOptions;
|
|
27
|
-
/** Basic auth credentials */
|
|
28
|
-
auth?: {
|
|
29
|
-
username: string;
|
|
30
|
-
password: string;
|
|
31
|
-
};
|
|
32
|
-
/** Dashboard title */
|
|
33
|
-
title?: string;
|
|
34
|
-
/** Logo URL */
|
|
35
|
-
logo?: string;
|
|
36
|
-
/** Override base path detection */
|
|
37
|
-
basePath?: string;
|
|
38
|
-
/** Disable actions (retry, remove, promote) */
|
|
39
|
-
readonly?: boolean;
|
|
40
|
-
/** Fields from job.data to extract as filterable tags (e.g., ['teamId', 'userId']) */
|
|
41
|
-
tags?: string[];
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Queue information for API responses
|
|
45
|
-
*/
|
|
46
|
-
interface QueueInfo {
|
|
47
|
-
name: string;
|
|
48
|
-
group?: string;
|
|
49
|
-
counts: {
|
|
50
|
-
waiting: number;
|
|
51
|
-
active: number;
|
|
52
|
-
completed: number;
|
|
53
|
-
failed: number;
|
|
54
|
-
delayed: number;
|
|
55
|
-
paused: number;
|
|
56
|
-
};
|
|
57
|
-
isPaused: boolean;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Queue group information for API responses
|
|
61
|
-
*/
|
|
62
|
-
interface QueueGroupInfo {
|
|
63
|
-
name: string;
|
|
64
|
-
queues: string[];
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Worker information from BullMQ
|
|
68
|
-
*/
|
|
69
|
-
interface WorkerInfo {
|
|
70
|
-
id: string;
|
|
71
|
-
name: string;
|
|
72
|
-
addr: string;
|
|
73
|
-
age: number;
|
|
74
|
-
idle: number;
|
|
75
|
-
started: number;
|
|
76
|
-
queueName: string;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Extracted tag key-value pairs from job data
|
|
80
|
-
*/
|
|
81
|
-
type JobTags = Record<string, string | number | boolean | null>;
|
|
82
|
-
/**
|
|
83
|
-
* Job information for API responses
|
|
84
|
-
*/
|
|
85
|
-
interface JobInfo {
|
|
86
|
-
id: string;
|
|
87
|
-
name: string;
|
|
88
|
-
data: unknown;
|
|
89
|
-
opts: {
|
|
90
|
-
attempts?: number;
|
|
91
|
-
delay?: number;
|
|
92
|
-
priority?: number;
|
|
93
|
-
};
|
|
94
|
-
progress: number | object;
|
|
95
|
-
attemptsMade: number;
|
|
96
|
-
processedOn?: number;
|
|
97
|
-
finishedOn?: number;
|
|
98
|
-
timestamp: number;
|
|
99
|
-
failedReason?: string;
|
|
100
|
-
stacktrace?: string[];
|
|
101
|
-
returnvalue?: unknown;
|
|
102
|
-
status: JobStatus;
|
|
103
|
-
duration?: number;
|
|
104
|
-
/** Extracted tag values from job.data based on configured tag fields */
|
|
105
|
-
tags?: JobTags;
|
|
106
|
-
/** Parent job info if this job is part of a flow */
|
|
107
|
-
parent?: {
|
|
108
|
-
id: string;
|
|
109
|
-
queueName: string;
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* BullMQ log lines for a job.
|
|
114
|
-
*/
|
|
115
|
-
interface JobLogsResponse {
|
|
116
|
-
logs: string[];
|
|
117
|
-
count: number;
|
|
118
|
-
start: number;
|
|
119
|
-
end: number;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Overview stats for dashboard
|
|
123
|
-
*/
|
|
124
|
-
interface OverviewStats {
|
|
125
|
-
totalJobs: number;
|
|
126
|
-
activeJobs: number;
|
|
127
|
-
failedJobs: number;
|
|
128
|
-
completedToday: number;
|
|
129
|
-
avgDuration: number;
|
|
130
|
-
queues: QueueInfo[];
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Paginated response wrapper
|
|
134
|
-
*/
|
|
135
|
-
interface PaginatedResponse<T> {
|
|
136
|
-
data: T[];
|
|
137
|
-
total: number;
|
|
138
|
-
cursor?: string;
|
|
139
|
-
hasMore: boolean;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Search result item
|
|
143
|
-
*/
|
|
144
|
-
interface SearchResult {
|
|
145
|
-
queue: string;
|
|
146
|
-
job: JobInfo;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Run item - job execution with queue context
|
|
150
|
-
*/
|
|
151
|
-
interface RunInfo extends JobInfo {
|
|
152
|
-
queueName: string;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Lightweight run info for list view - only fields needed for table display
|
|
156
|
-
* Excludes large fields like full job.data, opts, progress, etc.
|
|
157
|
-
*/
|
|
158
|
-
interface RunInfoList {
|
|
159
|
-
id: string;
|
|
160
|
-
name: string;
|
|
161
|
-
status: JobStatus;
|
|
162
|
-
queueName: string;
|
|
163
|
-
tags?: JobTags;
|
|
164
|
-
processedOn?: number;
|
|
165
|
-
timestamp: number;
|
|
166
|
-
duration?: number;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Scheduler info for repeatable jobs
|
|
170
|
-
*/
|
|
171
|
-
interface SchedulerInfo {
|
|
172
|
-
key: string;
|
|
173
|
-
name: string;
|
|
174
|
-
queueName: string;
|
|
175
|
-
pattern?: string;
|
|
176
|
-
every?: number;
|
|
177
|
-
next?: number;
|
|
178
|
-
endDate?: number;
|
|
179
|
-
tz?: string;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Delayed job info
|
|
183
|
-
*/
|
|
184
|
-
interface DelayedJobInfo {
|
|
185
|
-
id: string;
|
|
186
|
-
name: string;
|
|
187
|
-
queueName: string;
|
|
188
|
-
delay: number;
|
|
189
|
-
processAt: number;
|
|
190
|
-
data: unknown;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Test job request
|
|
194
|
-
*/
|
|
195
|
-
interface TestJobRequest {
|
|
196
|
-
queueName: string;
|
|
197
|
-
jobName: string;
|
|
198
|
-
data: unknown;
|
|
199
|
-
opts?: {
|
|
200
|
-
delay?: number;
|
|
201
|
-
priority?: number;
|
|
202
|
-
attempts?: number;
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Sort direction
|
|
207
|
-
*/
|
|
208
|
-
type SortDirection = "asc" | "desc";
|
|
209
|
-
/**
|
|
210
|
-
* Sort options for API requests
|
|
211
|
-
*/
|
|
212
|
-
interface SortOptions {
|
|
213
|
-
field: string;
|
|
214
|
-
direction: SortDirection;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Valid sort fields for runs/jobs
|
|
218
|
-
*/
|
|
219
|
-
type RunSortField = "timestamp" | "name" | "status" | "duration" | "queueName";
|
|
220
|
-
/**
|
|
221
|
-
* Valid sort fields for repeatable schedulers
|
|
222
|
-
*/
|
|
223
|
-
type RepeatableSortField = "name" | "queueName" | "pattern" | "next" | "tz";
|
|
224
|
-
/**
|
|
225
|
-
* Valid sort fields for delayed schedulers
|
|
226
|
-
*/
|
|
227
|
-
type DelayedSortField = "name" | "queueName" | "processAt" | "delay";
|
|
228
|
-
/**
|
|
229
|
-
* Hourly bucket for metrics aggregation
|
|
230
|
-
*/
|
|
231
|
-
interface HourlyBucket {
|
|
232
|
-
/** Unix timestamp (start of hour) */
|
|
233
|
-
hour: number;
|
|
234
|
-
/** Number of completed jobs */
|
|
235
|
-
completed: number;
|
|
236
|
-
/** Number of failed jobs */
|
|
237
|
-
failed: number;
|
|
238
|
-
/** Average processing duration in ms */
|
|
239
|
-
avgDuration: number;
|
|
240
|
-
/** Average queue wait time in ms */
|
|
241
|
-
avgWaitTime: number;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Metrics for a single queue
|
|
245
|
-
*/
|
|
246
|
-
interface QueueMetrics {
|
|
247
|
-
queueName: string;
|
|
248
|
-
buckets: HourlyBucket[];
|
|
249
|
-
summary: {
|
|
250
|
-
totalCompleted: number;
|
|
251
|
-
totalFailed: number;
|
|
252
|
-
/** Error rate as 0-1 */
|
|
253
|
-
errorRate: number;
|
|
254
|
-
/** Average processing duration in ms */
|
|
255
|
-
avgDuration: number;
|
|
256
|
-
/** Average queue wait time in ms */
|
|
257
|
-
avgWaitTime: number;
|
|
258
|
-
/** Average throughput per hour */
|
|
259
|
-
throughputPerHour: number;
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Slowest job entry
|
|
264
|
-
*/
|
|
265
|
-
interface SlowestJob {
|
|
266
|
-
name: string;
|
|
267
|
-
queueName: string;
|
|
268
|
-
duration: number;
|
|
269
|
-
jobId: string;
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Most failing job type entry
|
|
273
|
-
*/
|
|
274
|
-
interface FailingJobType {
|
|
275
|
-
name: string;
|
|
276
|
-
queueName: string;
|
|
277
|
-
failCount: number;
|
|
278
|
-
totalCount: number;
|
|
279
|
-
errorRate: number;
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Complete metrics response
|
|
283
|
-
*/
|
|
284
|
-
interface MetricsResponse {
|
|
285
|
-
/** Metrics per queue */
|
|
286
|
-
queues: QueueMetrics[];
|
|
287
|
-
/** Aggregated metrics across all queues */
|
|
288
|
-
aggregate: Omit<QueueMetrics, "queueName"> & {
|
|
289
|
-
queueName: "all";
|
|
290
|
-
};
|
|
291
|
-
/** Top 10 slowest jobs */
|
|
292
|
-
slowestJobs: SlowestJob[];
|
|
293
|
-
/** Top 10 most failing job types */
|
|
294
|
-
mostFailingTypes: FailingJobType[];
|
|
295
|
-
/** Timestamp when metrics were computed */
|
|
296
|
-
computedAt: number;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* A node in a flow tree representing a job and its children
|
|
300
|
-
*/
|
|
301
|
-
interface FlowNode {
|
|
302
|
-
job: JobInfo;
|
|
303
|
-
queueName: string;
|
|
304
|
-
children?: FlowNode[];
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Flow summary for list view
|
|
308
|
-
*/
|
|
309
|
-
interface FlowSummary {
|
|
310
|
-
/** Root job ID */
|
|
311
|
-
id: string;
|
|
312
|
-
/** Root job name */
|
|
313
|
-
name: string;
|
|
314
|
-
/** Queue containing root job */
|
|
315
|
-
queueName: string;
|
|
316
|
-
/** Root job status */
|
|
317
|
-
status: JobStatus;
|
|
318
|
-
/** Total number of jobs in flow */
|
|
319
|
-
totalJobs: number;
|
|
320
|
-
/** Number of completed jobs */
|
|
321
|
-
completedJobs: number;
|
|
322
|
-
/** Number of failed jobs */
|
|
323
|
-
failedJobs: number;
|
|
324
|
-
/** When flow was created */
|
|
325
|
-
timestamp: number;
|
|
326
|
-
/** Duration if completed */
|
|
327
|
-
duration?: number;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Request to create a test flow
|
|
331
|
-
*/
|
|
332
|
-
interface CreateFlowRequest {
|
|
333
|
-
name: string;
|
|
334
|
-
queueName: string;
|
|
335
|
-
data?: unknown;
|
|
336
|
-
children: CreateFlowChildRequest[];
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Child job in a flow creation request
|
|
340
|
-
*/
|
|
341
|
-
interface CreateFlowChildRequest {
|
|
342
|
-
name: string;
|
|
343
|
-
queueName: string;
|
|
344
|
-
data?: unknown;
|
|
345
|
-
children?: CreateFlowChildRequest[];
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Activity bucket for timeline
|
|
349
|
-
*/
|
|
350
|
-
interface ActivityBucket {
|
|
351
|
-
/** Unix timestamp (start of bucket) */
|
|
352
|
-
time: number;
|
|
353
|
-
/** Number of completed jobs */
|
|
354
|
-
completed: number;
|
|
355
|
-
/** Number of failed jobs */
|
|
356
|
-
failed: number;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Activity stats response for the 7-day timeline
|
|
360
|
-
*/
|
|
361
|
-
interface ActivityStatsResponse {
|
|
362
|
-
/** Activity buckets (4-hour intervals over 7 days) */
|
|
363
|
-
buckets: ActivityBucket[];
|
|
364
|
-
/** Start time of the first bucket */
|
|
365
|
-
startTime: number;
|
|
366
|
-
/** End time (now) */
|
|
367
|
-
endTime: number;
|
|
368
|
-
/** Size of each bucket in ms */
|
|
369
|
-
bucketSize: number;
|
|
370
|
-
/** Total completed in period */
|
|
371
|
-
totalCompleted: number;
|
|
372
|
-
/** Total failed in period */
|
|
373
|
-
totalFailed: number;
|
|
374
|
-
/** Timestamp when stats were computed */
|
|
375
|
-
computedAt: number;
|
|
376
|
-
}
|
|
1
|
+
import { Queue } from 'bullmq';
|
|
2
|
+
import { Q as QueueGroup, i as QueueGroupInfo, j as QueueInfo, O as OverviewStats, M as MetricsResponse, a as ActivityStatsResponse, g as JobStatus, r as SortOptions, P as PaginatedResponse, J as JobInfo, f as JobLogsResponse, o as SearchResult, m as RunInfoList, S as SchedulerInfo, D as DelayedJobInfo, T as TestJobRequest, e as FlowSummary, d as FlowNode, b as CreateFlowRequest, W as WorkbenchOptions } from './types-DhcUr9Xm.js';
|
|
3
|
+
export { A as ActivityBucket, C as CreateFlowChildRequest, c as DelayedSortField, F as FailingJobType, H as HourlyBucket, h as JobTags, k as QueueMetrics, R as RepeatableSortField, l as RunInfo, n as RunSortField, p as SlowestJob, q as SortDirection, s as WorkerInfo } from './types-DhcUr9Xm.js';
|
|
377
4
|
|
|
378
5
|
/**
|
|
379
6
|
* Manages queue operations for the Workbench dashboard
|
|
@@ -690,39 +317,6 @@ declare class WorkbenchCore {
|
|
|
690
317
|
};
|
|
691
318
|
}
|
|
692
319
|
|
|
693
|
-
interface FetchHandlerResult {
|
|
694
|
-
/**
|
|
695
|
-
* Web-standard fetch handler. Accepts a `Request` and returns a `Response`.
|
|
696
|
-
* Suitable for Elysia's `.mount(path, handler)`, Next.js route handlers,
|
|
697
|
-
* Bun.serve, and any other web-standards-friendly runtime.
|
|
698
|
-
*/
|
|
699
|
-
fetch: (req: Request) => Promise<Response>;
|
|
700
|
-
/**
|
|
701
|
-
* The underlying `WorkbenchCore` instance. Exposed so adapters can read
|
|
702
|
-
* config, query state, or wire up custom auth strategies.
|
|
703
|
-
*/
|
|
704
|
-
core: WorkbenchCore;
|
|
705
|
-
}
|
|
706
|
-
/**
|
|
707
|
-
* Build a self-contained web-fetch handler for Workbench: API routes,
|
|
708
|
-
* `/config`, static `/assets/:file`, an `index.html` catch-all with a
|
|
709
|
-
* correct `<base href>`, CORS on `/api/*`, and optional Basic Auth on
|
|
710
|
-
* everything.
|
|
711
|
-
*
|
|
712
|
-
* This is the engine shared by every fetch-native adapter (Elysia, Next.js).
|
|
713
|
-
* Express and Fastify adapters use {@link buildRouteTable} directly instead.
|
|
714
|
-
*
|
|
715
|
-
* When `options.basePath` is set, the handler rewrites the incoming Request
|
|
716
|
-
* URL to strip that prefix before routing. This makes the bridge work
|
|
717
|
-
* uniformly for both fetch hosts:
|
|
718
|
-
*
|
|
719
|
-
* - `Elysia.mount()` already strips the prefix before calling us — the
|
|
720
|
-
* strip below is a no-op in that case.
|
|
721
|
-
* - Next.js App Router preserves the full path — the strip is what lets
|
|
722
|
-
* our internal routes (`/api/*`, `/config`, …) match.
|
|
723
|
-
*/
|
|
724
|
-
declare function createFetchHandler(options: WorkbenchOptions | Queue[]): FetchHandlerResult;
|
|
725
|
-
|
|
726
320
|
/**
|
|
727
321
|
* Framework-agnostic HTTP method.
|
|
728
322
|
*/
|
|
@@ -768,16 +362,6 @@ interface RouteDef {
|
|
|
768
362
|
*/
|
|
769
363
|
declare function buildRouteTable(core: WorkbenchCore): RouteDef[];
|
|
770
364
|
|
|
771
|
-
/**
|
|
772
|
-
* Create API routes for Workbench as a Hono app.
|
|
773
|
-
*
|
|
774
|
-
* Iterates the framework-agnostic `buildRouteTable(core)` and registers
|
|
775
|
-
* each route on a fresh Hono instance. Adapters that don't speak Hono can
|
|
776
|
-
* use `buildRouteTable` directly — see `@maydotinc/q-studio/express` and
|
|
777
|
-
* `@maydotinc/q-studio-fastify`.
|
|
778
|
-
*/
|
|
779
|
-
declare function createApiRoutes(core: WorkbenchCore): Hono;
|
|
780
|
-
|
|
781
365
|
declare function computeBasePath(pathname: string): string;
|
|
782
366
|
/**
|
|
783
367
|
* Resolve the dashboard's base path, preferring an explicit override.
|
|
@@ -813,21 +397,6 @@ declare const BASIC_AUTH_CHALLENGE: {
|
|
|
813
397
|
body: string;
|
|
814
398
|
};
|
|
815
399
|
|
|
816
|
-
/**
|
|
817
|
-
* Build a fully-wired Hono app for Workbench:
|
|
818
|
-
*
|
|
819
|
-
* - `POST /api/*`, `GET /api/*` etc. — JSON API
|
|
820
|
-
* - `GET /config` — UI bootstrap config
|
|
821
|
-
* - `GET /assets/:file` — static asset reader
|
|
822
|
-
* - `GET *` — `index.html` with `<base href>`
|
|
823
|
-
* - CORS on `/api/*`
|
|
824
|
-
* - Basic auth on everything when `core.requiresAuth()` is true
|
|
825
|
-
*
|
|
826
|
-
* Used directly by `@maydotinc/q-studio-hono` (returned as-is for `.route()`
|
|
827
|
-
* mounting) and indirectly by `createFetchHandler` for non-Hono adapters.
|
|
828
|
-
*/
|
|
829
|
-
declare function buildWorkbenchApp(core: WorkbenchCore): Hono;
|
|
830
|
-
|
|
831
400
|
interface StaticAssetResult {
|
|
832
401
|
status: 200 | 404;
|
|
833
402
|
body: Buffer | null;
|
|
@@ -861,4 +430,4 @@ declare function renderIndexHtml(basePath: string, title: string): IndexHtmlResu
|
|
|
861
430
|
*/
|
|
862
431
|
declare const UI_DIST_PATH: string;
|
|
863
432
|
|
|
864
|
-
export {
|
|
433
|
+
export { ActivityStatsResponse, BASIC_AUTH_CHALLENGE, CreateFlowRequest, DelayedJobInfo, FlowNode, FlowSummary, type Handler, type HandlerInput, type HandlerResult, type HttpMethod, type IndexHtmlResult, JobInfo, JobStatus, MetricsResponse, OverviewStats, PaginatedResponse, QueueGroup, QueueGroupInfo, QueueInfo, QueueManager, type RouteDef, RunInfoList, SchedulerInfo, SearchResult, SortOptions, type StaticAssetResult, TestJobRequest, UI_DIST_PATH, WorkbenchCore, WorkbenchOptions, buildRouteTable, checkBasicAuth, computeBasePath, renderIndexHtml, resolveBasePath, serveStaticAsset };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BASIC_AUTH_CHALLENGE,
|
|
3
|
+
QueueManager,
|
|
4
|
+
UI_DIST_PATH,
|
|
5
|
+
WorkbenchCore,
|
|
6
|
+
buildRouteTable,
|
|
7
|
+
checkBasicAuth,
|
|
8
|
+
computeBasePath,
|
|
9
|
+
renderIndexHtml,
|
|
10
|
+
resolveBasePath,
|
|
11
|
+
serveStaticAsset
|
|
12
|
+
} from "./chunk-L36RXNVW.js";
|
|
13
|
+
export {
|
|
14
|
+
BASIC_AUTH_CHALLENGE,
|
|
15
|
+
QueueManager,
|
|
16
|
+
UI_DIST_PATH,
|
|
17
|
+
WorkbenchCore,
|
|
18
|
+
buildRouteTable,
|
|
19
|
+
checkBasicAuth,
|
|
20
|
+
computeBasePath,
|
|
21
|
+
renderIndexHtml,
|
|
22
|
+
resolveBasePath,
|
|
23
|
+
serveStaticAsset
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=core.js.map
|
package/dist/core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
1
|
import {
|
|
3
2
|
BASIC_AUTH_CHALLENGE,
|
|
3
|
+
WorkbenchCore,
|
|
4
4
|
buildRouteTable,
|
|
5
5
|
checkBasicAuth,
|
|
6
6
|
renderIndexHtml,
|
|
7
7
|
resolveBasePath,
|
|
8
|
-
serveStaticAsset
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
serveStaticAsset
|
|
9
|
+
} from "./chunk-L36RXNVW.js";
|
|
10
|
+
|
|
11
|
+
// src/index.ts
|
|
11
12
|
import express from "express";
|
|
12
13
|
function qStudio(options) {
|
|
13
14
|
const core = new WorkbenchCore(options);
|
|
@@ -52,7 +53,7 @@ function qStudio(options) {
|
|
|
52
53
|
router.get("/config", (_req, res) => {
|
|
53
54
|
res.json(core.getConfig());
|
|
54
55
|
});
|
|
55
|
-
router.get("/favicon.ico", (
|
|
56
|
+
router.get("/favicon.ico", (_req, res) => {
|
|
56
57
|
const asset = serveStaticAsset("favicon.ico");
|
|
57
58
|
if (asset.status === 404 || !asset.body) {
|
|
58
59
|
res.status(404).type("text/plain").send("Not found");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n BASIC_AUTH_CHALLENGE,\n buildRouteTable,\n checkBasicAuth,\n renderIndexHtml,\n resolveBasePath,\n serveStaticAsset,\n WorkbenchCore,\n type WorkbenchOptions,\n} from \"./core\";\nimport type { Queue } from \"bullmq\";\nimport express, { type Router } from \"express\";\n\nexport function qStudio(options: WorkbenchOptions | Queue[]): Router {\n const core = new WorkbenchCore(options);\n const router = express.Router();\n\n if (core.requiresAuth()) {\n router.use((req, res, next) => {\n if (\n !checkBasicAuth(\n req.headers.authorization,\n core.options.auth!.username,\n core.options.auth!.password,\n )\n ) {\n res.set(BASIC_AUTH_CHALLENGE.headers);\n res.status(BASIC_AUTH_CHALLENGE.status).send(BASIC_AUTH_CHALLENGE.body);\n return;\n }\n next();\n });\n }\n\n router.use(\"/api\", (_req, res, next) => {\n res.set(\"Access-Control-Allow-Origin\", \"*\");\n res.set(\"Access-Control-Allow-Methods\", \"GET,HEAD,PUT,PATCH,POST,DELETE\");\n res.set(\"Access-Control-Allow-Headers\", \"*\");\n next();\n });\n\n router.use(\"/api\", express.json());\n\n for (const route of buildRouteTable(core)) {\n router[route.method](`/api${route.path}`, async (req, res) => {\n try {\n const result = await route.handler({\n params: req.params as Record<string, string>,\n query: req.query as Record<string, string | undefined>,\n body: req.body,\n });\n res.status(result.status).json(result.body);\n } catch (error) {\n res.status(500).json({\n error:\n error instanceof Error ? error.message : \"Internal server error\",\n });\n }\n });\n }\n\n router.get(\"/config\", (_req, res) => {\n res.json(core.getConfig());\n });\n\n router.get(\"/favicon.ico\", (_req, res) => {\n const asset = serveStaticAsset(\"favicon.ico\");\n if (asset.status === 404 || !asset.body) {\n res.status(404).type(\"text/plain\").send(\"Not found\");\n return;\n }\n\n res.status(200).type(asset.contentType).send(asset.body);\n });\n\n router.get(\"/assets/:file\", (req, res) => {\n const asset = serveStaticAsset(req.params.file as string);\n if (asset.status === 404 || !asset.body) {\n res.status(404).type(\"text/plain\").send(\"Not found\");\n return;\n }\n res.status(200).type(asset.contentType).send(asset.body);\n });\n\n router.use((req, res, next) => {\n if (req.method !== \"GET\") {\n next();\n return;\n }\n const pathname = (req.originalUrl ?? req.url).split(\"?\")[0] ?? \"/\";\n const basePath = resolveBasePath(core.options.basePath, pathname);\n const html = renderIndexHtml(basePath, core.options.title || \"Workbench\");\n res.status(200).type(\"text/html; charset=utf-8\").send(html.body);\n });\n\n return router;\n}\n\nexport type { WorkbenchOptions } from \"./core\";\n"],"mappings":";;;;;;;;;;;AAWA,OAAO,aAA8B;AAE9B,SAAS,QAAQ,SAA6C;AACnE,QAAM,OAAO,IAAI,cAAc,OAAO;AACtC,QAAM,SAAS,QAAQ,OAAO;AAE9B,MAAI,KAAK,aAAa,GAAG;AACvB,WAAO,IAAI,CAAC,KAAK,KAAK,SAAS;AAC7B,UACE,CAAC;AAAA,QACC,IAAI,QAAQ;AAAA,QACZ,KAAK,QAAQ,KAAM;AAAA,QACnB,KAAK,QAAQ,KAAM;AAAA,MACrB,GACA;AACA,YAAI,IAAI,qBAAqB,OAAO;AACpC,YAAI,OAAO,qBAAqB,MAAM,EAAE,KAAK,qBAAqB,IAAI;AACtE;AAAA,MACF;AACA,WAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;AACtC,QAAI,IAAI,+BAA+B,GAAG;AAC1C,QAAI,IAAI,gCAAgC,gCAAgC;AACxE,QAAI,IAAI,gCAAgC,GAAG;AAC3C,SAAK;AAAA,EACP,CAAC;AAED,SAAO,IAAI,QAAQ,QAAQ,KAAK,CAAC;AAEjC,aAAW,SAAS,gBAAgB,IAAI,GAAG;AACzC,WAAO,MAAM,MAAM,EAAE,OAAO,MAAM,IAAI,IAAI,OAAO,KAAK,QAAQ;AAC5D,UAAI;AACF,cAAM,SAAS,MAAM,MAAM,QAAQ;AAAA,UACjC,QAAQ,IAAI;AAAA,UACZ,OAAO,IAAI;AAAA,UACX,MAAM,IAAI;AAAA,QACZ,CAAC;AACD,YAAI,OAAO,OAAO,MAAM,EAAE,KAAK,OAAO,IAAI;AAAA,MAC5C,SAAS,OAAO;AACd,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,OACE,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAC7C,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,IAAI,WAAW,CAAC,MAAM,QAAQ;AACnC,QAAI,KAAK,KAAK,UAAU,CAAC;AAAA,EAC3B,CAAC;AAED,SAAO,IAAI,gBAAgB,CAAC,MAAM,QAAQ;AACxC,UAAM,QAAQ,iBAAiB,aAAa;AAC5C,QAAI,MAAM,WAAW,OAAO,CAAC,MAAM,MAAM;AACvC,UAAI,OAAO,GAAG,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW;AACnD;AAAA,IACF;AAEA,QAAI,OAAO,GAAG,EAAE,KAAK,MAAM,WAAW,EAAE,KAAK,MAAM,IAAI;AAAA,EACzD,CAAC;AAED,SAAO,IAAI,iBAAiB,CAAC,KAAK,QAAQ;AACxC,UAAM,QAAQ,iBAAiB,IAAI,OAAO,IAAc;AACxD,QAAI,MAAM,WAAW,OAAO,CAAC,MAAM,MAAM;AACvC,UAAI,OAAO,GAAG,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW;AACnD;AAAA,IACF;AACA,QAAI,OAAO,GAAG,EAAE,KAAK,MAAM,WAAW,EAAE,KAAK,MAAM,IAAI;AAAA,EACzD,CAAC;AAED,SAAO,IAAI,CAAC,KAAK,KAAK,SAAS;AAC7B,QAAI,IAAI,WAAW,OAAO;AACxB,WAAK;AACL;AAAA,IACF;AACA,UAAM,YAAY,IAAI,eAAe,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,KAAK;AAC/D,UAAM,WAAW,gBAAgB,KAAK,QAAQ,UAAU,QAAQ;AAChE,UAAM,OAAO,gBAAgB,UAAU,KAAK,QAAQ,SAAS,WAAW;AACxE,QAAI,OAAO,GAAG,EAAE,KAAK,0BAA0B,EAAE,KAAK,KAAK,IAAI;AAAA,EACjE,CAAC;AAED,SAAO;AACT;","names":[]}
|