@versori/run 0.4.10 → 0.4.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/fs/1.0.19/exists.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAqCT"}
1
+ {"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/fs/1.0.20/exists.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAqCT"}
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _RotatingFileHandler_maxBytes, _RotatingFileHandler_maxBackupCount, _RotatingFileHandler_currentFileSize;
13
- import { existsSync } from "../../fs/1.0.19/exists.js";
13
+ import { existsSync } from "../../fs/1.0.20/exists.js";
14
14
  import { FileHandler } from "./file_handler.js";
15
15
  import { encoderSymbol, filenameSymbol, fileSymbol, modeSymbol, openOptionsSymbol, } from "./_file_handler_symbols.js";
16
16
  /**
@@ -6,6 +6,6 @@ export declare class CredentialHolder<T> {
6
6
  #private;
7
7
  constructor(initialValue: T, isValid: (t: T) => boolean, refresh: (force?: boolean) => Promise<T | undefined>);
8
8
  get(refresh?: boolean): Promise<T>;
9
- refresh(_force?: boolean): void;
9
+ refresh(force?: boolean): void;
10
10
  }
11
11
  //# sourceMappingURL=CredentialHolder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CredentialHolder.d.ts","sourceRoot":"","sources":["../../../../src/src/connection/internal/CredentialHolder.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,qBAAa,gBAAgB,CAAC,CAAC;;gBAQvB,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOlD,GAAG,CAAC,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,CAAC,CAAC;IA0B/C,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAiClC"}
1
+ {"version":3,"file":"CredentialHolder.d.ts","sourceRoot":"","sources":["../../../../src/src/connection/internal/CredentialHolder.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,qBAAa,gBAAgB,CAAC,CAAC;;gBAQvB,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOlD,GAAG,CAAC,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,CAAC,CAAC;IA0B/C,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;CAiCjC"}
@@ -60,7 +60,7 @@ export class CredentialHolder {
60
60
  // the value with a new promise.
61
61
  return __classPrivateFieldGet(this, _CredentialHolder_value, "f");
62
62
  }
63
- refresh(_force) {
63
+ refresh(force) {
64
64
  if (__classPrivateFieldGet(this, _CredentialHolder_isRefreshing, "f")) {
65
65
  return;
66
66
  }
@@ -68,7 +68,7 @@ export class CredentialHolder {
68
68
  // refresh works by replacing the existing #value promise with a new one which is pending
69
69
  // on a new promise which is refreshing the credential.
70
70
  // multiple calls to refresh() will be ignored until the first refresh is complete.
71
- __classPrivateFieldSet(this, _CredentialHolder_value, new Promise((resolve, reject) => __classPrivateFieldGet(this, _CredentialHolder_refresh, "f").call(this).then((refreshed) => {
71
+ __classPrivateFieldSet(this, _CredentialHolder_value, new Promise((resolve, reject) => __classPrivateFieldGet(this, _CredentialHolder_refresh, "f").call(this, force).then((refreshed) => {
72
72
  if (!refreshed) {
73
73
  reject(new Error('Refreshed credential is undefined'));
74
74
  return;
@@ -1,7 +1,7 @@
1
+ import { Logger } from '@versori/run/observability';
2
+ import { PlatformApi } from '@versori/run/services/platform';
1
3
  import { NextFunction, Request, Response } from 'express';
2
4
  import { ConnectionFactory } from '../../../connection/types.js';
3
- import { Logger } from '../../../observability/mod.js';
4
- import { PlatformApi } from '../../../services/platform/mod.js';
5
5
  import { ConfigReader } from '../types.js';
6
6
  export type CreateWebhookMiddleWareOpts = {
7
7
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"webhookmiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/webhookmiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAc,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAiD,YAAY,EAAE,MAAM,aAAa,CAAC;AAU1F,MAAM,MAAM,2BAA2B,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAmCF,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA2EpE;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA6DpE;AAED,wBAAgB,oCAAoC,CAChD,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAqFpE"}
1
+ {"version":3,"file":"webhookmiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/webhookmiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAc,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU3C,MAAM,MAAM,2BAA2B,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAGF,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA4GpE;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAkGpE;AAED,wBAAgB,oCAAoC,CAChD,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAoFpE"}
@@ -10,42 +10,45 @@
10
10
  * As of the Change Date, in accordance with the Business Source License,
11
11
  * use of this software will be governed by the Apache License, Version 2.0.
12
12
  */
