@richardmcquiston01/error-log-adapter 0.4.0 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,17 @@ interface ErrorLogEntry<TCode extends string = string> {
10
10
  source?: string;
11
11
  /** ISO 8601 timestamp. Adapters fill this in when it is omitted. */
12
12
  timestamp?: string;
13
+ /**
14
+ * Optional UUID that identifies this entry. Adapters generate a new one for
15
+ * every `log` call when it is omitted, so logging the same entry twice stores
16
+ * it twice. Supply the same `id` (and, for S3, the same `timestamp`) to make
17
+ * a retry safe: sinks that can detect a repeat overwrite or skip the existing
18
+ * record instead of adding another. It must be a UUID, for example from
19
+ * `crypto.randomUUID()`; anything else makes `log` return `ok: false`.
20
+ * Redis, the flat file and NDJSON file adapters, and the console cannot
21
+ * detect a repeat.
22
+ */
23
+ id?: string;
13
24
  }
14
25
  /** Outcome of a `log` call. Callers should check `ok`. */
15
26
  interface ErrorLogResult {
@@ -34,8 +45,16 @@ interface SerializedErrorLogEntry {
34
45
  timestamp: string;
35
46
  }
36
47
  /**
37
- * Converts `Error` instances into plain objects, since `JSON.stringify`
38
- * renders them as `{}`. Other values are returned unchanged.
48
+ * Returns a copy of `cause` that `JSON.stringify` can always handle, so a
49
+ * strange cause can never stop an entry from being stored.
50
+ *
51
+ * - `Error` objects (including ones from another realm) become
52
+ * `{ name, message, stack }`, plus `cause` and, for an `AggregateError`,
53
+ * `errors`, which are converted the same way.
54
+ * - Circular references become `"[Circular]"`, and anything nested deeper than
55
+ * `MAX_CAUSE_DEPTH` levels becomes `"[Truncated]"`.
56
+ * - `BigInt`, `Symbol` and function values, and non-finite numbers, become strings.
57
+ * - A property or `toJSON` that throws is replaced by a short description.
39
58
  */
40
59
  declare function serializeCause(cause: unknown): unknown;
41
60
  /** Returns a JSON-safe copy of the entry, adding a timestamp if missing. */
@@ -56,13 +75,34 @@ interface WebhookErrorOptions {
56
75
  headers?: Record<string, string>;
57
76
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
58
77
  prefix?: string;
78
+ /**
79
+ * Allow a plain `http://` URL. Entries contain error messages and stack
80
+ * traces, so they are only sent over `https://` unless this is `true`.
81
+ * `http://localhost`, `127.0.0.1` and `[::1]` are always allowed.
82
+ * Defaults to `false`.
83
+ */
84
+ allowInsecure?: boolean;
85
+ /**
86
+ * How long to wait for the webhook to answer, in milliseconds. Defaults to
87
+ * 10000. Pass `Infinity` to wait without limit. When it passes, the request is
88
+ * cancelled, so the connection is closed rather than left open; the server may
89
+ * still have received the entry.
90
+ */
91
+ timeoutMs?: number;
59
92
  }
60
93
  declare class WebhookErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
61
94
  private readonly url;
62
95
  private readonly options;
63
96
  private readonly prefix;
97
+ private readonly timeoutMs;
98
+ /** Scheme and host only. Webhook URLs often carry a secret in the path or query. */
99
+ private readonly target;
100
+ /** @throws {RangeError} if `url` is not a valid `https://` URL (see `allowInsecure`) or `timeoutMs` is invalid. */
64
101
  constructor(url: string, options?: WebhookErrorOptions);
65
102
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
103
+ private redirectMessage;
104
+ /** Replaces the full URL in a message with its origin, in case the runtime put it there. */
105
+ private redact;
66
106
  private fail;
67
107
  }
68
108
 
