@friggframework/core 2.0.0-next.111 → 2.0.0-next.113

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.
Files changed (74) hide show
  1. package/.eslintrc.json +18 -1
  2. package/CLAUDE.md +101 -13
  3. package/README.md +19 -22
  4. package/core/CLAUDE.md +28 -13
  5. package/core/Worker.js +32 -37
  6. package/core/create-handler.js +97 -197
  7. package/core/index.js +8 -1
  8. package/core/invocation-scope.js +225 -0
  9. package/core/secrets-to-env.js +7 -6
  10. package/database/config.js +0 -7
  11. package/database/documentdb-encryption-service.js +6 -2
  12. package/database/documentdb-utils.js +2 -1
  13. package/database/encryption/README.md +25 -1
  14. package/database/encryption/encryption-schema-registry.js +3 -0
  15. package/database/encryption/integration-mapping-encryption.js +97 -0
  16. package/database/encryption/logger.js +5 -2
  17. package/database/encryption/prisma-encryption-extension.js +20 -9
  18. package/errors/fetch-error.js +48 -65
  19. package/handlers/app-definition-loader.js +38 -2
  20. package/handlers/app-handler-helpers.js +18 -4
  21. package/handlers/backend-utils.js +10 -13
  22. package/handlers/database-migration-handler.js +10 -1
  23. package/handlers/integration-event-dispatcher.js +2 -2
  24. package/handlers/routers/integration-webhook-routers.js +13 -6
  25. package/handlers/routers/websocket.js +27 -7
  26. package/handlers/workers/db-migration.js +12 -1
  27. package/handlers/workers/dlq-processor.js +64 -38
  28. package/index.js +19 -1
  29. package/integrations/integration-base.js +56 -38
  30. package/integrations/integration-router.js +21 -20
  31. package/integrations/repositories/integration-mapping-query-pipeline.js +152 -0
  32. package/integrations/repositories/integration-mapping-query.js +193 -0
  33. package/integrations/repositories/integration-mapping-repository-documentdb.js +53 -0
  34. package/integrations/repositories/integration-mapping-repository-interface.js +48 -0
  35. package/integrations/repositories/integration-mapping-repository-mongo.js +72 -0
  36. package/integrations/repositories/integration-mapping-repository-postgres.js +118 -0
  37. package/integrations/use-cases/delete-integration-for-user.js +24 -13
  38. package/jest.config.js +2 -0
  39. package/logs/.eslintrc.json +26 -1
  40. package/logs/__fixtures__/events.js +82 -0
  41. package/logs/__fixtures__/matchers.js +45 -0
  42. package/logs/__fixtures__/secrets.js +59 -0
  43. package/logs/__fixtures__/vectors.js +329 -0
  44. package/logs/__fixtures__/with-env.js +45 -0
  45. package/logs/context.js +109 -0
  46. package/logs/contract-keys.js +67 -0
  47. package/logs/debug-shims.js +46 -0
  48. package/logs/denied-keys.js +21 -0
  49. package/logs/index.js +14 -3
  50. package/logs/jest-logger-setup.js +25 -0
  51. package/logs/levels.js +71 -0
  52. package/logs/logger-runtime.js +137 -0
  53. package/logs/logger.js +134 -42
  54. package/logs/record.js +276 -0
  55. package/logs/redact.js +328 -0
  56. package/logs/serialize.js +329 -0
  57. package/logs/sinks.js +93 -0
  58. package/logs/summarize-event.js +163 -0
  59. package/modules/module.js +32 -19
  60. package/modules/requester/oauth-2.js +28 -22
  61. package/modules/requester/requester.js +69 -6
  62. package/package.json +5 -6
  63. package/queues/queue-delivery.js +41 -0
  64. package/queues/queuer-util.js +1 -15
  65. package/telemetry/bind-telemetry-context.js +4 -0
  66. package/telemetry/instrument-handler.js +19 -2
  67. package/telemetry/no-op-telemetry.js +4 -0
  68. package/telemetry/otel-telemetry.js +25 -6
  69. package/telemetry/telemetry-context.js +19 -8
  70. package/telemetry/telemetry-runtime.js +17 -0
  71. package/telemetry/telemetry-service.js +1 -0
  72. package/types/errors/index.d.ts +24 -10
  73. package/types/logs/index.d.ts +61 -2
  74. package/user/repositories/user-repository-documentdb.js +10 -42