13
- // TODO: this gets called for every request for all endpoints, can we cache this?
14
- async function getStaticActivation(opts) {
15
- const { data: activations } = await opts.platformApi.listActivations({
16
- path: {
17
- organisation_id: opts.organisationId,
18
- environment_id: opts.environmentId,
19
- },
20
- query: {
21
- static: true,
22
- },
23
- throwOnError: true,
24
- });
25
- let activation;
26
- if (activations && activations.length > 0) {
27
- if (activations.length > 1) {
28
- opts.log.warn('Multiple static activations found, using the first one', {
29
- activationsCount: activations.length,
30
- });
31
- }
32
- activation = activations[0];
33
- }
34
- else {
35
- opts.log.error('No static activation found', { webhookId: opts.id });
36
- }
37
- return activation;
38
- }
39
- // TODO: Refactor this so we don't have like three different middlewares for static and dynamic webhooks
13
+ import { LRUCache } from 'lru-cache';
40
14
  export function createStaticWebhookMiddleware(opts) {
15
+ // create lru cache for activation
16
+ const activationCache = new LRUCache({ max: 100, ttl: 5 * 60 * 1000 }); // 5 minute ttl
17
+ const staticActivationID = "static";
18
+ const getStaticActivation = (forceFetch = false) => {
19
+ const cachedActivation = activationCache.get(staticActivationID);
20
+ if (cachedActivation && !forceFetch) {
21
+ return cachedActivation;
22
+ }
23
+ else {
24
+ const fetchActivation = async () => {
25
+ const { data: activations } = await opts.platformApi.listActivations({
26
+ path: {
27
+ organisation_id: opts.organisationId,
28
+ environment_id: opts.environmentId,
29
+ },
30
+ query: {
31
+ static: true,
32
+ },
33
+ throwOnError: true,
34
+ });
35
+ if (activations.length === 0) {
36
+ throw new Error('No static activation found');
37
+ }
38
+ return activations[0];
39
+ };
40
+ const activationPromise = fetchActivation();
41
+ activationCache.set(staticActivationID, activationPromise);
42
+ return activationPromise;
43
+ }
44
+ };
41
45
  if (opts.connName === undefined) {
42
46
  opts.log.warn(`No connection ID found for webhook, accepting any requests which is unsecure!`, { webhookId: opts.id });
43
47
  return async (_req, res, next) => {
44
- res.locals.activation = await getStaticActivation(opts);
48
+ res.locals.activation = await getStaticActivation();
45
49
  next();
46
50
  };
47
51
  }
48
- // TODO(@teo): move db access to outside of the middleware??? (genuine question - not instruction)
49
52
  return async (req, res, next) => {
50
53
  if (!opts.connName) {
51
54
  // This is mainly for type safety, but we should never reach this point
@@ -59,14 +62,13 @@ export function createStaticWebhookMiddleware(opts) {
59
62
  res.status(500).json({ error: 'Missing connection for webhook' });
60
63
  return;
61
64
  }
62
- const activation = await getStaticActivation(opts);
63
- if (!activation) {
64
- opts.log.error('No activation found for static webhook', {
65
- webhookId: opts.id,
66
- connName: opts.connName,
67
- });
68
- res.status(500).json({ error: 'No activation found for static webhook' });
69
- return;
65
+ let activation;
66
+ try {
67
+ activation = await getStaticActivation();
68
+ }
69
+ catch (err) {
70
+ opts.log.error('Failed to get static activation', { error: err });
71
+ activation = await getStaticActivation(true);
70
72
  }
71
73
  res.locals.activation = activation;
72
74
  const { data: cnx } = await opts.platformApi.getConnection({
@@ -89,18 +91,44 @@ export function createStaticWebhookMiddleware(opts) {
89
91
  };
90
92
  }
91
93
  export function createActIdDynamicWebhookMiddleware(opts) {
94
+ // create lru cache for activation
95
+ const activationCache = new LRUCache({ max: 100, ttl: 5 * 60 * 1000 }); // 5 minute ttl
96
+ const getActivation = (activationId, forceFetch = false) => {
97
+ const cachedActivation = activationCache.get(activationId);
98
+ if (cachedActivation && !forceFetch) {
99
+ return cachedActivation;
100
+ }
101
+ else {
102
+ const fetchActivation = async () => {
103
+ const activation = await opts.platformApi.getActivation({
104
+ path: {
105
+ organisation_id: opts.organisationId,
106
+ environment_id: opts.environmentId,
107
+ activation_id: activationId,
108
+ },
109
+ throwOnError: true,
110
+ });
111
+ return activation.data;
112
+ };
113
+ const activationPromise = fetchActivation();
114
+ activationCache.set(activationId, activationPromise);
115
+ return activationPromise;
116
+ }
117
+ };
92
118
  if (!opts.connName) {
93
119
  opts.log.warn(`No template ID found for webhook, accepting any requests which is unsecure!`, { webhookId: opts.id });
94
120
  return async (req, res, next) => {
95
121
  const activationId = req.params.activationId;
96
- const activation = await opts.platformApi.getActivation({
97
- path: {
98
- organisation_id: opts.organisationId,
99
- environment_id: opts.environmentId,
100
- activation_id: activationId,
101
- },
102
- throwOnError: true,
103
- });
122
+ let activation;
123
+ try {
124
+ activation = await await getActivation(activationId);
125
+ ;
126
+ }
127
+ catch (err) {
128
+ opts.log.error('Failed to get static activation', { error: err });
129
+ activation = await await getActivation(activationId, true);
130
+ ;
131
+ }
104
132
  res.locals.activation = activation;
105
133
  next();
106
134
  };
@@ -114,14 +142,16 @@ export function createActIdDynamicWebhookMiddleware(opts) {
114
142
  }
115
143
  const templateId = opts.cfgReader.getTemplateID(opts.connName);
116
144
  const activationId = req.params.activationId;
117
- const activation = await opts.platformApi.getActivation({
118
- path: {
119
- organisation_id: opts.organisationId,
120
- environment_id: opts.environmentId,
121
- activation_id: activationId,
122
- },
123
- throwOnError: true,
124
- });
145
+ let activation;
146
+ try {
147
+ activation = await await getActivation(activationId);
148
+ ;
149
+ }
150
+ catch (err) {
151
+ opts.log.error('Failed to get static activation', { error: err });
152
+ activation = await await getActivation(activationId, true);
153
+ ;
154
+ }
125
155
  const conn = await opts.platformApi.getActivationConnection({
126
156
  path: {
127
157
  organisation_id: opts.organisationId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versori/run",
3
- "version": "0.4.10",
3
+ "version": "0.4.12",
4
4
  "description": "Versori Run",
5
5
  "homepage": "https://github.com/versori/versori-run#readme",
6
6
  "repository": {
@@ -1 +1 @@
1
- {"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/fs/1.0.19/exists.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAqCT"}
1
+ {"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/fs/1.0.20/exists.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,GAAG,GAAG,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAqCT"}
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var _RotatingFileHandler_maxBytes, _RotatingFileHandler_maxBackupCount, _RotatingFileHandler_currentFileSize;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.RotatingFileHandler = void 0;
16
- const exists_js_1 = require("../../fs/1.0.19/exists.js");
16
+ const exists_js_1 = require("../../fs/1.0.20/exists.js");
17
17
  const file_handler_js_1 = require("./file_handler.js");
18
18
  const _file_handler_symbols_js_1 = require("./_file_handler_symbols.js");
19
19
  /**
@@ -6,6 +6,6 @@ export declare class CredentialHolder<T> {
6
6
  #private;
7
7
  constructor(initialValue: T, isValid: (t: T) => boolean, refresh: (force?: boolean) => Promise<T | undefined>);
8
8
  get(refresh?: boolean): Promise<T>;
9
- refresh(_force?: boolean): void;
9
+ refresh(force?: boolean): void;
10
10
  }
11
11
  //# sourceMappingURL=CredentialHolder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CredentialHolder.d.ts","sourceRoot":"","sources":["../../../../src/src/connection/internal/CredentialHolder.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,qBAAa,gBAAgB,CAAC,CAAC;;gBAQvB,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOlD,GAAG,CAAC,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,CAAC,CAAC;IA0B/C,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAiClC"}
1
+ {"version":3,"file":"CredentialHolder.d.ts","sourceRoot":"","sources":["../../../../src/src/connection/internal/CredentialHolder.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,qBAAa,gBAAgB,CAAC,CAAC;;gBAQvB,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,EAC1B,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAOlD,GAAG,CAAC,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,CAAC,CAAC;IA0B/C,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;CAiCjC"}
@@ -64,7 +64,7 @@ class CredentialHolder {
64
64
  // the value with a new promise.
65
65
  return __classPrivateFieldGet(this, _CredentialHolder_value, "f");
66
66
  }
67
- refresh(_force) {
67
+ refresh(force) {
68
68
  if (__classPrivateFieldGet(this, _CredentialHolder_isRefreshing, "f")) {
69
69
  return;
70
70
  }
@@ -72,7 +72,7 @@ class CredentialHolder {
72
72
  // refresh works by replacing the existing #value promise with a new one which is pending
73
73
  // on a new promise which is refreshing the credential.
74
74
  // multiple calls to refresh() will be ignored until the first refresh is complete.
75
- __classPrivateFieldSet(this, _CredentialHolder_value, new Promise((resolve, reject) => __classPrivateFieldGet(this, _CredentialHolder_refresh, "f").call(this).then((refreshed) => {
75
+ __classPrivateFieldSet(this, _CredentialHolder_value, new Promise((resolve, reject) => __classPrivateFieldGet(this, _CredentialHolder_refresh, "f").call(this, force).then((refreshed) => {
76
76
  if (!refreshed) {
77
77
  reject(new Error('Refreshed credential is undefined'));
78
78
  return;
@@ -1,7 +1,7 @@
1
+ import { Logger } from '@versori/run/observability';
2
+ import { PlatformApi } from '@versori/run/services/platform';
1
3
  import { NextFunction, Request, Response } from 'express';
2
4
  import { ConnectionFactory } from '../../../connection/types.js';
3
- import { Logger } from '../../../observability/mod.js';
4
- import { PlatformApi } from '../../../services/platform/mod.js';
5
5
  import { ConfigReader } from '../types.js';
6
6
  export type CreateWebhookMiddleWareOpts = {
7
7
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"webhookmiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/webhookmiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAc,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,EAAiD,YAAY,EAAE,MAAM,aAAa,CAAC;AAU1F,MAAM,MAAM,2BAA2B,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAmCF,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA2EpE;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA6DpE;AAED,wBAAgB,oCAAoC,CAChD,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAqFpE"}
1
+ {"version":3,"file":"webhookmiddleware.d.ts","sourceRoot":"","sources":["../../../../../src/src/dsl/http/versori/webhookmiddleware.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAc,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU3C,MAAM,MAAM,2BAA2B,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,SAAS,EAAE,YAAY,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAGF,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CA4GpE;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAkGpE;AAED,wBAAgB,oCAAoC,CAChD,IAAI,EAAE,2BAA2B,GAClC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAoFpE"}
@@ -15,42 +15,45 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.createStaticWebhookMiddleware = createStaticWebhookMiddleware;
16
16
  exports.createActIdDynamicWebhookMiddleware = createActIdDynamicWebhookMiddleware;
17
17
  exports.createUserIdDynamicWebhookMiddleware = createUserIdDynamicWebhookMiddleware;
18
- // TODO: this gets called for every request for all endpoints, can we cache this?
19
- async function getStaticActivation(opts) {
20
- const { data: activations } = await opts.platformApi.listActivations({
21
- path: {
22
- organisation_id: opts.organisationId,
23
- environment_id: opts.environmentId,
24
- },
25
- query: {
26
- static: true,
27
- },
28
- throwOnError: true,
29
- });
30
- let activation;
31
- if (activations && activations.length > 0) {
32
- if (activations.length > 1) {
33
- opts.log.warn('Multiple static activations found, using the first one', {
34
- activationsCount: activations.length,
35
- });
36
- }
37
- activation = activations[0];
38
- }
39
- else {
40
- opts.log.error('No static activation found', { webhookId: opts.id });
41
- }
42
- return activation;
43
- }
44
- // TODO: Refactor this so we don't have like three different middlewares for static and dynamic webhooks
18
+ const lru_cache_1 = require("lru-cache");
45
19
  function createStaticWebhookMiddleware(opts) {
20
+ // create lru cache for activation
21
+ const activationCache = new lru_cache_1.LRUCache({ max: 100, ttl: 5 * 60 * 1000 }); // 5 minute ttl
22
+ const staticActivationID = "static";
23
+ const getStaticActivation = (forceFetch = false) => {
24
+ const cachedActivation = activationCache.get(staticActivationID);
25
+ if (cachedActivation && !forceFetch) {
26
+ return cachedActivation;
27
+ }
28
+ else {
29
+ const fetchActivation = async () => {
30
+ const { data: activations } = await opts.platformApi.listActivations({
31
+ path: {
32
+ organisation_id: opts.organisationId,
33
+ environment_id: opts.environmentId,
34
+ },
35
+ query: {
36
+ static: true,
37
+ },
38
+ throwOnError: true,
39
+ });
40
+ if (activations.length === 0) {
41
+ throw new Error('No static activation found');
42
+ }
43
+ return activations[0];
44
+ };
45
+ const activationPromise = fetchActivation();
46
+ activationCache.set(staticActivationID, activationPromise);
47
+ return activationPromise;
48
+ }
49
+ };
46
50
  if (opts.connName === undefined) {
47
51
  opts.log.warn(`No connection ID found for webhook, accepting any requests which is unsecure!`, { webhookId: opts.id });
48
52
  return async (_req, res, next) => {
49
- res.locals.activation = await getStaticActivation(opts);
53
+ res.locals.activation = await getStaticActivation();
50
54
  next();
51
55
  };
52
56
  }
53
- // TODO(@teo): move db access to outside of the middleware??? (genuine question - not instruction)
54
57
  return async (req, res, next) => {
55
58
  if (!opts.connName) {
56
59
  // This is mainly for type safety, but we should never reach this point
@@ -64,14 +67,13 @@ function createStaticWebhookMiddleware(opts) {
64
67
  res.status(500).json({ error: 'Missing connection for webhook' });
65
68
  return;
66
69
  }
67
- const activation = await getStaticActivation(opts);
68
- if (!activation) {
69
- opts.log.error('No activation found for static webhook', {
70
- webhookId: opts.id,
71
- connName: opts.connName,
72
- });
73
- res.status(500).json({ error: 'No activation found for static webhook' });
74
- return;
70
+ let activation;
71
+ try {
72
+ activation = await getStaticActivation();
73
+ }
74
+ catch (err) {
75
+ opts.log.error('Failed to get static activation', { error: err });
76
+ activation = await getStaticActivation(true);
75
77
  }
76
78
  res.locals.activation = activation;
77
79
  const { data: cnx } = await opts.platformApi.getConnection({
@@ -94,18 +96,44 @@ function createStaticWebhookMiddleware(opts) {
94
96
  };
95
97
  }
96
98
  function createActIdDynamicWebhookMiddleware(opts) {
99
+ // create lru cache for activation
100
+ const activationCache = new lru_cache_1.LRUCache({ max: 100, ttl: 5 * 60 * 1000 }); // 5 minute ttl
101
+ const getActivation = (activationId, forceFetch = false) => {
102
+ const cachedActivation = activationCache.get(activationId);
103
+ if (cachedActivation && !forceFetch) {
104
+ return cachedActivation;
105
+ }
106
+ else {
107
+ const fetchActivation = async () => {
108
+ const activation = await opts.platformApi.getActivation({
109
+ path: {
110
+ organisation_id: opts.organisationId,
111
+ environment_id: opts.environmentId,
112
+ activation_id: activationId,
113
+ },
114
+ throwOnError: true,
115
+ });
116
+ return activation.data;
117
+ };
118
+ const activationPromise = fetchActivation();
119
+ activationCache.set(activationId, activationPromise);
120
+ return activationPromise;
121
+ }
122
+ };
97
123
  if (!opts.connName) {
98
124
  opts.log.warn(`No template ID found for webhook, accepting any requests which is unsecure!`, { webhookId: opts.id });
99
125
  return async (req, res, next) => {
100
126
  const activationId = req.params.activationId;
101
- const activation = await opts.platformApi.getActivation({
102
- path: {
103
- organisation_id: opts.organisationId,
104
- environment_id: opts.environmentId,
105
- activation_id: activationId,
106
- },
107
- throwOnError: true,
108
- });
127
+ let activation;
128
+ try {
129
+ activation = await await getActivation(activationId);
130
+ ;
131
+ }
132
+ catch (err) {
133
+ opts.log.error('Failed to get static activation', { error: err });
134
+ activation = await await getActivation(activationId, true);
135
+ ;
136
+ }
109
137
  res.locals.activation = activation;
110
138
  next();
111
139
  };
@@ -119,14 +147,16 @@ function createActIdDynamicWebhookMiddleware(opts) {
119
147
  }
120
148
  const templateId = opts.cfgReader.getTemplateID(opts.connName);
121
149
  const activationId = req.params.activationId;
122
- const activation = await opts.platformApi.getActivation({
123
- path: {
124
- organisation_id: opts.organisationId,
125
- environment_id: opts.environmentId,
126
- activation_id: activationId,
127
- },
128
- throwOnError: true,
129
- });
150
+ let activation;
151
+ try {
152
+ activation = await await getActivation(activationId);
153
+ ;
154
+ }
155
+ catch (err) {
156
+ opts.log.error('Failed to get static activation', { error: err });
157
+ activation = await await getActivation(activationId, true);
158
+ ;
159
+ }
130
160
  const conn = await opts.platformApi.getActivationConnection({
131
161
  path: {
132
162
  organisation_id: opts.organisationId,