@friggframework/core 2.0.0--canary.622.ce0381c.0 → 2.0.0--canary.623.71305f2.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.
Files changed (66) hide show
  1. package/README.md +0 -40
  2. package/application/index.js +9 -10
  3. package/core/create-handler.js +10 -114
  4. package/generated/prisma-mongodb/edge.js +4 -16
  5. package/generated/prisma-mongodb/index-browser.js +1 -13
  6. package/generated/prisma-mongodb/index.d.ts +96 -1495
  7. package/generated/prisma-mongodb/index.js +4 -16
  8. package/generated/prisma-mongodb/package.json +1 -1
  9. package/generated/prisma-mongodb/schema.prisma +0 -24
  10. package/generated/prisma-mongodb/wasm.js +4 -16
  11. package/generated/prisma-postgresql/edge.js +4 -16
  12. package/generated/prisma-postgresql/index-browser.js +1 -13
  13. package/generated/prisma-postgresql/index.d.ts +91 -1541
  14. package/generated/prisma-postgresql/index.js +4 -16
  15. package/generated/prisma-postgresql/package.json +1 -1
  16. package/generated/prisma-postgresql/schema.prisma +0 -23
  17. package/generated/prisma-postgresql/wasm.js +4 -16
  18. package/handlers/app-definition-loader.js +3 -26
  19. package/handlers/integration-event-dispatcher.js +15 -34
  20. package/handlers/routers/integration-webhook-routers.js +7 -23
  21. package/index.js +9 -11
  22. package/integrations/integration-base.js +23 -88
  23. package/modules/module.js +15 -2
  24. package/modules/requester/requester.js +46 -111
  25. package/package.json +5 -12
  26. package/prisma-mongodb/schema.prisma +0 -24
  27. package/prisma-postgresql/schema.prisma +0 -23
  28. package/reporting/README.md +1 -8
  29. package/reporting/reporting-router.js +1 -16
  30. package/reporting/use-cases/list-integrations-report.js +6 -61
  31. package/application/commands/usage-commands.js +0 -56
  32. package/prisma-postgresql/migrations/20260705000000_create_usage_counter/migration.sql +0 -26
  33. package/telemetry/README.md +0 -331
  34. package/telemetry/bind-telemetry-context.js +0 -51
  35. package/telemetry/canonical-counters.js +0 -52
  36. package/telemetry/exporters/console-exporter.js +0 -19
  37. package/telemetry/exporters/datadog-exporter.js +0 -11
  38. package/telemetry/exporters/honeycomb-exporter.js +0 -13
  39. package/telemetry/exporters/otlp-exporter.js +0 -42
  40. package/telemetry/exporters/passthrough-exporter.js +0 -25
  41. package/telemetry/exporters/resolve-exporter.js +0 -39
  42. package/telemetry/exporters/telemetry-exporter-interface.js +0 -17
  43. package/telemetry/index.js +0 -60
  44. package/telemetry/instrument-handler.js +0 -82
  45. package/telemetry/no-op-telemetry.js +0 -71
  46. package/telemetry/north-star.js +0 -103
  47. package/telemetry/otel-telemetry.js +0 -218
  48. package/telemetry/plugin-subscribers-singleton.js +0 -51
  49. package/telemetry/plugin-subscribers.js +0 -77
  50. package/telemetry/telemetry-config.js +0 -120
  51. package/telemetry/telemetry-context.js +0 -40
  52. package/telemetry/telemetry-event-bus.js +0 -58
  53. package/telemetry/telemetry-service-interface.js +0 -49
  54. package/telemetry/telemetry-service.js +0 -42
  55. package/telemetry/telemetry-singleton.js +0 -41
  56. package/telemetry/usage-rollup-singleton.js +0 -74
  57. package/telemetry/usage-rollup-subscriber.js +0 -116
  58. package/telemetry/usage-windows.js +0 -14
  59. package/usage/README.md +0 -54
  60. package/usage/index.js +0 -19
  61. package/usage/repositories/usage-repository-documentdb.js +0 -199
  62. package/usage/repositories/usage-repository-factory.js +0 -28
  63. package/usage/repositories/usage-repository-interface.js +0 -37
  64. package/usage/repositories/usage-repository-mongo.js +0 -12
  65. package/usage/repositories/usage-repository-postgres.js +0 -152
  66. package/usage/tracked-metrics.js +0 -38
package/README.md CHANGED
@@ -200,46 +200,6 @@ const secureData = cryptor.encrypt(JSON.stringify({
200
200
  }));