@@ -1,5 +1,64 @@
1
- declare module "@friggframework/logs/logger" {
1
+ declare module "@friggframework/core/logs" {
2
+ export type LogLevel = "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL";
3
+
4
+ export type LogFields = Record<string, unknown>;
5
+
6
+ export interface LogRecord {
7
+ readonly timestamp: string;
8
+ readonly level: LogLevel;
9
+ readonly message: string;
10
+ readonly logger: string;
11
+ readonly [key: string]: unknown;
12
+ }
13
+
14
+ export interface Logger {
15
+ readonly name: string;
16
+ trace(message: unknown, fields?: LogFields): void;
17
+ debug(message: unknown, fields?: LogFields): void;
18
+ info(message: unknown, fields?: LogFields): void;
19
+ warn(message: unknown, fields?: LogFields): void;
20
+ error(message: unknown, fields?: LogFields): void;
21
+ fatal(message: unknown, fields?: LogFields): void;
22
+ child(bindings: LogFields | (() => LogFields)): Logger;
23
+ isLevelEnabled(level: string): boolean;
24
+ }
25
+
26
+ export interface LogSink {
27
+ name: string;
28
+ write(record: LogRecord): void;
29
+ flush?(options: { signal?: AbortSignal }): Promise<void> | void;
30
+ }
31
+
32
+ export interface MemorySink extends LogSink {
33
+ readonly records: LogRecord[];
34
+ clear(): void;
35
+ }
36
+
37
+ export interface SerializedError {
38
+ type: string;
39
+ message: string;
40
+ code?: string | number;
41
+ status?: number;
42
+ stack?: string;
43
+ cause?: SerializedError | string;
44
+ }
45
+
46
+ export function getLogger(name?: string): Logger;
47
+ export function createMemorySink(options?: { install?: boolean }): MemorySink;
48
+ export function resetLoggerForTests(options?: {
49
+ level?: LogLevel | Lowercase<LogLevel>;
50
+ sinks?: LogSink[];
51
+ /** Record frigg.* WARN+ records without eventName. Kept across resets that omit it. */
52
+ trackViolations?: boolean;
53
+ }): void;
54
+ export function serializeError(error: unknown): SerializedError;
55
+ export function redactValue(value: unknown): unknown;
56
+ export function toSanitizedSurrogate(error: unknown): Error;
57
+
58
+ /** @deprecated Use getLogger or this.logger. */
2
59
  export function debug(...messages: any[]): void;
60
+ /** @deprecated Use getLogger or this.logger. */
3
61
  export function initDebugLog(...initMessages: any[]): void;
4
- export function flushDebugLog(error: any): void;
62
+ /** @deprecated Use getLogger or this.logger. */
63
+ export function flushDebugLog(error?: any): void;
5
64
  }
@@ -17,6 +17,9 @@ const { ClientSafeError } = require('../../errors');
17
17
  const {
18
18
  DocumentDBEncryptionService,
19
19
  } = require('../../database/documentdb-encryption-service');
20
+ const { getLogger } = require('../../logs');
21
+
22
+ const log = getLogger('frigg.user');
20
23
 
21
24
  /**
22
25
  * User repository for DocumentDB.
@@ -145,19 +148,8 @@ class UserRepositoryDocumentDB extends UserRepositoryInterface {
145
148
 
146
149
  // Defensive check: verify document was found after insert
147
150
  if (!created) {
148
- console.error(
149
- '[UserRepositoryDocumentDB] User not found after insert',
150
- {
151
- insertedId: fromObjectId(insertedId),
152
- params: {
153
- username: params.username,
154
- appUserId: params.appUserId,
155
- email: params.email,
156
- },
157
- }
158
- );
159
151
  throw new Error(
160
- 'Failed to create individual user: Document not found after insert. ' +
152
+ `Failed to create individual user: Document not found after insert (insertedId ${fromObjectId(insertedId)}). ` +
161
153
  'This indicates a database consistency issue.'
162
154
  );
163
155
  }
@@ -195,18 +187,8 @@ class UserRepositoryDocumentDB extends UserRepositoryInterface {
195
187
 
196
188
  // Defensive check: verify document was found after insert
197
189
  if (!created) {
198
- console.error(
199
- '[UserRepositoryDocumentDB] Organization user not found after insert',
200
- {
201
- insertedId: fromObjectId(insertedId),
202
- params: {
203
- appOrgId: params.appOrgId,
204
- name: params.name,
205
- },
206
- }
207
- );
208
190
  throw new Error(
209
- 'Failed to create organization user: Document not found after insert. ' +
191
+ `Failed to create organization user: Document not found after insert (insertedId ${fromObjectId(insertedId)}). ` +
210
192
  'This indicates a database consistency issue.'
211
193
  );
212
194
  }
@@ -291,15 +273,8 @@ class UserRepositoryDocumentDB extends UserRepositoryInterface {
291
273
 
292
274
  // Defensive check: verify document was found after update
293
275
  if (!updated) {
294
- console.error(
295
- '[UserRepositoryDocumentDB] Individual user not found after update',
296
- {
297
- userId: fromObjectId(objectId),
298
- updates,
299
- }
300
- );
301
276
  throw new Error(
302
- 'Failed to update individual user: Document not found after update. ' +
277
+ `Failed to update individual user: Document not found after update (userId ${userId}). ` +
303
278
  'This indicates a database consistency issue.'
304
279
  );
305
280
  }
@@ -332,15 +307,8 @@ class UserRepositoryDocumentDB extends UserRepositoryInterface {
332
307
  const updated = await findOne(this.prisma, 'User', { _id: objectId });
333
308
 
334
309
  if (!updated) {
335
- console.error(
336
- '[UserRepositoryDocumentDB] Organization user not found after update',
337
- {
338
- userId: fromObjectId(objectId),
339
- updates,
340
- }
341
- );
342
310
  throw new Error(
343
- 'Failed to update organization user: Document not found after update. ' +
311
+ `Failed to update organization user: Document not found after update (userId ${userId}). ` +
344
312
  'This indicates a database consistency issue.'
345
313
  );
346
314
  }
@@ -363,9 +331,9 @@ class UserRepositoryDocumentDB extends UserRepositoryInterface {
363
331
 
364
332
  _mapUser(doc) {
365
333
  if (!doc) {
366
- console.warn(
367
- '[UserRepositoryDocumentDB] _mapUser received null/undefined document'
368
- );
334
+ log.warn('_mapUser received a null document', {
335
+ eventName: 'frigg.user.map_user_null',
336
+ });
369
337
  return null;
370
338
  }
371
339