@richardmcquiston01/error-log-adapter 0.6.0 → 0.8.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
@@ -1022,4 +1022,157 @@ declare class EventEmitterErrorAdapter<TCode extends string = string> implements
1022
1022
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1023
1023
  }
1024
1024
 
1025
- export { 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, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
1025
+ /**
1026
+ * The only things this adapter needs from a socket: `send` and `readyState`. The
1027
+ * browser `WebSocket`, Node's global `WebSocket`, Deno, Bun, and the `ws` package
1028
+ * all fit as they are.
1029
+ */
1030
+ interface WebSocketLike {
1031
+ send(data: string): unknown;
1032
+ readonly readyState: number;
1033
+ }
1034
+ interface WebSocketErrorOptions {
1035
+ /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
1036
+ prefix?: string;
1037
+ }
1038
+ /**
1039
+ * Sends each entry as one JSON text message (the serialized entry plus its UUID
1040
+ * `id`) over a socket you own. You connect, and reconnect, the socket; this
1041
+ * adapter never opens one and keeps no buffer. If the socket is not open when
1042
+ * `log` is called, the entry is not sent and `log` returns `ok: false`, so
1043
+ * combine it with a durable adapter in a `CompositeErrorAdapter` when entries
1044
+ * must not be lost while the socket is down.
1045
+ *
1046
+ * `ok: true` means the socket accepted the message, not that the server
1047
+ * received it: a WebSocket gives no acknowledgement, and a connection that
1048
+ * drops after `send` loses the message.
1049
+ *
1050
+ * ```ts
1051
+ * const socket = new WebSocket('wss://logs.example.com/errors');
1052
+ * const adapter = new WebSocketErrorAdapter(socket);
1053
+ * ```
1054
+ */
1055
+ declare class WebSocketErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
1056
+ private readonly socket;
1057
+ private readonly prefix;
1058
+ constructor(socket: WebSocketLike, options?: WebSocketErrorOptions);
1059
+ log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1060
+ }
1061
+
1062
+ /** One event as `PutLogEvents` takes it. */
1063
+ interface CloudWatchLogEvent {
1064
+ /** Milliseconds since the epoch. */
1065
+ timestamp: number;
1066
+ message: string;
1067
+ }
1068
+ /** The parameters this adapter passes to `putLogEvents`. */
1069
+ interface CloudWatchPutLogEventsInput {
1070
+ logGroupName: string;
1071
+ logStreamName: string;
1072
+ logEvents: CloudWatchLogEvent[];
1073
+ }
1074
+ /**
1075
+ * What an AWS SDK client needs to offer. The AWS SDK v3 aggregated client
1076
+ * (`new CloudWatchLogs({ ... })` from `@aws-sdk/client-cloudwatch-logs`) fits as
1077
+ * it is. `createLogGroup` and `createLogStream` are only used when
1078
+ * `createMissing` is on (the default); leave them out of a hand-written client
1079
+ * that cannot create them.
1080
+ */
1081
+ interface CloudWatchLogsClientLike {
1082
+ putLogEvents(input: CloudWatchPutLogEventsInput): Promise<unknown>;
1083
+ createLogGroup?(input: {
1084
+ logGroupName: string;
1085
+ }): Promise<unknown>;
1086
+ createLogStream?(input: {
1087
+ logGroupName: string;
1088
+ logStreamName: string;
1089
+ }): Promise<unknown>;
1090
+ }
1091
+ interface CloudWatchBatchOptions {
1092
+ /** Send once this many events are buffered. */
1093
+ batchSize: number;
1094
+ /**
1095
+ * Also send when the oldest buffered event has waited this long (ms). The
1096
+ * timer does not keep the process alive, so call `flush()` before exiting.
1097
+ */
1098
+ maxWaitMs?: number;
1099
+ }
1100
+ interface CloudWatchLogsErrorOptions {
1101
+ /**
1102
+ * Create the log stream, and the log group if that is missing too, when
1103
+ * `PutLogEvents` says they do not exist, then try again once. This needs the
1104
+ * `logs:CreateLogStream` (and `logs:CreateLogGroup`) permissions and only runs
1105
+ * after a "not found" answer, so a stream that exists costs nothing. A group
1106
+ * created this way never expires its logs; set a retention policy on it.
1107
+ * Defaults to `true`.
1108
+ */
1109
+ createMissing?: boolean;
1110
+ /**
1111
+ * Buffer events and send them together, up to the 10,000 events and 1 MiB
1112
+ * that one request allows. Off by default: one request per entry.
1113
+ */
1114
+ batch?: CloudWatchBatchOptions;
1115
+ /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
1116
+ prefix?: string;
1117
+ /**
1118
+ * How long a request may take before `log` (or `flush`) gives up waiting, in
1119
+ * milliseconds. Defaults to 10000. Pass `Infinity` to wait without limit. The
1120
+ * request cannot be cancelled, so it may still finish afterwards; in batch
1121
+ * mode the events stay buffered and are sent again by the next flush.
1122
+ */
1123
+ timeoutMs?: number;
1124
+ }
1125
+ /**
1126
+ * Sends entries to one CloudWatch Logs stream through `PutLogEvents`, each as a
1127
+ * JSON event (the serialized entry plus its UUID `id`) stamped with the entry's
1128
+ * time, so Logs Insights can query its fields. AWS no longer asks for sequence
1129
+ * tokens, so none are tracked.
1130
+ *
1131
+ * By default each entry is its own request and `log` resolves once CloudWatch
1132
+ * accepts it. With `batch`, events are buffered and sent together; `log` then
1133
+ * resolves ok as soon as the event is buffered (it is not stored yet), except
1134
+ * for the call that fills the batch, which resolves with the send result. Call
1135
+ * `flush()` before shutting down.
1136
+ *
1137
+ * CloudWatch can answer ok and still reject events it considers too old (over
1138
+ * 14 days) or too new (over 2 hours ahead); that is reported as `ok: false`. An
1139
+ * event over 256 KiB is refused before sending, since CloudWatch would reject
1140
+ * the whole request.
1141
+ *
1142
+ * In AWS Lambda, ECS and similar runtimes, anything written to stdout already
1143
+ * reaches CloudWatch; this adapter is for apps running elsewhere.
1144
+ */
1145
+ declare class CloudWatchLogsErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
1146
+ private readonly client;
1147
+ private readonly logGroupName;
1148
+ private readonly logStreamName;
1149
+ private readonly createMissing;
1150
+ private readonly batch;
1151
+ private readonly logPrefix;
1152
+ private readonly timeoutMs;
1153
+ private buffer;
1154
+ private timer;
1155
+ private readonly flushQueue;
1156
+ /** @throws {RangeError} if a name is empty, the batch or timeout options are invalid, or `createMissing` is on but the client cannot create streams. */
1157
+ constructor(client: CloudWatchLogsClientLike, logGroupName: string, logStreamName: string, options?: CloudWatchLogsErrorOptions);
1158
+ log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1159
+ /**
1160
+ * Sends any buffered events now. Resolves ok when nothing is buffered. Events
1161
+ * from a failed send stay buffered and are retried by the next flush.
1162
+ */
1163
+ flush(): Promise<ErrorLogResult>;
1164
+ private addToBatch;
1165
+ private scheduleFlush;
1166
+ private sendBuffered;
1167
+ /**
1168
+ * Sends one request, creating the stream first if CloudWatch says it is
1169
+ * missing. Resolves to a description of any events CloudWatch refused, or
1170
+ * undefined when it took them all.
1171
+ */
1172
+ private send;
1173
+ private putLogEvents;
1174
+ private createStream;
1175
+ private fail;
1176
+ }
1177
+
1178
+ export { 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 };
package/dist/index.d.ts CHANGED
@@ -1022,4 +1022,157 @@ declare class EventEmitterErrorAdapter<TCode extends string = string> implements
1022
1022
  log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1023