@@ -73,26 +113,63 @@ interface CollectionLike {
73
113
  interface MongoDbErrorOptions {
74
114
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
75
115
  prefix?: string;
116
+ /**
117
+ * How long `log` waits for the insert before giving up, in milliseconds. Defaults to
118
+ * 10000. Pass `Infinity` to wait without limit. The call cannot be cancelled,
119
+ * so it may still finish after `log` has returned a failure.
120
+ */
121
+ timeoutMs?: number;
76
122
  }
77
123
  declare class MongoDbErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
78
124
  private readonly collection;
79
125
  private readonly prefix;
126
+ private readonly timeoutMs;
127
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or Infinity. */
80
128
  constructor(collection: CollectionLike, options?: MongoDbErrorOptions);
81
129
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
82
130
  }
83
131
 
132
+ interface CompositeErrorOptions {
133
+ /**
134
+ * How long to wait for each adapter before reporting it as failed, in
135
+ * milliseconds. Defaults to 30000, longer than the 10000 default of the built-in
136
+ * adapters so their own, more specific timeout messages come first. This only
137
+ * matters for a custom adapter that can hang: one stuck adapter then cannot
138
+ * hold back the result of the others. Pass `Infinity` to wait without limit.
139
+ */
140
+ timeoutMs?: number;
141
+ }
84
142
  /** Sends every entry to several adapters. Succeeds only if all of them do. */
85
143
  declare class CompositeErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
86
144
  private readonly adapters;
87
- constructor(adapters: ReadonlyArray<ErrorLogAdapter<TCode>>);
145
+ private readonly timeoutMs;
146
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or Infinity. */
147
+ constructor(adapters: ReadonlyArray<ErrorLogAdapter<TCode>>, options?: CompositeErrorOptions);
88
148
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
89
149
  }
90
150
 
91
151
  /** Event handler slot. Typed loosely so real DOM `IDBTransaction` objects fit. */
92
152
  type IdbHandler = ((event: never) => unknown) | null;
153
+ /** The error object of a failed request or transaction (a `DOMException`). */
154
+ interface IdbErrorLike {
155
+ name?: string;
156
+ message?: string;
157
+ }
158
+ /** The subset of an `IDBRequest` this adapter uses. */
159
+ interface IdbRequestLike {
160
+ onerror: IdbHandler;
161
+ readonly error?: IdbErrorLike | null;
162
+ }
93
163
  /** The subset of an `IDBObjectStore` this adapter uses. */
94
164
  interface IdbObjectStoreLike {
165
+ /** Returns an `IDBRequest`. Fakes that return nothing also work. */
95
166
  add(value: unknown): unknown;
167
+ /**
168
+ * Replaces the record with the same key. Used for entries that carry their own
169
+ * `id`, so logging one again does not fail on the existing key. A real
170
+ * `IDBObjectStore` has it; a fake without it falls back to `add`.
171
+ */
172
+ put?(value: unknown): unknown;
96
173
  }
97
174
  /** The subset of an `IDBTransaction` this adapter uses. */
