pgbeam 0.4.1 → 0.4.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 +1 -1
- package/dist/index.cjs +79 -17
- package/dist/index.d.cts +12 -3
- package/dist/index.d.mts +12 -3
- package/dist/index.mjs +79 -17
- package/dist/{operations-map.gen-c7vqzfzd.cjs → operations-map.gen-fpzclg56.cjs} +9 -0
- package/dist/{operations-map.gen-g44nmkz5.js → operations-map.gen-g1lyg7rw.js} +9 -0
- package/dist/{operations-map.gen-inkg4leg.d.ts → operations-map.gen-koycyd31.d.ts} +272 -8
- package/dist/operations.cjs +46 -5
- package/dist/operations.d.cts +1 -1
- package/dist/operations.d.mts +1 -1
- package/dist/operations.mjs +46 -5
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as operationsByPath, a as operationsByTag } from './operations-map.gen-
|
|
1
|
+
import { o as operationsByPath, a as operationsByTag } from './operations-map.gen-g1lyg7rw.js';
|
|
2
2
|
|
|
3
3
|
class ApiError extends Error {
|
|
4
4
|
constructor(status, statusText, body){
|
|
@@ -144,6 +144,58 @@ function isMutatingMethod(method) {
|
|
|
144
144
|
const upper = method.toUpperCase();
|
|
145
145
|
return upper === "POST" || upper === "PATCH";
|
|
146
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Resolve a lazy token, or give up once `timeoutMs` has passed without it.
|
|
149
|
+
*
|
|
150
|
+
* A token function is a network call in disguise. Both browser clients resolve
|
|
151
|
+
* a JWT from an auth endpoint (`authClient.token()`), so an auth endpoint that
|
|
152
|
+
* accepts the request and never answers is a stall like any other. It just
|
|
153
|
+
* happened before the attempt loop, where none of this module's bounds reach:
|
|
154
|
+
* `AbortSignal.timeout` is attached to the fetch, `totalBudgetMs` is measured
|
|
155
|
+
* from the first attempt, and neither exists yet. A `try`/`catch` in the token
|
|
156
|
+
* function does not cover it either, because a call that never answers never
|
|
157
|
+
* rejects. The result was a request with no ceiling of any kind, which is
|
|
158
|
+
* exactly what every other bound in this file was written to rule out.
|
|
159
|
+
*
|
|
160
|
+
* The failure is reported as a timed-out `NetworkError`, the same shape a
|
|
161
|
+
* stalled attempt produces, because it is the same event to a caller: the
|
|
162
|
+
* request never got an answer and a second try tests the same thing again.
|
|
163
|
+
* `lib/query-provider.tsx` in the dashboard already withholds its retry on
|
|
164
|
+
* `timedOut`, so it gets the right behaviour here for free.
|
|
165
|
+
*
|
|
166
|
+
* The bound is `timeoutMs`, the per-attempt ceiling, because the token round
|
|
167
|
+
* trip is an attempt. A call whose token stalls and whose request then stalls
|
|
168
|
+
* costs two of them, which is the honest cost of two sequential round trips and
|
|
169
|
+
* still finite, where before it was unbounded.
|
|
170
|
+
*
|
|
171
|
+
* `timeoutMs` of 0 disables the fetch timeout by documented contract, so it
|
|
172
|
+
* disables this one too rather than inventing a ceiling the caller turned off.
|
|
173
|
+
*/ async function resolveToken(token, ctx) {
|
|
174
|
+
if (typeof token !== "function") return token;
|
|
175
|
+
if (ctx.timeoutMs <= 0) return token();
|
|
176
|
+
const stalled = Symbol("token-timeout");
|
|
177
|
+
let timer;
|
|
178
|
+
const deadline = new Promise((resolve)=>{
|
|
179
|
+
timer = setTimeout(()=>resolve(stalled), ctx.timeoutMs);
|
|
180
|
+
});
|
|
181
|
+
// A rejection from `token()` wins the race and propagates unchanged: the
|
|
182
|
+
// function decided it had failed, and relabelling that as a network timeout
|
|
183
|
+
// would lose the reason.
|
|
184
|
+
const resolved = await Promise.race([
|
|
185
|
+
token(),
|
|
186
|
+
deadline
|
|
187
|
+
]).finally(()=>clearTimeout(timer));
|
|
188
|
+
if (resolved !== stalled) return resolved;
|
|
189
|
+
throw new NetworkError({
|
|
190
|
+
method: ctx.method,
|
|
191
|
+
url: ctx.url,
|
|
192
|
+
attempts: 0,
|
|
193
|
+
elapsedMs: Date.now() - ctx.startedAt,
|
|
194
|
+
timedOut: true,
|
|
195
|
+
timeoutMs: ctx.timeoutMs,
|
|
196
|
+
cause: new Error("token resolution did not settle")
|
|
197
|
+
});
|
|
198
|
+
}
|
|
147
199
|
async function fetcher(options) {
|
|
148
200
|
let url = options.path;
|
|
149
201
|
if (options.pathParams) {
|
|
@@ -159,19 +211,27 @@ async function fetcher(options) {
|
|
|
159
211
|
}
|
|
160
212
|
}
|
|
161
213
|
}
|
|
162
|
-
const headers = {};
|
|
163
|
-
if (options.token) {
|
|
164
|
-
headers.Authorization = `Bearer ${options.token}`;
|
|
165
|
-
}
|
|
166
|
-
if (options.body !== undefined) {
|
|
167
|
-
headers["Content-Type"] = "application/json";
|
|
168
|
-
}
|
|
169
214
|
const fetchFn = options.fetchImpl ?? globalThis.fetch;
|
|
170
215
|
const retry = resolveRetry(options.retry);
|
|
171
216
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
172
217
|
const startedAt = Date.now();
|
|
173
218
|
const urlStr = fullUrl.toString();
|
|
174
219
|
const fetchBody = options.body !== undefined ? JSON.stringify(options.body) : undefined;
|
|
220
|
+
// Resolved once, before the attempt loop, so retries reuse one token rather
|
|
221
|
+
// than paying for a fresh auth round trip each time.
|
|
222
|
+
const token = await resolveToken(options.token, {
|
|
223
|
+
method: options.method,
|
|
224
|
+
url: urlStr,
|
|
225
|
+
startedAt,
|
|
226
|
+
timeoutMs
|
|
227
|
+
});
|
|
228
|
+
const headers = {};
|
|
229
|
+
if (token) {
|
|
230
|
+
headers.Authorization = `Bearer ${token}`;
|
|
231
|
+
}
|
|
232
|
+
if (options.body !== undefined) {
|
|
233
|
+
headers["Content-Type"] = "application/json";
|
|
234
|
+
}
|
|
175
235
|
// Generate idempotency key once, reused across all retry attempts.
|
|
176
236
|
const idempotencyKey = retry.maxRetries > 0 && retry.idempotencyKeys && isMutatingMethod(options.method) ? generateUUID() : undefined;
|
|
177
237
|
for(let attempt = 0; attempt <= retry.maxRetries; attempt++){
|
|
@@ -274,14 +334,16 @@ class PgBeamClient {
|
|
|
274
334
|
this._timeoutMs = options.timeoutMs;
|
|
275
335
|
this._operations = options.operations ?? publicRegistry;
|
|
276
336
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
337
|
+
/**
|
|
338
|
+
* `token` is handed to the fetcher unresolved on purpose.
|
|
339
|
+
*
|
|
340
|
+
* Awaiting a token function here put the auth round trip outside every bound
|
|
341
|
+
* the fetcher applies, so a token endpoint that accepted the request and never
|
|
342
|
+
* answered left the call outstanding with no ceiling at all: not `timeoutMs`,
|
|
343
|
+
* not the retry budget, and with no `timedOut` signal for a caller to branch
|
|
344
|
+
* on. The fetcher resolves it under the same per-attempt timeout as the
|
|
345
|
+
* request it authenticates.
|
|
346
|
+
*/ async _send(meta, params) {
|
|
285
347
|
return fetcher({
|
|
286
348
|
method: meta.method,
|
|
287
349
|
path: meta.path,
|
|
@@ -289,7 +351,7 @@ class PgBeamClient {
|
|
|
289
351
|
queryParams: params.queryParams,
|
|
290
352
|
body: params.body,
|
|
291
353
|
baseUrl: this._baseUrl,
|
|
292
|
-
token,
|
|
354
|
+
token: this._tokenOrFn,
|
|
293
355
|
fetchImpl: this._fetchImpl,
|
|
294
356
|
onResponse: this._onResponse,
|
|
295
357
|
retry: this._retry,
|
|
@@ -53,6 +53,10 @@
|
|
|
53
53
|
method: "GET",
|
|
54
54
|
path: "/v1/projects/{project_id}/audit-logs/export"
|
|
55
55
|
},
|
|
56
|
+
getAuditSessionSummary: {
|
|
57
|
+
method: "GET",
|
|
58
|
+
path: "/v1/projects/{project_id}/audit-logs/sessions/{session_id}"
|
|
59
|
+
},
|
|
56
60
|
verifyAuditChain: {
|
|
57
61
|
method: "GET",
|
|
58
62
|
path: "/v1/projects/{project_id}/audit-logs/verify"
|
|
@@ -455,6 +459,11 @@ const operationsByPath = {
|
|
|
455
459
|
path: "/v1/projects/{project_id}/audit-logs/export",
|
|
456
460
|
operationId: "exportAuditLogs"
|
|
457
461
|
},
|
|
462
|
+
"GET /v1/projects/{project_id}/audit-logs/sessions/{session_id}": {
|
|
463
|
+
method: "GET",
|
|
464
|
+
path: "/v1/projects/{project_id}/audit-logs/sessions/{session_id}",
|
|
465
|
+
operationId: "getAuditSessionSummary"
|
|
466
|
+
},
|
|
458
467
|
"GET /v1/projects/{project_id}/audit-logs/verify": {
|
|
459
468
|
method: "GET",
|
|
460
469
|
path: "/v1/projects/{project_id}/audit-logs/verify",
|
|
@@ -53,6 +53,10 @@
|
|
|
53
53
|
method: "GET",
|
|
54
54
|
path: "/v1/projects/{project_id}/audit-logs/export"
|
|
55
55
|
},
|
|
56
|
+
getAuditSessionSummary: {
|
|
57
|
+
method: "GET",
|
|
58
|
+
path: "/v1/projects/{project_id}/audit-logs/sessions/{session_id}"
|
|
59
|
+
},
|
|
56
60
|
verifyAuditChain: {
|
|
57
61
|
method: "GET",
|
|
58
62
|
path: "/v1/projects/{project_id}/audit-logs/verify"
|
|
@@ -455,6 +459,11 @@ const operationsByPath = {
|
|
|
455
459
|
path: "/v1/projects/{project_id}/audit-logs/export",
|
|
456
460
|
operationId: "exportAuditLogs"
|
|
457
461
|
},
|
|
462
|
+
"GET /v1/projects/{project_id}/audit-logs/sessions/{session_id}": {
|
|
463
|
+
method: "GET",
|
|
464
|
+
path: "/v1/projects/{project_id}/audit-logs/sessions/{session_id}",
|
|
465
|
+
operationId: "getAuditSessionSummary"
|
|
466
|
+
},
|
|
458
467
|
"GET /v1/projects/{project_id}/audit-logs/verify": {
|
|
459
468
|
method: "GET",
|
|
460
469
|
path: "/v1/projects/{project_id}/audit-logs/verify",
|