@capsara/sdk 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 (139) hide show
  1. package/LICENSE +74 -0
  2. package/README.md +230 -0
  3. package/dist/builder/capsa-builder.d.ts +167 -0
  4. package/dist/builder/capsa-builder.d.ts.map +1 -0
  5. package/dist/builder/capsa-builder.js +489 -0
  6. package/dist/builder/capsa-builder.js.map +1 -0
  7. package/dist/client/capsara-client.d.ts +96 -0
  8. package/dist/client/capsara-client.d.ts.map +1 -0
  9. package/dist/client/capsara-client.js +266 -0
  10. package/dist/client/capsara-client.js.map +1 -0
  11. package/dist/errors/account-error.d.ts +73 -0
  12. package/dist/errors/account-error.d.ts.map +1 -0
  13. package/dist/errors/account-error.js +155 -0
  14. package/dist/errors/account-error.js.map +1 -0
  15. package/dist/errors/audit-error.d.ts +34 -0
  16. package/dist/errors/audit-error.d.ts.map +1 -0
  17. package/dist/errors/audit-error.js +93 -0
  18. package/dist/errors/audit-error.js.map +1 -0
  19. package/dist/errors/auth-error.d.ts +38 -0
  20. package/dist/errors/auth-error.d.ts.map +1 -0
  21. package/dist/errors/auth-error.js +87 -0
  22. package/dist/errors/auth-error.js.map +1 -0
  23. package/dist/errors/capsa-error.d.ts +64 -0
  24. package/dist/errors/capsa-error.d.ts.map +1 -0
  25. package/dist/errors/capsa-error.js +172 -0
  26. package/dist/errors/capsa-error.js.map +1 -0
  27. package/dist/errors/capsara-error.d.ts +52 -0
  28. package/dist/errors/capsara-error.d.ts.map +1 -0
  29. package/dist/errors/capsara-error.js +83 -0
  30. package/dist/errors/capsara-error.js.map +1 -0
  31. package/dist/errors/index.d.ts +8 -0
  32. package/dist/errors/index.d.ts.map +1 -0
  33. package/dist/errors/index.js +7 -0
  34. package/dist/errors/index.js.map +1 -0
  35. package/dist/index.d.ts +7 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +5 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/internal/capsa-cache.d.ts +49 -0
  40. package/dist/internal/capsa-cache.d.ts.map +1 -0
  41. package/dist/internal/capsa-cache.js +118 -0
  42. package/dist/internal/capsa-cache.js.map +1 -0
  43. package/dist/internal/config/http-client.d.ts +37 -0
  44. package/dist/internal/config/http-client.d.ts.map +1 -0
  45. package/dist/internal/config/http-client.js +63 -0
  46. package/dist/internal/config/http-client.js.map +1 -0
  47. package/dist/internal/config/retry-interceptor.d.ts +18 -0
  48. package/dist/internal/config/retry-interceptor.d.ts.map +1 -0
  49. package/dist/internal/config/retry-interceptor.js +103 -0
  50. package/dist/internal/config/retry-interceptor.js.map +1 -0
  51. package/dist/internal/crypto/compression.d.ts +15 -0
  52. package/dist/internal/crypto/compression.d.ts.map +1 -0
  53. package/dist/internal/crypto/compression.js +34 -0
  54. package/dist/internal/crypto/compression.js.map +1 -0
  55. package/dist/internal/crypto/key-generator.d.ts +23 -0
  56. package/dist/internal/crypto/key-generator.d.ts.map +1 -0
  57. package/dist/internal/crypto/key-generator.js +65 -0
  58. package/dist/internal/crypto/key-generator.js.map +1 -0
  59. package/dist/internal/crypto/primitives.d.ts +67 -0
  60. package/dist/internal/crypto/primitives.d.ts.map +1 -0
  61. package/dist/internal/crypto/primitives.js +230 -0
  62. package/dist/internal/crypto/primitives.js.map +1 -0
  63. package/dist/internal/crypto/signatures.d.ts +30 -0
  64. package/dist/internal/crypto/signatures.d.ts.map +1 -0
  65. package/dist/internal/crypto/signatures.js +153 -0
  66. package/dist/internal/crypto/signatures.js.map +1 -0
  67. package/dist/internal/decryptor/capsa-decryptor.d.ts +89 -0
  68. package/dist/internal/decryptor/capsa-decryptor.d.ts.map +1 -0
  69. package/dist/internal/decryptor/capsa-decryptor.js +263 -0
  70. package/dist/internal/decryptor/capsa-decryptor.js.map +1 -0
  71. package/dist/internal/http-factory.d.ts +78 -0
  72. package/dist/internal/http-factory.d.ts.map +1 -0
  73. package/dist/internal/http-factory.js +201 -0
  74. package/dist/internal/http-factory.js.map +1 -0
  75. package/dist/internal/index.d.ts +5 -0
  76. package/dist/internal/index.d.ts.map +1 -0
  77. package/dist/internal/index.js +5 -0
  78. package/dist/internal/index.js.map +1 -0
  79. package/dist/internal/retry-executor.d.ts +74 -0
  80. package/dist/internal/retry-executor.d.ts.map +1 -0
  81. package/dist/internal/retry-executor.js +204 -0
  82. package/dist/internal/retry-executor.js.map +1 -0
  83. package/dist/internal/services/account-service.d.ts +56 -0
  84. package/dist/internal/services/account-service.d.ts.map +1 -0
  85. package/dist/internal/services/account-service.js +114 -0
  86. package/dist/internal/services/account-service.js.map +1 -0
  87. package/dist/internal/services/audit-service.d.ts +25 -0
  88. package/dist/internal/services/audit-service.d.ts.map +1 -0
  89. package/dist/internal/services/audit-service.js +43 -0
  90. package/dist/internal/services/audit-service.js.map +1 -0
  91. package/dist/internal/services/auth-service.d.ts +44 -0
  92. package/dist/internal/services/auth-service.d.ts.map +1 -0
  93. package/dist/internal/services/auth-service.js +170 -0
  94. package/dist/internal/services/auth-service.js.map +1 -0
  95. package/dist/internal/services/capsa-service.d.ts +40 -0
  96. package/dist/internal/services/capsa-service.d.ts.map +1 -0
  97. package/dist/internal/services/capsa-service.js +82 -0
  98. package/dist/internal/services/capsa-service.js.map +1 -0
  99. package/dist/internal/services/download-service.d.ts +62 -0
  100. package/dist/internal/services/download-service.d.ts.map +1 -0
  101. package/dist/internal/services/download-service.js +114 -0
  102. package/dist/internal/services/download-service.js.map +1 -0
  103. package/dist/internal/services/key-service.d.ts +28 -0
  104. package/dist/internal/services/key-service.d.ts.map +1 -0
  105. package/dist/internal/services/key-service.js +45 -0
  106. package/dist/internal/services/key-service.js.map +1 -0
  107. package/dist/internal/services/limits-service.d.ts +30 -0
  108. package/dist/internal/services/limits-service.d.ts.map +1 -0
  109. package/dist/internal/services/limits-service.js +73 -0
  110. package/dist/internal/services/limits-service.js.map +1 -0
  111. package/dist/internal/services/upload-service.d.ts +61 -0
  112. package/dist/internal/services/upload-service.d.ts.map +1 -0
  113. package/dist/internal/services/upload-service.js +258 -0
  114. package/dist/internal/services/upload-service.js.map +1 -0
  115. package/dist/internal/types.d.ts +74 -0
  116. package/dist/internal/types.d.ts.map +1 -0
  117. package/dist/internal/types.js +3 -0
  118. package/dist/internal/types.js.map +1 -0
  119. package/dist/internal/upload/multipart-builder.d.ts +57 -0
  120. package/dist/internal/upload/multipart-builder.d.ts.map +1 -0
  121. package/dist/internal/upload/multipart-builder.js +139 -0
  122. package/dist/internal/upload/multipart-builder.js.map +1 -0
  123. package/dist/internal/utils/id-generator.d.ts +8 -0
  124. package/dist/internal/utils/id-generator.d.ts.map +1 -0
  125. package/dist/internal/utils/id-generator.js +20 -0
  126. package/dist/internal/utils/id-generator.js.map +1 -0
  127. package/dist/internal/utils/mimetype-lookup.d.ts +8 -0
  128. package/dist/internal/utils/mimetype-lookup.d.ts.map +1 -0
  129. package/dist/internal/utils/mimetype-lookup.js +118 -0
  130. package/dist/internal/utils/mimetype-lookup.js.map +1 -0
  131. package/dist/internal/version.d.ts +20 -0
  132. package/dist/internal/version.d.ts.map +1 -0
  133. package/dist/internal/version.js +25 -0
  134. package/dist/internal/version.js.map +1 -0
  135. package/dist/types/index.d.ts +143 -0
  136. package/dist/types/index.d.ts.map +1 -0
  137. package/dist/types/index.js +20 -0
  138. package/dist/types/index.js.map +1 -0
  139. package/package.json +61 -0
