@blimu/backend 1.1.0 → 1.1.3
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.
- package/README.md +6 -13
- package/dist/__tests__/token-verifier.test.cjs +17662 -0
- package/dist/__tests__/token-verifier.test.cjs.map +1 -0
- package/dist/__tests__/token-verifier.test.d.mts +2 -0
- package/dist/__tests__/token-verifier.test.d.ts +2 -0
- package/dist/__tests__/token-verifier.test.mjs +17661 -0
- package/dist/__tests__/token-verifier.test.mjs.map +1 -0
- package/dist/auth-strategies.cjs +42 -0
- package/dist/auth-strategies.cjs.map +1 -0
- package/dist/auth-strategies.d.mts +16 -0
- package/dist/auth-strategies.d.ts +16 -0
- package/dist/auth-strategies.mjs +17 -0
- package/dist/auth-strategies.mjs.map +1 -0
- package/dist/client.cjs +483 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +26 -18
- package/dist/client.d.ts +26 -18
- package/dist/client.mjs +447 -39
- package/dist/client.mjs.map +1 -1
- package/dist/{main.js → index.cjs} +294 -399
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +15 -33
- package/dist/index.d.ts +15 -33
- package/dist/index.mjs +440 -330
- package/dist/index.mjs.map +1 -1
- package/dist/{schema-B1usIXCr.d.mts → schema-BbKn_i-U.d.mts} +82 -93
- package/dist/{schema-B1usIXCr.d.ts → schema-BbKn_i-U.d.ts} +82 -93
- package/dist/{schema.js → schema.cjs} +2 -1
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.mts +1 -2
- package/dist/schema.d.ts +1 -2
- package/dist/{schema.zod-CRNAHxbc.d.mts → schema.zod-DtXVS-1g.d.mts} +38 -48
- package/dist/{schema.zod-CRNAHxbc.d.ts → schema.zod-DtXVS-1g.d.ts} +38 -48
- package/dist/{schema.zod.js → schema.zod.cjs} +175 -248
- package/dist/schema.zod.cjs.map +1 -0
- package/dist/schema.zod.d.mts +1 -1
- package/dist/schema.zod.d.ts +1 -1
- package/dist/schema.zod.mjs +173 -242
- package/dist/schema.zod.mjs.map +1 -1
- package/dist/services/{bulk_resources.js → bulk_resources.cjs} +4 -2
- package/dist/services/bulk_resources.cjs.map +1 -0
- package/dist/services/bulk_resources.d.mts +4 -6
- package/dist/services/bulk_resources.d.ts +4 -6
- package/dist/services/bulk_resources.mjs +2 -1
- package/dist/services/bulk_resources.mjs.map +1 -1
- package/dist/services/{bulk_roles.js → bulk_roles.cjs} +4 -2
- package/dist/services/bulk_roles.cjs.map +1 -0
- package/dist/services/bulk_roles.d.mts +3 -5
- package/dist/services/bulk_roles.d.ts +3 -5
- package/dist/services/bulk_roles.mjs +2 -1
- package/dist/services/bulk_roles.mjs.map +1 -1
- package/dist/services/{entitlements.js → entitlements.cjs} +6 -4
- package/dist/services/entitlements.cjs.map +1 -0
- package/dist/services/entitlements.d.mts +4 -6
- package/dist/services/entitlements.d.ts +4 -6
- package/dist/services/entitlements.mjs +4 -3
- package/dist/services/entitlements.mjs.map +1 -1
- package/dist/services/{plans.js → plans.cjs} +6 -4
- package/dist/services/plans.cjs.map +1 -0
- package/dist/services/plans.d.mts +6 -8
- package/dist/services/plans.d.ts +6 -8
- package/dist/services/plans.mjs +4 -3
- package/dist/services/plans.mjs.map +1 -1
- package/dist/services/{resource_members.js → resource_members.cjs} +4 -2
- package/dist/services/resource_members.cjs.map +1 -0
- package/dist/services/resource_members.d.mts +4 -6
- package/dist/services/resource_members.d.ts +4 -6
- package/dist/services/resource_members.mjs +2 -1
- package/dist/services/resource_members.mjs.map +1 -1
- package/dist/services/{resources.js → resources.cjs} +8 -6
- package/dist/services/resources.cjs.map +1 -0
- package/dist/services/resources.d.mts +8 -10
- package/dist/services/resources.d.ts +8 -10
- package/dist/services/resources.mjs +6 -5
- package/dist/services/resources.mjs.map +1 -1
- package/dist/services/{roles.js → roles.cjs} +6 -4
- package/dist/services/roles.cjs.map +1 -0
- package/dist/services/roles.d.mts +4 -6
- package/dist/services/roles.d.ts +4 -6
- package/dist/services/roles.mjs +4 -3
- package/dist/services/roles.mjs.map +1 -1
- package/dist/services/{usage.js → usage.cjs} +8 -6
- package/dist/services/usage.cjs.map +1 -0
- package/dist/services/usage.d.mts +5 -7
- package/dist/services/usage.d.ts +5 -7
- package/dist/services/usage.mjs +6 -5
- package/dist/services/usage.mjs.map +1 -1
- package/dist/services/{users.js → users.cjs} +9 -7
- package/dist/services/users.cjs.map +1 -0
- package/dist/services/users.d.mts +3 -5
- package/dist/services/users.d.ts +3 -5
- package/dist/services/users.mjs +7 -6
- package/dist/services/users.mjs.map +1 -1
- package/dist/{token-verifier.js → token-verifier.cjs} +14 -31
- package/dist/token-verifier.cjs.map +1 -0
- package/dist/token-verifier.d.mts +5 -5
- package/dist/token-verifier.d.ts +5 -5
- package/dist/token-verifier.mjs +13 -34
- package/dist/token-verifier.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{utils.js → utils.cjs} +10 -3
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.mts +4 -3
- package/dist/utils.d.ts +4 -3
- package/dist/utils.mjs +7 -2
- package/dist/utils.mjs.map +1 -1
- package/package.json +37 -25
- package/dist/client.js +0 -70
- package/dist/client.js.map +0 -1
- package/dist/index.js +0 -1042
- package/dist/index.js.map +0 -1
- package/dist/main.d.mts +0 -19
- package/dist/main.d.ts +0 -19
- package/dist/main.js.map +0 -1
- package/dist/main.mjs +0 -1264
- package/dist/main.mjs.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/schema.zod.js.map +0 -1
- package/dist/services/bulk_resources.js.map +0 -1
- package/dist/services/bulk_roles.js.map +0 -1
- package/dist/services/entitlements.js.map +0 -1
- package/dist/services/plans.js.map +0 -1
- package/dist/services/resource_members.js.map +0 -1
- package/dist/services/resources.js.map +0 -1
- package/dist/services/roles.js.map +0 -1
- package/dist/services/usage.js.map +0 -1
- package/dist/services/users.js.map +0 -1
- package/dist/token-verifier.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/src/client.ts +0 -74
- package/src/index.ts +0 -55
- package/src/main.ts +0 -3
- package/src/schema.ts +0 -430
- package/src/schema.zod.ts +0 -558
- package/src/services/bulk_resources.ts +0 -24
- package/src/services/bulk_roles.ts +0 -22
- package/src/services/entitlements.ts +0 -58
- package/src/services/plans.ts +0 -57
- package/src/services/resource_members.ts +0 -25
- package/src/services/resources.ts +0 -91
- package/src/services/roles.ts +0 -58
- package/src/services/usage.ts +0 -93
- package/src/services/users.ts +0 -100
- package/src/token-verifier.ts +0 -280
- package/src/utils.ts +0 -56
package/src/token-verifier.ts
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { FetchError } from 'client';
|
|
2
|
-
import * as crypto from 'crypto';
|
|
3
|
-
import * as jwt from 'jsonwebtoken';
|
|
4
|
-
|
|
5
|
-
export interface JWK {
|
|
6
|
-
kty: string;
|
|
7
|
-
use: string;
|
|
8
|
-
kid: string;
|
|
9
|
-
alg: string;
|
|
10
|
-
n: string;
|
|
11
|
-
e: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface JWKSet {
|
|
15
|
-
keys: JWK[];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface CachedJWK {
|
|
19
|
-
key: crypto.KeyObject;
|
|
20
|
-
kid: string;
|
|
21
|
-
expiresAt: number;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface VerifyTokenOptions {
|
|
25
|
-
url?: string; // Direct URL to JWK endpoint (for custom scenarios)
|
|
26
|
-
secretKey?: string; // API key/secret key - uses runtimeApiUrl + JWK endpoint
|
|
27
|
-
token: string;
|
|
28
|
-
runtimeApiUrl?: string; // Optional override for runtime API URL
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface TokenVerifierOptions {
|
|
32
|
-
runtimeApiUrl?: string; // Default from BLIMU_AUTH_API_URL env var
|
|
33
|
-
cacheTTL?: number; // Default: 1 hour
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export class TokenVerifier {
|
|
37
|
-
private readonly cache = new Map<string, CachedJWK>();
|
|
38
|
-
private readonly cacheTTL: number;
|
|
39
|
-
private readonly runtimeApiUrl: string;
|
|
40
|
-
|
|
41
|
-
constructor(options?: TokenVerifierOptions) {
|
|
42
|
-
this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1000; // 1 hour
|
|
43
|
-
|
|
44
|
-
const blimuAuthApiUrl =
|
|
45
|
-
typeof process !== 'undefined' && process.env.BLIMU_AUTH_API_URL
|
|
46
|
-
? process.env.BLIMU_AUTH_API_URL
|
|
47
|
-
: undefined;
|
|
48
|
-
|
|
49
|
-
// if we have secretKey, we can call runtime-api directly, otherwise we need to use customer specific auth-api
|
|
50
|
-
this.runtimeApiUrl = blimuAuthApiUrl ?? 'https://api.blimu.dev';
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Fetch JWK Set from runtime-api
|
|
55
|
-
*/
|
|
56
|
-
private async fetchJWKSet(
|
|
57
|
-
endpoint: string,
|
|
58
|
-
headers?: Record<string, string>
|
|
59
|
-
): Promise<JWKSet> {
|
|
60
|
-
console.log(`[TokenVerifier] 📡 Fetching JWK Set from: ${endpoint}`);
|
|
61
|
-
if (headers) {
|
|
62
|
-
console.log(
|
|
63
|
-
`[TokenVerifier] 📡 Request headers: ${JSON.stringify(Object.keys(headers).map((k) => `${k}: ${k === 'x-api-key' ? '***' : headers[k]}`))}`
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const response = await fetch(endpoint, {
|
|
68
|
-
method: 'GET',
|
|
69
|
-
headers: {
|
|
70
|
-
'Content-Type': 'application/json',
|
|
71
|
-
...headers,
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
console.log(
|
|
76
|
-
`[TokenVerifier] 📡 Response status: ${response.status} ${response.statusText}`
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
if (!response.ok) {
|
|
80
|
-
const errorText = await response.text();
|
|
81
|
-
console.error(
|
|
82
|
-
`[TokenVerifier] ❌ Failed to fetch JWKs: ${response.status} ${errorText}`
|
|
83
|
-
);
|
|
84
|
-
throw new FetchError('Failed to fetch JWKs', response.status, errorText);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const jwkSet = (await response.json()) as JWKSet;
|
|
88
|
-
console.log(
|
|
89
|
-
`[TokenVerifier] ✅ Successfully fetched JWK Set with ${jwkSet.keys.length} keys`
|
|
90
|
-
);
|
|
91
|
-
return jwkSet;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Convert JWK to KeyObject
|
|
96
|
-
*/
|
|
97
|
-
private jwkToKeyObject(jwk: JWK): crypto.KeyObject {
|
|
98
|
-
return crypto.createPublicKey({
|
|
99
|
-
key: {
|
|
100
|
-
kty: jwk.kty,
|
|
101
|
-
n: jwk.n,
|
|
102
|
-
e: jwk.e,
|
|
103
|
-
alg: jwk.alg,
|
|
104
|
-
},
|
|
105
|
-
format: 'jwk',
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Get public key for a specific key ID
|
|
111
|
-
*/
|
|
112
|
-
private async getPublicKey(
|
|
113
|
-
kid: string,
|
|
114
|
-
cacheKey: string,
|
|
115
|
-
endpoint: string,
|
|
116
|
-
headers?: Record<string, string>
|
|
117
|
-
): Promise<crypto.KeyObject> {
|
|
118
|
-
// Check cache first
|
|
119
|
-
const cached = this.cache.get(cacheKey);
|
|
120
|
-
if (cached && cached.expiresAt > Date.now()) {
|
|
121
|
-
console.log(`[TokenVerifier] ✅ Using cached key for kid: ${kid}`);
|
|
122
|
-
return cached.key;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
console.log(
|
|
126
|
-
`[TokenVerifier] 🔍 Cache miss or expired. Fetching new key for kid: ${kid}`
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
// Fetch JWK Set
|
|
130
|
-
const jwkSet = await this.fetchJWKSet(endpoint, headers);
|
|
131
|
-
|
|
132
|
-
// Find the key with matching kid
|
|
133
|
-
const jwk = jwkSet.keys.find((k) => k.kid === kid);
|
|
134
|
-
if (!jwk) {
|
|
135
|
-
const availableKids = jwkSet.keys.map((k) => k.kid).join(', ');
|
|
136
|
-
console.error(
|
|
137
|
-
`[TokenVerifier] ❌ Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`
|
|
138
|
-
);
|
|
139
|
-
throw new Error(
|
|
140
|
-
`Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log(`[TokenVerifier] ✅ Found key with kid: ${kid}`);
|
|
145
|
-
|
|
146
|
-
// Convert JWK to KeyObject
|
|
147
|
-
const keyObject = this.jwkToKeyObject(jwk);
|
|
148
|
-
|
|
149
|
-
// Cache the key
|
|
150
|
-
this.cache.set(cacheKey, {
|
|
151
|
-
key: keyObject,
|
|
152
|
-
kid,
|
|
153
|
-
expiresAt: Date.now() + this.cacheTTL,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
return keyObject;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Verify JWT token using JWKs from runtime-api
|
|
161
|
-
*/
|
|
162
|
-
async verifyToken<T = any>(options: VerifyTokenOptions): Promise<T> {
|
|
163
|
-
const { url, secretKey, token, runtimeApiUrl } = options;
|
|
164
|
-
|
|
165
|
-
if (!url && !secretKey) {
|
|
166
|
-
throw new Error('Either url or secretKey must be provided');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (url && secretKey) {
|
|
170
|
-
throw new Error('Cannot provide both url and secretKey');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Decode token header to get kid (without verification)
|
|
174
|
-
const decoded = jwt.decode(token, { complete: true });
|
|
175
|
-
if (!decoded || typeof decoded === 'string') {
|
|
176
|
-
throw new Error('Invalid token format');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const header = decoded.header;
|
|
180
|
-
if (!header.kid) {
|
|
181
|
-
throw new Error('Token missing kid in header');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
let endpoint: string;
|
|
185
|
-
let cacheKey: string;
|
|
186
|
-
let headers: Record<string, string> | undefined;
|
|
187
|
-
|
|
188
|
-
if (secretKey) {
|
|
189
|
-
// Use secretKey with runtimeApiUrl
|
|
190
|
-
const apiUrl = runtimeApiUrl ?? this.runtimeApiUrl;
|
|
191
|
-
endpoint = `${apiUrl}/v1/auth/.well-known/jwks.json`;
|
|
192
|
-
cacheKey = secretKey;
|
|
193
|
-
headers = {
|
|
194
|
-
'x-api-key': secretKey,
|
|
195
|
-
};
|
|
196
|
-
console.log(
|
|
197
|
-
`[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`
|
|
198
|
-
);
|
|
199
|
-
} else {
|
|
200
|
-
// Use direct URL
|
|
201
|
-
endpoint = url!;
|
|
202
|
-
cacheKey = url!;
|
|
203
|
-
console.log(
|
|
204
|
-
`[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Get public key for this kid
|
|
209
|
-
let publicKey: crypto.KeyObject;
|
|
210
|
-
try {
|
|
211
|
-
publicKey = await this.getPublicKey(
|
|
212
|
-
header.kid,
|
|
213
|
-
cacheKey,
|
|
214
|
-
endpoint,
|
|
215
|
-
headers
|
|
216
|
-
);
|
|
217
|
-
console.log(
|
|
218
|
-
`[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid}`
|
|
219
|
-
);
|
|
220
|
-
} catch (error) {
|
|
221
|
-
console.error(
|
|
222
|
-
`[TokenVerifier] ❌ Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`
|
|
223
|
-
);
|
|
224
|
-
// If verification fails, clear cache and retry once (handles key rotation)
|
|
225
|
-
this.clearCache(cacheKey);
|
|
226
|
-
console.log(`[TokenVerifier] 🔄 Retrying after cache clear...`);
|
|
227
|
-
try {
|
|
228
|
-
publicKey = await this.getPublicKey(
|
|
229
|
-
header.kid,
|
|
230
|
-
cacheKey,
|
|
231
|
-
endpoint,
|
|
232
|
-
headers
|
|
233
|
-
);
|
|
234
|
-
console.log(
|
|
235
|
-
`[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid} (retry)`
|
|
236
|
-
);
|
|
237
|
-
} catch (retryError) {
|
|
238
|
-
console.error(
|
|
239
|
-
`[TokenVerifier] ❌ Failed to get public key (retry): ${retryError instanceof Error ? retryError.message : String(retryError)}`
|
|
240
|
-
);
|
|
241
|
-
throw retryError;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Verify token
|
|
246
|
-
try {
|
|
247
|
-
const payload = jwt.verify(token, publicKey, {
|
|
248
|
-
algorithms: ['RS256'],
|
|
249
|
-
}) as T;
|
|
250
|
-
console.log(`[TokenVerifier] ✅ Token verified successfully`);
|
|
251
|
-
return payload;
|
|
252
|
-
} catch (error) {
|
|
253
|
-
console.error(
|
|
254
|
-
`[TokenVerifier] ❌ JWT verification failed: ${error instanceof Error ? error.message : String(error)}`
|
|
255
|
-
);
|
|
256
|
-
throw error;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Clear cache (useful for testing or key rotation)
|
|
262
|
-
*/
|
|
263
|
-
clearCache(secretKeyOrUrl?: string): void {
|
|
264
|
-
if (secretKeyOrUrl) {
|
|
265
|
-
this.cache.delete(secretKeyOrUrl);
|
|
266
|
-
} else {
|
|
267
|
-
this.cache.clear();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Convenience function to verify a token
|
|
274
|
-
*/
|
|
275
|
-
export async function verifyToken<T = any>(
|
|
276
|
-
options: VerifyTokenOptions
|
|
277
|
-
): Promise<T> {
|
|
278
|
-
const verifier = new TokenVerifier();
|
|
279
|
-
return verifier.verifyToken<T>(options);
|
|
280
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { parseSSEStream, parseNDJSONStream } from '@blimu/fetch';
|
|
2
|
-
|
|
3
|
-
export type PaginableQuery = { limit?: number; offset?: number } & Record<
|
|
4
|
-
string,
|
|
5
|
-
unknown
|
|
6
|
-
>;
|
|
7
|
-
|
|
8
|
-
export async function* paginate<T>(
|
|
9
|
-
fetchPage: (
|
|
10
|
-
query?: any,
|
|
11
|
-
init?: Omit<RequestInit, 'method' | 'body'>
|
|
12
|
-
) => Promise<{
|
|
13
|
-
data?: T[];
|
|
14
|
-
hasMore?: boolean;
|
|
15
|
-
limit?: number;
|
|
16
|
-
offset?: number;
|
|
17
|
-
}>,
|
|
18
|
-
initialQuery: PaginableQuery = {},
|
|
19
|
-
pageSize = 100
|
|
20
|
-
): AsyncGenerator<T, void, unknown> {
|
|
21
|
-
let offset = Number(initialQuery.offset ?? 0);
|
|
22
|
-
const limit = Number(initialQuery.limit ?? pageSize);
|
|
23
|
-
// shallow copy to avoid mutating caller
|
|
24
|
-
const baseQuery: any = { ...initialQuery };
|
|
25
|
-
while (true) {
|
|
26
|
-
const page = await fetchPage({ ...baseQuery, limit, offset });
|
|
27
|
-
const items = page.data ?? [];
|
|
28
|
-
for (const item of items) {
|
|
29
|
-
yield item as T;
|
|
30
|
-
}
|
|
31
|
-
if (!page.hasMore || items.length < limit) break;
|
|
32
|
-
offset += limit;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function listAll<T>(
|
|
37
|
-
fetchPage: (
|
|
38
|
-
query?: any,
|
|
39
|
-
init?: Omit<RequestInit, 'method' | 'body'>
|
|
40
|
-
) => Promise<{
|
|
41
|
-
data?: T[];
|
|
42
|
-
hasMore?: boolean;
|
|
43
|
-
limit?: number;
|
|
44
|
-
offset?: number;
|
|
45
|
-
}>,
|
|
46
|
-
query: PaginableQuery = {},
|
|
47
|
-
pageSize = 100
|
|
48
|
-
): Promise<T[]> {
|
|
49
|
-
const out: T[] = [];
|
|
50
|
-
for await (const item of paginate<T>(fetchPage, query, pageSize))
|
|
51
|
-
out.push(item);
|
|
52
|
-
return out;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Re-export streaming parsers from @blimu/fetch
|
|
56
|
-
export { parseSSEStream, parseNDJSONStream };
|