201
201
  ```
202
202
 
203
- ### 4b. Telemetry & Usage Tracking (`/telemetry`, `/usage`)
204
-
205
- Vendor-neutral OpenTelemetry observability plus durable, per-integration usage
206
- counters (ADR-011). No-op by default (zero cold-start cost); framework seams are
207
- auto-instrumented so integrations get handler/API-module/webhook metrics for free.
208
-
209
- **Usage:**
210
- ```javascript
211
- // App definition — turn on export + declare a North Star:
212
- const Definition = {
213
- name: 'my-app',
214
- telemetry: {
215
- exporter: { type: 'otlp', endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT },
216
- northStar: { default: { name: 'records.synced' } },
217
- },
218
- };
219
-
220
- // Integration code — custom metrics/spans (this.telemetry is auto-tagged):
221
- await this.telemetry.span('delta_sync', async () => {
222
- this.telemetry.count('records.synced', batch.length, { entity: 'contact' });
223
- });
224
-
225
- // Declare which usage counters an integration reports (opts into reporting):
226
- class HubSpotIntegration extends IntegrationBase {
227
- static Definition = {
228
- name: 'hubspot',
229
- usage: { canonical: ['records.synced', 'api.requests'] },
230
- };
231
- }
232
-
233
- // Read the durable usage store (never an APM):
234
- const frigg = createFriggCommands({ integrationClass: HubSpotIntegration });
235
- await frigg.usage.getTotalsByDimension({ metric: 'records.synced', groupBy: 'integrationType' });
236
- ```
237
-
238
- **See:** [`telemetry/README.md`](telemetry/README.md) for the full guide
239
- (exporters, custom metrics, the Usage-Counter contract, North Star, the plugin
240
- tap, cardinality rules, and caveats) and [`usage/README.md`](usage/README.md) for
241
- the store internals.
242
-
243
203
  ### 5. Error Handling (`/errors`)
244
204
 
245
205
  Standardized error types with proper HTTP status codes.
@@ -4,10 +4,15 @@ const {
4
4
  } = require('./commands/integration-commands');
5
5
  const { createUserCommands } = require('./commands/user-commands');
6
6
  const { createEntityCommands } = require('./commands/entity-commands');
7
- const { createCredentialCommands } = require('./commands/credential-commands');
8
- const { createProcessCommands } = require('./commands/process-commands');
9
- const { createSchedulerCommands } = require('./commands/scheduler-commands');
10
- const { createUsageCommands } = require('./commands/usage-commands');
7
+ const {
8
+ createCredentialCommands,
9
+ } = require('./commands/credential-commands');
10
+ const {
11
+ createProcessCommands,
12
+ } = require('./commands/process-commands');
13
+ const {
14
+ createSchedulerCommands,
15
+ } = require('./commands/scheduler-commands');
11
16
 
12
17
  /**
13
18
  * Create a unified command factory with all CRUD operations
@@ -51,11 +56,6 @@ function createFriggCommands({ integrationClass }) {
51
56
 
52
57
  // Process commands
53
58
  ...processCommands,
54
-
55
- // Usage read/write — nested to match `frigg.usage.*`. The North Star
56
- // read takes its config as a call argument, so nothing telemetry-specific
57
- // is threaded through this general factory.
58
- usage: createUsageCommands(),
59
59
  };
60
60
  }
61
61
 
@@ -70,7 +70,6 @@ module.exports = {
70
70
  createCredentialCommands,
71
71
  createProcessCommands,
72
72
  createSchedulerCommands,
73
- createUsageCommands,
74
73
 
75
74
  // Legacy standalone function
76
75
  findIntegrationContextByExternalEntityId,
@@ -4,93 +4,6 @@
4
4
 
5
5
  const { initDebugLog, flushDebugLog } = require('../logs');
6
6
  const { secretsToEnv } = require('./secrets-to-env');
7
- const { getTelemetry } = require('../telemetry/telemetry-singleton');
8
- const {
9
- getUsageRollupSubscriber,
10
- } = require('../telemetry/usage-rollup-singleton');
11
- const {
12
- getPluginTelemetrySubscribers,
13
- } = require('../telemetry/plugin-subscribers-singleton');
14
-
15
- // Bounds the tail latency telemetry adds to every warm invocation. Kept low so
16
- // an unreachable OTLP endpoint (e.g. a VPC Lambda with no NAT/egress) costs at
17
- // most this, not multiple seconds. Override with OTEL_FLUSH_TIMEOUT_MS.
18
- const DEFAULT_FLUSH_TIMEOUT_MS =
19
- Number(process.env.OTEL_FLUSH_TIMEOUT_MS) || 500;
20
-
21
- /**
22
- * Fold the invocation's buffered usage counters into the durable store, then
23
- * clear the buffer. On an SQS redelivery (ApproximateReceiveCount > 1) we
24
- * DISCARD rather than flush — the prior delivery already counted, and the usage
25
- * accuracy contract is "approximate, skip obvious redeliveries". Fully guarded.
26
- */
27
- async function flushUsageRollup(subscriber, eventSummary, shouldUseDatabase) {
28
- if (!subscriber) return;
29
- try {
30
- // Persisting usage requires a DB connection. DB-free handlers (e.g. the
31
- // webhook-receipt route) never called connectPrisma, so drop the buffer
32
- // instead of issuing a connectionless Prisma write.
33
- if (!shouldUseDatabase) {
34
- subscriber.discard();
35
- return;
36
- }
37
- // Discard only when EVERY record in the batch is a redelivery. The buffer
38
- // is invocation-scoped (not per-message), so discarding on *any*
39
- // redelivery would drop the fresh records' counts too (silent
40
- // under-count). For a mixed batch we flush: preserving fresh counts and
41
- // at worst re-counting the one redelivered record is strictly better than
42
- // losing fresh data for an approximate store. (Integration queue workers
43
- // are batchSize:1 today, so a batch is all-or-nothing; this keeps it
44
- // correct if batchSize is ever raised.)
45
- const records = Array.isArray(eventSummary?.records)
46
- ? eventSummary.records
47
- : [];
48
- const allRedelivered =
49
- records.length > 0 &&
50
- records.every((r) => Number(r.receiveCount) > 1);
51
- if (allRedelivered) {
52
- subscriber.discard();
53
- } else {
54
- await subscriber.flush();
55
- }
56
- } catch (_) {
57
- // Usage rollup must never break the handler.
58
- }
59
- }
60
-
61
- /**
62
- * Flush telemetry before the Lambda container freezes. Because
63
- * `callbackWaitsForEmptyEventLoop=false` (below) stops the event loop the moment
64
- * the handler returns, OTel's timer-driven batch processors would never fire —
65
- * so spans/metrics must be flushed synchronously here. Bounded by a timeout so a
66
- * stalled exporter can never block the response, and fully guarded so a flush
67
- * failure never breaks the handler.
68
- */
69
- async function flushTelemetry(telemetry, timeoutMs) {
70
- try {
71
- if (
72
- !telemetry ||
73
- typeof telemetry.isEnabled !== 'function' ||
74
- !telemetry.isEnabled()
75
- ) {
76
- return;
77
- }
78
- let timer;
79
- const deadline = new Promise((resolve) => {
80
- timer = setTimeout(resolve, timeoutMs);
81
- });
82
- try {
83
- await Promise.race([
84
- Promise.resolve(telemetry.forceFlush()),
85
- deadline,
86
- ]);
87
- } finally {
88
- clearTimeout(timer);
89
- }
90
- } catch (_) {
91
- // Telemetry flush must never break the handler.
92
- }
93
- }
94
7
 
95
8
  // Best-effort extraction of correlation identifiers from a Lambda event.
96
9
  // For SQS: pulls messageIds + parsed event/processId/integrationId from each
@@ -123,7 +36,8 @@ const summarizeLambdaEvent = (event) => {
123
36
  if (event.httpMethod || event.requestContext?.http) {
124
37
  return {
125
38
  source: 'http',
126
- method: event.httpMethod || event.requestContext?.http?.method,
39
+ method:
40
+ event.httpMethod || event.requestContext?.http?.method,
127
41
  path: event.path || event.rawPath,
128
42
  };
129
43
  }
@@ -136,9 +50,6 @@ const createHandler = (optionByName = {}) => {
136
50
  isUserFacingResponse = true,
137
51
  method,
138
52
  shouldUseDatabase = true,
139
- telemetry,
140
- flushTimeoutMs = DEFAULT_FLUSH_TIMEOUT_MS,
141
- usageRollup,
142
53
  } = optionByName;
143
54
 
144
55
  if (!method) {
@@ -147,23 +58,16 @@ const createHandler = (optionByName = {}) => {
147
58
 
148
59
  return async (event, context) => {
149
60
  const eventSummary = summarizeLambdaEvent(event);
150
- const activeTelemetry = telemetry || getTelemetry();
151
- const activeUsageRollup =
152
- usageRollup !== undefined
153
- ? usageRollup
154
- : getUsageRollupSubscriber();
155
-
156
- // Wire adopter-declared telemetry subscribers once per cold start.
157
- // Memoized in the singleton, so this is a cheap
158
- // no-op after the first invocation.
159
- getPluginTelemetrySubscribers();
160
61
 
161
62
  try {
162
- console.info(`[createHandler] ${eventName}: handler entry`, {
163
- eventName,
164
- awsRequestId: context?.awsRequestId,
165
- ...eventSummary,
166
- });
63
+ console.info(
64
+ `[createHandler] ${eventName}: handler entry`,
65
+ {
66
+ eventName,
67
+ awsRequestId: context?.awsRequestId,
68
+ ...eventSummary,
69
+ }
70
+ );
167
71
 
168
72
  initDebugLog(eventName, event);
169
73
 
@@ -235,14 +139,6 @@ const createHandler = (optionByName = {}) => {
235
139
 
236
140
  // Here we can just rethrow and let AWS build the response.
237
141
  throw error;
238
- } finally {
239
- // Flush telemetry + usage before the container freezes.
240
- await flushTelemetry(activeTelemetry, flushTimeoutMs);
241
- await flushUsageRollup(
242
- activeUsageRollup,
243
- eventSummary,
244
- shouldUseDatabase
245
- );
246
142
  }
247
143
  };
248
144
  };