@@ -0,0 +1,170 @@
1
+ /** Authentication service for managing access tokens and refresh tokens. */
2
+ import { CapsaraAuthError } from '../../errors/auth-error.js';
3
+ import { createHttpClient } from '../http-factory.js';
4
+ export class AuthService {
5
+ accessToken = null;
6
+ refreshToken = null;
7
+ tokenExpiresAt = null;
8
+ http;
9
+ authStateCallbacks = new Set();
10
+ expectedIssuer;
11
+ expectedAudience;
12
+ lastRefreshError = null;
13
+ constructor(baseUrl, options) {
14
+ const httpOptions = {
15
+ baseUrl,
16
+ timeout: options?.timeout,
17
+ retry: options?.retry,
18
+ userAgent: options?.userAgent,
19
+ };
20
+ this.http = createHttpClient(httpOptions);
21
+ this.expectedIssuer = options?.expectedIssuer ?? 'vault.api';
22
+ this.expectedAudience = options?.expectedAudience ?? 'vault.api';
23
+ }
24
+ onAuthChange(callback) {
25
+ this.authStateCallbacks.add(callback);
26
+ }
27
+ offAuthChange(callback) {
28
+ this.authStateCallbacks.delete(callback);
29
+ }
30
+ emitAuthChange(event) {
31
+ const state = { isAuthenticated: this.isAuthenticated(), event };
32
+ this.authStateCallbacks.forEach((callback) => {
33
+ try {
34
+ callback(state);
35
+ }
36
+ catch (error) {
37
+ // eslint-disable-next-line no-console
38
+ console.error('Auth state callback error:', error);
39
+ }
40
+ });
41
+ }
42
+ decodeJWT(token) {
43
+ try {
44
+ const parts = token.split('.');
45
+ if (parts.length !== 3)
46
+ return null;
47
+ const payload = parts[1];
48
+ if (!payload)
49
+ return null;
50
+ const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
51
+ const jsonPayload = Buffer.from(base64, 'base64').toString('utf-8');
52
+ return JSON.parse(jsonPayload);
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ validateAndExtractExpiry(token) {
59
+ const payload = this.decodeJWT(token);
60
+ if (!payload || !payload.exp)
61
+ return null;
62
+ const expiryMs = payload.exp * 1000;
63
+ if (payload.iss && payload.iss !== this.expectedIssuer) {
64
+ // eslint-disable-next-line no-console
65
+ console.warn(`JWT issuer mismatch: expected '${this.expectedIssuer}', got '${payload.iss}'`);
66
+ }
67
+ if (payload.aud && payload.aud !== this.expectedAudience) {
68
+ // eslint-disable-next-line no-console
69
+ console.warn(`JWT audience mismatch: expected '${this.expectedAudience}', got '${payload.aud}'`);
70
+ }
71
+ return expiryMs;
72
+ }
73
+ isTokenExpired(bufferSeconds = 30) {
74
+ if (!this.tokenExpiresAt)
75
+ return true;
76
+ return Date.now() >= this.tokenExpiresAt - bufferSeconds * 1000;
77
+ }
78
+ async login(credentials) {
79
+ try {
80
+ const response = await this.http.post('/api/auth/login', credentials);
81
+ this.accessToken = response.data.accessToken;
82
+ this.refreshToken = response.data.refreshToken || null;
83
+ if (response.data.expiresIn) {
84
+ this.tokenExpiresAt = Date.now() + response.data.expiresIn * 1000;
85
+ }
86
+ else if (response.data.accessToken) {
87
+ this.tokenExpiresAt = this.validateAndExtractExpiry(response.data.accessToken);
88
+ }
89
+ this.emitAuthChange('login');
90
+ return response.data;
91
+ }
92
+ catch (error) {
93
+ throw CapsaraAuthError.fromApiError(error);
94
+ }
95
+ }
96
+ async refresh() {
97
+ if (!this.refreshToken)
98
+ return false;
99
+ try {
100
+ const response = await this.http.post('/api/auth/refresh', { refreshToken: this.refreshToken });
101
+ this.accessToken = response.data.accessToken;
102
+ this.refreshToken = response.data.refreshToken || this.refreshToken;
103
+ if (response.data.expiresIn) {
104
+ this.tokenExpiresAt = Date.now() + response.data.expiresIn * 1000;
105
+ }
106
+ else if (response.data.accessToken) {
107
+ this.tokenExpiresAt = this.validateAndExtractExpiry(response.data.accessToken);
108
+ }
109
+ this.lastRefreshError = null;
110
+ this.emitAuthChange('refresh');
111
+ return true;
112
+ }
113
+ catch (error) {
114
+ this.lastRefreshError = error instanceof Error ? error : new Error(String(error));
115
+ // eslint-disable-next-line no-console
116
+ console.warn('Token refresh failed:', error instanceof Error ? error.message : 'Unknown error');
117
+ return false;
118
+ }
119
+ }
120
+ getLastRefreshError() {
121
+ return this.lastRefreshError;
122
+ }
123
+ getToken() {
124
+ return this.accessToken;
125
+ }
126
+ getRefreshToken() {
127
+ return this.refreshToken;
128
+ }
129
+ isAuthenticated() {
130
+ return this.accessToken !== null;
131
+ }
132
+ canRefresh() {
133
+ return this.refreshToken !== null;
134
+ }
135
+ async logout() {
136
+ const currentAccessToken = this.accessToken;
137
+ const currentRefreshToken = this.refreshToken;
138
+ this.accessToken = null;
139
+ this.refreshToken = null;
140
+ this.tokenExpiresAt = null;
141
+ if (currentAccessToken && currentRefreshToken) {
142
+ try {
143
+ await this.http.post('/api/auth/logout', { refreshToken: currentRefreshToken }, { headers: { Authorization: `Bearer ${currentAccessToken}` } });
144
+ this.emitAuthChange('logout');
145
+ return true;
146
+ }
147
+ catch (error) {
148
+ // eslint-disable-next-line no-console
149
+ console.warn('Server-side logout failed (tokens cleared locally):', error instanceof Error ? error.message : 'Unknown error');
150
+ this.emitAuthChange('logout');
151
+ return false;
152
+ }
153
+ }
154
+ this.emitAuthChange('logout');
155
+ return true;
156
+ }
157
+ setToken(token) {
158
+ this.accessToken = token;
159
+ this.tokenExpiresAt = this.validateAndExtractExpiry(token);
160
+ }
161
+ setRefreshToken(token) {
162
+ this.refreshToken = token;
163
+ }
164
+ setTokens(accessToken, refreshToken) {
165
+ this.accessToken = accessToken;
166
+ this.refreshToken = refreshToken;
167
+ this.tokenExpiresAt = this.validateAndExtractExpiry(accessToken);
168
+ }
169
+ }
170
+ //# sourceMappingURL=auth-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-service.js","sourceRoot":"","sources":["../../../src/internal/services/auth-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** Capsa CRUD operations service. */
2
+ import type { AxiosInstance } from 'axios';
3
+ import { type DecryptedCapsa } from '../decryptor/capsa-decryptor.js';
4
+ import type { Capsa, CapsaListFilters, CapsaListResponse } from '../../types/index.js';
5
+ import type { KeyManager } from './key-service.js';
6
+ export interface CapsaServiceOptions {
7
+ axiosInstance: AxiosInstance;
8
+ keyManager: KeyManager;
9
+ }
10
+ export declare class CapsaService {
11
+ private http;
12
+ private keyManager;
13
+ constructor(options: CapsaServiceOptions);
14
+ /**
15
+ * Get capsa by ID (encrypted)
16
+ * @param capsaId - Capsa ID
17
+ * @returns Encrypted capsa
18
+ */
19
+ getCapsa(capsaId: string): Promise<Capsa>;
20
+ /**
21
+ * Get and decrypt capsa
22
+ * @param capsaId - Capsa ID
23
+ * @param privateKey - Private key for decryption
24
+ * @param verifySignature - Whether to verify signature (default: true)
25
+ * @returns Decrypted capsa
26
+ */
27
+ getDecryptedCapsa(capsaId: string, privateKey: string, verifySignature?: boolean): Promise<DecryptedCapsa>;
28
+ /**
29
+ * List capsas with cursor-based pagination
30
+ * @param filters - Query filters
31
+ * @returns Paginated capsa list (always returns valid structure, even if empty)
32
+ */
33
+ listCapsas(filters?: CapsaListFilters): Promise<CapsaListResponse>;
34
+ /**
35
+ * Soft delete a capsa
36
+ * @param capsaId - Capsa ID
37
+ */
38
+ deleteCapsa(capsaId: string): Promise<void>;
39
+ }
40
+ //# sourceMappingURL=capsa-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capsa-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/capsa-service.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGpF,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,UAAU,CAAa;gBAEnB,OAAO,EAAE,mBAAmB;IAKxC;;;;OAIG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAS/C;;;;;;OAMG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,UAAO,GACrB,OAAO,CAAC,cAAc,CAAC;IAmB1B;;;;OAIG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsBxE;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOlD"}
@@ -0,0 +1,82 @@
1
+ /** Capsa CRUD operations service. */
2
+ import { decryptCapsa } from '../decryptor/capsa-decryptor.js';
3
+ import { CapsaraCapsaError } from '../../errors/capsa-error.js';
4
+ export class CapsaService {
5
+ http;
6
+ keyManager;
7
+ constructor(options) {
8
+ this.http = options.axiosInstance;
9
+ this.keyManager = options.keyManager;
10
+ }
11
+ /**
12
+ * Get capsa by ID (encrypted)
13
+ * @param capsaId - Capsa ID
14
+ * @returns Encrypted capsa
15
+ */
16
+ async getCapsa(capsaId) {
17
+ try {
18
+ const response = await this.http.get(`/api/capsas/${capsaId}`);
19
+ return response.data;
20
+ }
21
+ catch (error) {
22
+ throw CapsaraCapsaError.fromApiError(error);
23
+ }
24
+ }
25
+ /**
26
+ * Get and decrypt capsa
27
+ * @param capsaId - Capsa ID
28
+ * @param privateKey - Private key for decryption
29
+ * @param verifySignature - Whether to verify signature (default: true)
30
+ * @returns Decrypted capsa
31
+ */
32
+ async getDecryptedCapsa(capsaId, privateKey, verifySignature = true) {
33
+ const capsa = await this.getCapsa(capsaId);
34
+ // Fetch creator's public key for signature verification
35
+ let creatorPublicKey;
36
+ if (verifySignature) {
37
+ const creatorKey = await this.keyManager.fetchExplicitPartyKey(capsa.creator);
38
+ creatorPublicKey = creatorKey?.publicKey;
39
+ }
40
+ return decryptCapsa(capsa, privateKey, undefined, // Auto-detect party from keychain
41
+ creatorPublicKey, verifySignature);
42
+ }
43
+ /**
44
+ * List capsas with cursor-based pagination
45
+ * @param filters - Query filters
46
+ * @returns Paginated capsa list (always returns valid structure, even if empty)
47
+ */
48
+ async listCapsas(filters) {
49
+ try {
50
+ const response = await this.http.get('/api/capsas', {
51
+ params: filters,
52
+ });
53
+ // Defensive handling for null/undefined response data
54
+ const data = response.data;
55
+ return {
56
+ capsas: data?.capsas ?? [],
57
+ pagination: {
58
+ limit: data?.pagination?.limit ?? filters?.limit ?? 20,
59
+ hasMore: data?.pagination?.hasMore ?? false,
60
+ nextCursor: data?.pagination?.nextCursor,
61
+ prevCursor: data?.pagination?.prevCursor,
62
+ },
63
+ };
64
+ }
65
+ catch (error) {
66
+ throw CapsaraCapsaError.fromApiError(error);
67
+ }
68
+ }
69
+ /**
70
+ * Soft delete a capsa
71
+ * @param capsaId - Capsa ID
72
+ */
73
+ async deleteCapsa(capsaId) {
74
+ try {
75
+ await this.http.delete(`/api/capsas/${capsaId}`);
76
+ }
77
+ catch (error) {
78
+ throw CapsaraCapsaError.fromApiError(error);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=capsa-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capsa-service.js","sourceRoot":"","sources":["../../../src/internal/services/capsa-service.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAGrC,OAAO,EAAE,YAAY,EAAuB,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAUhE,MAAM,OAAO,YAAY;IACf,IAAI,CAAgB;IACpB,UAAU,CAAa;IAE/B,YAAY,OAA4B;QACtC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAe;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAQ,eAAe,OAAO,EAAE,CAAC,CAAC;YACtE,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,iBAAiB,CAAC,YAAY,CAAC,KAAuB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,iBAAiB,CACrB,OAAe,EACf,UAAkB,EAClB,eAAe,GAAG,IAAI;QAEtB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE3C,wDAAwD;QACxD,IAAI,gBAAoC,CAAC;QACzC,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9E,gBAAgB,GAAG,UAAU,EAAE,SAAS,CAAC;QAC3C,CAAC;QAED,OAAO,YAAY,CACjB,KAAK,EACL,UAAU,EACV,SAAS,EAAE,kCAAkC;QAC7C,gBAAgB,EAChB,eAAe,CAChB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,OAA0B;QACzC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAoB,aAAa,EAAE;gBACrE,MAAM,EAAE,OAAkC;aAC3C,CAAC,CAAC;YAEH,sDAAsD;YACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;gBAC1B,UAAU,EAAE;oBACV,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,EAAE;oBACtD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,IAAI,KAAK;oBAC3C,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU;oBACxC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU;iBACzC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,iBAAiB,CAAC,YAAY,CAAC,KAAuB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,iBAAiB,CAAC,YAAY,CAAC,KAAuB,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,62 @@
1
+ /** File download and decryption service. */
2
+ import type { AxiosInstance } from 'axios';
3
+ import type { RetryConfig, RetryLogger } from '../config/retry-interceptor.js';
4
+ export interface DownloadServiceOptions {
5
+ axiosInstance: AxiosInstance;
6
+ blobClient: AxiosInstance;
7
+ retryConfig: Required<RetryConfig>;
8
+ logger: RetryLogger;
9
+ }
10
+ export interface FileMetadata {
11
+ iv: string;
12
+ authTag: string;
13
+ compressed?: boolean;
14
+ encryptedFilename: string;
15
+ filenameIV: string;
16
+ filenameAuthTag: string;
17
+ }
18
+ export interface DecryptedFileResult {
19
+ data: Buffer;
20
+ filename: string;
21
+ }
22
+ export declare class DownloadService {
23
+ private http;
24
+ private blobDownloadClient;
25
+ private retryConfig;
26
+ private logger;
27
+ constructor(options: DownloadServiceOptions);
28
+ /**
29
+ * Get download URL for encrypted file
30
+ * @param capsaId - Capsa ID
31
+ * @param fileId - File ID
32
+ * @param expiresInMinutes - URL expiration in minutes (default: 60)
33
+ * @returns Download URL and expiration
34
+ */
35
+ getFileDownloadUrl(capsaId: string, fileId: string, expiresInMinutes?: number): Promise<{
36
+ downloadUrl: string;
37
+ expiresAt: string;
38
+ }>;
39
+ /**
40
+ * Download encrypted file from blob storage
41
+ * @param capsaId - Capsa ID
42
+ * @param fileId - File ID
43
+ * @returns Encrypted file data
44
+ */
45
+ downloadEncryptedFile(capsaId: string, fileId: string): Promise<Buffer>;
46
+ /**
47
+ * Download and decrypt file
48
+ * @param capsaId - Capsa ID
49
+ * @param fileId - File ID
50
+ * @param masterKey - Decrypted master key (raw Buffer)
51
+ * @param metadata - File metadata for decryption
52
+ * @returns Decrypted file data and filename
53
+ */
54
+ downloadAndDecryptFile(capsaId: string, fileId: string, masterKey: Buffer, metadata: FileMetadata): Promise<DecryptedFileResult>;
55
+ /** Download file with retry logic. */
56
+ private downloadFileWithRetry;
57
+ /**
58
+ * Calculate retry delay with exponential backoff
59
+ */
60
+ private calculateRetryDelay;
61
+ }
62
+ //# sourceMappingURL=download-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/download-service.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAM3C,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,aAAa,CAAC;IAC1B,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,kBAAkB,CAAgB;IAC1C,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,MAAM,CAAc;gBAEhB,OAAO,EAAE,sBAAsB;IAO3C;;;;;;OAMG;IACG,kBAAkB,CACtB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,gBAAgB,SAAK,GACpB,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAmBtD;;;;;OAKG;IACG,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK7E;;;;;;;OAOG;IACG,sBAAsB,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,mBAAmB,CAAC;IA2B/B,sCAAsC;YACxB,qBAAqB;IA8BnC;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAc5B"}
@@ -0,0 +1,114 @@
1
+ /** File download and decryption service. */
2
+ import { decryptFilename } from '../decryptor/capsa-decryptor.js';
3
+ import { decryptAESRaw } from '../crypto/primitives.js';
4
+ import { decompressData } from '../crypto/compression.js';
5
+ import { CapsaraCapsaError } from '../../errors/capsa-error.js';
6
+ export class DownloadService {
7
+ http;
8
+ blobDownloadClient;
9
+ retryConfig;
10
+ logger;
11
+ constructor(options) {
12
+ this.http = options.axiosInstance;
13
+ this.blobDownloadClient = options.blobClient;
14
+ this.retryConfig = options.retryConfig;
15
+ this.logger = options.logger;
16
+ }
17
+ /**
18
+ * Get download URL for encrypted file
19
+ * @param capsaId - Capsa ID
20
+ * @param fileId - File ID
21
+ * @param expiresInMinutes - URL expiration in minutes (default: 60)
22
+ * @returns Download URL and expiration
23
+ */
24
+ async getFileDownloadUrl(capsaId, fileId, expiresInMinutes = 60) {
25
+ try {
26
+ const response = await this.http.get(`/api/capsas/${capsaId}/files/${fileId}/download`, {
27
+ params: { expires: expiresInMinutes },
28
+ });
29
+ return {
30
+ downloadUrl: response.data.downloadUrl,
31
+ expiresAt: response.data.expiresAt,
32
+ };
33
+ }
34
+ catch (error) {
35
+ throw CapsaraCapsaError.fromApiError(error);
36
+ }
37
+ }
38
+ /**
39
+ * Download encrypted file from blob storage
40
+ * @param capsaId - Capsa ID
41
+ * @param fileId - File ID
42
+ * @returns Encrypted file data
43
+ */
44
+ async downloadEncryptedFile(capsaId, fileId) {
45
+ const { downloadUrl } = await this.getFileDownloadUrl(capsaId, fileId);
46
+ return this.downloadFileWithRetry(downloadUrl, 0);
47
+ }
48
+ /**
49
+ * Download and decrypt file
50
+ * @param capsaId - Capsa ID
51
+ * @param fileId - File ID
52
+ * @param masterKey - Decrypted master key (raw Buffer)
53
+ * @param metadata - File metadata for decryption
54
+ * @returns Decrypted file data and filename
55
+ */
56
+ async downloadAndDecryptFile(capsaId, fileId, masterKey, metadata) {
57
+ try {
58
+ const encryptedData = await this.downloadEncryptedFile(capsaId, fileId);
59
+ // Decrypt using raw Buffer APIs to avoid base64 round-trip overhead
60
+ const ivBuffer = Buffer.from(metadata.iv, 'base64url');
61
+ const authTagBuffer = Buffer.from(metadata.authTag, 'base64url');
62
+ let decryptedData = decryptAESRaw(encryptedData, masterKey, ivBuffer, authTagBuffer);
63
+ if (metadata.compressed) {
64
+ decryptedData = await decompressData(decryptedData);
65
+ }
66
+ const filename = decryptFilename(metadata.encryptedFilename, masterKey, metadata.filenameIV, metadata.filenameAuthTag);
67
+ return { data: decryptedData, filename };
68
+ }
69
+ catch (error) {
70
+ // Wrap error with capsaId and fileId context for debugging
71
+ throw CapsaraCapsaError.downloadFailed(capsaId, fileId, error);
72
+ }
73
+ }
74
+ /** Download file with retry logic. */
75
+ async downloadFileWithRetry(downloadUrl, retryCount) {
76
+ try {
77
+ const response = await this.blobDownloadClient.get(downloadUrl, {
78
+ responseType: 'arraybuffer',
79
+ });
80
+ return Buffer.from(response.data);
81
+ }
82
+ catch (error) {
83
+ const axiosError = error;
84
+ const status = axiosError.response?.status;
85
+ const isRetryable = status === 503 || status === 429;
86
+ if (isRetryable && retryCount < this.retryConfig.maxRetries) {
87
+ const retryDelay = this.calculateRetryDelay(axiosError, retryCount, status);
88
+ if (this.retryConfig.enableLogging) {
89
+ this.logger.log(`[Capsara SDK] Retry attempt ${retryCount + 1}/${this.retryConfig.maxRetries} ` +
90
+ `for ${status} error (file download) - waiting ${Math.floor(retryDelay)}ms`);
91
+ }
92
+ await new Promise(resolve => globalThis.setTimeout(resolve, retryDelay));
93
+ return this.downloadFileWithRetry(downloadUrl, retryCount + 1);
94
+ }
95
+ throw error;
96
+ }
97
+ }
98
+ /**
99
+ * Calculate retry delay with exponential backoff
100
+ */
101
+ calculateRetryDelay(error, retryCount, _status) {
102
+ const responseData = error.response?.data;
103
+ const errorObj = responseData?.error;
104
+ const serverDelay = errorObj?.retryAfter;
105
+ if (typeof serverDelay === 'number') {
106
+ return Math.min(serverDelay * 1000, this.retryConfig.maxDelay);
107
+ }
108
+ // Exponential backoff with jitter
109
+ const exponentialDelay = this.retryConfig.baseDelay * Math.pow(2, retryCount);
110
+ const jitter = Math.random() * 0.3 * exponentialDelay;
111
+ return Math.min(exponentialDelay + jitter, this.retryConfig.maxDelay);
112
+ }
113
+ }
114
+ //# sourceMappingURL=download-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-service.js","sourceRoot":"","sources":["../../../src/internal/services/download-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /** Party key management for fetching public keys. */
2
+ import type { PartyKey } from '../../types/index.js';
3
+ import { type HttpTimeoutConfig } from '../config/http-client.js';
4
+ import type { RetryConfig } from '../config/retry-interceptor.js';
5
+ export interface KeyManagerOptions {
6
+ timeout?: Partial<HttpTimeoutConfig>;
7
+ retry?: RetryConfig;
8
+ }
9
+ export declare class KeyManager {
10
+ private axiosInstance;
11
+ constructor(baseUrl: string, getToken: () => string | null, options?: KeyManagerOptions);
12
+ /**
13
+ * Fetch a single party key by exact ID (excludes delegates)
14
+ * Always fetches fresh from API to handle remote key rotations
15
+ * @param partyId - Party ID to fetch
16
+ * @returns Party key or undefined if not found
17
+ */
18
+ fetchExplicitPartyKey(partyId: string): Promise<PartyKey | undefined>;
19
+ /**
20
+ * Fetch party keys from API (includes delegates)
21
+ * Always fetches fresh from API to handle remote key rotations
22
+ * Uses POST to avoid URL length limits with large batches
23
+ * @param partyIds - Array of party IDs
24
+ * @returns Array of party keys with public keys and fingerprints (includes delegates)
25
+ */
26
+ fetchPartyKeys(partyIds: string[]): Promise<PartyKey[]>;
27
+ }
28
+ //# sourceMappingURL=key-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/key-service.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAGrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,aAAa,CAAgB;gBAGnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,EAC7B,OAAO,CAAC,EAAE,iBAAiB;IAyB7B;;;;;OAKG;IACG,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAU3E;;;;;;OAMG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAQ9D"}
@@ -0,0 +1,45 @@
1
+ /** Party key management for fetching public keys. */
2
+ import axios from 'axios';
3
+ import { createAxiosConfig, configureRetryInterceptor, DEFAULT_TIMEOUT_CONFIG, } from '../config/http-client.js';
4
+ export class KeyManager {
5
+ axiosInstance;
6
+ constructor(baseUrl, getToken, options) {
7
+ const timeoutConfig = {
8
+ ...DEFAULT_TIMEOUT_CONFIG,
9
+ ...options?.timeout,
10
+ };
11
+ const axiosConfig = createAxiosConfig(baseUrl, timeoutConfig.apiTimeout, timeoutConfig);
12
+ this.axiosInstance = axios.create(axiosConfig);
13
+ configureRetryInterceptor(this.axiosInstance, options?.retry);
14
+ this.axiosInstance.interceptors.request.use((config) => {
15
+ const token = getToken();
16
+ if (token) {
17
+ config.headers.Authorization = `Bearer ${token}`;
18
+ }
19
+ return config;
20
+ });
21
+ }
22
+ /**
23
+ * Fetch a single party key by exact ID (excludes delegates)
24
+ * Always fetches fresh from API to handle remote key rotations
25
+ * @param partyId - Party ID to fetch
26
+ * @returns Party key or undefined if not found
27
+ */
28
+ async fetchExplicitPartyKey(partyId) {
29
+ const response = await this.axiosInstance.post('/api/party/keys', { ids: [partyId] });
30
+ // Return only the explicitly requested party (API may include delegates)
31
+ return response.data.parties.find((p) => p.id === partyId);
32
+ }
33
+ /**
34
+ * Fetch party keys from API (includes delegates)
35
+ * Always fetches fresh from API to handle remote key rotations
36
+ * Uses POST to avoid URL length limits with large batches
37
+ * @param partyIds - Array of party IDs
38
+ * @returns Array of party keys with public keys and fingerprints (includes delegates)
39
+ */
40
+ async fetchPartyKeys(partyIds) {
41
+ const response = await this.axiosInstance.post('/api/party/keys', { ids: partyIds });
42
+ return response.data.parties;
43
+ }
44
+ }
45
+ //# sourceMappingURL=key-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-service.js","sourceRoot":"","sources":["../../../src/internal/services/key-service.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAErD,OAAO,KAAwB,MAAM,OAAO,CAAC;AAE7C,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,GAEvB,MAAM,0BAA0B,CAAC;AAQlC,MAAM,OAAO,UAAU;IACb,aAAa,CAAgB;IAErC,YACE,OAAe,EACf,QAA6B,EAC7B,OAA2B;QAE3B,MAAM,aAAa,GAAG;YACpB,GAAG,sBAAsB;YACzB,GAAG,OAAO,EAAE,OAAO;SACpB,CAAC;QAEF,MAAM,WAAW,GAAG,iBAAiB,CACnC,OAAO,EACP,aAAa,CAAC,UAAU,EACxB,aAAa,CACd,CAAC;QACF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAE/C,yBAAyB,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;YACzB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,OAAO,CAAC,aAAa,GAAG,UAAU,KAAK,EAAE,CAAC;YACnD,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,qBAAqB,CAAC,OAAe;QACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAC5C,iBAAiB,EACjB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CACnB,CAAC;QAEF,yEAAyE;QACzE,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAAC,QAAkB;QACrC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAC5C,iBAAiB,EACjB,EAAE,GAAG,EAAE,QAAQ,EAAE,CAClB,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ /** System limits management with caching. */
2
+ import type { SystemLimits } from '../../types/index.js';
3
+ import { type HttpTimeoutConfig } from '../config/http-client.js';
4
+ import type { RetryConfig } from '../config/retry-interceptor.js';
5
+ export declare class LimitsManager {
6
+ private axiosInstance;
7
+ private cachedLimits;
8
+ private readonly cacheTTL;
9
+ constructor(baseUrl: string, timeout?: Partial<HttpTimeoutConfig>, retry?: RetryConfig);
10
+ /**
11
+ * Fetch system limits from API
12
+ * @returns System limits
13
+ */
14
+ private fetchLimits;
15
+ /**
16
+ * Get system limits (from cache or fetch from API)
17
+ * @returns System limits
18
+ */
19
+ getLimits(): Promise<SystemLimits>;
20
+ /**
21
+ * Clear the limits cache (useful for testing or forcing refresh)
22
+ */
23
+ clearCache(): void;
24
+ /**
25
+ * Get fallback limits (for reference)
26
+ * @returns Hardcoded fallback limits
27
+ */
28
+ static getFallbackLimits(): SystemLimits;
29
+ }
30
+ //# sourceMappingURL=limits-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits-service.d.ts","sourceRoot":"","sources":["../../../src/internal/services/limits-service.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAG7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAiBlE,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;gBAEhD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,EAAE,WAAW;IAgBtF;;;OAGG;YACW,WAAW;IAUzB;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAqBxC;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,MAAM,CAAC,iBAAiB,IAAI,YAAY;CAGzC"}