1023
  }
1024
1024
 
1025
- export { 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, WebStorageErrorAdapter, type WebStorageErrorOptions, type WebStorageErrorRecord, WebhookErrorAdapter, type WebhookErrorOptions, buildCreateErrorLogTableSql, buildErrorLogTableDdl, buildMySqlWidenColumnsSql, buildSupabaseSetupSql, createErrorLogStore, formatErrorLogLine, serializeCause, serializeEntry };
1025
+ /**
1026
+ * The only things this adapter needs from a socket: `send` and `readyState`. The
1027
+ * browser `WebSocket`, Node's global `WebSocket`, Deno, Bun, and the `ws` package
1028
+ * all fit as they are.
1029
+ */
1030
+ interface WebSocketLike {
1031
+ send(data: string): unknown;
1032
+ readonly readyState: number;
1033
+ }
1034
+ interface WebSocketErrorOptions {
1035
+ /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
1036
+ prefix?: string;
1037
+ }
1038
+ /**
1039
+ * Sends each entry as one JSON text message (the serialized entry plus its UUID
1040
+ * `id`) over a socket you own. You connect, and reconnect, the socket; this
1041
+ * adapter never opens one and keeps no buffer. If the socket is not open when
1042
+ * `log` is called, the entry is not sent and `log` returns `ok: false`, so
1043
+ * combine it with a durable adapter in a `CompositeErrorAdapter` when entries
1044
+ * must not be lost while the socket is down.
1045
+ *
1046
+ * `ok: true` means the socket accepted the message, not that the server
1047
+ * received it: a WebSocket gives no acknowledgement, and a connection that
1048
+ * drops after `send` loses the message.
1049
+ *
1050
+ * ```ts
1051
+ * const socket = new WebSocket('wss://logs.example.com/errors');
1052
+ * const adapter = new WebSocketErrorAdapter(socket);
1053
+ * ```
1054
+ */
1055
+ declare class WebSocketErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
1056
+ private readonly socket;
1057
+ private readonly prefix;
1058
+ constructor(socket: WebSocketLike, options?: WebSocketErrorOptions);
1059
+ log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1060
+ }
1061
+
1062
+ /** One event as `PutLogEvents` takes it. */
1063
+ interface CloudWatchLogEvent {
1064
+ /** Milliseconds since the epoch. */
1065
+ timestamp: number;
1066
+ message: string;
1067
+ }
1068
+ /** The parameters this adapter passes to `putLogEvents`. */
1069
+ interface CloudWatchPutLogEventsInput {
1070
+ logGroupName: string;
1071
+ logStreamName: string;
1072
+ logEvents: CloudWatchLogEvent[];
1073
+ }
1074
+ /**
1075
+ * What an AWS SDK client needs to offer. The AWS SDK v3 aggregated client
1076
+ * (`new CloudWatchLogs({ ... })` from `@aws-sdk/client-cloudwatch-logs`) fits as
1077
+ * it is. `createLogGroup` and `createLogStream` are only used when
1078
+ * `createMissing` is on (the default); leave them out of a hand-written client
1079
+ * that cannot create them.
1080
+ */
1081
+ interface CloudWatchLogsClientLike {
1082
+ putLogEvents(input: CloudWatchPutLogEventsInput): Promise<unknown>;
1083
+ createLogGroup?(input: {
1084
+ logGroupName: string;
1085
+ }): Promise<unknown>;
1086
+ createLogStream?(input: {
1087
+ logGroupName: string;
1088
+ logStreamName: string;
1089
+ }): Promise<unknown>;
1090
+ }
1091
+ interface CloudWatchBatchOptions {
1092
+ /** Send once this many events are buffered. */
1093
+ batchSize: number;
1094
+ /**
1095
+ * Also send when the oldest buffered event has waited this long (ms). The
1096
+ * timer does not keep the process alive, so call `flush()` before exiting.
1097
+ */
1098
+ maxWaitMs?: number;
1099
+ }
1100
+ interface CloudWatchLogsErrorOptions {
1101
+ /**
1102
+ * Create the log stream, and the log group if that is missing too, when
1103
+ * `PutLogEvents` says they do not exist, then try again once. This needs the
1104
+ * `logs:CreateLogStream` (and `logs:CreateLogGroup`) permissions and only runs
1105
+ * after a "not found" answer, so a stream that exists costs nothing. A group
1106
+ * created this way never expires its logs; set a retention policy on it.
1107
+ * Defaults to `true`.
1108
+ */
1109
+ createMissing?: boolean;
1110
+ /**
1111
+ * Buffer events and send them together, up to the 10,000 events and 1 MiB
1112
+ * that one request allows. Off by default: one request per entry.
1113
+ */
1114
+ batch?: CloudWatchBatchOptions;
1115
+ /** Text printed before failure messages. Defaults to `[error-log-adapter]`. */
1116
+ prefix?: string;
1117
+ /**
1118
+ * How long a request may take before `log` (or `flush`) gives up waiting, in
1119
+ * milliseconds. Defaults to 10000. Pass `Infinity` to wait without limit. The
1120
+ * request cannot be cancelled, so it may still finish afterwards; in batch
1121
+ * mode the events stay buffered and are sent again by the next flush.
1122
+ */
1123
+ timeoutMs?: number;
1124
+ }
1125
+ /**
1126
+ * Sends entries to one CloudWatch Logs stream through `PutLogEvents`, each as a
1127
+ * JSON event (the serialized entry plus its UUID `id`) stamped with the entry's
1128
+ * time, so Logs Insights can query its fields. AWS no longer asks for sequence
1129
+ * tokens, so none are tracked.
1130
+ *
1131
+ * By default each entry is its own request and `log` resolves once CloudWatch
1132
+ * accepts it. With `batch`, events are buffered and sent together; `log` then
1133
+ * resolves ok as soon as the event is buffered (it is not stored yet), except
1134
+ * for the call that fills the batch, which resolves with the send result. Call
1135
+ * `flush()` before shutting down.
1136
+ *
1137
+ * CloudWatch can answer ok and still reject events it considers too old (over
1138
+ * 14 days) or too new (over 2 hours ahead); that is reported as `ok: false`. An
1139
+ * event over 256 KiB is refused before sending, since CloudWatch would reject
1140
+ * the whole request.
1141
+ *
1142
+ * In AWS Lambda, ECS and similar runtimes, anything written to stdout already
1143
+ * reaches CloudWatch; this adapter is for apps running elsewhere.
1144
+ */
1145
+ declare class CloudWatchLogsErrorAdapter<TCode extends string = string> implements ErrorLogAdapter<TCode> {
1146
+ private readonly client;
1147
+ private readonly logGroupName;
1148
+ private readonly logStreamName;
1149
+ private readonly createMissing;
1150
+ private readonly batch;
1151
+ private readonly logPrefix;
1152
+ private readonly timeoutMs;
1153
+ private buffer;
1154
+ private timer;
1155
+ private readonly flushQueue;
1156
+ /** @throws {RangeError} if a name is empty, the batch or timeout options are invalid, or `createMissing` is on but the client cannot create streams. */
1157
+ constructor(client: CloudWatchLogsClientLike, logGroupName: string, logStreamName: string, options?: CloudWatchLogsErrorOptions);
1158
+ log(entry: ErrorLogEntry<TCode>): Promise<ErrorLogResult>;
1159
+ /**
1160
+ * Sends any buffered events now. Resolves ok when nothing is buffered. Events
1161
+ * from a failed send stay buffered and are retried by the next flush.
1162
+ */
1163
+ flush(): Promise<ErrorLogResult>;
1164
+ private addToBatch;
1165
+ private scheduleFlush;
1166
+ private sendBuffered;
1167
+ /**
1168
+ * Sends one request, creating the stream first if CloudWatch says it is
1169
+ * missing. Resolves to a description of any events CloudWatch refused, or
1170
+ * undefined when it took them all.
1171
+ */
1172
+ private send;
1173
+ private putLogEvents;
1174
+ private createStream;
1175
+ private fail;
1176
+ }
1177
+
1178
+ export { 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 };
package/dist/index.mjs CHANGED
@@ -241,10 +241,10 @@ async function hmacSha256Hex(secret, message) {
241
241
  "signingSecret needs Web Crypto (crypto.subtle), which this runtime does not provide, so the entry was not sent unsigned"
242
242
  );
