@estopia/shared 1.0.0 → 1.0.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.
Files changed (103) hide show
  1. package/dist/broker/eventTypes.d.ts +20 -0
  2. package/dist/broker/eventTypes.d.ts.map +1 -0
  3. package/dist/broker/eventTypes.js +8 -0
  4. package/dist/broker/eventTypes.js.map +1 -0
  5. package/dist/broker/publisher.d.ts +16 -0
  6. package/dist/broker/publisher.d.ts.map +1 -0
  7. package/dist/broker/publisher.js +124 -0
  8. package/dist/broker/publisher.js.map +1 -0
  9. package/dist/broker/subscriber.d.ts +14 -0
  10. package/dist/broker/subscriber.d.ts.map +1 -0
  11. package/dist/broker/subscriber.js +60 -0
  12. package/dist/broker/subscriber.js.map +1 -0
  13. package/dist/database/cockroach.d.ts +11 -0
  14. package/dist/database/cockroach.d.ts.map +1 -0
  15. package/dist/database/cockroach.js +27 -0
  16. package/dist/database/cockroach.js.map +1 -0
  17. package/dist/database/dataTypes.d.ts +99 -0
  18. package/dist/database/dataTypes.d.ts.map +1 -0
  19. package/dist/database/dataTypes.js +7 -0
  20. package/dist/database/dataTypes.js.map +1 -0
  21. package/{src/database/types.ts → dist/database/types.d.ts} +8 -9
  22. package/dist/database/types.d.ts.map +1 -0
  23. package/dist/database/types.js +3 -0
  24. package/dist/database/types.js.map +1 -0
  25. package/dist/helpers/middlware/auth.d.ts +10 -0
  26. package/dist/helpers/middlware/auth.d.ts.map +1 -0
  27. package/dist/helpers/middlware/auth.js +55 -0
  28. package/dist/helpers/middlware/auth.js.map +1 -0
  29. package/dist/helpers/middlware/secure.d.ts +11 -0
  30. package/dist/helpers/middlware/secure.d.ts.map +1 -0
  31. package/dist/helpers/middlware/secure.js +42 -0
  32. package/dist/helpers/middlware/secure.js.map +1 -0
  33. package/dist/helpers/validateJWTToken.d.ts +16 -0
  34. package/dist/helpers/validateJWTToken.d.ts.map +1 -0
  35. package/dist/helpers/validateJWTToken.js +36 -0
  36. package/dist/helpers/validateJWTToken.js.map +1 -0
  37. package/{src/index.ts → dist/index.d.ts} +16 -24
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +24 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/logging/logger.d.ts +13 -0
  42. package/dist/logging/logger.d.ts.map +1 -0
  43. package/dist/logging/logger.js +81 -0
  44. package/dist/logging/logger.js.map +1 -0
  45. package/dist/types/ENUMS.d.ts +32 -0
  46. package/dist/types/ENUMS.d.ts.map +1 -0
  47. package/dist/types/ENUMS.js +41 -0
  48. package/dist/types/ENUMS.js.map +1 -0
  49. package/dist/types/directs.d.ts +16 -0
  50. package/dist/types/directs.d.ts.map +1 -0
  51. package/dist/types/directs.js +3 -0
  52. package/dist/types/directs.js.map +1 -0
  53. package/dist/types/medical.d.ts +32 -0
  54. package/dist/types/medical.d.ts.map +1 -0
  55. package/dist/types/medical.js +3 -0
  56. package/dist/types/medical.js.map +1 -0
  57. package/dist/types/messages.d.ts +24 -0
  58. package/dist/types/messages.d.ts.map +1 -0
  59. package/dist/types/messages.js +3 -0
  60. package/dist/types/messages.js.map +1 -0
  61. package/{src/types/request.ts → dist/types/request.d.ts} +22 -23
  62. package/dist/types/request.d.ts.map +1 -0
  63. package/dist/types/request.js +3 -0
  64. package/dist/types/request.js.map +1 -0
  65. package/dist/types/servers.d.ts +32 -0
  66. package/dist/types/servers.d.ts.map +1 -0
  67. package/dist/types/servers.js +3 -0
  68. package/dist/types/servers.js.map +1 -0
  69. package/dist/types/servicePayloads.d.ts +32 -0
  70. package/dist/types/servicePayloads.d.ts.map +1 -0
  71. package/dist/types/servicePayloads.js +10 -0
  72. package/dist/types/servicePayloads.js.map +1 -0
  73. package/dist/types/ticketsAndReporting.d.ts +29 -0
  74. package/dist/types/ticketsAndReporting.d.ts.map +1 -0
  75. package/dist/types/ticketsAndReporting.js +3 -0
  76. package/dist/types/ticketsAndReporting.js.map +1 -0
  77. package/dist/types/user.d.ts +29 -0
  78. package/dist/types/user.d.ts.map +1 -0
  79. package/dist/types/user.js +3 -0
  80. package/dist/types/user.js.map +1 -0
  81. package/package.json +10 -4
  82. package/.github/workflows/tests.yml +0 -29
  83. package/scripts/migrations/1670000000000-initial.js +0 -107
  84. package/scripts/package.json +0 -20
  85. package/src/broker/eventTypes.ts +0 -23
  86. package/src/broker/publisher.ts +0 -82
  87. package/src/broker/subscriber.ts +0 -51
  88. package/src/database/cockroach.ts +0 -27
  89. package/src/helpers/middlware/auth.ts +0 -55
  90. package/src/helpers/middlware/secure.ts +0 -48
  91. package/src/helpers/validateJWTToken.ts +0 -38
  92. package/src/logging/logger.ts +0 -103
  93. package/src/types/ENUMS.ts +0 -45
  94. package/src/types/directs.ts +0 -18
  95. package/src/types/medical.ts +0 -36
  96. package/src/types/messages.ts +0 -27
  97. package/src/types/servers.ts +0 -36
  98. package/src/types/servicePayloads.ts +0 -40
  99. package/src/types/ticketsAndReporting.ts +0 -32
  100. package/src/types/user.ts +0 -34
  101. package/tests/verifyJWTToken.test.ts +0 -27
  102. package/tsconfig.json +0 -48
  103. package/vitest.config.ts +0 -9
