1 | import { |
2 | connect, |
3 | headers as natsHeaders, |
4 | jwtAuthenticator, |
5 | nkeyAuthenticator, |
6 | } from "nats" |
7 |
|
8 | |
9 | * Publish message |
10 | * Publish one message to a NATS subject, with optional headers. A string payload is sent as-is, anything else as JSON. With jetstream on, it waits for the stream's acknowledgement and returns the stream and sequence. |
11 | */ |
12 | export async function main( |
13 | auth: RT.Nats, |
14 | subject: string, |
15 | payload: any, |
16 | headers: { [key: string]: string } | undefined, |
17 | jetstream: boolean = false |
18 | ) { |
19 | if (payload === undefined) throw new Error("payload is required") |
20 | |
21 | const servers = (auth.servers ?? []).map((s) => s.trim()).filter((s) => s) |
22 | if (!servers.length) throw new Error("The nats resource lists no servers") |
23 | const a = auth.auth ?? { label: "NO_AUTH" } |
24 | |
25 | const seed = (s: string) => new TextEncoder().encode(s.trim()) |
26 | const nc = await connect({ |
27 | servers, |
28 | tls: auth.require_tls ? {} : undefined, |
29 | token: a.label === "TOKEN" ? a.token : undefined, |
30 | user: a.label === "USER_PASSWORD" ? a.user : undefined, |
31 | pass: a.label === "USER_PASSWORD" ? a.password : undefined, |
32 | authenticator: |
33 | a.label === "NKEY" |
34 | ? nkeyAuthenticator(seed(a.seed)) |
35 | : a.label === "JWT" |
36 | ? jwtAuthenticator(a.jwt.trim(), seed(a.seed)) |
37 | : undefined, |
38 | maxReconnectAttempts: 0, |
39 | }) |
40 | try { |
41 | const data = new TextEncoder().encode( |
42 | typeof payload === "string" ? payload : JSON.stringify(payload) |
43 | ) |
44 | const entries = Object.entries(headers ?? {}) |
45 | const h = entries.length ? natsHeaders() : undefined |
46 | for (const [k, v] of entries) h!.append(k, String(v)) |
47 | if (jetstream) { |
48 | const ack = await nc.jetstream().publish(subject, data, { headers: h }) |
49 | return { |
50 | subject, |
51 | stream: ack.stream, |
52 | seq: ack.seq, |
53 | duplicate: ack.duplicate, |
54 | } |
55 | } |
56 | nc.publish(subject, data, { headers: h }) |
57 | |
58 | await nc.flush() |
59 | return { subject } |
60 | } finally { |
61 | await nc.close() |
62 | } |
63 | } |
64 |
|