98
175
  interface IdbTransactionLike {
@@ -100,9 +177,7 @@ interface IdbTransactionLike {
100
177
  oncomplete: IdbHandler;
101
178
  onerror: IdbHandler;
102
179
  onabort: IdbHandler;
103
- readonly error?: {
104
- message?: string;
105
- } | null;
180
+ readonly error?: IdbErrorLike | null;
106
181
  }
107
182
  /** The subset of an `IDBDatabase` this adapter uses. */
108
183
  interface IdbDatabaseLike {
@@ -128,6 +203,13 @@ interface IndexedDbErrorOptions {
128
203
  storeName?: string;
129
204
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
130
205
  prefix?: string;
206
+ /**
207
+ * How long `log` waits for the transaction to finish, in milliseconds. Defaults
208
+ * to 10000. Pass `Infinity` to wait without limit. A transaction can stay
209
+ * pending when a version change in another tab blocks it, or when the browser
210
+ * has evicted the origin's storage. The write may still finish afterwards.
211
+ */
212
+ timeoutMs?: number;
131
213
  }
132
214
  /**
133
215
  * Creates the error log object store (UUID `id` key, `timestamp` index).
@@ -138,9 +220,18 @@ declare class IndexedDbErrorAdapter<TCode extends string = string> implements Er
138
220
  private readonly database;
139
221
  private readonly storeName;
140
222
  private readonly prefix;
223
+ private readonly timeoutMs;
224
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or Infinity. */
141
225
  constructor(database: IdbDatabaseLike, options?: IndexedDbErrorOptions);
142
226
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
143
- /** Resolves once the transaction commits; rejects if it errors or aborts. */
227
+ /**
228
+ * Resolves once the transaction commits; rejects if the request fails, the
229
+ * transaction aborts, or it does not finish within `timeoutMs`.
230
+ *
231
+ * Error events are handled here (`preventDefault` and `stopPropagation`), so a
232
+ * failed log write does not reach the `onerror` handler an app may have set on
233
+ * its own database object.
234
+ */
144
235
  private write;
145
236
  }
146
237
 
@@ -166,6 +257,12 @@ interface SqliteErrorOptions {
166
257
  createTable?: boolean;
167
258
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
168
259
  prefix?: string;
260
+ /**
261
+ * How long `log` waits for the driver before giving up, in milliseconds. Defaults
262
+ * to 10000. Pass `Infinity` to wait without limit. The call cannot be
263
+ * cancelled, so it may still finish after `log` has returned a failure.
264
+ */
265
+ timeoutMs?: number;
169
266
  }
170
267
  /**
171
268
  * Returns the statements that create the error log table and its index.
@@ -177,13 +274,16 @@ declare class SqliteErrorAdapter<TCode extends string = string> implements Error
177
274
  private readonly tableName;
178
275
  private readonly createTable;
179
276
  private readonly prefix;
277
+ private readonly timeoutMs;
180
278
  private tableReady;
181
- /** @throws {RangeError} if `options.tableName` is not a plain identifier. */
279
+ /** @throws {RangeError} if `options.tableName` is not a plain identifier or `options.timeoutMs` is invalid. */
182
280
  constructor(client: SqliteClientLike, options?: SqliteErrorOptions);
183
281
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
184
282
  /** Creates the table once. A failed attempt is retried on the next log call. */
185
283
  private ensureTable;
186
284
  private runCreateStatements;
285
+ /** Runs one statement, giving up waiting after `timeoutMs`. */
286
+ private run;
187
287
  }
188
288
 
189
289
  /**
@@ -194,6 +294,14 @@ interface StorageLike {
194
294
  getItem(key: string): string | null;
195
295
  setItem(key: string, value: string): void;
196
296
  }
297
+ /**
298
+ * The part of `navigator.locks` this adapter uses. `localStorage` is shared by
299
+ * every tab of an origin and has no atomic update, so a lock keeps two tabs from
300
+ * overwriting each other's entry.
301
+ */
302
+ interface LockManagerLike {
303
+ request<T>(name: string, callback: () => T | Promise<T>): Promise<T>;
304
+ }
197
305
  /** A stored record: the serialized entry plus its generated UUID. */