@@ -0,0 +1,20 @@
1
+ export interface UserRegisteredEvent {
2
+ userId: string;
3
+ email: string;
4
+ verificationCode: string;
5
+ }
6
+ export interface PasswordResetEvent {
7
+ userId: string;
8
+ email: string;
9
+ resetToken: string;
10
+ }
11
+ export type EventPayloads = UserRegisteredEvent | PasswordResetEvent;
12
+ export interface EventMap {
13
+ USER_REGISTERED: UserRegisteredEvent;
14
+ PASSWORD_RESET: PasswordResetEvent;
15
+ }
16
+ export declare const EVENTS: {
17
+ readonly USER_REGISTERED: "user.registered";
18
+ readonly PASSWORD_RESET: "password.reset";
19
+ };
20
+ //# sourceMappingURL=eventTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventTypes.d.ts","sourceRoot":"","sources":["../../src/broker/eventTypes.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAErE,MAAM,WAAW,QAAQ;IACvB,eAAe,EAAE,mBAAmB,CAAC;IACrC,cAAc,EAAE,kBAAkB,CAAC;CACpC;AAED,eAAO,MAAM,MAAM;;;CAGT,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EVENTS = void 0;
4
+ exports.EVENTS = {
5
+ USER_REGISTERED: 'user.registered',
6
+ PASSWORD_RESET: 'password.reset',
7
+ };
8
+ //# sourceMappingURL=eventTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventTypes.js","sourceRoot":"","sources":["../../src/broker/eventTypes.ts"],"names":[],"mappings":";;;AAmBa,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;CACxB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { EventMap } from './eventTypes';
2
+ export declare class EventPublisher {
3
+ private url;
4
+ private connection?;
5
+ private channel?;
6
+ private exchange;
7
+ constructor(url: string);
8
+ connect(): Promise<void>;
9
+ /**
10
+ * Publish an event. The payload type is keyed by the same keys used in your EventPayloads map.
11
+ * Ensures the routing key exists in EVENTS and that the publisher is connected.
12
+ */
13
+ publish<K extends keyof EventMap>(eventName: K, payload: EventMap[K]): Promise<void>;
14
+ close(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=publisher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/broker/publisher.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,QAAQ,EAAU,MAAM,cAAc,CAAC;AAE/D,qBAAa,cAAc;IAKb,OAAO,CAAC,GAAG;IAJvB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,OAAO,CAAC,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAoB;gBAEhB,GAAG,EAAE,MAAM;IAEzB,OAAO;IAOb;;;OAGG;IACG,OAAO,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IA8CpE,KAAK;CAcZ"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.EventPublisher = void 0;
37
+ const amqplib = __importStar(require("amqplib"));
38
+ const eventTypes_1 = require("./eventTypes");
39
+ class EventPublisher {
40
+ url;
41
+ connection;
42
+ channel;
43
+ exchange = 'estopia.events';
44
+ constructor(url) {
45
+ this.url = url;
46
+ }
47
+ async connect() {
48
+ if (this.connection && this.channel)
49
+ return; // already connected
50
+ this.connection = await amqplib.connect(this.url);
51
+ this.channel = await this.connection.createChannel();
52
+ await this.channel.assertExchange(this.exchange, 'topic', { durable: true });
53
+ }
54
+ /**
55
+ * Publish an event. The payload type is keyed by the same keys used in your EventPayloads map.
56
+ * Ensures the routing key exists in EVENTS and that the publisher is connected.
57
+ */
58
+ async publish(eventName, payload) {
59
+ // Auto-connect if needed
60
+ if (!this.channel) {
61
+ await this.connect();
62
+ }
63
+ const routingKey = eventTypes_1.EVENTS[eventName];
64
+ if (!routingKey || typeof routingKey !== 'string') {
65
+ throw new Error(`No routing key configured for event ${String(eventName)}`);
66
+ }
67
+ let body;
68
+ try {
69
+ body = Buffer.from(JSON.stringify(payload));
70
+ }
71
+ catch (err) {
72
+ throw new Error('Failed to serialize payload for publish');
73
+ }
74
+ // Basic retry with exponential backoff
75
+ const maxRetries = 3;
76
+ const baseBackoffMs = 200;
77
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
78
+ try {
79
+ // channel.publish is synchronous; wrap in try/catch in case of closed channel
80
+ this.channel.publish(this.exchange, routingKey, body, { persistent: true });
81
+ return;
82
+ }
83
+ catch (err) {
84
+ // if last attempt, rethrow
85
+ if (attempt === maxRetries)
86
+ throw err;
87
+ // try reconnect + backoff
88
+ try {
89
+ // reset connection and attempt reconnect
90
+ await this.close();
91
+ }
92
+ catch (_) { }
93
+ try {
94
+ await this.connect();
95
+ }
96
+ catch (_) {
97
+ // failed to reconnect, will backoff and retry loop
98
+ }
99
+ const backoff = baseBackoffMs * Math.pow(2, attempt);
100
+ await new Promise((res) => setTimeout(res, backoff));
101
+ }
102
+ }
103
+ }
104
+ async close() {
105
+ try {
106
+ if (this.channel)
107
+ await this.channel.close();
108
+ }
109
+ catch (e) {
110
+ // ignore
111
+ }
112
+ try {
113
+ if (this.connection)
114
+ await this.connection.close();
115
+ }
116
+ catch (e) {
117
+ // ignore
118
+ }
119
+ this.channel = undefined;
120
+ this.connection = undefined;
121
+ }
122
+ }
123
+ exports.EventPublisher = EventPublisher;
124
+ //# sourceMappingURL=publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/broker/publisher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { EventMap } from './eventTypes';
2
+ type EventHandler<T> = (payload: T) => Promise<void> | void;
3
+ export declare class EventSubscriber {
4
+ private url;
5
+ private connection?;
6
+ private channel?;
7
+ private exchange;
8
+ constructor(url: string);
9
+ connect(): Promise<void>;
10
+ subscribe<K extends keyof EventMap>(eventName: K, handler: EventHandler<EventMap[K]>): Promise<void>;
11
+ close(): Promise<void>;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=subscriber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../src/broker/subscriber.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEhD,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE5D,qBAAa,eAAe;IAKd,OAAO,CAAC,GAAG;IAJvB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,OAAO,CAAC,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAoB;gBAEhB,GAAG,EAAE,MAAM;IAEzB,OAAO;IAOP,SAAS,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAyBpF,KAAK;CAMZ"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventSubscriber = void 0;
4
+ const amqplib = require('amqplib');
5
+ const eventTypes_1 = require("./eventTypes");
6
+ class EventSubscriber {
7
+ url;
8
+ connection;
9
+ channel;
10
+ exchange = 'estopia.events';
11
+ constructor(url) {
12
+ this.url = url;
13
+ }
14
+ async connect() {
15
+ if (this.connection && this.channel)
16
+ return;
17
+ this.connection = await amqplib.connect(this.url);
18
+ this.channel = await this.connection.createChannel();
19
+ await this.channel.assertExchange(this.exchange, 'topic', { durable: true });
20
+ }
21
+ async subscribe(eventName, handler) {
22
+ if (!this.channel)
23
+ throw new Error('Subscriber not connected');
24
+ const q = await this.channel.assertQueue('', { exclusive: true });
25
+ const routing = eventTypes_1.EVENTS[eventName];
26
+ await this.channel.bindQueue(q.queue, this.exchange, routing);
27
+ await this.channel.consume(q.queue, (msg) => {
28
+ if (msg) {
29
+ let payload;
30
+ try {
31
+ payload = JSON.parse(msg.content.toString());
32
+ }
33
+ catch (err) {
34
+ // malformed message -> nack and requeue false
35
+ this.channel?.nack(msg, false, false);
36
+ return;
37
+ }
38
+ Promise.resolve(handler(payload))
39
+ .then(() => this.channel?.ack(msg))
40
+ .catch(() => this.channel?.nack(msg, false, true));
41
+ }
42
+ });
43
+ }
44
+ async close() {
45
+ try {
46
+ if (this.channel)
47
+ await this.channel.close();
48
+ }
49
+ catch (e) { }
50
+ try {
51
+ if (this.connection)
52
+ await this.connection.close();
53
+ }
54
+ catch (e) { }
55
+ this.channel = undefined;
56
+ this.connection = undefined;
57
+ }
58
+ }
59
+ exports.EventSubscriber = EventSubscriber;
60
+ //# sourceMappingURL=subscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriber.js","sourceRoot":"","sources":["../../src/broker/subscriber.ts"],"names":[],"mappings":";;;AAAA,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AACnC,6CAAgD;AAIhD,MAAa,eAAe;IAKN;IAJZ,UAAU,CAAO;IACjB,OAAO,CAAO;IACd,QAAQ,GAAG,gBAAgB,CAAC;IAEpC,YAAoB,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;IAEnC,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAC5C,IAAI,CAAC,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;QACrD,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,SAAS,CAA2B,SAAY,EAAE,OAAkC;QACxF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE/D,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,mBAAM,CAAC,SAAgC,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE5D,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAe,EAAE,EAAE;YACtD,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,OAAoB,CAAC;gBACzB,IAAI,CAAC;oBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,8CAA8C;oBAC9C,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;oBACtC,OAAO;gBACT,CAAC;gBAED,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;qBAC9B,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;qBAClC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YAAC,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC;YAAC,IAAI,IAAI,CAAC,UAAU;gBAAE,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;CACF;AA7CD,0CA6CC"}
@@ -0,0 +1,11 @@
1
+ import { CockroachConfig } from './types';
2
+ import { Kysely } from 'kysely';
3
+ import { DB } from './dataTypes';
4
+ /**
5
+ * Creates and tests a new connection pool for a CockroachDB cluster.
6
+ * * @param config - The connection configuration for CockroachDB.
7
+ * @returns A promise that resolves to a connected Pool instance.
8
+ * @throws Will throw an error if the connection fails.
9
+ */
10
+ export declare function createCockroachDBConnection(config: CockroachConfig): Promise<Kysely<DB>>;
11
+ //# sourceMappingURL=cockroach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockroach.d.ts","sourceRoot":"","sources":["../../src/database/cockroach.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAmB,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAe9F"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCockroachDBConnection = createCockroachDBConnection;
4
+ const pg_1 = require("pg");
5
+ const kysely_1 = require("kysely");
6
+ /**
7
+ * Creates and tests a new connection pool for a CockroachDB cluster.
8
+ * * @param config - The connection configuration for CockroachDB.
9
+ * @returns A promise that resolves to a connected Pool instance.
10
+ * @throws Will throw an error if the connection fails.
11
+ */
12
+ async function createCockroachDBConnection(config) {
13
+ try {
14
+ const db = new kysely_1.Kysely({
15
+ dialect: new kysely_1.PostgresDialect({
16
+ pool: new pg_1.Pool(config)
17
+ })
18
+ });
19
+ console.log('Successfully connected to CockroachDB.');
20
+ return db;
21
+ }
22
+ catch (error) {
23
+ console.error('Failed to connect to CockroachDB:', error);
24
+ throw error;
25
+ }
26
+ }
27
+ //# sourceMappingURL=cockroach.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockroach.js","sourceRoot":"","sources":["../../src/database/cockroach.ts"],"names":[],"mappings":";;AAWA,kEAeC;AA1BD,2BAA0B;AAE1B,mCAAiD;AAGjD;;;;;GAKG;AACI,KAAK,UAAU,2BAA2B,CAAC,MAAuB;IACvE,IAAI,CAAC;QAEH,MAAM,EAAE,GAAG,IAAI,eAAM,CAAK;YACxB,OAAO,EAAE,IAAI,wBAAe,CAAC;gBAC3B,IAAI,EAAE,IAAI,SAAI,CAAC,MAAM,CAAC;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACtD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * This file was generated by kysely-codegen.
3
+ * Please do not edit it manually.
4
+ */
5
+ import type { ColumnType } from "kysely";
6
+ export type AppType = "medAndroid" | "medIOS" | "web";
7
+ export type FactorAuthType = "email" | "whatsapp";
8
+ export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
9
+ export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
10
+ export type Timestamp = ColumnType<Date, Date | string, Date | string>;
11
+ export type VerificationType = "email" | "password_reset" | "phone";
12
+ export interface AuthApps {
13
+ id: Generated<Int8>;
14
+ name: string;
15
+ secret: string;
16
+ user_id: Int8;
17
+ }
18
+ export interface FactorAuthentication {
19
+ code: string;
20
+ data: string;
21
+ expiry_at: Timestamp;
22
+ id: Generated<Int8>;
23
+ is_verified: Generated<boolean | null>;
24
+ type: FactorAuthType;
25
+ user_id: Int8;
26
+ }
27
+ export interface NotificationSettings {
28
+ added_to_dm: Generated<boolean | null>;
29
+ direct_call: Generated<boolean | null>;
30
+ direct_message: Generated<boolean | null>;
31
+ group_dm_mention: Generated<boolean | null>;
32
+ group_dm_message: Generated<boolean | null>;
33
+ id: Generated<Int8>;
34
+ server_everyone_mention: Generated<boolean | null>;
35
+ server_mention: Generated<boolean | null>;
36
+ server_reply: Generated<boolean | null>;
37
+ user_id: Int8;
38
+ }
39
+ export interface Passkeys {
40
+ counter: Int8;
41
+ id: Generated<Int8>;
42
+ key_id: Buffer;
43
+ name: string | null;
44
+ public_key: Buffer;
45
+ transports: string[] | null;
46
+ user_id: Int8;
47
+ }
48
+ export interface Pgmigrations {
49
+ id: Generated<Int8>;
50
+ name: string;
51
+ run_on: Timestamp;
52
+ }
53
+ export interface SecureTokens {
54
+ created_at: Generated<Timestamp>;
55
+ expiry_at: Timestamp;
56
+ id: Generated<Int8>;
57
+ token_uuid: string;
58
+ user_id: Int8;
59
+ }
60
+ export interface Tokens {
61
+ app: AppType | null;
62
+ created_at: Generated<Timestamp>;
63
+ expiry_at: Timestamp;
64
+ fcm_token: string | null;
65
+ id: Generated<Int8>;
66
+ refresh_token: string;
67
+ user_id: Int8;
68
+ }
69
+ export interface Users {
70
+ created_at: Generated<Timestamp>;
71
+ disabled: Generated<boolean | null>;
72
+ icon_url: string | null;
73
+ id: Generated<Int8>;
74
+ is_admin: Generated<boolean | null>;
75
+ password_hash: string;
76
+ username: string;
77
+ }
78
+ export interface UserVerifications {
79
+ created_at: Generated<Timestamp>;
80
+ data: string | null;
81
+ expiry_at: Timestamp;
82
+ id: Generated<Int8>;
83
+ is_verified: Generated<boolean | null>;
84
+ ownership_code: string;
85
+ type: VerificationType;
86
+ user_id: Int8;
87
+ }
88
+ export interface DB {
89
+ auth_apps: AuthApps;
90
+ factor_authentication: FactorAuthentication;
91
+ notification_settings: NotificationSettings;
92
+ passkeys: Passkeys;
93
+ pgmigrations: Pgmigrations;
94
+ secure_tokens: SecureTokens;
95
+ tokens: Tokens;
96
+ user_verifications: UserVerifications;
97
+ users: Users;
98
+ }
99
+ //# sourceMappingURL=dataTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataTypes.d.ts","sourceRoot":"","sources":["../../src/database/dataTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * This file was generated by kysely-codegen.
4
+ * Please do not edit it manually.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=dataTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataTypes.js","sourceRoot":"","sources":["../../src/database/dataTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
@@ -1,9 +1,8 @@
1
- import { PoolConfig as CockroachOptions } from 'pg';
2
-
3
- /**
4
- * Configuration for connecting to a CockroachDB cluster.
5
- * This extends the 'pg' PoolConfig type for full compatibility.
6
- */
7
- export interface CockroachConfig extends CockroachOptions {
8
- // You can add custom properties here if needed
9
- }
1
+ import { PoolConfig as CockroachOptions } from 'pg';
2
+ /**
3
+ * Configuration for connecting to a CockroachDB cluster.
4
+ * This extends the 'pg' PoolConfig type for full compatibility.
5
+ */
6
+ export interface CockroachConfig extends CockroachOptions {
7
+ }
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,IAAI,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;CAExD"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { EstopiaRequest } from '../../types/request';
2
+ /**
3
+ * Middleware to require authentication.
4
+ * - Supports Authorization: Bearer <token> header (case-insensitive)
5
+ * - Falls back to cookies.auth_token
6
+ * - On success: sets req.auth = { ...payload, token } and calls next()
7
+ * - On failure: responds with 401 and an appropriate error message
8
+ */
9
+ export declare function requireAuth(req: EstopiaRequest, res: any, next: any): any;
10
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/helpers/middlware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,OA4CnE"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requireAuth = requireAuth;
4
+ const validateJWTToken_1 = require("../validateJWTToken");
5
+ /**
6
+ * Middleware to require authentication.
7
+ * - Supports Authorization: Bearer <token> header (case-insensitive)
8
+ * - Falls back to cookies.auth_token
9
+ * - On success: sets req.auth = { ...payload, token } and calls next()
10
+ * - On failure: responds with 401 and an appropriate error message
11
+ */
12
+ function requireAuth(req, res, next) {
13
+ // Get Authorization header (many frameworks provide case-insensitive header lookup)
14
+ const authHeader = typeof req.header === 'function' ? req.header('Authorization') : undefined;
15
+ // Extract token from "Bearer <token>" or use header value directly
16
+ let token;
17
+ if (typeof authHeader === 'string' && authHeader.trim() !== '') {
18
+ const bearerMatch = authHeader.match(/^\s*Bearer\s+(.+)\s*$/i);
19
+ token = bearerMatch ? bearerMatch[1] : authHeader.trim();
20
+ }
21
+ // Fallback to cookie
22
+ if (!token && req && req.cookies && typeof req.cookies.auth_token === 'string') {
23
+ token = req.cookies.auth_token;
24
+ }
25
+ if (!token) {
26
+ return res.status(401).json({ error: 'Missing authorization token' });
27
+ }
28
+ try {
29
+ const payload = (0, validateJWTToken_1.validateJWTToken)(token);
30
+ if (!payload) {
31
+ return res.status(401).json({ error: 'Invalid token' });
32
+ }
33
+ // Attach auth info to request
34
+ req.auth = { ...payload, token };
35
+ return next();
36
+ }
37
+ catch (err) {
38
+ // Log warning if logger available, otherwise fallback to console
39
+ try {
40
+ if (req && req.logger && typeof req.logger.warn === 'function') {
41
+ req.logger.warn('Auth verification failed', err);
42
+ }
43
+ else {
44
+ // Keep message concise for logs
45
+ // eslint-disable-next-line no-console
46
+ console.warn('Auth verification failed', err);
47
+ }
48
+ }
49
+ catch {
50
+ // swallow logging errors
51
+ }
52
+ return res.status(401).json({ error: 'Invalid authorization' });
53
+ }
54
+ }
55
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/helpers/middlware/auth.ts"],"names":[],"mappings":";;AAUA,kCA4CC;AArDD,0DAAuD;AAEvD;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,GAAmB,EAAE,GAAQ,EAAE,IAAS;IAClE,oFAAoF;IACpF,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9F,mEAAmE;IACnE,IAAI,KAAyB,CAAC;IAC9B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/D,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC/D,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC/E,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,8BAA8B;QAC9B,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC;QACjC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,iEAAiE;QACjE,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC/D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,gCAAgC;gBAChC,sCAAsC;gBACtC,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;QACD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Response } from 'express';
2
+ import { EstopiaRequest } from '../../types/request';
3
+ /**
4
+ * Middleware to require authentication.
5
+ * - Supports Authorization: Bearer <token> header (case-insensitive)
6
+ * - Falls back to cookies.auth_token
7
+ * - On success: sets req.auth = { ...payload, token } and calls next()
8
+ * - On failure: responds with 401 and an appropriate error message
9
+ */
10
+ export declare function requireSecure(req: EstopiaRequest, res: Response, next: any): Promise<any>;
11
+ //# sourceMappingURL=secure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure.d.ts","sourceRoot":"","sources":["../../../src/helpers/middlware/secure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,gBAmChF"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requireSecure = requireSecure;
4
+ /**
5
+ * Middleware to require authentication.
6
+ * - Supports Authorization: Bearer <token> header (case-insensitive)
7
+ * - Falls back to cookies.auth_token
8
+ * - On success: sets req.auth = { ...payload, token } and calls next()
9
+ * - On failure: responds with 401 and an appropriate error message
10
+ */
11
+ async function requireSecure(req, res, next) {
12
+ // This middleware only validates the Secure-Token cookie against the DB.
13
+ // It does NOT require a valid JWT — per request: "it doesn't matter if the JWT token exists".
14
+ // Read secure token from cookie
15
+ const secureToken = req && req.cookies['Secure-Token'];
16
+ if (!secureToken) {
17
+ return res.status(403).json({ error: 'Missing secure token' });
18
+ }
19
+ // Expect a Kysely DB instance to be available on app.locals.db
20
+ const cockroachPool = req.cockroachPool;
21
+ try {
22
+ const db = cockroachPool;
23
+ // Query secure_tokens table by token_uuid
24
+ const row = await db.selectFrom('secure_tokens').selectAll().where('token_uuid', '=', secureToken).executeTakeFirst();
25
+ if (!row) {
26
+ return res.status(403).json({ error: 'Secure token not found' });
27
+ }
28
+ // expiry_at may be a Date or string depending on driver; normalize
29
+ const expiry = row.expiry_at ? new Date(row.expiry_at) : null;
30
+ if (!expiry || expiry.getTime() <= Date.now()) {
31
+ return res.status(403).json({ error: 'Secure token expired' });
32
+ }
33
+ // Attach minimal auth context to request (no JWT required)
34
+ req.auth = { secureToken, userId: row.user_id.toString() };
35
+ return next();
36
+ }
37
+ catch (err) {
38
+ console.error('Failed to validate secure token', err?.message || err);
39
+ return res.status(500).json({ error: 'Failed to validate secure token' });
40
+ }
41
+ }
42
+ //# sourceMappingURL=secure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secure.js","sourceRoot":"","sources":["../../../src/helpers/middlware/secure.ts"],"names":[],"mappings":";;AAYA,sCAmCC;AA1CD;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CAAC,GAAmB,EAAE,GAAa,EAAE,IAAS;IAC/E,yEAAyE;IACzE,8FAA8F;IAE9F,gCAAgC;IAChC,MAAM,WAAW,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,+DAA+D;IAC/D,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,aAA2B,CAAC;QACvC,0CAA0C;QAC1C,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAEtH,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,mEAAmE;QACnE,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,2DAA2D;QAC3D,GAAG,CAAC,IAAI,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC3D,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface DecodedJWT {
2
+ userId: string;
3
+ jti?: string;
4
+ iat?: number;
5
+ exp?: number;
6
+ }
7
+ /**
8
+ * Verify a JWT and return the decoded payload. Throws on invalid/expired token.
9
+ */
10
+ export declare function validateJWTToken(token: string): DecodedJWT;
11
+ /**
12
+ * Try to verify a token and return the decoded payload, or null if invalid.
13
+ */
14
+ export declare function tryValidateJWTToken(token: string): DecodedJWT | null;
15
+ export default validateJWTToken;
16
+ //# sourceMappingURL=validateJWTToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateJWTToken.d.ts","sourceRoot":"","sources":["../../src/helpers/validateJWTToken.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAS1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAMpE;AAED,eAAe,gBAAgB,CAAC"}