@richardmcquiston01/error-log-adapter 0.9.0 → 0.10.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.cts CHANGED
@@ -802,9 +802,16 @@ interface FirebaseErrorRecord {
802
802
  */
803
803
  interface FirestoreCollectionLike {
804
804
  doc(documentId: string): {
805
- set(data: FirebaseErrorRecord): Promise<unknown>;
805
+ set(data: FirestoreErrorRecord): Promise<unknown>;
806
806
  };
807
807
  }
808
+ /**
809
+ * What the Firestore adapter writes: the usual fields, plus the expiry field
810
+ * (a `Date`, which Firestore stores as a timestamp) when `expireAfterMs` is set.
811
+ */
812
+ type FirestoreErrorRecord = FirebaseErrorRecord & {
813
+ [field: string]: unknown;
814
+ };
808
815
  /**
809
816
  * The only thing the Realtime Database adapter needs from a reference:
810
817
  * `push(value)`, which resolves once the write is saved. A `firebase-admin`
@@ -843,6 +850,25 @@ interface FirebaseErrorOptions {
843
850
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
844
851
  prefix?: string;
845
852
  }
853
+ interface FirestoreErrorOptions extends FirebaseErrorOptions {
854
+ /**
855
+ * Add an expiry time to every document: the entry's `timestamp` plus this
856
+ * many milliseconds, stored as a Firestore timestamp in `expireField`. This
857
+ * only writes the field. Firestore deletes nothing until you turn on a TTL
858
+ * policy for that field, for example:
859
+ *
860
+ * ```sh
861
+ * gcloud firestore fields ttls update expire_at \
862
+ * --collection-group=error_log --enable-ttl
863
+ * ```
864
+ *
865
+ * Firestore then removes documents some time after they expire (typically
866
+ * within a day), and the deletes are billed like any other. Off by default.
867
+ */
868
+ expireAfterMs?: number;
869
+ /** Name of the expiry field. Defaults to `expire_at`. Only used with `expireAfterMs`. */
870
+ expireField?: string;
871
+ }
846
872
  /**
847
873
  * Writes each entry as a document in a Firestore collection. The document id is
848
874
  * the entry's UUID, so the SDK finishing one queued write twice cannot create two
@@ -855,8 +881,10 @@ declare class FirestoreErrorAdapter<TCode extends string = string> implements Er
855
881
  private readonly collection;
856
882
  private readonly prefix;
857
883
  private readonly timeoutMs;
858
- /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`. */
859
- constructor(collection: FirestoreCollectionLike, options?: FirebaseErrorOptions);
884
+ private readonly expireAfterMs;
885
+ private readonly expireField;
886
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`, or the expiry options are invalid. */
887
+ constructor(collection: FirestoreCollectionLike, options?: FirestoreErrorOptions);
860
888
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
861
889
  }
862
890
  /**
@@ -1303,4 +1331,4 @@ declare class BatchingErrorAdapter<TCode extends string = string> implements Err
1303
1331
  private drop;
1304
1332
  }
1305
1333
 
1306
- export { type BatchCapableAdapter, BatchingErrorAdapter, type BatchingErrorOptions, type CloudWatchBatchOptions, type CloudWatchLogEvent, type CloudWatchLogsClientLike, CloudWatchLogsErrorAdapter, type CloudWatchLogsErrorOptions, type CloudWatchPutLogEventsInput, type CollectionLike, CompositeErrorAdapter, type CompositeErrorOptions, ConsoleErrorAdapter, type ConsoleErrorOptions, type EmitterLike, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, EventEmitterErrorAdapter, type EventEmitterErrorOptions, type EventEmitterErrorRecord, 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, WebSocketErrorAdapter, type WebSocketErrorOptions, type WebSocketLike, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
1334
+ export { type BatchCapableAdapter, BatchingErrorAdapter, type BatchingErrorOptions, type CloudWatchBatchOptions, type CloudWatchLogEvent, type CloudWatchLogsClientLike, CloudWatchLogsErrorAdapter, type CloudWatchLogsErrorOptions, type CloudWatchPutLogEventsInput, type CollectionLike, CompositeErrorAdapter, type CompositeErrorOptions, ConsoleErrorAdapter, type ConsoleErrorOptions, type EmitterLike, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, EventEmitterErrorAdapter, type EventEmitterErrorOptions, type EventEmitterErrorRecord, type FileSystemLike, type FirebaseErrorOptions, type FirebaseErrorRecord, type FirestoreCollectionLike, FirestoreErrorAdapter, type FirestoreErrorOptions, type FirestoreErrorRecord, 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, WebSocketErrorAdapter, type WebSocketErrorOptions, type WebSocketLike, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
package/dist/index.d.ts CHANGED
@@ -802,9 +802,16 @@ interface FirebaseErrorRecord {
802
802
  */
803
803
  interface FirestoreCollectionLike {
804
804
  doc(documentId: string): {
805
- set(data: FirebaseErrorRecord): Promise<unknown>;
805
+ set(data: FirestoreErrorRecord): Promise<unknown>;
806
806
  };
807
807
  }
808
+ /**
809
+ * What the Firestore adapter writes: the usual fields, plus the expiry field
810
+ * (a `Date`, which Firestore stores as a timestamp) when `expireAfterMs` is set.
811
+ */
812
+ type FirestoreErrorRecord = FirebaseErrorRecord & {
813
+ [field: string]: unknown;
814
+ };
808
815
  /**
809
816
  * The only thing the Realtime Database adapter needs from a reference:
810
817
  * `push(value)`, which resolves once the write is saved. A `firebase-admin`
@@ -843,6 +850,25 @@ interface FirebaseErrorOptions {
843
850
  /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
844
851
  prefix?: string;
845
852
  }
853
+ interface FirestoreErrorOptions extends FirebaseErrorOptions {
854
+ /**
855
+ * Add an expiry time to every document: the entry's `timestamp` plus this
856
+ * many milliseconds, stored as a Firestore timestamp in `expireField`. This
857
+ * only writes the field. Firestore deletes nothing until you turn on a TTL
858
+ * policy for that field, for example:
859
+ *
860
+ * ```sh
861
+ * gcloud firestore fields ttls update expire_at \
862
+ * --collection-group=error_log --enable-ttl
863
+ * ```
864
+ *
865
+ * Firestore then removes documents some time after they expire (typically
866
+ * within a day), and the deletes are billed like any other. Off by default.
867
+ */
868
+ expireAfterMs?: number;
869
+ /** Name of the expiry field. Defaults to `expire_at`. Only used with `expireAfterMs`. */
870
+ expireField?: string;
871
+ }
846
872
  /**
847
873
  * Writes each entry as a document in a Firestore collection. The document id is
848
874
  * the entry's UUID, so the SDK finishing one queued write twice cannot create two
@@ -855,8 +881,10 @@ declare class FirestoreErrorAdapter<TCode extends string = string> implements Er
855
881
  private readonly collection;
856
882
  private readonly prefix;
857
883
  private readonly timeoutMs;
858
- /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`. */
859
- constructor(collection: FirestoreCollectionLike, options?: FirebaseErrorOptions);
884
+ private readonly expireAfterMs;
885
+ private readonly expireField;
886
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`, or the expiry options are invalid. */
887
+ constructor(collection: FirestoreCollectionLike, options?: FirestoreErrorOptions);
860
888
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
861
889
  }
862
890
  /**
@@ -1303,4 +1331,4 @@ declare class BatchingErrorAdapter<TCode extends string = string> implements Err
1303
1331
  private drop;
1304
1332
  }
1305
1333
 
1306
- export { type BatchCapableAdapter, BatchingErrorAdapter, type BatchingErrorOptions, type CloudWatchBatchOptions, type CloudWatchLogEvent, type CloudWatchLogsClientLike, CloudWatchLogsErrorAdapter, type CloudWatchLogsErrorOptions, type CloudWatchPutLogEventsInput, type CollectionLike, CompositeErrorAdapter, type CompositeErrorOptions, ConsoleErrorAdapter, type ConsoleErrorOptions, type EmitterLike, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, EventEmitterErrorAdapter, type EventEmitterErrorOptions, type EventEmitterErrorRecord, 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, WebSocketErrorAdapter, type WebSocketErrorOptions, type WebSocketLike, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
1334
+ export { type BatchCapableAdapter, BatchingErrorAdapter, type BatchingErrorOptions, type CloudWatchBatchOptions, type CloudWatchLogEvent, type CloudWatchLogsClientLike, CloudWatchLogsErrorAdapter, type CloudWatchLogsErrorOptions, type CloudWatchPutLogEventsInput, type CollectionLike, CompositeErrorAdapter, type CompositeErrorOptions, ConsoleErrorAdapter, type ConsoleErrorOptions, type EmitterLike, type ErrorLogAdapter, type ErrorLogEntry, type ErrorLogResult, EventEmitterErrorAdapter, type EventEmitterErrorOptions, type EventEmitterErrorRecord, type FileSystemLike, type FirebaseErrorOptions, type FirebaseErrorRecord, type FirestoreCollectionLike, FirestoreErrorAdapter, type FirestoreErrorOptions, type FirestoreErrorRecord, 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, WebSocketErrorAdapter, type WebSocketErrorOptions, type WebSocketLike, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
package/dist/index.mjs CHANGED
@@ -1574,6 +1574,15 @@ var S3ErrorAdapter = class {
1574
1574
  };
1575
1575
 
1576
1576
  // src/adapters/firebase-error-adapter.ts
1577
+ var DEFAULT_EXPIRE_FIELD = "expire_at";
1578
+ var RESERVED_FIELDS = /* @__PURE__ */ new Set([
1579
+ "id",
1580
+ "code",
1581
+ "message",
1582
+ "timestamp",
1583
+ "source",
1584
+ "cause"
1585
+ ]);
1577
1586
  function waitForWrite(start, timeoutMs) {
1578
1587
  return withTimeout(
1579
1588
  start,
@@ -1598,7 +1607,7 @@ function buildRecord(entry) {
1598
1607
  return record;
1599
1608
  }
1600
1609
  var FirestoreErrorAdapter = class {
1601
- /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`. */
1610
+ /** @throws {RangeError} if `options.timeoutMs` is not a positive number or `Infinity`, or the expiry options are invalid. */
1602
1611
  constructor(collection, options = {}) {
1603
1612
  this.collection = collection;
1604
1613
  this.prefix = options.prefix ?? DEFAULT_PREFIX;
@@ -1606,10 +1615,31 @@ var FirestoreErrorAdapter = class {
1606
1615
  options.timeoutMs,
1607
1616
  "FirestoreErrorAdapter"
1608
1617
  );
1618
+ this.expireAfterMs = options.expireAfterMs;
1619
+ this.expireField = options.expireField ?? DEFAULT_EXPIRE_FIELD;
1620
+ if (this.expireAfterMs !== void 0 && (!Number.isFinite(this.expireAfterMs) || this.expireAfterMs <= 0)) {
1621
+ throw new RangeError(
1622
+ `FirestoreErrorAdapter: expireAfterMs must be a positive number of milliseconds, received ${String(options.expireAfterMs)}.`
1623
+ );
1624
+ }
1625
+ if (this.expireField === "" || /[./]/.test(this.expireField) || RESERVED_FIELDS.has(this.expireField)) {
1626
+ throw new RangeError(
1627
+ `FirestoreErrorAdapter: expireField must be a name other than ${[...RESERVED_FIELDS].join(", ")}, without "." or "/", received ${JSON.stringify(this.expireField)}.`
1628
+ );
1629
+ }
1609
1630
  }
1610
1631
  async log(entry) {
1611
1632
  try {
1612
- const record = buildRecord(entry);
1633
+ const record = { ...buildRecord(entry) };
1634
+ if (this.expireAfterMs !== void 0) {
1635
+ const occurredAt = Date.parse(record.timestamp);
1636
+ if (Number.isNaN(occurredAt)) {
1637
+ throw new RangeError(
1638
+ `timestamp "${record.timestamp}" is not a valid ISO 8601 date, so the expiry time cannot be worked out`
1639
+ );
1640
+ }
1641
+ record[this.expireField] = new Date(occurredAt + this.expireAfterMs);
1642
+ }
1613
1643
  await waitForWrite(
1614
1644
  () => this.collection.doc(record.id).set(record),
1615
1645
  this.timeoutMs