@barnum/barnum 0.0.0-main-7025fec1 → 0.0.0-main-68fd94ca
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/index.ts +1 -0
- package/package.json +1 -1
- package/types.ts +63 -0
package/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./barnum-config-schema.zod.js";
|
|
2
2
|
export * from "./barnum-cli-schema.zod.js";
|
|
3
3
|
export { BarnumConfig, type RunOptions } from "./run.js";
|
|
4
|
+
export { Handler, createHandler, isHandler } from "./types.js";
|
|
4
5
|
export type {
|
|
5
6
|
HandlerDefinition,
|
|
6
7
|
HandlerContext,
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
|
|
3
4
|
export interface HandlerDefinition<C = unknown, V = unknown> {
|
|
4
5
|
stepConfigValidator: z.ZodType<C>;
|
|
@@ -17,3 +18,65 @@ export interface FollowUpTask {
|
|
|
17
18
|
kind: string;
|
|
18
19
|
value: unknown;
|
|
19
20
|
}
|
|
21
|
+
|
|
22
|
+
// ==================== Opaque Handler ====================
|
|
23
|
+
|
|
24
|
+
const HANDLER_BRAND = Symbol.for("barnum:handler");
|
|
25
|
+
|
|
26
|
+
export class Handler<C = unknown, V = unknown> {
|
|
27
|
+
readonly [HANDLER_BRAND] = true as const;
|
|
28
|
+
/** @internal */ readonly __filePath: string;
|
|
29
|
+
/** @internal */ readonly __definition: HandlerDefinition<C, V>;
|
|
30
|
+
|
|
31
|
+
/** @internal */
|
|
32
|
+
constructor(definition: HandlerDefinition<C, V>, filePath: string) {
|
|
33
|
+
this.__definition = definition;
|
|
34
|
+
this.__filePath = filePath;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
handle(context: HandlerContext<C, V>): Promise<FollowUpTask[]> {
|
|
38
|
+
return this.__definition.handle(context);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isHandler(x: unknown): x is Handler {
|
|
43
|
+
return typeof x === "object" && x !== null && HANDLER_BRAND in x;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getCallerFilePath(): string {
|
|
47
|
+
const original = Error.prepareStackTrace;
|
|
48
|
+
let callerFile: string | undefined;
|
|
49
|
+
|
|
50
|
+
Error.prepareStackTrace = (_err, stack) => {
|
|
51
|
+
// Frame 0: getCallerFilePath
|
|
52
|
+
// Frame 1: createHandler
|
|
53
|
+
// Frame 2: the file that called createHandler
|
|
54
|
+
const frame = stack[2];
|
|
55
|
+
callerFile = frame?.getFileName() ?? undefined;
|
|
56
|
+
return "";
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const err = new Error();
|
|
60
|
+
void err.stack;
|
|
61
|
+
Error.prepareStackTrace = original;
|
|
62
|
+
|
|
63
|
+
if (!callerFile) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"createHandler: could not determine caller file path from stack trace. " +
|
|
66
|
+
"Pass the path explicitly: createHandler(definition, { path: import.meta.filename })",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (callerFile.startsWith("file://")) {
|
|
71
|
+
return fileURLToPath(callerFile);
|
|
72
|
+
}
|
|
73
|
+
return callerFile;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function createHandler<C, V>(
|
|
77
|
+
definition: HandlerDefinition<C, V>,
|
|
78
|
+
opts?: { path?: string },
|
|
79
|
+
): Handler<C, V> {
|
|
80
|
+
const filePath = opts?.path ?? getCallerFilePath();
|
|
81
|
+
return new Handler(definition, filePath);
|
|
82
|
+
}
|