198
306
  interface WebStorageErrorRecord extends SerializedErrorLogEntry {
199
307
  id: string;
@@ -205,24 +313,51 @@ interface WebStorageErrorOptions {
205
313
  maxEntries?: number;
206
314
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
207
315
  prefix?: string;
316
+ /**
317
+ * Lock manager that makes tabs sharing a `localStorage` take turns. Defaults to
318
+ * `navigator.locks` when the browser has it. This reduces lost entries but does
319
+ * not remove them: a tab in another process can still read a stale copy
320
+ * (measured in Chromium). Pass `null` to turn locking off.
321
+ */
322
+ locks?: LockManagerLike | null;
208
323
  }
209
324
  /**
210
325
  * Keeps the newest entries in a Web Storage object (`sessionStorage` or
211
326
  * `localStorage`) as a JSON array under one key, capped at `maxEntries`.
212
327
  * When the store is full, the oldest entries are dropped until the new one fits.
328
+ *
329
+ * `sessionStorage` belongs to one tab, so it is safe. `localStorage` is shared by
330
+ * every tab of the origin and has no atomic update: two tabs logging at the same
331
+ * moment can overwrite each other's entry while both get `ok: true`. In Chromium,
332
+ * tabs in separate processes (the usual case) even read a stale copy, so a lock
333
+ * reduces the loss without removing it. Where tabs may log at the same time and
334
+ * every entry matters, use `IndexedDbErrorAdapter`, whose writes are transactional.
213
335
  */
214
336
  declare class WebStorageErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
215
337
  private readonly storage;
216
338
  private readonly key;
217
339
  private readonly maxEntries;
218
340
  private readonly prefix;
341
+ private readonly locks;
219
342
  /** @throws {RangeError} if `options.maxEntries` is not a positive integer. */
220
343
  constructor(storage: StorageLike, options?: WebStorageErrorOptions);
221
344
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
222
- /** Reads, appends, trims, and writes back. Runs without awaiting, so calls never interleave. */
345
+ /**
346
+ * Appends under a cross-tab lock when one is available. If the lock itself
347
+ * cannot be taken (for example a sandboxed frame), the entry is still written
348
+ * without it rather than lost.
349
+ */
350
+ private appendLocked;
351
+ /** Reads, appends, trims, and writes back. Runs without awaiting, so calls in one tab never interleave. */
223
352
  private append;
224
353
  /** Returns the stored records, or none if the value is missing or unreadable. */
225
354
  private readRecords;
355
+ /**
356
+ * Copies an unusable value to `<key>.corrupt` before it is replaced, so data
357
+ * the host app stored under the same key is not silently destroyed. Only the
358
+ * first one is kept; a later unusable value would not overwrite it.
359
+ */
360
+ private setAside;
226
361
  }
227
362
 
228
363
  /**
@@ -281,7 +416,7 @@ declare class FlatFileErrorAdapter<TCode extends string = string> implements Err
281
416
  private readonly prefix;
282
417
  private fs;
283
418
  private directoryReady;
284
- private queue;
419
+ private readonly queue;
285
420
  /** @throws {RangeError} if `maxBytes` or `maxFiles` is not a positive integer. */
286
421
  constructor(filePath: string, options?: FlatFileErrorOptions);
287
422
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
@@ -334,7 +469,7 @@ declare class JsonFileErrorAdapter<TCode extends string = string> implements Err
334
469
  private readonly prefix;
335
470
  private fs;
336
471
  private directoryReady;
337
- private queue;
472
+ private readonly queue;
338
473
  /** @throws {RangeError} if `maxEntries` or `indent` is invalid, or `maxEntries` is used outside array mode. */
339
474
  constructor(filePath: string, options?: JsonFileErrorOptions);
340
475
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
@@ -371,6 +506,12 @@ interface SqlErrorOptions {
371
506
  createTable?: boolean;
372
507
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
373
508
  prefix?: string;
509
+ /**
510
+ * How long `log` waits for each database statement before giving up, in milliseconds. Defaults
511
+ * to 10000. Pass `Infinity` to wait without limit. The call cannot be
512
+ * cancelled, so it may still finish after `log` has returned a failure.
513
+ */
514
+ timeoutMs?: number;
374
515
  }
375
516
  /**
376
517
  * Returns the statements that create the error log table and its index for a
@@ -381,6 +522,12 @@ interface SqlErrorOptions {
381
522
  * cause, and `DATETIME(3)` columns holding UTC times.
382
523
  */
383
524
  declare function buildErrorLogTableDdl(dialect: SqlDialect, tableName?: string): string[];
525
+ /**
526
+ * Returns the statement that widens the `code` and `source` columns of a MySQL
527
+ * table created by `buildErrorLogTableDdl` in 0.4.0 or earlier, where they were
528
+ * `VARCHAR(255)` and a longer value made the insert fail. Run it once.
529
+ */
530
+ declare function buildMySqlWidenColumnsSql(tableName?: string): string[];
384
531
  /** Shared by the Postgres and MySQL adapters: only the SQL text and time format differ. */
385
532
  declare abstract class SqlErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
386
533
  private readonly client;
@@ -389,6 +536,7 @@ declare abstract class SqlErrorAdapter<TCode extends string = string> implements
389
536
  private readonly tableName;
390
537
  private readonly createTable;
391
538
  private readonly prefix;
539
+ private readonly timeoutMs;
392
540
  private tableReady;
