-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmod.ts
More file actions
90 lines (85 loc) · 3.38 KB
/
mod.ts
File metadata and controls
90 lines (85 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { parseArgs } from "@std/cli/parse-args";
import type { Protocol } from "./types.ts";
// List of slack-cli communication protocols supported
const DEFAULT_PROTOCOL = "default";
const MSG_BOUNDARY_PROTOCOL = "message-boundaries";
const SUPPORTED_NAMED_PROTOCOLS = [
MSG_BOUNDARY_PROTOCOL,
];
/**
* The baseline CLI<=> SDK protocol: all hook responses from this project go to stdout,
* and the CLI reads both stdout and stderr and combines them to interpret the hook response.
* This simplistic protocol has inherent limitations: cannot log diagnostic info!
* @param args command-line arguments passed to this process
*/
export const BaseProtocol = function (args: string[]): Protocol {
const { manifest: manifestOnly = false } = parseArgs(args);
// If the particular hook invocation is requesting for manifest generation, we ensure any logging is a no-op,
// so as to not litter stdout with logging - and confuse the CLI's manifest JSON payload parsing.
const loggerMethod = manifestOnly ? () => {} : console.log;
return {
name: DEFAULT_PROTOCOL,
log: loggerMethod,
error: loggerMethod,
warn: loggerMethod,
respond: console.log,
};
};
/**
* Protocol implementation that only uses stdout, but uses message boundaries to differentiate between
* diagnostic information and hook responses.
* @param args command-line arguments passed to this process
*/
export const MessageBoundaryProtocol = function (
args: string[],
): Required<Pick<Protocol, "getCLIFlags">> & Protocol {
const { boundary } = parseArgs(
args,
);
if (!boundary) throw new Error("no boundary argument provided!");
const protocol = {
name: MSG_BOUNDARY_PROTOCOL,
log: console.log,
error: console.error,
warn: console.warn,
// deno-lint-ignore no-explicit-any
respond: (data: any) => {
console.log(boundary + data + boundary);
},
getCLIFlags:
() => [`--protocol=${MSG_BOUNDARY_PROTOCOL}`, `--boundary=${boundary}`],
};
return protocol;
};
// A map of protocol names to protocol implementations
const PROTOCOL_MAP = {
[SUPPORTED_NAMED_PROTOCOLS[0]]: MessageBoundaryProtocol,
};
/**
* Based on the arguments provided by the CLI to the SDK hook process, returns an appropriate Protocol interface
* for communicating with the CLI over the specified protocol.
* @param args string[] An array of strings representing the command-line flags/arguments passed to the hook
*/
export const getProtocolInterface = function (args: string[]): Protocol {
const { protocol: protocolRequestedByCLI } = parseArgs(
args,
);
if (protocolRequestedByCLI) {
if (SUPPORTED_NAMED_PROTOCOLS.includes(protocolRequestedByCLI)) {
const iface = PROTOCOL_MAP[protocolRequestedByCLI];
// Allow support for protocol implementations to either be:
// - a function, that takes arguments passed to this process, to dynamically instantiate a Protocol interface
// - an object implementing the Protocol interface directly
if (typeof iface === "function") {
return iface(args);
} else {
return iface;
}
}
}
// If protocol negotiation fails for any reason, return the base protocol
// In the base protocol, if only a manifest is being requested, then we must
// return the manifest JSON over stdout, so the logging interface passed into
// BaseProtocol is a no-op function (to prevent logging to stdout)
return BaseProtocol(args);
};