fastify-wrap 0.1.0

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 (150) hide show
  1. package/README.md +980 -0
  2. package/dist/src/client/TestClient.d.ts +33 -0
  3. package/dist/src/client/TestClient.d.ts.map +1 -0
  4. package/dist/src/client/TestClient.js +359 -0
  5. package/dist/src/client/TestClient.js.map +1 -0
  6. package/dist/src/client/index.d.ts +4 -0
  7. package/dist/src/client/index.d.ts.map +1 -0
  8. package/dist/src/client/index.js +3 -0
  9. package/dist/src/client/index.js.map +1 -0
  10. package/dist/src/client/sign.d.ts +12 -0
  11. package/dist/src/client/sign.d.ts.map +1 -0
  12. package/dist/src/client/sign.js +44 -0
  13. package/dist/src/client/sign.js.map +1 -0
  14. package/dist/src/client/types.d.ts +41 -0
  15. package/dist/src/client/types.d.ts.map +1 -0
  16. package/dist/src/client/types.js +20 -0
  17. package/dist/src/client/types.js.map +1 -0
  18. package/dist/src/common/auth/AuthStrategy.d.ts +6 -0
  19. package/dist/src/common/auth/AuthStrategy.d.ts.map +1 -0
  20. package/dist/src/common/auth/AuthStrategy.js +2 -0
  21. package/dist/src/common/auth/AuthStrategy.js.map +1 -0
  22. package/dist/src/common/auth/JwtStrategy.d.ts +9 -0
  23. package/dist/src/common/auth/JwtStrategy.d.ts.map +1 -0
  24. package/dist/src/common/auth/JwtStrategy.js +34 -0
  25. package/dist/src/common/auth/JwtStrategy.js.map +1 -0
  26. package/dist/src/common/auth/NonceStore.d.ts +22 -0
  27. package/dist/src/common/auth/NonceStore.d.ts.map +1 -0
  28. package/dist/src/common/auth/NonceStore.js +27 -0
  29. package/dist/src/common/auth/NonceStore.js.map +1 -0
  30. package/dist/src/common/auth/SecretResolvers.d.ts +18 -0
  31. package/dist/src/common/auth/SecretResolvers.d.ts.map +1 -0
  32. package/dist/src/common/auth/SecretResolvers.js +30 -0
  33. package/dist/src/common/auth/SecretResolvers.js.map +1 -0
  34. package/dist/src/common/auth/SignatureStrategy.d.ts +23 -0
  35. package/dist/src/common/auth/SignatureStrategy.d.ts.map +1 -0
  36. package/dist/src/common/auth/SignatureStrategy.js +115 -0
  37. package/dist/src/common/auth/SignatureStrategy.js.map +1 -0
  38. package/dist/src/common/auth/index.d.ts +4 -0
  39. package/dist/src/common/auth/index.d.ts.map +1 -0
  40. package/dist/src/common/auth/index.js +3 -0
  41. package/dist/src/common/auth/index.js.map +1 -0
  42. package/dist/src/common/auth/signToken.d.ts +4 -0
  43. package/dist/src/common/auth/signToken.d.ts.map +1 -0
  44. package/dist/src/common/auth/signToken.js +11 -0
  45. package/dist/src/common/auth/signToken.js.map +1 -0
  46. package/dist/src/common/config/loader.d.ts +10 -0
  47. package/dist/src/common/config/loader.d.ts.map +1 -0
  48. package/dist/src/common/config/loader.js +20 -0
  49. package/dist/src/common/config/loader.js.map +1 -0
  50. package/dist/src/common/container/index.d.ts +7 -0
  51. package/dist/src/common/container/index.d.ts.map +1 -0
  52. package/dist/src/common/container/index.js +15 -0
  53. package/dist/src/common/container/index.js.map +1 -0
  54. package/dist/src/common/db/index.d.ts +19 -0
  55. package/dist/src/common/db/index.d.ts.map +1 -0
  56. package/dist/src/common/db/index.js +64 -0
  57. package/dist/src/common/db/index.js.map +1 -0
  58. package/dist/src/common/dto/PageResult.d.ts +12 -0
  59. package/dist/src/common/dto/PageResult.d.ts.map +1 -0
  60. package/dist/src/common/dto/PageResult.js +2 -0
  61. package/dist/src/common/dto/PageResult.js.map +1 -0
  62. package/dist/src/common/errorHandler.d.ts +3 -0
  63. package/dist/src/common/errorHandler.d.ts.map +1 -0
  64. package/dist/src/common/errorHandler.js +47 -0
  65. package/dist/src/common/errorHandler.js.map +1 -0
  66. package/dist/src/common/exceptions/AuthException.d.ts +5 -0
  67. package/dist/src/common/exceptions/AuthException.d.ts.map +1 -0
  68. package/dist/src/common/exceptions/AuthException.js +8 -0
  69. package/dist/src/common/exceptions/AuthException.js.map +1 -0
  70. package/dist/src/common/exceptions/BaseException.d.ts +4 -0
  71. package/dist/src/common/exceptions/BaseException.d.ts.map +1 -0
  72. package/dist/src/common/exceptions/BaseException.js +7 -0
  73. package/dist/src/common/exceptions/BaseException.js.map +1 -0
  74. package/dist/src/common/exceptions/BusinessException.d.ts +5 -0
  75. package/dist/src/common/exceptions/BusinessException.d.ts.map +1 -0
  76. package/dist/src/common/exceptions/BusinessException.js +8 -0
  77. package/dist/src/common/exceptions/BusinessException.js.map +1 -0
  78. package/dist/src/common/exceptions/NotFoundException.d.ts +5 -0
  79. package/dist/src/common/exceptions/NotFoundException.d.ts.map +1 -0
  80. package/dist/src/common/exceptions/NotFoundException.js +8 -0
  81. package/dist/src/common/exceptions/NotFoundException.js.map +1 -0
  82. package/dist/src/common/exceptions/ServiceException.d.ts +5 -0
  83. package/dist/src/common/exceptions/ServiceException.d.ts.map +1 -0
  84. package/dist/src/common/exceptions/ServiceException.js +8 -0
  85. package/dist/src/common/exceptions/ServiceException.js.map +1 -0
  86. package/dist/src/common/exceptions/index.d.ts +6 -0
  87. package/dist/src/common/exceptions/index.d.ts.map +1 -0
  88. package/dist/src/common/exceptions/index.js +6 -0
  89. package/dist/src/common/exceptions/index.js.map +1 -0
  90. package/dist/src/common/migrate/index.d.ts +3 -0
  91. package/dist/src/common/migrate/index.d.ts.map +1 -0
  92. package/dist/src/common/migrate/index.js +49 -0
  93. package/dist/src/common/migrate/index.js.map +1 -0
  94. package/dist/src/common/redis/index.d.ts +14 -0
  95. package/dist/src/common/redis/index.d.ts.map +1 -0
  96. package/dist/src/common/redis/index.js +41 -0
  97. package/dist/src/common/redis/index.js.map +1 -0
  98. package/dist/src/common/scanner/auth-factory.d.ts +42 -0
  99. package/dist/src/common/scanner/auth-factory.d.ts.map +1 -0
  100. package/dist/src/common/scanner/auth-factory.js +86 -0
  101. package/dist/src/common/scanner/auth-factory.js.map +1 -0
  102. package/dist/src/common/scanner/decorators.d.ts +123 -0
  103. package/dist/src/common/scanner/decorators.d.ts.map +1 -0
  104. package/dist/src/common/scanner/decorators.js +158 -0
  105. package/dist/src/common/scanner/decorators.js.map +1 -0
  106. package/dist/src/common/scanner/handler-factory.d.ts +38 -0
  107. package/dist/src/common/scanner/handler-factory.d.ts.map +1 -0
  108. package/dist/src/common/scanner/handler-factory.js +76 -0
  109. package/dist/src/common/scanner/handler-factory.js.map +1 -0
  110. package/dist/src/common/scanner/index.d.ts +16 -0
  111. package/dist/src/common/scanner/index.d.ts.map +1 -0
  112. package/dist/src/common/scanner/index.js +157 -0
  113. package/dist/src/common/scanner/index.js.map +1 -0
  114. package/dist/src/common/validation/decorators.d.ts +28 -0
  115. package/dist/src/common/validation/decorators.d.ts.map +1 -0
  116. package/dist/src/common/validation/decorators.js +70 -0
  117. package/dist/src/common/validation/decorators.js.map +1 -0
  118. package/dist/src/common/validation/errorRules.d.ts +5 -0
  119. package/dist/src/common/validation/errorRules.d.ts.map +1 -0
  120. package/dist/src/common/validation/errorRules.js +56 -0
  121. package/dist/src/common/validation/errorRules.js.map +1 -0
  122. package/dist/src/common/validation/index.d.ts +4 -0
  123. package/dist/src/common/validation/index.d.ts.map +1 -0
  124. package/dist/src/common/validation/index.js +3 -0
  125. package/dist/src/common/validation/index.js.map +1 -0
  126. package/dist/src/common/validation/schema.d.ts +35 -0
  127. package/dist/src/common/validation/schema.d.ts.map +1 -0
  128. package/dist/src/common/validation/schema.js +67 -0
  129. package/dist/src/common/validation/schema.js.map +1 -0
  130. package/dist/src/index.d.ts +26 -0
  131. package/dist/src/index.d.ts.map +1 -0
  132. package/dist/src/index.js +293 -0
  133. package/dist/src/index.js.map +1 -0
  134. package/dist/src/main.d.ts +2 -0
  135. package/dist/src/main.d.ts.map +1 -0
  136. package/dist/src/main.js +27 -0
  137. package/dist/src/main.js.map +1 -0
  138. package/dist/src/modules/health/controller/HealthController.d.ts +11 -0
  139. package/dist/src/modules/health/controller/HealthController.d.ts.map +1 -0
  140. package/dist/src/modules/health/controller/HealthController.js +31 -0
  141. package/dist/src/modules/health/controller/HealthController.js.map +1 -0
  142. package/dist/src/modules/health/service/HealthService.d.ts +4 -0
  143. package/dist/src/modules/health/service/HealthService.d.ts.map +1 -0
  144. package/dist/src/modules/health/service/HealthService.js +6 -0
  145. package/dist/src/modules/health/service/HealthService.js.map +1 -0
  146. package/dist/src/types.d.ts +75 -0
  147. package/dist/src/types.d.ts.map +1 -0
  148. package/dist/src/types.js +2 -0
  149. package/dist/src/types.js.map +1 -0
  150. package/package.json +53 -0