393
541
  protected constructor(client: SqlClientLike, dialect: SqlDialect, adapterName: string, options: SqlErrorOptions);
394
542
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
@@ -396,6 +544,8 @@ declare abstract class SqlErrorAdapter<TCode extends string = string> implements
396
544
  /** Creates the table once. A failed attempt is retried on the next log call. */
397
545
  private ensureTable;
398
546
  private runCreateStatements;
547
+ /** Runs one statement, giving up waiting after `timeoutMs`. */
548
+ private query;
399
549
  }
400
550
  /**
401
551
  * Writes entries to Postgres. Pass a `pg` `Pool` or `Client`.
@@ -454,6 +604,12 @@ interface RedisErrorOptions {
454
604
  side?: 'left' | 'right';
455
605
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
456
606
  prefix?: string;
607
+ /**
608
+ * How long `log` waits for each Redis command before giving up, in milliseconds. Defaults
609
+ * to 10000. Pass `Infinity` to wait without limit. The call cannot be
610
+ * cancelled, so it may still finish after `log` has returned a failure.
611
+ */
612
+ timeoutMs?: number;
457
613
  }
458
614
  /**
459
615
  * Writes entries to Redis, either as a capped list of JSON strings or as a
@@ -467,6 +623,7 @@ declare class RedisErrorAdapter<TCode extends string = string> implements ErrorL
467
623
  private readonly maxEntries;
468
624
  private readonly side;
469
625
  private readonly prefix;
626
+ private readonly timeoutMs;
470
627
  /** @throws {RangeError} if `key` is empty, `maxEntries` is not a positive integer, or `mode` / `side` is unknown. */
471
628
  constructor(client: RedisClientLike, options?: RedisErrorOptions);
472
629
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
@@ -476,6 +633,8 @@ declare class RedisErrorAdapter<TCode extends string = string> implements ErrorL
476
633
  * stored by now, so a trim failure is reported but does not fail the call;
477
634
  * the next successful write trims the list again.
478
635
  */
636
+ /** Sends one command, giving up waiting after `timeoutMs`. */
637
+ private send;
479
638
  private trimList;
480
639
  }
481
640
 
@@ -528,6 +687,13 @@ interface S3ErrorOptions {
528
687
  batch?: S3BatchOptions;
529
688
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
530
689
  prefix?: string;
690
+ /**
691
+ * How long an upload may take before `log` (or `flush`) gives up waiting, in
692
+ * milliseconds. Defaults to 10000. Pass `Infinity` to wait without limit. The
693
+ * upload cannot be cancelled, so it may still finish afterwards; in batch mode
694
+ * the entries stay buffered and are uploaded again by the next flush.
695
+ */
696
+ timeoutMs?: number;
531
697
  }
532
698
  /**
533
699
  * Stores entries as objects in an S3-compatible bucket, keyed by date and UUID:
@@ -546,9 +712,10 @@ declare class S3ErrorAdapter<TCode extends string = string> implements ErrorLogA
546
712
  private readonly contentType;
547
713
  private readonly batch;
548
714
  private readonly logPrefix;
715
+ private readonly timeoutMs;
549
716
  private buffer;
550
717
  private timer;
551
- private flushQueue;
718
+ private readonly flushQueue;
552
719
  /** @throws {RangeError} if `bucket` is empty or the batch options are invalid. */
553
720
  constructor(client: S3ClientLike, bucket: string, options?: S3ErrorOptions);