243
243
  }
244
- const encoder = new TextEncoder();
244
+ const encoder2 = new TextEncoder();
245
245
  const key = await subtle.importKey(
246
246
  "raw",
247
- encoder.encode(secret),
247
+ encoder2.encode(secret),
248
248
  { name: "HMAC", hash: "SHA-256" },
249
249
  false,
250
250
  ["sign"]
@@ -252,7 +252,7 @@ async function hmacSha256Hex(secret, message) {
252
252
  const signature = await subtle.sign(
253
253
  "HMAC",
254
254
  key,
255
- encoder.encode(message)
255
+ encoder2.encode(message)
256
256
  );
257
257
  return Array.from(
258
258
  new Uint8Array(signature),
@@ -1770,7 +1770,332 @@ var EventEmitterErrorAdapter = class {
1770
1770
  }
1771
1771
  }
1772
1772
  };
1773
+
1774
+ // src/adapters/websocket-error-adapter.ts
1775
+ var OPEN = 1;
1776
+ var STATE_NAMES = {
1777
+ 0: "still connecting",
1778
+ 1: "open",
1779
+ 2: "closing",
1780
+ 3: "closed"
1781
+ };
1782
+ var WebSocketErrorAdapter = class {
1783
+ constructor(socket, options = {}) {
1784
+ this.socket = socket;
1785
+ this.prefix = options.prefix ?? DEFAULT_PREFIX;
1786
+ }
1787
+ async log(entry) {
1788
+ try {
1789
+ const state = this.socket.readyState;
1790
+ if (state !== OPEN) {
1791
+ throw new Error(
1792
+ `the socket is ${STATE_NAMES[state] ?? `in unknown state ${String(state)}`} (readyState ${String(state)}), so the entry was not sent; connect or reconnect it first`
1793
+ );
1794
+ }
1795
+ this.socket.send(
1796
+ JSON.stringify({ id: resolveEntryId(entry), ...serializeEntry(entry) })
1797
+ );
1798
+ return { ok: true };
1799
+ } catch (error) {
1800
+ return reportFailure({
1801
+ adapterName: "WebSocketErrorAdapter",
1802
+ prefix: this.prefix,
1803
+ action: "to send over the socket",
1804
+ error
1805
+ });
1806
+ }
1807
+ }
1808
+ };
1809
+
1810
+ // src/adapters/cloudwatch-logs-error-adapter.ts
1811
+ var MAX_EVENT_BYTES = 262144;
1812
+ var EVENT_OVERHEAD_BYTES = 26;
1813
+ var MAX_BATCH_BYTES = 1048576;
1814
+ var MAX_BATCH_EVENTS = 1e4;
1815
+ var MAX_BATCH_SPAN_MS = 24 * 60 * 60 * 1e3;
1816
+ var BUFFER_LIMIT_MULTIPLIER2 = 10;
1817
+ var encoder = new TextEncoder();
1818
+ function eventBytes(message) {
1819
+ return encoder.encode(message).length + EVENT_OVERHEAD_BYTES;
1820
+ }
1821
+ function errorName(error) {
1822
+ return typeof error === "object" && error !== null ? error.name : void 0;
1823
+ }
1824
+ function splitIntoRequests(events) {
1825
+ const requests = [];
1826
+ let current = [];
1827
+ let bytes = 0;
1828
+ for (const event of events) {
1829
+ const size = eventBytes(event.message);
1830
+ const first = current[0];
1831
+ if (first !== void 0 && (current.length >= MAX_BATCH_EVENTS || bytes + size > MAX_BATCH_BYTES || event.timestamp - first.timestamp > MAX_BATCH_SPAN_MS)) {
1832
+ requests.push(current);
1833
+ current = [];
1834
+ bytes = 0;
1835
+ }
1836
+ current.push(event);
1837
+ bytes += size;
1838
+ }
1839
+ if (current.length > 0) {
1840
+ requests.push(current);
1841
+ }
1842
+ return requests;
1843
+ }
1844
+ var CloudWatchLogsErrorAdapter = class {
1845
+ /** @throws {RangeError} if a name is empty, the batch or timeout options are invalid, or `createMissing` is on but the client cannot create streams. */
1846
+ constructor(client, logGroupName, logStreamName, options = {}) {
1847
+ this.client = client;
1848
+ this.logGroupName = logGroupName;
1849
+ this.logStreamName = logStreamName;
1850
+ this.buffer = [];
1851
+ this.timer = null;
1852
+ this.flushQueue = new SerialQueue();
1853
+ this.createMissing = options.createMissing ?? true;
1854
+ this.batch = options.batch;
1855
+ this.logPrefix = options.prefix ?? DEFAULT_PREFIX;
1856
+ this.timeoutMs = resolveTimeoutMs(
1857
+ options.timeoutMs,
1858
+ "CloudWatchLogsErrorAdapter"
1859
+ );
1860
+ if (logGroupName === "") {
1861
+ throw new RangeError(
1862
+ "CloudWatchLogsErrorAdapter: logGroupName must not be empty."
1863
+ );
1864
+ }
1865
+ if (logStreamName === "") {
1866
+ throw new RangeError(
1867
+ "CloudWatchLogsErrorAdapter: logStreamName must not be empty."
1868
+ );
1869
+ }
1870
+ if (this.createMissing && typeof client.createLogStream !== "function") {
1871
+ throw new RangeError(
1872
+ "CloudWatchLogsErrorAdapter: createMissing is on, but the client has no createLogStream method. Pass createMissing: false, or use an AWS SDK CloudWatchLogs client."
1873
+ );
1874
+ }
1875
+ if (this.batch !== void 0) {
1876
+ if (!Number.isInteger(this.batch.batchSize) || this.batch.batchSize < 1) {
1877
+ throw new RangeError(
1878
+ `CloudWatchLogsErrorAdapter: batch.batchSize must be a positive integer, received ${String(this.batch.batchSize)}.`
1879
+ );
1880
+ }
1881
+ if (this.batch.maxWaitMs !== void 0 && (!Number.isFinite(this.batch.maxWaitMs) || this.batch.maxWaitMs <= 0)) {
1882
+ throw new RangeError(
1883
+ `CloudWatchLogsErrorAdapter: batch.maxWaitMs must be a positive number, received ${String(this.batch.maxWaitMs)}.`
1884
+ );
1885
+ }
1886
+ }
1887
+ }
1888
+ async log(entry) {
1889
+ try {
1890
+ const id = resolveEntryId(entry);
1891
+ const record = { id, ...serializeEntry(entry) };
1892
+ const timestamp = Date.parse(record.timestamp);
1893
+ if (Number.isNaN(timestamp)) {
1894
+ throw new RangeError(
1895
+ `timestamp "${record.timestamp}" is not a valid ISO 8601 date`
1896
+ );
1897
+ }
1898
+ const message = JSON.stringify(record);
1899
+ const size = eventBytes(message);
1900
+ if (size > MAX_EVENT_BYTES) {
1901
+ throw new RangeError(
1902
+ `the event is ${size} bytes, over the ${MAX_EVENT_BYTES} byte limit CloudWatch Logs puts on one event, so it was not sent; shorten the message or cause`
1903
+ );
1904
+ }
1905
+ const event = { id, timestamp, message };
1906
+ if (this.batch === void 0) {
1907
+ const rejection = await this.send([event]);
1908
+ if (rejection !== void 0) {
1909
+ throw new Error(rejection);
1910
+ }
1911
+ return { ok: true };
1912
+ }
1913
+ return await this.addToBatch(event, this.batch);
1914
+ } catch (error) {
1915
+ return this.fail(error);
1916
+ }
1917
+ }
1918
+ /**
1919
+ * Sends any buffered events now. Resolves ok when nothing is buffered. Events
1920
+ * from a failed send stay buffered and are retried by the next flush.
1921
+ */
1922
+ flush() {
1923
+ return this.flushQueue.run(
1924
+ () => this.sendBuffered()
1925
+ );
1926
+ }
1927
+ async addToBatch(event, batch) {
1928
+ this.buffer.push(event);
1929
+ const limit = batch.batchSize * BUFFER_LIMIT_MULTIPLIER2;
1930
+ if (this.buffer.length > limit) {
1931
+ const dropped = this.buffer.length - limit;
1932
+ this.buffer = this.buffer.slice(dropped);
1933
+ console.error(
1934
+ `${this.logPrefix} CloudWatchLogsErrorAdapter: dropped the ${dropped} oldest buffered events because sends to log stream "${this.logStreamName}" keep failing and the buffer is full (${limit} events).`
1935
+ );
1936
+ }
1937
+ if (this.buffer.length >= batch.batchSize) {
1938
+ return this.flush();
1939
+ }
1940
+ this.scheduleFlush(batch);
1941
+ return { ok: true };
1942
+ }
1943
+ scheduleFlush(batch) {
1944
+ if (batch.maxWaitMs === void 0 || this.timer !== null) {
1945
+ return;
1946
+ }
1947
+ const timer = setTimeout(() => {
1948
+ this.timer = null;
1949
+ void this.flush();
1950
+ }, batch.maxWaitMs);
1951
+ timer.unref?.();
1952
+ this.timer = timer;
1953
+ }
1954
+ async sendBuffered() {
1955
+ if (this.timer !== null) {
1956
+ clearTimeout(this.timer);
1957
+ this.timer = null;
1958
+ }
1959
+ const pending = this.buffer.slice();
1960
+ if (pending.length === 0) {
1961
+ return { ok: true };
1962
+ }
1963
+ pending.sort(
1964
+ (a, b) => a.timestamp - b.timestamp
1965
+ );
1966
+ let rejectedTotal = 0;
1967
+ let lastRejection = "";
1968
+ try {
1969
+ for (const request of splitIntoRequests(pending)) {
1970
+ const rejection = await this.send(request);
1971
+ const sent = new Set(request);
1972
+ this.buffer = this.buffer.filter(
1973
+ (event) => !sent.has(event)
1974
+ );
1975
+ if (rejection !== void 0) {
1976
+ rejectedTotal += request.length;
1977
+ lastRejection = rejection;
1978
+ }
1979
+ }
1980
+ } catch (error) {
1981
+ if (this.batch !== void 0) {
1982
+ this.scheduleFlush(this.batch);
1983
+ }
1984
+ return this.fail(error, this.buffer.length);
1985
+ }
1986
+ if (rejectedTotal > 0) {
1987
+ return this.fail(new Error(lastRejection), rejectedTotal);
1988
+ }
1989
+ return { ok: true };
1990
+ }
1991
+ /**
1992
+ * Sends one request, creating the stream first if CloudWatch says it is
1993
+ * missing. Resolves to a description of any events CloudWatch refused, or
1994
+ * undefined when it took them all.
1995
+ */
1996
+ async send(events) {
1997
+ let output;
1998
+ try {
1999
+ output = await this.putLogEvents(events);
2000
+ } catch (error) {
2001
+ if (!this.createMissing || errorName(error) !== "ResourceNotFoundException") {
2002
+ throw error;
2003
+ }
2004
+ await this.createStream();
2005
+ output = await this.putLogEvents(events);
2006
+ }
2007
+ return describeRejection(output, events.length);
2008
+ }
2009
+ putLogEvents(events) {
2010
+ return withTimeout(
2011
+ () => this.client.putLogEvents({
2012
+ logGroupName: this.logGroupName,
2013
+ logStreamName: this.logStreamName,
2014
+ logEvents: events.map(
2015
+ ({ timestamp, message }) => ({
2016
+ timestamp,
2017
+ message
2018
+ })
2019
+ )
2020
+ }),
2021
+ this.timeoutMs,
2022
+ timeoutMessage("CloudWatch Logs", this.timeoutMs)
2023
+ );
2024
+ }
2025
+ async createStream() {
2026
+ const createStream = () => withTimeout(
2027
+ () => this.client.createLogStream({
2028
+ logGroupName: this.logGroupName,
2029
+ logStreamName: this.logStreamName
2030
+ }),
2031
+ this.timeoutMs,
2032
+ timeoutMessage("CloudWatch Logs", this.timeoutMs, "create the stream")
2033
+ );
2034
+ try {
2035
+ await createStream();
2036
+ } catch (error) {
2037
+ const name = errorName(error);
2038
+ if (name === "ResourceAlreadyExistsException") {
2039
+ return;
2040
+ }
2041
+ if (name !== "ResourceNotFoundException" || typeof this.client.createLogGroup !== "function") {
2042
+ throw error;
2043
+ }
2044
+ const createGroup = this.client.createLogGroup.bind(this.client);
2045
+ try {
2046
+ await withTimeout(
2047
+ () => createGroup({ logGroupName: this.logGroupName }),
2048
+ this.timeoutMs,
2049
+ timeoutMessage("CloudWatch Logs", this.timeoutMs, "create the group")
2050
+ );
2051
+ } catch (groupError) {
2052
+ if (errorName(groupError) !== "ResourceAlreadyExistsException") {
2053
+ throw groupError;
2054
+ }
2055
+ }
2056
+ try {
2057
+ await createStream();
2058
+ } catch (retryError) {
2059
+ if (errorName(retryError) !== "ResourceAlreadyExistsException") {
2060
+ throw retryError;
2061
+ }
2062
+ }
2063
+ }
2064
+ }
2065
+ fail(error, count) {
2066
+ return reportFailure({
2067
+ adapterName: "CloudWatchLogsErrorAdapter",
2068
+ prefix: this.logPrefix,
2069
+ action: `to send to log stream "${this.logStreamName}" in log group "${this.logGroupName}"${count === void 0 ? "" : ` (${count} event${count === 1 ? "" : "s"} affected)`}`,
2070
+ error
2071
+ });
2072
+ }
2073
+ };
2074
+ function describeRejection(output, eventCount) {
2075
+ const info = typeof output === "object" && output !== null ? output.rejectedLogEventsInfo : void 0;
2076
+ if (info === void 0 || info === null) {
2077
+ return void 0;
2078
+ }
2079
+ const reasons = [];
2080
+ if (info.tooOldLogEventEndIndex !== void 0) {
2081
+ reasons.push(
2082
+ `${info.tooOldLogEventEndIndex} event(s) were older than the 14 days CloudWatch accepts`
2083
+ );
2084
+ }
2085
+ if (info.expiredLogEventEndIndex !== void 0) {
2086
+ reasons.push(
2087
+ `${info.expiredLogEventEndIndex} event(s) were older than the log group's retention period`
2088
+ );
2089
+ }
2090
+ if (info.tooNewLogEventStartIndex !== void 0) {
2091
+ reasons.push(
2092
+ `${Math.max(0, eventCount - info.tooNewLogEventStartIndex)} event(s) were more than 2 hours ahead of the current time`
2093
+ );
2094
+ }
2095
+ return reasons.length === 0 ? void 0 : `CloudWatch Logs accepted the request but rejected events: ${reasons.join("; ")}`;
2096
+ }
1773
2097
  export {
2098
+ CloudWatchLogsErrorAdapter,
1774
2099
  CompositeErrorAdapter,
1775
2100
  ConsoleErrorAdapter,
1776
2101
  EventEmitterErrorAdapter,
@@ -1786,6 +2111,7 @@ export {
1786
2111
  S3ErrorAdapter,
1787
2112
  SqliteErrorAdapter,
1788
2113
  SupabaseErrorAdapter,
2114
+ WebSocketErrorAdapter,
1789
2115
  WebStorageErrorAdapter,
1790
2116
  WebhookErrorAdapter,
1791
2117
  buildCreateErrorLogTableSql,