@unito/integration-sdk 0.1.10 → 0.1.11
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/src/index.cjs +20 -28
- package/dist/src/index.d.ts +1 -0
- package/dist/src/integration.js +2 -17
- package/dist/src/resources/cache.d.ts +0 -1
- package/dist/src/resources/cache.js +0 -9
- package/dist/src/resources/provider.d.ts +3 -3
- package/dist/test/resources/cache.test.js +2 -2
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/integration.ts +2 -20
- package/src/resources/cache.ts +0 -12
- package/src/resources/provider.ts +3 -3
- package/test/resources/cache.test.ts +2 -2
package/dist/src/index.cjs
CHANGED
|
@@ -118,13 +118,6 @@ class Logger {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
/**
|
|
122
|
-
* Array of created caches kept to allow for graceful shutdown on exit signals.
|
|
123
|
-
*/
|
|
124
|
-
const caches = [];
|
|
125
|
-
const shutdownCaches = async () => {
|
|
126
|
-
return Promise.allSettled(caches.map(cache => cache.quit()));
|
|
127
|
-
};
|
|
128
121
|
class Cache {
|
|
129
122
|
cacheInstance;
|
|
130
123
|
constructor(cacheInstance) {
|
|
@@ -153,8 +146,6 @@ class Cache {
|
|
|
153
146
|
*/
|
|
154
147
|
static create(redisUrl) {
|
|
155
148
|
const cacheInstance = redisUrl ? new cachette.WriteThroughCache(redisUrl) : new cachette.LocalCache();
|
|
156
|
-
// Push to the array of caches for graceful shutdown on exit signals.
|
|
157
|
-
caches.push(cacheInstance);
|
|
158
149
|
// Intended: the correlation id will be the same for all logs of Cachette.
|
|
159
150
|
const correlationId = uuid__namespace.v4();
|
|
160
151
|
const logger = new Logger({ correlation_id: correlationId });
|
|
@@ -265,13 +256,13 @@ function buildHttpError(responseStatus, message) {
|
|
|
265
256
|
return httpError;
|
|
266
257
|
}
|
|
267
258
|
|
|
268
|
-
const middleware$
|
|
259
|
+
const middleware$7 = (req, res, next) => {
|
|
269
260
|
res.locals.correlationId = req.header('X-Unito-Correlation-Id') ?? uuid__namespace.v4();
|
|
270
261
|
next();
|
|
271
262
|
};
|
|
272
263
|
|
|
273
264
|
const ADDITIONAL_CONTEXT_HEADER = 'X-Unito-Additional-Logging-Context';
|
|
274
|
-
const middleware$
|
|
265
|
+
const middleware$6 = (req, res, next) => {
|
|
275
266
|
const logger = new Logger({ correlation_id: res.locals.correlationId });
|
|
276
267
|
res.locals.logger = logger;
|
|
277
268
|
const rawAdditionalContext = req.header(ADDITIONAL_CONTEXT_HEADER);
|
|
@@ -288,7 +279,7 @@ const middleware$5 = (req, res, next) => {
|
|
|
288
279
|
};
|
|
289
280
|
|
|
290
281
|
const CREDENTIALS_HEADER = 'X-Unito-Credentials';
|
|
291
|
-
const middleware$
|
|
282
|
+
const middleware$5 = (req, res, next) => {
|
|
292
283
|
const credentialsHeader = req.header(CREDENTIALS_HEADER);
|
|
293
284
|
if (credentialsHeader) {
|
|
294
285
|
let credentials;
|
|
@@ -303,6 +294,22 @@ const middleware$4 = (req, res, next) => {
|
|
|
303
294
|
next();
|
|
304
295
|
};
|
|
305
296
|
|
|
297
|
+
const SECRETS_HEADER = 'X-Unito-Secrets';
|
|
298
|
+
const middleware$4 = (req, res, next) => {
|
|
299
|
+
const secretsHeader = req.header(SECRETS_HEADER);
|
|
300
|
+
if (secretsHeader) {
|
|
301
|
+
let secrets;
|
|
302
|
+
try {
|
|
303
|
+
secrets = JSON.parse(Buffer.from(secretsHeader, 'base64').toString('utf8'));
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
throw new BadRequestError(`Malformed HTTP header ${SECRETS_HEADER}`);
|
|
307
|
+
}
|
|
308
|
+
res.locals.secrets = secrets;
|
|
309
|
+
}
|
|
310
|
+
next();
|
|
311
|
+
};
|
|
312
|
+
|
|
306
313
|
const middleware$3 = (req, res, next) => {
|
|
307
314
|
const rawSelect = req.query.select;
|
|
308
315
|
if (typeof rawSelect === 'string') {
|
|
@@ -686,6 +693,7 @@ class Integration {
|
|
|
686
693
|
app.use(express.json());
|
|
687
694
|
// Must be one of the first handlers (to catch all the errors).
|
|
688
695
|
app.use(middleware$1);
|
|
696
|
+
app.use(middleware$7);
|
|
689
697
|
app.use(middleware$6);
|
|
690
698
|
app.use(middleware$5);
|
|
691
699
|
app.use(middleware$4);
|
|
@@ -710,22 +718,6 @@ class Integration {
|
|
|
710
718
|
app.use(middleware);
|
|
711
719
|
// Start the server.
|
|
712
720
|
this.instance = app.listen(this.port, () => console.info(`Server started on port ${this.port}.`));
|
|
713
|
-
// Trap exit signals.
|
|
714
|
-
['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signalType => {
|
|
715
|
-
process.once(signalType, async () => {
|
|
716
|
-
console.info(`Received termination signal ${signalType}. Exiting.`);
|
|
717
|
-
try {
|
|
718
|
-
if (this.instance) {
|
|
719
|
-
this.instance.close();
|
|
720
|
-
}
|
|
721
|
-
await shutdownCaches();
|
|
722
|
-
}
|
|
723
|
-
catch (e) {
|
|
724
|
-
console.error('Failed to gracefully exit', e);
|
|
725
|
-
}
|
|
726
|
-
process.exit();
|
|
727
|
-
});
|
|
728
|
-
});
|
|
729
721
|
}
|
|
730
722
|
}
|
|
731
723
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { Cache } from './resources/cache.js';
|
|
|
3
3
|
export { default as Integration } from './integration.js';
|
|
4
4
|
export * from './handler.js';
|
|
5
5
|
export { Provider, type Response as ProviderResponse, type RequestOptions as ProviderRequestOptions, type RateLimiter, } from './resources/provider.js';
|
|
6
|
+
export type { Secrets } from './middlewares/secrets.js';
|
|
6
7
|
export type { Credentials } from './middlewares/credentials.js';
|
|
7
8
|
export * as HttpErrors from './httpErrors.js';
|
|
8
9
|
export * from './resources/context.js';
|
package/dist/src/integration.js
CHANGED
|
@@ -3,11 +3,11 @@ import { InvalidHandler } from './errors.js';
|
|
|
3
3
|
import correlationIdMiddleware from './middlewares/correlationId.js';
|
|
4
4
|
import loggerMiddleware from './middlewares/logger.js';
|
|
5
5
|
import credentialsMiddleware from './middlewares/credentials.js';
|
|
6
|
+
import secretsMiddleware from './middlewares/secrets.js';
|
|
6
7
|
import selectsMiddleware from './middlewares/selects.js';
|
|
7
8
|
import errorsMiddleware from './middlewares/errors.js';
|
|
8
9
|
import finishMiddleware from './middlewares/finish.js';
|
|
9
10
|
import notFoundMiddleware from './middlewares/notFound.js';
|
|
10
|
-
import { shutdownCaches } from './resources/cache.js';
|
|
11
11
|
import { Handler } from './handler.js';
|
|
12
12
|
function printErrorMessage(message) {
|
|
13
13
|
console.error();
|
|
@@ -65,6 +65,7 @@ export default class Integration {
|
|
|
65
65
|
app.use(correlationIdMiddleware);
|
|
66
66
|
app.use(loggerMiddleware);
|
|
67
67
|
app.use(credentialsMiddleware);
|
|
68
|
+
app.use(secretsMiddleware);
|
|
68
69
|
app.use(selectsMiddleware);
|
|
69
70
|
// Load handlers as needed.
|
|
70
71
|
if (this.handlers.length) {
|
|
@@ -86,21 +87,5 @@ export default class Integration {
|
|
|
86
87
|
app.use(notFoundMiddleware);
|
|
87
88
|
// Start the server.
|
|
88
89
|
this.instance = app.listen(this.port, () => console.info(`Server started on port ${this.port}.`));
|
|
89
|
-
// Trap exit signals.
|
|
90
|
-
['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signalType => {
|
|
91
|
-
process.once(signalType, async () => {
|
|
92
|
-
console.info(`Received termination signal ${signalType}. Exiting.`);
|
|
93
|
-
try {
|
|
94
|
-
if (this.instance) {
|
|
95
|
-
this.instance.close();
|
|
96
|
-
}
|
|
97
|
-
await shutdownCaches();
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
console.error('Failed to gracefully exit', e);
|
|
101
|
-
}
|
|
102
|
-
process.exit();
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
90
|
}
|
|
106
91
|
}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { WriteThroughCache, LocalCache } from 'cachette';
|
|
2
2
|
import * as uuid from 'uuid';
|
|
3
3
|
import Logger from './logger.js';
|
|
4
|
-
/**
|
|
5
|
-
* Array of created caches kept to allow for graceful shutdown on exit signals.
|
|
6
|
-
*/
|
|
7
|
-
const caches = [];
|
|
8
|
-
export const shutdownCaches = async () => {
|
|
9
|
-
return Promise.allSettled(caches.map(cache => cache.quit()));
|
|
10
|
-
};
|
|
11
4
|
export class Cache {
|
|
12
5
|
cacheInstance;
|
|
13
6
|
constructor(cacheInstance) {
|
|
@@ -36,8 +29,6 @@ export class Cache {
|
|
|
36
29
|
*/
|
|
37
30
|
static create(redisUrl) {
|
|
38
31
|
const cacheInstance = redisUrl ? new WriteThroughCache(redisUrl) : new LocalCache();
|
|
39
|
-
// Push to the array of caches for graceful shutdown on exit signals.
|
|
40
|
-
caches.push(cacheInstance);
|
|
41
32
|
// Intended: the correlation id will be the same for all logs of Cachette.
|
|
42
33
|
const correlationId = uuid.v4();
|
|
43
34
|
const logger = new Logger({ correlation_id: correlationId });
|
|
@@ -9,14 +9,14 @@ import Logger from '../resources/logger.js';
|
|
|
9
9
|
* NOTE: make sure to return one of the supported HttpErrors from the SDK, otherwise the error will be translated to a
|
|
10
10
|
* generic server (500) error.
|
|
11
11
|
*
|
|
12
|
-
* @param
|
|
12
|
+
* @param options - The credentials and the logger from the RequestOptions passed with the provider call.
|
|
13
13
|
* @param targetFunction - The function to call the provider.
|
|
14
14
|
* @returns The response from the provider.
|
|
15
15
|
* @throws RateLimitExceededError when the rate limit is exceeded.
|
|
16
16
|
* @throws WouldExceedRateLimitError when the next call would exceed the rate limit.
|
|
17
17
|
* @throws HttpError when the provider returns an error.
|
|
18
18
|
*/
|
|
19
|
-
export type RateLimiter = <T>(
|
|
19
|
+
export type RateLimiter = <T>(options: {
|
|
20
20
|
credentials: Credentials;
|
|
21
21
|
logger: Logger;
|
|
22
22
|
}, targetFunction: () => Promise<Response<T>>) => Promise<Response<T>>;
|
|
@@ -37,7 +37,7 @@ export interface Response<T> {
|
|
|
37
37
|
}
|
|
38
38
|
export declare class Provider {
|
|
39
39
|
protected rateLimiter: RateLimiter | undefined;
|
|
40
|
-
protected prepareRequest: (
|
|
40
|
+
protected prepareRequest: (options: {
|
|
41
41
|
credentials: Credentials;
|
|
42
42
|
logger: Logger;
|
|
43
43
|
}) => {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { describe, it } from 'node:test';
|
|
3
3
|
import { LocalCache } from 'cachette';
|
|
4
|
-
import { Cache
|
|
4
|
+
import { Cache } from '../../src/resources/cache.js';
|
|
5
5
|
describe('Cache', () => {
|
|
6
6
|
describe('initializeCache', () => {
|
|
7
7
|
it('no redis url returns Cache with a inner LocalCache', async () => {
|
|
8
8
|
const cache = Cache.create();
|
|
9
9
|
assert.ok(cache instanceof Cache);
|
|
10
10
|
assert.ok(cache['cacheInstance'] instanceof LocalCache);
|
|
11
|
-
await
|
|
11
|
+
await cache['cacheInstance'].quit();
|
|
12
12
|
});
|
|
13
13
|
it('redis url returns (tries) WriteThroughCache', () => {
|
|
14
14
|
assert.throws(() => Cache.create('fakeredis'), Error, 'Invalid redis url fakereis.');
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export {
|
|
|
9
9
|
type RequestOptions as ProviderRequestOptions,
|
|
10
10
|
type RateLimiter,
|
|
11
11
|
} from './resources/provider.js';
|
|
12
|
+
export type { Secrets } from './middlewares/secrets.js';
|
|
12
13
|
export type { Credentials } from './middlewares/credentials.js';
|
|
13
14
|
export * as HttpErrors from './httpErrors.js';
|
|
14
15
|
export * from './resources/context.js';
|
package/src/integration.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { InvalidHandler } from './errors.js';
|
|
|
5
5
|
import correlationIdMiddleware from './middlewares/correlationId.js';
|
|
6
6
|
import loggerMiddleware from './middlewares/logger.js';
|
|
7
7
|
import credentialsMiddleware from './middlewares/credentials.js';
|
|
8
|
+
import secretsMiddleware from './middlewares/secrets.js';
|
|
8
9
|
import selectsMiddleware from './middlewares/selects.js';
|
|
9
10
|
import errorsMiddleware from './middlewares/errors.js';
|
|
10
11
|
import finishMiddleware from './middlewares/finish.js';
|
|
11
12
|
import notFoundMiddleware from './middlewares/notFound.js';
|
|
12
|
-
import { shutdownCaches } from './resources/cache.js';
|
|
13
13
|
import { HandlersInput, Handler } from './handler.js';
|
|
14
14
|
|
|
15
15
|
function printErrorMessage(message: string) {
|
|
@@ -81,6 +81,7 @@ export default class Integration {
|
|
|
81
81
|
app.use(correlationIdMiddleware);
|
|
82
82
|
app.use(loggerMiddleware);
|
|
83
83
|
app.use(credentialsMiddleware);
|
|
84
|
+
app.use(secretsMiddleware);
|
|
84
85
|
app.use(selectsMiddleware);
|
|
85
86
|
|
|
86
87
|
// Load handlers as needed.
|
|
@@ -105,24 +106,5 @@ export default class Integration {
|
|
|
105
106
|
|
|
106
107
|
// Start the server.
|
|
107
108
|
this.instance = app.listen(this.port, () => console.info(`Server started on port ${this.port}.`));
|
|
108
|
-
|
|
109
|
-
// Trap exit signals.
|
|
110
|
-
['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signalType => {
|
|
111
|
-
process.once(signalType, async () => {
|
|
112
|
-
console.info(`Received termination signal ${signalType}. Exiting.`);
|
|
113
|
-
|
|
114
|
-
try {
|
|
115
|
-
if (this.instance) {
|
|
116
|
-
this.instance.close();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await shutdownCaches();
|
|
120
|
-
} catch (e) {
|
|
121
|
-
console.error('Failed to gracefully exit', e);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
process.exit();
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
109
|
}
|
|
128
110
|
}
|
package/src/resources/cache.ts
CHANGED
|
@@ -2,15 +2,6 @@ import { WriteThroughCache, LocalCache, CacheInstance, FetchingFunction, Cachabl
|
|
|
2
2
|
import * as uuid from 'uuid';
|
|
3
3
|
import Logger from './logger.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Array of created caches kept to allow for graceful shutdown on exit signals.
|
|
7
|
-
*/
|
|
8
|
-
const caches: CacheInstance[] = [];
|
|
9
|
-
|
|
10
|
-
export const shutdownCaches = async () => {
|
|
11
|
-
return Promise.allSettled(caches.map(cache => cache.quit()));
|
|
12
|
-
};
|
|
13
|
-
|
|
14
5
|
export class Cache {
|
|
15
6
|
private cacheInstance: CacheInstance;
|
|
16
7
|
|
|
@@ -53,9 +44,6 @@ export class Cache {
|
|
|
53
44
|
public static create(redisUrl?: string): Cache {
|
|
54
45
|
const cacheInstance: CacheInstance = redisUrl ? new WriteThroughCache(redisUrl) : new LocalCache();
|
|
55
46
|
|
|
56
|
-
// Push to the array of caches for graceful shutdown on exit signals.
|
|
57
|
-
caches.push(cacheInstance);
|
|
58
|
-
|
|
59
47
|
// Intended: the correlation id will be the same for all logs of Cachette.
|
|
60
48
|
const correlationId = uuid.v4();
|
|
61
49
|
|
|
@@ -11,7 +11,7 @@ import Logger from '../resources/logger.js';
|
|
|
11
11
|
* NOTE: make sure to return one of the supported HttpErrors from the SDK, otherwise the error will be translated to a
|
|
12
12
|
* generic server (500) error.
|
|
13
13
|
*
|
|
14
|
-
* @param
|
|
14
|
+
* @param options - The credentials and the logger from the RequestOptions passed with the provider call.
|
|
15
15
|
* @param targetFunction - The function to call the provider.
|
|
16
16
|
* @returns The response from the provider.
|
|
17
17
|
* @throws RateLimitExceededError when the rate limit is exceeded.
|
|
@@ -19,7 +19,7 @@ import Logger from '../resources/logger.js';
|
|
|
19
19
|
* @throws HttpError when the provider returns an error.
|
|
20
20
|
*/
|
|
21
21
|
export type RateLimiter = <T>(
|
|
22
|
-
|
|
22
|
+
options: { credentials: Credentials; logger: Logger },
|
|
23
23
|
targetFunction: () => Promise<Response<T>>,
|
|
24
24
|
) => Promise<Response<T>>;
|
|
25
25
|
|
|
@@ -38,7 +38,7 @@ export interface Response<T> {
|
|
|
38
38
|
|
|
39
39
|
export class Provider {
|
|
40
40
|
protected rateLimiter: RateLimiter | undefined = undefined;
|
|
41
|
-
protected prepareRequest: (
|
|
41
|
+
protected prepareRequest: (options: { credentials: Credentials; logger: Logger }) => {
|
|
42
42
|
url: string;
|
|
43
43
|
headers: Record<string, string>;
|
|
44
44
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { describe, it } from 'node:test';
|
|
3
3
|
import { LocalCache } from 'cachette';
|
|
4
|
-
import { Cache
|
|
4
|
+
import { Cache } from '../../src/resources/cache.js';
|
|
5
5
|
|
|
6
6
|
describe('Cache', () => {
|
|
7
7
|
describe('initializeCache', () => {
|
|
@@ -11,7 +11,7 @@ describe('Cache', () => {
|
|
|
11
11
|
assert.ok(cache instanceof Cache);
|
|
12
12
|
assert.ok(cache['cacheInstance'] instanceof LocalCache);
|
|
13
13
|
|
|
14
|
-
await
|
|
14
|
+
await cache['cacheInstance'].quit();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('redis url returns (tries) WriteThroughCache', () => {
|