554
721
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
@@ -604,11 +771,19 @@ interface FirestoreCollectionLike {
604
771
  * ```ts
605
772
  * const refLike: RealtimeDatabaseRefLike = {
606
773
  * push: (value) => push(ref(db, 'error_log'), value),
774
+ * child: (key) => ({ set: (value) => set(ref(db, `error_log/${key}`), value) }),
607
775
  * };
608
776
  * ```
777
+ *
778
+ * `child(key).set(value)` is only needed for entries that carry their own `id`
779
+ * (see `ErrorLogEntry.id`): they are written under that key, so logging the same
780
+ * entry again overwrites the record instead of adding a second one.
609
781
  */
610
782
  interface RealtimeDatabaseRefLike {
611
783
  push(value: FirebaseErrorRecord): PromiseLike<unknown>;
784
+ child?(key: string): {
785
+ set(value: FirebaseErrorRecord): PromiseLike<unknown>;
786
+ };
612
787
  }
613
788
  interface FirebaseErrorOptions {
614
789
  /**
@@ -618,7 +793,9 @@ interface FirebaseErrorOptions {
618
793
  * The Firebase SDKs keep writes queued while the connection is down, and
619
794
  * their promises stay pending until it returns, so without a limit `log`
620
795
  * could hang for as long as an outage lasts. A write that timed out is still
621
- * queued by the SDK and may be saved later.
796
+ * queued by the SDK and may be saved later. Retry a timeout only with the same
797
+ * `ErrorLogEntry.id`, so the retry overwrites the first write instead of
798
+ * adding a second one.
622
799
  */
623
800
  timeoutMs?: number;
624
801
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
@@ -626,7 +803,11 @@ interface FirebaseErrorOptions {
626
803
  }
627
804
  /**
628
805
  * Writes each entry as a document in a Firestore collection. The document id is
629
- * the entry's UUID, so retrying a write never creates a duplicate.
806
+ * the entry's UUID, so the SDK finishing one queued write twice cannot create two
807
+ * documents. Calling `log` again without an `id` on the entry is a new write
808
+ * with a new UUID: if a call reported a timeout, the first write may still be
809
+ * saved later, and logging the same entry again can store it twice. Give the
810
+ * entry an `id` and the retry overwrites the same document.
630
811
  */
631
812
  declare class FirestoreErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
632
813
  private readonly collection;
@@ -684,26 +865,46 @@ interface SupabaseClientLike {
684
865
  };
685
866
  }
686
867
  interface SupabaseErrorOptions {
687
- /** Table to write to. Defaults to `error_log`. */
868
+ /** Table to write to. Defaults to `error_log`. Letters, digits and `_` only. */
688
869
  tableName?: string;
689
870
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
690
871
  prefix?: string;
872
+ /**
873
+ * How long `log` waits for Supabase to answer before giving up, in milliseconds. Defaults
874
+ * to 10000. Pass `Infinity` to wait without limit. The call cannot be
875
+ * cancelled, so it may still finish after `log` has returned a failure.
876
+ */
877
+ timeoutMs?: number;
691
878
  }
692
879
  interface SupabaseSetupOptions {
693
880
  /**
694
- * Postgres roles allowed to insert, for example `['anon', 'authenticated']`
695
- * when the browser logs with the public key. Leave empty when only a server
696
- * using the service role key logs: that role bypasses row level security.
881
+ * Postgres roles allowed to insert through the API, for example
882
+ * `['authenticated']`. Leave empty when only a server using the service role
883
+ * key logs: that role bypasses row level security, so it needs no policy, and
884
+ * its key must never be shipped to a browser.
885
+ *
886
+ * The generated policy only checks the size of each field. It does not tie a
887
+ * row to a user, so any holder of an allowed role's key can still add entries
888
+ * of their own making: forged entries can hide real incidents, and a flood of
889
+ * them uses up your database quota. Prefer `authenticated` over `anon`.
697
890
  */
698
891
  insertRoles?: string[];
892
+ /**
893
+ * Required to allow `anon` (or `public`) to insert. The `anon` key is part of
894
+ * your frontend, so this lets anyone who loads the page write to the log.
895
+ * Defaults to `false`.
896
+ */
897
+ allowPublicInsert?: boolean;
699
898
  }
700
899
  /**
701
900
  * Returns the SQL to run once in the Supabase SQL editor: the error log table,
702
901
  * with row level security turned on (as Supabase recommends for every table in
703
902
  * an exposed schema) and, optionally, an insert-only policy for the given roles.
704
- * Nobody but the service role can read the log through the API.
903
+ * The policy limits the size of each field. Nobody but the service role can read
904
+ * the log through the API.
705
905
  *
706
- * @throws {RangeError} if the table name or a role is not a plain identifier.
906
+ * @throws {RangeError} if the table name or a role is not a plain identifier, or
907
+ * `anon` / `public` is listed without `allowPublicInsert: true`.
707
908
  */
708
909
  declare function buildSupabaseSetupSql(tableName?: string, options?: SupabaseSetupOptions): string[];
709
910
  /**
@@ -721,10 +922,11 @@ declare class SupabaseErrorAdapter<TCode extends string = string> implements Err
721
922
  private readonly client;
722
923
  private readonly tableName;
723
924
  private readonly prefix;
724
- /** @throws {RangeError} if `options.tableName` is empty. */
925
+ private readonly timeoutMs;
926
+ /** @throws {RangeError} if `options.tableName` is not a plain identifier or `options.timeoutMs` is invalid. */
725
927
  constructor(client: SupabaseClientLike, options?: SupabaseErrorOptions);
726
928
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
727
929
  private fail;
728
930
  }
