+3
docker-compose.yaml
+3
docker-compose.yaml
-1
go.mod
-1
go.mod
-2
go.sum
-2
go.sum
···
73
73
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
74
74
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
75
75
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
76
-
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
77
-
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
78
76
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
79
77
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
80
78
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+528
-2
package-lock.json
+528
-2
package-lock.json
···
1
1
{
2
-
"name": "churros-notella",
2
+
"name": "notella",
3
3
"lockfileVersion": 3,
4
4
"requires": true,
5
5
"packages": {
···
8
8
"@prisma/client": "^5.20.0"
9
9
},
10
10
"devDependencies": {
11
-
"prisma": "^5.20.0"
11
+
"nats": "^2.28.2",
12
+
"prisma": "^5.20.0",
13
+
"tsx": "^4.19.2"
14
+
}
15
+
},
16
+
"node_modules/@esbuild/aix-ppc64": {
17
+
"version": "0.23.1",
18
+
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
19
+
"integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
20
+
"cpu": [
21
+
"ppc64"
22
+
],
23
+
"dev": true,
24
+
"license": "MIT",
25
+
"optional": true,
26
+
"os": [
27
+
"aix"
28
+
],
29
+
"engines": {
30
+
"node": ">=18"
31
+
}
32
+
},
33
+
"node_modules/@esbuild/android-arm": {
34
+
"version": "0.23.1",
35
+
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
36
+
"integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
37
+
"cpu": [
38
+
"arm"
39
+
],
40
+
"dev": true,
41
+
"license": "MIT",
42
+
"optional": true,
43
+
"os": [
44
+
"android"
45
+
],
46
+
"engines": {
47
+
"node": ">=18"
48
+
}
49
+
},
50
+
"node_modules/@esbuild/android-arm64": {
51
+
"version": "0.23.1",
52
+
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
53
+
"integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
54
+
"cpu": [
55
+
"arm64"
56
+
],
57
+
"dev": true,
58
+
"license": "MIT",
59
+
"optional": true,
60
+
"os": [
61
+
"android"
62
+
],
63
+
"engines": {
64
+
"node": ">=18"
65
+
}
66
+
},
67
+
"node_modules/@esbuild/android-x64": {
68
+
"version": "0.23.1",
69
+
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
70
+
"integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
71
+
"cpu": [
72
+
"x64"
73
+
],
74
+
"dev": true,
75
+
"license": "MIT",
76
+
"optional": true,
77
+
"os": [
78
+
"android"
79
+
],
80
+
"engines": {
81
+
"node": ">=18"
82
+
}
83
+
},
84
+
"node_modules/@esbuild/darwin-arm64": {
85
+
"version": "0.23.1",
86
+
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
87
+
"integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
88
+
"cpu": [
89
+
"arm64"
90
+
],
91
+
"dev": true,
92
+
"license": "MIT",
93
+
"optional": true,
94
+
"os": [
95
+
"darwin"
96
+
],
97
+
"engines": {
98
+
"node": ">=18"
99
+
}
100
+
},
101
+
"node_modules/@esbuild/darwin-x64": {
102
+
"version": "0.23.1",
103
+
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
104
+
"integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
105
+
"cpu": [
106
+
"x64"
107
+
],
108
+
"dev": true,
109
+
"license": "MIT",
110
+
"optional": true,
111
+
"os": [
112
+
"darwin"
113
+
],
114
+
"engines": {
115
+
"node": ">=18"
116
+
}
117
+
},
118
+
"node_modules/@esbuild/freebsd-arm64": {
119
+
"version": "0.23.1",
120
+
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
121
+
"integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
122
+
"cpu": [
123
+
"arm64"
124
+
],
125
+
"dev": true,
126
+
"license": "MIT",
127
+
"optional": true,
128
+
"os": [
129
+
"freebsd"
130
+
],
131
+
"engines": {
132
+
"node": ">=18"
133
+
}
134
+
},
135
+
"node_modules/@esbuild/freebsd-x64": {
136
+
"version": "0.23.1",
137
+
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
138
+
"integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
139
+
"cpu": [
140
+
"x64"
141
+
],
142
+
"dev": true,
143
+
"license": "MIT",
144
+
"optional": true,
145
+
"os": [
146
+
"freebsd"
147
+
],
148
+
"engines": {
149
+
"node": ">=18"
150
+
}
151
+
},
152
+
"node_modules/@esbuild/linux-arm": {
153
+
"version": "0.23.1",
154
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
155
+
"integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
156
+
"cpu": [
157
+
"arm"
158
+
],
159
+
"dev": true,
160
+
"license": "MIT",
161
+
"optional": true,
162
+
"os": [
163
+
"linux"
164
+
],
165
+
"engines": {
166
+
"node": ">=18"
167
+
}
168
+
},
169
+
"node_modules/@esbuild/linux-arm64": {
170
+
"version": "0.23.1",
171
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
172
+
"integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
173
+
"cpu": [
174
+
"arm64"
175
+
],
176
+
"dev": true,
177
+
"license": "MIT",
178
+
"optional": true,
179
+
"os": [
180
+
"linux"
181
+
],
182
+
"engines": {
183
+
"node": ">=18"
184
+
}
185
+
},
186
+
"node_modules/@esbuild/linux-ia32": {
187
+
"version": "0.23.1",
188
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
189
+
"integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
190
+
"cpu": [
191
+
"ia32"
192
+
],
193
+
"dev": true,
194
+
"license": "MIT",
195
+
"optional": true,
196
+
"os": [
197
+
"linux"
198
+
],
199
+
"engines": {
200
+
"node": ">=18"
201
+
}
202
+
},
203
+
"node_modules/@esbuild/linux-loong64": {
204
+
"version": "0.23.1",
205
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
206
+
"integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
207
+
"cpu": [
208
+
"loong64"
209
+
],
210
+
"dev": true,
211
+
"license": "MIT",
212
+
"optional": true,
213
+
"os": [
214
+
"linux"
215
+
],
216
+
"engines": {
217
+
"node": ">=18"
218
+
}
219
+
},
220
+
"node_modules/@esbuild/linux-mips64el": {
221
+
"version": "0.23.1",
222
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
223
+
"integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
224
+
"cpu": [
225
+
"mips64el"
226
+
],
227
+
"dev": true,
228
+
"license": "MIT",
229
+
"optional": true,
230
+
"os": [
231
+
"linux"
232
+
],
233
+
"engines": {
234
+
"node": ">=18"
235
+
}
236
+
},
237
+
"node_modules/@esbuild/linux-ppc64": {
238
+
"version": "0.23.1",
239
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
240
+
"integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
241
+
"cpu": [
242
+
"ppc64"
243
+
],
244
+
"dev": true,
245
+
"license": "MIT",
246
+
"optional": true,
247
+
"os": [
248
+
"linux"
249
+
],
250
+
"engines": {
251
+
"node": ">=18"
252
+
}
253
+
},
254
+
"node_modules/@esbuild/linux-riscv64": {
255
+
"version": "0.23.1",
256
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
257
+
"integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
258
+
"cpu": [
259
+
"riscv64"
260
+
],
261
+
"dev": true,
262
+
"license": "MIT",
263
+
"optional": true,
264
+
"os": [
265
+
"linux"
266
+
],
267
+
"engines": {
268
+
"node": ">=18"
269
+
}
270
+
},
271
+
"node_modules/@esbuild/linux-s390x": {
272
+
"version": "0.23.1",
273
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
274
+
"integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
275
+
"cpu": [
276
+
"s390x"
277
+
],
278
+
"dev": true,
279
+
"license": "MIT",
280
+
"optional": true,
281
+
"os": [
282
+
"linux"
283
+
],
284
+
"engines": {
285
+
"node": ">=18"
286
+
}
287
+
},
288
+
"node_modules/@esbuild/linux-x64": {
289
+
"version": "0.23.1",
290
+
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
291
+
"integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
292
+
"cpu": [
293
+
"x64"
294
+
],
295
+
"dev": true,
296
+
"license": "MIT",
297
+
"optional": true,
298
+
"os": [
299
+
"linux"
300
+
],
301
+
"engines": {
302
+
"node": ">=18"
303
+
}
304
+
},
305
+
"node_modules/@esbuild/netbsd-x64": {
306
+
"version": "0.23.1",
307
+
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
308
+
"integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
309
+
"cpu": [
310
+
"x64"
311
+
],
312
+
"dev": true,
313
+
"license": "MIT",
314
+
"optional": true,
315
+
"os": [
316
+
"netbsd"
317
+
],
318
+
"engines": {
319
+
"node": ">=18"
320
+
}
321
+
},
322
+
"node_modules/@esbuild/openbsd-arm64": {
323
+
"version": "0.23.1",
324
+
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
325
+
"integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
326
+
"cpu": [
327
+
"arm64"
328
+
],
329
+
"dev": true,
330
+
"license": "MIT",
331
+
"optional": true,
332
+
"os": [
333
+
"openbsd"
334
+
],
335
+
"engines": {
336
+
"node": ">=18"
337
+
}
338
+
},
339
+
"node_modules/@esbuild/openbsd-x64": {
340
+
"version": "0.23.1",
341
+
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
342
+
"integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
343
+
"cpu": [
344
+
"x64"
345
+
],
346
+
"dev": true,
347
+
"license": "MIT",
348
+
"optional": true,
349
+
"os": [
350
+
"openbsd"
351
+
],
352
+
"engines": {
353
+
"node": ">=18"
354
+
}
355
+
},
356
+
"node_modules/@esbuild/sunos-x64": {
357
+
"version": "0.23.1",
358
+
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
359
+
"integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
360
+
"cpu": [
361
+
"x64"
362
+
],
363
+
"dev": true,
364
+
"license": "MIT",
365
+
"optional": true,
366
+
"os": [
367
+
"sunos"
368
+
],
369
+
"engines": {
370
+
"node": ">=18"
371
+
}
372
+
},
373
+
"node_modules/@esbuild/win32-arm64": {
374
+
"version": "0.23.1",
375
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
376
+
"integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
377
+
"cpu": [
378
+
"arm64"
379
+
],
380
+
"dev": true,
381
+
"license": "MIT",
382
+
"optional": true,
383
+
"os": [
384
+
"win32"
385
+
],
386
+
"engines": {
387
+
"node": ">=18"
388
+
}
389
+
},
390
+
"node_modules/@esbuild/win32-ia32": {
391
+
"version": "0.23.1",
392
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
393
+
"integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
394
+
"cpu": [
395
+
"ia32"
396
+
],
397
+
"dev": true,
398
+
"license": "MIT",
399
+
"optional": true,
400
+
"os": [
401
+
"win32"
402
+
],
403
+
"engines": {
404
+
"node": ">=18"
405
+
}
406
+
},
407
+
"node_modules/@esbuild/win32-x64": {
408
+
"version": "0.23.1",
409
+
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
410
+
"integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
411
+
"cpu": [
412
+
"x64"
413
+
],
414
+
"dev": true,
415
+
"license": "MIT",
416
+
"optional": true,
417
+
"os": [
418
+
"win32"
419
+
],
420
+
"engines": {
421
+
"node": ">=18"
12
422
}
13
423
},
14
424
"node_modules/@prisma/client": {
···
73
483
"@prisma/debug": "5.20.0"
74
484
}
75
485
},
486
+
"node_modules/esbuild": {
487
+
"version": "0.23.1",
488
+
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
489
+
"integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
490
+
"dev": true,
491
+
"hasInstallScript": true,
492
+
"license": "MIT",
493
+
"bin": {
494
+
"esbuild": "bin/esbuild"
495
+
},
496
+
"engines": {
497
+
"node": ">=18"
498
+
},
499
+
"optionalDependencies": {
500
+
"@esbuild/aix-ppc64": "0.23.1",
501
+
"@esbuild/android-arm": "0.23.1",
502
+
"@esbuild/android-arm64": "0.23.1",
503
+
"@esbuild/android-x64": "0.23.1",
504
+
"@esbuild/darwin-arm64": "0.23.1",
505
+
"@esbuild/darwin-x64": "0.23.1",
506
+
"@esbuild/freebsd-arm64": "0.23.1",
507
+
"@esbuild/freebsd-x64": "0.23.1",
508
+
"@esbuild/linux-arm": "0.23.1",
509
+
"@esbuild/linux-arm64": "0.23.1",
510
+
"@esbuild/linux-ia32": "0.23.1",
511
+
"@esbuild/linux-loong64": "0.23.1",
512
+
"@esbuild/linux-mips64el": "0.23.1",
513
+
"@esbuild/linux-ppc64": "0.23.1",
514
+
"@esbuild/linux-riscv64": "0.23.1",
515
+
"@esbuild/linux-s390x": "0.23.1",
516
+
"@esbuild/linux-x64": "0.23.1",
517
+
"@esbuild/netbsd-x64": "0.23.1",
518
+
"@esbuild/openbsd-arm64": "0.23.1",
519
+
"@esbuild/openbsd-x64": "0.23.1",
520
+
"@esbuild/sunos-x64": "0.23.1",
521
+
"@esbuild/win32-arm64": "0.23.1",
522
+
"@esbuild/win32-ia32": "0.23.1",
523
+
"@esbuild/win32-x64": "0.23.1"
524
+
}
525
+
},
76
526
"node_modules/fsevents": {
77
527
"version": "2.3.3",
78
528
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
···
87
537
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
88
538
}
89
539
},
540
+
"node_modules/get-tsconfig": {
541
+
"version": "4.8.1",
542
+
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
543
+
"integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
544
+
"dev": true,
545
+
"license": "MIT",
546
+
"dependencies": {
547
+
"resolve-pkg-maps": "^1.0.0"
548
+
},
549
+
"funding": {
550
+
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
551
+
}
552
+
},
553
+
"node_modules/nats": {
554
+
"version": "2.28.2",
555
+
"resolved": "https://registry.npmjs.org/nats/-/nats-2.28.2.tgz",
556
+
"integrity": "sha512-02cvR8EPach+0BfVaQjPgsbPFn6uMjEQAuvXS2ppg8jiWEm2KYdfmeFmtshiU9b2+kFh3LSEKMEaIfRgk3K8tw==",
557
+
"dev": true,
558
+
"license": "Apache-2.0",
559
+
"dependencies": {
560
+
"nkeys.js": "1.1.0"
561
+
},
562
+
"engines": {
563
+
"node": ">= 14.0.0"
564
+
}
565
+
},
566
+
"node_modules/nkeys.js": {
567
+
"version": "1.1.0",
568
+
"resolved": "https://registry.npmjs.org/nkeys.js/-/nkeys.js-1.1.0.tgz",
569
+
"integrity": "sha512-tB/a0shZL5UZWSwsoeyqfTszONTt4k2YS0tuQioMOD180+MbombYVgzDUYHlx+gejYK6rgf08n/2Df99WY0Sxg==",
570
+
"dev": true,
571
+
"license": "Apache-2.0",
572
+
"dependencies": {
573
+
"tweetnacl": "1.0.3"
574
+
},
575
+
"engines": {
576
+
"node": ">=10.0.0"
577
+
}
578
+
},
90
579
"node_modules/prisma": {
91
580
"version": "5.20.0",
92
581
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz",
···
105
594
"optionalDependencies": {
106
595
"fsevents": "2.3.3"
107
596
}
597
+
},
598
+
"node_modules/resolve-pkg-maps": {
599
+
"version": "1.0.0",
600
+
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
601
+
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
602
+
"dev": true,
603
+
"license": "MIT",
604
+
"funding": {
605
+
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
606
+
}
607
+
},
608
+
"node_modules/tsx": {
609
+
"version": "4.19.2",
610
+
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz",
611
+
"integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==",
612
+
"dev": true,
613
+
"license": "MIT",
614
+
"dependencies": {
615
+
"esbuild": "~0.23.0",
616
+
"get-tsconfig": "^4.7.5"
617
+
},
618
+
"bin": {
619
+
"tsx": "dist/cli.mjs"
620
+
},
621
+
"engines": {
622
+
"node": ">=18.0.0"
623
+
},
624
+
"optionalDependencies": {
625
+
"fsevents": "~2.3.3"
626
+
}
627
+
},
628
+
"node_modules/tweetnacl": {
629
+
"version": "1.0.3",
630
+
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
631
+
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
632
+
"dev": true,
633
+
"license": "Unlicense"
108
634
}
109
635
}
110
636
}
+3
-1
package.json
+3
-1
package.json
+4
-3
receiver.go
+4
-3
receiver.go
···
1
1
package notella
2
2
3
3
import (
4
-
"github.com/nats-io/nats.go/jetstream"
4
+
ll "github.com/ewen-lbh/label-logger-go"
5
+
"github.com/nats-io/nats.go"
5
6
)
6
7
7
-
func NatsReceiver(m jetstream.Msg) {
8
-
8
+
func NatsReceiver(m *nats.Msg) {
9
+
ll.Log("Received", "cyan", "message: %s", string(m.Data))
9
10
}
+62
scripts/mocksender.ts
+62
scripts/mocksender.ts
···
1
+
import { connect, StringCodec, JetStreamManager, NatsConnection } from "nats"
2
+
3
+
async function setupStream(
4
+
jetStreamManager: JetStreamManager,
5
+
streamName: string,
6
+
subject: string
7
+
) {
8
+
try {
9
+
// Try to add the stream (will not recreate if it exists)
10
+
await jetStreamManager.streams.add({
11
+
name: streamName,
12
+
subjects: [subject],
13
+
})
14
+
console.log(`Stream '${streamName}' created or already exists.`)
15
+
} catch (err) {
16
+
console.error(`Error setting up stream: ${err.message}`)
17
+
}
18
+
}
19
+
20
+
async function publishMessages(
21
+
nc: NatsConnection,
22
+
subject: string,
23
+
messageCount: number,
24
+
delayMs: number
25
+
) {
26
+
const js = nc.jetstream()
27
+
const sc = StringCodec()
28
+
29
+
for (let i = 1; i <= messageCount; i++) {
30
+
const message = `Mock Order #${i}`
31
+
await js.publish(subject, sc.encode(message))
32
+
console.log(`Sent message: ${message}`)
33
+
await new Promise((resolve) => setTimeout(resolve, delayMs))
34
+
}
35
+
}
36
+
37
+
async function main() {
38
+
const streamName = "notella:stream"
39
+
const subject = "notella:notification"
40
+
41
+
// Connect to the NATS server
42
+
const nc = await connect({ servers: "localhost:4222" })
43
+
console.log("Connected to NATS")
44
+
45
+
// Create a JetStream manager to manage streams
46
+
const jsm = await nc.jetstreamManager()
47
+
48
+
// Ensure the stream exists
49
+
await setupStream(jsm, streamName, subject)
50
+
51
+
// Publish messages at intervals
52
+
const messageCount = 20
53
+
const delayMs = 1000 // 1 second delay between messages
54
+
await publishMessages(nc, subject, messageCount, delayMs)
55
+
56
+
console.log("Finished sending messages.")
57
+
await nc.close()
58
+
}
59
+
60
+
main().catch((err) => {
61
+
console.error(`Error in sender: ${err.message}`)
62
+
})
+54
-21
server/main.go
+54
-21
server/main.go
···
5
5
import (
6
6
"context"
7
7
"fmt"
8
+
"log"
8
9
"os"
9
10
"os/signal"
10
11
"syscall"
···
16
17
ll "github.com/ewen-lbh/label-logger-go"
17
18
"github.com/joho/godotenv"
18
19
"github.com/nats-io/nats.go"
19
-
"github.com/nats-io/nats.go/jetstream"
20
20
)
21
21
22
22
type Configuration struct {
···
28
28
}
29
29
30
30
var Version = "DEV"
31
+
32
+
const StreamName = "notella:stream"
33
+
const SubjectName = "notella:notification"
31
34
32
35
func main() {
33
36
figure.NewColorFigure("Notella", "", "yellow", true).Print()
···
66
69
return
67
70
}
68
71
69
-
ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second)
70
-
defer cancel()
71
-
72
-
js, err := jetstream.New(nc)
72
+
js, err := nc.JetStream()
73
73
if err != nil {
74
74
ll.ErrorDisplay("could not connect to Jetstream", err)
75
75
return
76
76
}
77
77
78
-
ll.Log("Initializing", "cyan", "a Jetstream stream [bold]notella:stream[reset], listening for [bold]notella:*[reset] subjects")
78
+
ll.Log("Initializing", "cyan", "a Jetstream stream [bold]%s[reset], listening for subject [bold]%s[reset]", StreamName, SubjectName)
79
79
80
-
s, err := js.CreateStream(ctx, jetstream.StreamConfig{
81
-
Name: "notella:stream",
82
-
Subjects: []string{"notella:*"},
80
+
_, err = js.AddStream(&nats.StreamConfig{
81
+
Name: StreamName,
82
+
Subjects: []string{SubjectName},
83
83
})
84
84
if err != nil {
85
85
ll.ErrorDisplay("could not create stream", err)
···
88
88
89
89
ll.Log("Initializing", "cyan", "Jetstream consumer [bold]NotellaConsumer[reset] with [bold]AckExplicitPolicy[reset]")
90
90
91
-
cons, err := s.CreateOrUpdateConsumer(ctx, jetstream.ConsumerConfig{
91
+
_, err = js.AddConsumer(StreamName, &nats.ConsumerConfig{
92
92
Durable: "NotellaConsumer",
93
-
AckPolicy: jetstream.AckExplicitPolicy,
93
+
AckPolicy: nats.AckExplicitPolicy,
94
94
})
95
95
if err != nil {
96
96
ll.ErrorDisplay("could not create consumer", err)
···
99
99
100
100
ll.Log("Starting", "cyan", "consumer [bold]NotellaConsumer[reset]")
101
101
102
-
cc, err := cons.Consume(func(msg jetstream.Msg) {
103
-
fmt.Println(string(msg.Data()))
104
-
msg.Ack()
105
-
}, jetstream.ConsumeErrHandler(func(consumeCtx jetstream.ConsumeContext, err error) {
106
-
fmt.Println(err)
107
-
}))
102
+
sub, err := js.PullSubscribe(SubjectName, "NotellaConsumer")
108
103
if err != nil {
109
104
ll.ErrorDisplay("could not start consumer", err)
110
105
return
111
106
}
112
-
defer cc.Stop()
107
+
108
+
// Setup a context to handle graceful shutdowns
109
+
ctx, cancel := context.WithCancel(context.Background())
110
+
defer cancel()
111
+
112
+
// Capture OS signals for graceful shutdown
113
+
go func() {
114
+
sigChan := make(chan os.Signal, 1)
115
+
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
116
+
<-sigChan
117
+
log.Println("Received shutdown signal, shutting down...")
118
+
cancel()
119
+
}()
120
+
121
+
// Continuously fetch and process messages
122
+
go func() {
123
+
for {
124
+
select {
125
+
case <-ctx.Done():
126
+
return
127
+
default:
128
+
// Fetch messages in batches
129
+
msgs, err := sub.Fetch(10, nats.MaxWait(5*time.Second))
130
+
if err != nil && err != nats.ErrTimeout {
131
+
log.Printf("Error fetching messages: %v", err)
132
+
time.Sleep(2 * time.Second) // Wait before retrying
133
+
continue
134
+
}
113
135
114
-
sig := make(chan os.Signal, 1)
115
-
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
116
-
<-sig
136
+
// Process each message
137
+
for _, msg := range msgs {
138
+
log.Printf("Processing message: %s", string(msg.Data))
139
+
// Simulate notification scheduling
140
+
notella.NatsReceiver(msg)
141
+
msg.Ack() // Acknowledge the message
142
+
}
143
+
}
144
+
}
145
+
}()
146
+
147
+
// Block until the context is canceled (i.e., server shutdown signal received)
148
+
<-ctx.Done()
149
+
log.Println("Server stopped.")
117
150
}