@@ -0,0 +1,33 @@
1
+ import type { Logger, ErrorHandler, Response, TestClientOptions } from './types';
2
+ export declare class TestClient {
3
+ private options;
4
+ private logger;
5
+ private refreshingPromise;
6
+ constructor(options: TestClientOptions);
7
+ /** Convenience: construct from a fixed credential. */
8
+ static withCredential(baseUrl: string, appKey: string, appSecret: string, logger?: boolean | Logger): TestClient;
9
+ get<T = unknown>(path: string, error?: ErrorHandler): Promise<T>;
10
+ post<T = unknown>(path: string, body?: unknown, error?: ErrorHandler): Promise<T>;
11
+ put<T = unknown>(path: string, body?: unknown, error?: ErrorHandler): Promise<T>;
12
+ delete<T = unknown>(path: string, error?: ErrorHandler): Promise<T>;
13
+ /** Upload a file with JSON metadata. jsonBody is signed; file is attached as multipart. */
14
+ upload<T = unknown>(path: string, jsonBody: Record<string, unknown>, file: {
15
+ data: Buffer | Uint8Array;
16
+ filename: string;
17
+ mimetype?: string;
18
+ }, error?: ErrorHandler): Promise<T>;
19
+ /** Download a file. Returns blob response. */
20
+ blob(path: string): Promise<Response<Blob>>;
21
+ /** POST that returns a blob response (e.g. file download with body params). */
22
+ postBlob(path: string, data?: unknown): Promise<Response<Blob>>;
23
+ private request;
24
+ private executeWithError;
25
+ private retryWithFreshCredential;
26
+ private dispatchError;
27
+ private shouldSkipAuth;
28
+ private logReq;
29
+ private logRes;
30
+ private logErr;
31
+ }
32
+ export declare function createTestClient(options: TestClientOptions): TestClient;
33
+ //# sourceMappingURL=TestClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestClient.d.ts","sourceRoot":"","sources":["../../../src/client/TestClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA6BjF,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,iBAAiB,CAA6B;gBAE1C,OAAO,EAAE,iBAAiB;IAMtC,sDAAsD;IACtD,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU;IAQ1G,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAIjF,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAIhF,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAIzE,2FAA2F;IACrF,MAAM,CAAC,CAAC,GAAG,OAAO,EACtB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EACxE,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,CAAC,CAAC;IAgCb,8CAA8C;IACxC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IA0CjD,+EAA+E;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YA8CvD,OAAO;YA6BP,gBAAgB;YAqDhB,wBAAwB;IAsEtC,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,MAAM;CAUf;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAEvE"}
@@ -0,0 +1,359 @@
1
+ import { signRequest } from './sign';
2
+ import { ApiError, IOException } from './types';
3
+ function resolveLogger(opt) {
4
+ if (opt === undefined || opt === false) {
5
+ return null;
6
+ }
7
+ if (opt === true) {
8
+ return console;
9
+ }
10
+ return opt;
11
+ }
12
+ function extractMessage(statusCode, body) {
13
+ if (body !== null && typeof body === 'object') {
14
+ const b = body;
15
+ if (typeof b.message === 'string')
16
+ return b.message;
17
+ if (typeof b.error === 'string')
18
+ return b.error;
19
+ }
20
+ return `HTTP ${statusCode}`;
21
+ }
22
+ function parseContentDisposition(header) {
23
+ if (header === null)
24
+ return undefined;
25
+ const match = header.match(/filename\*?=(?:UTF-8''|utf-8'')?([^;\s]+)/i);
26
+ if (match !== null)
27
+ return decodeURIComponent(match[1]);
28
+ return undefined;
29
+ }
30
+ export class TestClient {
31
+ options;
32
+ logger;
33
+ refreshingPromise;
34
+ constructor(options) {
35
+ this.options = options;
36
+ this.logger = resolveLogger(options.logger);
37
+ this.refreshingPromise = null;
38
+ }
39
+ /** Convenience: construct from a fixed credential. */
40
+ static withCredential(baseUrl, appKey, appSecret, logger) {
41
+ return new TestClient({
42
+ baseUrl,
43
+ getCredential: () => ({ appKey, appSecret }),
44
+ logger,
45
+ });
46
+ }
47
+ async get(path, error) {
48
+ return this.request('GET', path, undefined, error);
49
+ }
50
+ async post(path, body, error) {
51
+ return this.request('POST', path, body, error);
52
+ }
53
+ async put(path, body, error) {
54
+ return this.request('PUT', path, body, error);
55
+ }
56
+ async delete(path, error) {
57
+ return this.request('DELETE', path, undefined, error);
58
+ }
59
+ /** Upload a file with JSON metadata. jsonBody is signed; file is attached as multipart. */
60
+ async upload(path, jsonBody, file, error) {
61
+ const skipAuth = this.shouldSkipAuth(path);
62
+ const cred = skipAuth ? null : this.options.getCredential();
63
+ const signHeaders = cred
64
+ ? signRequest(cred, 'POST', this.options.baseUrl + path, jsonBody)
65
+ : null;
66
+ const url = this.options.baseUrl + path;
67
+ const boundary = `----NodeTestClient${Date.now()}`;
68
+ const body = buildMultipartBody(boundary, jsonBody, file);
69
+ const init = {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`,
73
+ },
74
+ body,
75
+ };
76
+ if (signHeaders !== null) {
77
+ Object.assign(init.headers, signHeaders);
78
+ }
79
+ const token = this.options.getToken?.() ?? null;
80
+ if (token !== null) {
81
+ init.headers['Authorization'] = `Bearer ${token}`;
82
+ }
83
+ this.logReq('POST', url, signHeaders, jsonBody);
84
+ return this.executeWithError('POST', url, init, error);
85
+ }
86
+ /** Download a file. Returns blob response. */
87
+ async blob(path) {
88
+ const skipAuth = this.shouldSkipAuth(path);
89
+ const cred = skipAuth ? null : this.options.getCredential();
90
+ const signHeaders = cred
91
+ ? signRequest(cred, 'GET', this.options.baseUrl + path, undefined)
92
+ : null;
93
+ const url = this.options.baseUrl + path;
94
+ const headers = {
95
+ 'Content-Type': 'application/json',
96
+ };
97
+ if (signHeaders !== null) {
98
+ Object.assign(headers, signHeaders);
99
+ }
100
+ const token = this.options.getToken?.() ?? null;
101
+ if (token !== null) {
102
+ headers['Authorization'] = `Bearer ${token}`;
103
+ }
104
+ this.logReq('GET', url, signHeaders, undefined);
105
+ let res;
106
+ try {
107
+ res = await fetch(url, { method: 'GET', headers });
108
+ }
109
+ catch (e) {
110
+ this.logErr('GET', url, e);
111
+ throw new IOException(e instanceof Error ? e : new Error(String(e)));
112
+ }
113
+ const blobData = await res.blob();
114
+ const filename = parseContentDisposition(res.headers.get('Content-Disposition'));
115
+ if (res.status === 401) {
116
+ this.options.onLoginRequired?.();
117
+ this.logRes('GET', url, res.status, `[Blob ${blobData.size}B ${blobData.type}]`);
118
+ return { status: res.status, body: blobData, filename };
119
+ }
120
+ this.logRes('GET', url, res.status, `[Blob ${blobData.size}B ${blobData.type}]`);
121
+ return { status: res.status, body: blobData, filename };
122
+ }
123
+ /** POST that returns a blob response (e.g. file download with body params). */
124
+ async postBlob(path, data) {
125
+ const skipAuth = this.shouldSkipAuth(path);
126
+ const cred = skipAuth ? null : this.options.getCredential();
127
+ const signHeaders = cred
128
+ ? signRequest(cred, 'POST', this.options.baseUrl + path, data)
129
+ : null;
130
+ const url = this.options.baseUrl + path;
131
+ const headers = {};
132
+ if (signHeaders !== null) {
133
+ Object.assign(headers, signHeaders);
134
+ }
135
+ const token = this.options.getToken?.() ?? null;
136
+ if (token !== null) {
137
+ headers['Authorization'] = `Bearer ${token}`;
138
+ }
139
+ const init = { method: 'POST', headers };
140
+ if (data !== undefined) {
141
+ headers['Content-Type'] = 'application/json';
142
+ init.body = JSON.stringify(data);
143
+ }
144
+ this.logReq('POST', url, signHeaders, data);
145
+ let res;
146
+ try {
147
+ res = await fetch(url, init);
148
+ }
149
+ catch (e) {
150
+ this.logErr('POST', url, e);
151
+ throw new IOException(e instanceof Error ? e : new Error(String(e)));
152
+ }
153
+ const blobData = await res.blob();
154
+ const filename = parseContentDisposition(res.headers.get('Content-Disposition'));
155
+ if (res.status === 401) {
156
+ this.options.onLoginRequired?.();
157
+ this.logRes('POST', url, res.status, `[Blob ${blobData.size}B ${blobData.type}]`);
158
+ return { status: res.status, body: blobData, filename };
159
+ }
160
+ this.logRes('POST', url, res.status, `[Blob ${blobData.size}B ${blobData.type}]`);
161
+ return { status: res.status, body: blobData, filename };
162
+ }
163
+ async request(method, path, body, error) {
164
+ const skipAuth = this.shouldSkipAuth(path);
165
+ const cred = skipAuth ? null : this.options.getCredential();
166
+ const signHeaders = cred
167
+ ? signRequest(cred, method, this.options.baseUrl + path, body)
168
+ : null;
169
+ const url = this.options.baseUrl + path;
170
+ const headers = {
171
+ 'Content-Type': 'application/json',
172
+ };
173
+ if (signHeaders !== null) {
174
+ Object.assign(headers, signHeaders);
175
+ }
176
+ const token = this.options.getToken?.() ?? null;
177
+ if (token !== null) {
178
+ headers['Authorization'] = `Bearer ${token}`;
179
+ }
180
+ const init = { method, headers };
181
+ if (body !== undefined) {
182
+ init.body = JSON.stringify(body);
183
+ }
184
+ this.logReq(method, url, signHeaders, body);
185
+ return this.executeWithError(method, url, init, error);
186
+ }
187
+ async executeWithError(method, url, init, error) {
188
+ let res;
189
+ try {
190
+ res = await fetch(url, init);
191
+ }
192
+ catch (e) {
193
+ this.logErr(method, url, e);
194
+ throw new IOException(e instanceof Error ? e : new Error(String(e)));
195
+ }
196
+ const rawText = await res.text();
197
+ let resBody;
198
+ try {
199
+ resBody = JSON.parse(rawText);
200
+ }
201
+ catch (e) {
202
+ this.logErr(method, url, e, rawText);
203
+ throw e;
204
+ }
205
+ // 401 handling
206
+ if (res.status === 401) {
207
+ const errorCode = resBody?.code;
208
+ // code=retry → refresh credential and retry once
209
+ if (errorCode === 'retry') {
210
+ this.logRes(method, url, res.status, resBody);
211
+ return this.retryWithFreshCredential(method, url, init, resBody);
212
+ }
213
+ // code=login → trigger login redirect
214
+ if (errorCode === 'login') {
215
+ this.logRes(method, url, res.status, resBody);
216
+ this.options.onLoginRequired?.();
217
+ throw new ApiError(res.status, extractMessage(res.status, resBody), errorCode, resBody);
218
+ }
219
+ }
220
+ this.logRes(method, url, res.status, resBody);
221
+ if (res.status === 200) {
222
+ return resBody;
223
+ }
224
+ const errCode = resBody?.code;
225
+ const apiErr = new ApiError(res.status, extractMessage(res.status, resBody), errCode, resBody);
226
+ this.dispatchError(error, apiErr.message);
227
+ throw apiErr;
228
+ }
229
+ async retryWithFreshCredential(method, url, originalInit, originalBody) {
230
+ const appKey = this.options.getCredential().appKey;
231
+ if (this.refreshingPromise === null) {
232
+ const refreshFn = this.options.refreshCredential;
233
+ if (refreshFn === undefined) {
234
+ throw new ApiError(401, extractMessage(401, originalBody), 'retry', originalBody);
235
+ }
236
+ this.refreshingPromise = refreshFn(appKey);
237
+ }
238
+ let newCred;
239
+ try {
240
+ newCred = await this.refreshingPromise;
241
+ }
242
+ catch (e) {
243
+ this.refreshingPromise = null;
244
+ throw e;
245
+ }
246
+ this.refreshingPromise = null;
247
+ const retryHeaders = signRequest(newCred, method, url, originalInit.body);
248
+ const retryInit = {
249
+ method,
250
+ headers: {
251
+ 'Content-Type': 'application/json',
252
+ ...retryHeaders,
253
+ },
254
+ };
255
+ if (originalInit.body !== undefined) {
256
+ retryInit.body = originalInit.body;
257
+ }
258
+ const retryToken = this.options.getToken?.() ?? null;
259
+ if (retryToken !== null) {
260
+ retryInit.headers['Authorization'] = `Bearer ${retryToken}`;
261
+ }
262
+ this.logReq(method, url, retryHeaders, originalInit.body);
263
+ let retryRes;
264
+ try {
265
+ retryRes = await fetch(url, retryInit);
266
+ }
267
+ catch (e) {
268
+ this.logErr(method, url, e);
269
+ throw new IOException(e instanceof Error ? e : new Error(String(e)));
270
+ }
271
+ const retryRawText = await retryRes.text();
272
+ let retryBody;
273
+ try {
274
+ retryBody = JSON.parse(retryRawText);
275
+ }
276
+ catch (e) {
277
+ this.logErr(method, url, e, retryRawText);
278
+ throw e;
279
+ }
280
+ this.logRes(method, url, retryRes.status, retryBody);
281
+ if (retryRes.status === 200) {
282
+ return retryBody;
283
+ }
284
+ const retryErrCode = retryBody?.code;
285
+ const apiErr = new ApiError(retryRes.status, extractMessage(retryRes.status, retryBody), retryErrCode, retryBody);
286
+ throw apiErr;
287
+ }
288
+ dispatchError(handler, message) {
289
+ const h = handler ?? 'toast';
290
+ if (h === 'toast') {
291
+ this.options.toast?.(message);
292
+ }
293
+ else if (h === 'alert') {
294
+ this.options.alert?.(message);
295
+ }
296
+ else {
297
+ h(message);
298
+ }
299
+ }
300
+ shouldSkipAuth(path) {
301
+ const skipPaths = this.options.skipAuthPaths;
302
+ if (skipPaths === undefined) {
303
+ return false;
304
+ }
305
+ return skipPaths.includes(path);
306
+ }
307
+ logReq(method, url, headers, body) {
308
+ const l = this.logger;
309
+ if (l === null)
310
+ return;
311
+ const payload = { method, url };
312
+ if (headers !== null) {
313
+ payload.headers = {
314
+ 'x-app-key': headers['x-app-key'],
315
+ 'x-timestamp': headers['x-timestamp'],
316
+ 'x-nonce': headers['x-nonce'],
317
+ 'x-signature': headers['x-signature'].substring(0, 16) + '...',
318
+ };
319
+ }
320
+ if (body !== undefined) {
321
+ payload.body = body;
322
+ }
323
+ l.log(`[test-client] REQ ${JSON.stringify(payload)}`);
324
+ }
325
+ logRes(method, url, status, body) {
326
+ const l = this.logger;
327
+ if (l === null)
328
+ return;
329
+ l.log(`[test-client] RES ${JSON.stringify({ method, url, status, body })}`);
330
+ }
331
+ logErr(method, url, err, rawText) {
332
+ const l = this.logger;
333
+ if (l === null)
334
+ return;
335
+ const msg = err instanceof Error ? err.message : String(err);
336
+ const payload = { method, url, error: msg };
337
+ if (rawText !== undefined) {
338
+ payload.raw = rawText.substring(0, 500);
339
+ }
340
+ l.log(`[test-client] ERR ${JSON.stringify(payload)}`);
341
+ }
342
+ }
343
+ export function createTestClient(options) {
344
+ return new TestClient(options);
345
+ }
346
+ function buildMultipartBody(boundary, jsonBody, file) {
347
+ const mime = file.mimetype ?? 'application/octet-stream';
348
+ const parts = [];
349
+ parts.push(Buffer.from(`--${boundary}\r\n`));
350
+ parts.push(Buffer.from(`Content-Disposition: form-data; name="_sign_body"\r\n\r\n`));
351
+ parts.push(Buffer.from(JSON.stringify(jsonBody)));
352
+ parts.push(Buffer.from(`\r\n--${boundary}\r\n`));
353
+ parts.push(Buffer.from(`Content-Disposition: form-data; name="file"; filename="${file.filename}"\r\n`));
354
+ parts.push(Buffer.from(`Content-Type: ${mime}\r\n\r\n`));
355
+ parts.push(Buffer.from(file.data));
356
+ parts.push(Buffer.from(`\r\n--${boundary}--\r\n`));
357
+ return Buffer.concat(parts);
358
+ }
359
+ //# sourceMappingURL=TestClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../../src/client/TestClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { TestClient, createTestClient } from './TestClient';
2
+ export { ApiError, IOException } from './types';
3
+ export type { TestClientOptions, Response, Logger, ErrorHandler, Credential } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { TestClient, createTestClient } from './TestClient';
2
+ export { ApiError, IOException } from './types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface Credential {
2
+ appKey: string;
3
+ appSecret: string;
4
+ }
5
+ export interface SignHeaders {
6
+ 'x-app-key': string;
7
+ 'x-timestamp': string;
8
+ 'x-nonce': string;
9
+ 'x-signature': string;
10
+ }
11
+ export declare function signRequest(cred: Credential, method: string, path: string, body: unknown): SignHeaders;
12
+ //# sourceMappingURL=sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../../src/client/sign.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAkCD,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,WAAW,CAYtG"}
@@ -0,0 +1,44 @@
1
+ // Node.js HMAC signing — mirrors browser sign.ts exactly,
2
+ // but uses crypto.createHmac instead of Web Crypto API.
3
+ import { createHmac, randomUUID, randomBytes } from 'node:crypto';
4
+ function canonicalBody(body) {
5
+ if (body === null || body === undefined) {
6
+ return '';
7
+ }
8
+ if (typeof body !== 'object') {
9
+ return String(body);
10
+ }
11
+ const keys = Object.keys(body).sort();
12
+ return JSON.stringify(body, keys);
13
+ }
14
+ function buildStringToSign(method, path, timestamp, nonce, body) {
15
+ const parts = [method, path, timestamp, nonce, canonicalBody(body)];
16
+ return parts.join('\n');
17
+ }
18
+ function generateNonce() {
19
+ // Node 19+ has randomUUID; fall back to v4 via randomBytes
20
+ if (typeof randomUUID === 'function') {
21
+ return randomUUID();
22
+ }
23
+ return v4Fallback();
24
+ }
25
+ function v4Fallback() {
26
+ const bytes = randomBytes(16);
27
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
28
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
29
+ const hex = bytes.toString('hex');
30
+ return `${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${hex.substring(20, 32)}`;
31
+ }
32
+ export function signRequest(cred, method, path, body) {
33
+ const timestamp = Date.now().toString();
34
+ const nonce = generateNonce();
35
+ const stringToSign = buildStringToSign(method, path, timestamp, nonce, body);
36
+ const signature = createHmac('sha256', cred.appSecret).update(stringToSign).digest('base64');
37
+ return {
38
+ 'x-app-key': cred.appKey,
39
+ 'x-timestamp': timestamp,
40
+ 'x-nonce': nonce,
41
+ 'x-signature': signature,
42
+ };
43
+ }
44
+ //# sourceMappingURL=sign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.js","sourceRoot":"","sources":["../../../src/client/sign.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,wDAAwD;AAExD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAclE,SAAS,aAAa,CAAC,IAAa;IAClC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,GAAa,MAAM,CAAC,IAAI,CAAC,IAA+B,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc,EAAE,IAAY,EAAE,SAAiB,EAAE,KAAa,EAAE,IAAa;IACtG,MAAM,KAAK,GAAa,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,aAAa;IACpB,2DAA2D;IAC3D,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE,CAAC;QACrC,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,KAAK,GAAW,WAAW,CAAC,EAAE,CAAC,CAAC;IACtC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,MAAM,GAAG,GAAW,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;AACrI,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,MAAc,EAAE,IAAY,EAAE,IAAa;IACvF,MAAM,SAAS,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAChD,MAAM,KAAK,GAAW,aAAa,EAAE,CAAC;IACtC,MAAM,YAAY,GAAW,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACrF,MAAM,SAAS,GAAW,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAErG,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,MAAM;QACxB,aAAa,EAAE,SAAS;QACxB,SAAS,EAAE,KAAK;QAChB,aAAa,EAAE,SAAS;KACzB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Credential } from './sign';
2
+ export type { Credential };
3
+ export interface Logger {
4
+ log(message: string): void;
5
+ }
6
+ export type ErrorHandler = 'toast' | 'alert' | ((message: string) => void);
7
+ export interface TestClientOptions {
8
+ /** Base URL prepended to all paths, e.g. "http://127.0.0.1:3001". */
9
+ baseUrl: string;
10
+ /** Returns current credential. Called before each request. */
11
+ getCredential: () => Credential;
12
+ /** Called on 401 code:retry with current appKey to obtain a fresh credential. */
13
+ refreshCredential?: (appKey: string) => Promise<Credential>;
14
+ /** Enable logging. Pass true for console.log, or a custom Logger. */
15
+ logger?: boolean | Logger;
16
+ /** Returns current JWT token. null = not logged in. */
17
+ getToken?: () => string | null;
18
+ /** Called on 401 code:login to redirect user to login page. */
19
+ onLoginRequired?: () => void;
20
+ /** Paths that skip HMAC signing (e.g. login endpoint). */
21
+ skipAuthPaths?: string[];
22
+ /** Called by error dispatch when handler is 'toast'. */
23
+ toast?: (message: string) => void;
24
+ /** Called by error dispatch when handler is 'alert'. */
25
+ alert?: (message: string) => void;
26
+ }
27
+ export interface Response<T = unknown> {
28
+ status: number;
29
+ body: T;
30
+ filename?: string;
31
+ }
32
+ export declare class ApiError extends Error {
33
+ statusCode: number;
34
+ code?: string;
35
+ body?: unknown;
36
+ constructor(statusCode: number, message: string, code?: string, body?: unknown);
37
+ }
38
+ export declare class IOException extends Error {
39
+ constructor(cause: Error);
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,UAAU,CAAC;IAChC,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC/B,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wDAAwD;IACxD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEH,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;CAO/E;AAED,qBAAa,WAAY,SAAQ,KAAK;gBACxB,KAAK,EAAE,KAAK;CAKzB"}
@@ -0,0 +1,20 @@
1
+ export class ApiError extends Error {
2
+ statusCode;
3
+ code;
4
+ body;
5
+ constructor(statusCode, message, code, body) {
6
+ super(message);
7
+ this.name = 'ApiError';
8
+ this.statusCode = statusCode;
9
+ this.code = code;
10
+ this.body = body;
11
+ }
12
+ }
13
+ export class IOException extends Error {
14
+ constructor(cause) {
15
+ super(cause.message);
16
+ this.name = 'IOException';
17
+ this.cause = cause;
18
+ }
19
+ }
20
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/client/types.ts"],"names":[],"mappings":"AAqCA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,UAAU,CAAS;IACnB,IAAI,CAAU;IACd,IAAI,CAAW;IAEf,YAAY,UAAkB,EAAE,OAAe,EAAE,IAAa,EAAE,IAAc;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,KAAK;IACpC,YAAY,KAAY;QACtB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import type { FastifyRequest, FastifyReply } from 'fastify';
2
+ import type { User } from '../../types';
3
+ export interface AuthStrategy {
4
+ authenticate(request: FastifyRequest, reply: FastifyReply, moduleName?: string): Promise<User>;
5
+ }
6
+ //# sourceMappingURL=AuthStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthStrategy.d.ts","sourceRoot":"","sources":["../../../../src/common/auth/AuthStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AuthStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthStrategy.js","sourceRoot":"","sources":["../../../../src/common/auth/AuthStrategy.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify';
2
+ import type { AuthStrategy } from './AuthStrategy';
3
+ import type { User } from '../../types';
4
+ export declare class JwtStrategy implements AuthStrategy {
5
+ private fastify;
6
+ constructor(fastify: FastifyInstance);
7
+ authenticate(request: FastifyRequest, _reply: FastifyReply, _moduleName?: string): Promise<User>;
8
+ }
9
+ //# sourceMappingURL=JwtStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JwtStrategy.d.ts","sourceRoot":"","sources":["../../../../src/common/auth/JwtStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGxC,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,EAAE,eAAe;IAI9B,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BvG"}
@@ -0,0 +1,34 @@
1
+ import { redis } from '../redis/index';
2
+ export class JwtStrategy {
3
+ fastify;
4
+ constructor(fastify) {
5
+ this.fastify = fastify;
6
+ }
7
+ async authenticate(request, _reply, _moduleName) {
8
+ await request.jwtVerify();
9
+ const user = request.user;
10
+ // Check Redis blacklist: if user.type and id exist, verify not blacklisted.
11
+ // Redis failures are caught and degrade to pass-through.
12
+ if (user.type && user.id) {
13
+ const blacklistKey = `${user.type}_blacklist:${user.id}`;
14
+ try {
15
+ const blacklisted = await redis.exists(blacklistKey);
16
+ if (blacklisted) {
17
+ const err = new Error('账号或密码错误');
18
+ err.statusCode = 401;
19
+ throw err;
20
+ }
21
+ }
22
+ catch (err) {
23
+ const is401 = err.statusCode === 401;
24
+ if (is401) {
25
+ throw err;
26
+ }
27
+ // Redis unavailable — degrade to pass-through
28
+ this.fastify.log.warn({ blacklistKey, err }, 'Redis blacklist check failed, pass-through');
29
+ }
30
+ }
31
+ return user;
32
+ }
33
+ }
34
+ //# sourceMappingURL=JwtStrategy.js.map