729
931
 
730
- export { type CollectionLike, CompositeErrorAdapter, ConsoleErrorAdapter, type ConsoleErrorOptions, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, type FileSystemLike, type FirebaseErrorOptions, type FirebaseErrorRecord, type FirestoreCollectionLike, FirestoreErrorAdapter, FlatFileErrorAdapter, type FlatFileErrorOptions, type IdbDatabaseLike, type IdbObjectStoreLike, type IdbTransactionLike, type IdbUpgradeDatabaseLike, IndexedDbErrorAdapter, type IndexedDbErrorOptions, type IndexedDbErrorRecord, JsonFileErrorAdapter, type JsonFileErrorOptions, type JsonFileErrorRecord, MongoDbErrorAdapter, type MongoDbErrorOptions, MySqlErrorAdapter, PostgresErrorAdapter, type ReadWriteFileSystemLike, RealtimeDatabaseErrorAdapter, type RealtimeDatabaseRefLike, type RedisClientLike, RedisErrorAdapter, type RedisErrorOptions, type S3BatchOptions, type S3ClientLike, S3ErrorAdapter, type S3ErrorOptions, type S3PutObjectInput, type SerializedErrorLogEntry, type SqlClientLike, type SqlDialect, type SqlErrorOptions, type SqliteClientLike, SqliteErrorAdapter, type SqliteErrorOptions, type StorageLike, type SupabaseClientLike, SupabaseErrorAdapter, type SupabaseErrorLike, type SupabaseErrorOptions, type SupabaseErrorRow, type SupabaseInsertResult, type SupabaseSetupOptions, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
932
+ export { type CollectionLike, CompositeErrorAdapter, type CompositeErrorOptions, ConsoleErrorAdapter, type ConsoleErrorOptions, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, type FileSystemLike, type FirebaseErrorOptions, type FirebaseErrorRecord, type FirestoreCollectionLike, FirestoreErrorAdapter, FlatFileErrorAdapter, type FlatFileErrorOptions, type IdbDatabaseLike, type IdbObjectStoreLike, type IdbRequestLike, type IdbTransactionLike, type IdbUpgradeDatabaseLike, IndexedDbErrorAdapter, type IndexedDbErrorOptions, type IndexedDbErrorRecord, JsonFileErrorAdapter, type JsonFileErrorOptions, type JsonFileErrorRecord, type LockManagerLike, MongoDbErrorAdapter, type MongoDbErrorOptions, MySqlErrorAdapter, PostgresErrorAdapter, type ReadWriteFileSystemLike, RealtimeDatabaseErrorAdapter, type RealtimeDatabaseRefLike, type RedisClientLike, RedisErrorAdapter, type RedisErrorOptions, type S3BatchOptions, type S3ClientLike, S3ErrorAdapter, type S3ErrorOptions, type S3PutObjectInput, type SerializedErrorLogEntry, type SqlClientLike, type SqlDialect, type SqlErrorOptions, type SqliteClientLike, SqliteErrorAdapter, type SqliteErrorOptions, type StorageLike, type SupabaseClientLike, SupabaseErrorAdapter, type SupabaseErrorLike, type SupabaseErrorOptions, type SupabaseErrorRow, type SupabaseInsertResult, type SupabaseSetupOptions, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };