@stigg/cache-runtime 2.0.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/configuration.d.ts +31 -0
- package/dist/configuration.js +91 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +24 -0
- package/dist/services/cacheRuntime.d.ts +66 -0
- package/dist/services/cacheRuntime.js +80 -0
- package/dist/services/entitlementsService.d.ts +81 -0
- package/dist/services/entitlementsService.js +423 -0
- package/dist/services/entitlementsService.utils.d.ts +16 -0
- package/dist/services/entitlementsService.utils.js +3 -0
- package/dist/services/inMemoryEntitlementsService.d.ts +23 -0
- package/dist/services/inMemoryEntitlementsService.js +152 -0
- package/dist/services/inMemoryLruCacheService.d.ts +6 -0
- package/dist/services/inMemoryLruCacheService.js +20 -0
- package/dist/services/initializationStateTracker.d.ts +25 -0
- package/dist/services/initializationStateTracker.js +53 -0
- package/dist/services/loggerService.d.ts +27 -0
- package/dist/services/loggerService.js +65 -0
- package/dist/services/redisEntitlementsService.d.ts +16 -0
- package/dist/services/redisEntitlementsService.js +54 -0
- package/dist/services/runtimeErrorHandler.d.ts +43 -0
- package/dist/services/runtimeErrorHandler.js +91 -0
- package/dist/types/errors.d.ts +24 -0
- package/dist/types/errors.js +3 -0
- package/dist/types/transport.d.ts +152 -0
- package/dist/types/transport.js +3 -0
- package/dist/utils/entitlementQuery.d.ts +10 -0
- package/dist/utils/entitlementQuery.js +22 -0
- package/package.json +36 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.InMemoryEntitlementsService = void 0;
|
|
10
|
+
const entitlementsService_1 = require("./entitlementsService");
|
|
11
|
+
const cache_core_1 = require("@stigg/cache-core");
|
|
12
|
+
const lodash_1 = require("lodash");
|
|
13
|
+
const WS_ERROR_RECONNECT_INTERVAL_MS = 5 * 1000;
|
|
14
|
+
class InMemoryEntitlementsService extends entitlementsService_1.EntitlementsService {
|
|
15
|
+
constructor(cacheService, entitlementsApi, hooks, loggerService, entitlementsTimeout, evaluator, offline, errorHandler) {
|
|
16
|
+
super(entitlementsApi, loggerService, cacheService, entitlementsTimeout, evaluator, offline, errorHandler);
|
|
17
|
+
this.cacheService = cacheService;
|
|
18
|
+
this.hooks = hooks;
|
|
19
|
+
this.entitlementsSubscription = null;
|
|
20
|
+
this.usageSubscription = null;
|
|
21
|
+
this.packagePublishedSubscription = null;
|
|
22
|
+
}
|
|
23
|
+
init() {
|
|
24
|
+
this.loggerService.log('Subscribing to real-time updates');
|
|
25
|
+
this.cleanup();
|
|
26
|
+
this.entitlementsSubscription = this.entitlementsApi.subscribeEntitlementsUpdated().subscribe((value) => this.onEntitlementsUpdated(value), (err) => this.websocketErrorHandling(err));
|
|
27
|
+
this.usageSubscription = this.entitlementsApi.subscribeUsageUpdated().subscribe((value) => this.onUsageUpdated(value), (err) => this.websocketErrorHandling(err));
|
|
28
|
+
this.packagePublishedSubscription = this.entitlementsApi.subscribePackagePublished().subscribe((value) => this.onPackagePublished(value), (err) => this.websocketErrorHandling(err));
|
|
29
|
+
this.isInitialized = true;
|
|
30
|
+
}
|
|
31
|
+
websocketErrorHandling(err) {
|
|
32
|
+
const isErrorRecoverable = this.isErrorRecoverable(err);
|
|
33
|
+
const actionDescription = isErrorRecoverable ? 'retrying to connect' : 'giving up permanently';
|
|
34
|
+
const errorReason = err.message || err.reason;
|
|
35
|
+
const logMessage = `Received error while handling websocket events. Error: ${errorReason} - ${actionDescription}`;
|
|
36
|
+
const isThrottleError = errorReason.includes('ThrottlerException');
|
|
37
|
+
if (isThrottleError) {
|
|
38
|
+
this.loggerService.log(logMessage);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.loggerService.error(logMessage);
|
|
42
|
+
}
|
|
43
|
+
if (isErrorRecoverable) {
|
|
44
|
+
this.cleanup();
|
|
45
|
+
setTimeout(() => this.init(), WS_ERROR_RECONNECT_INTERVAL_MS);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
cleanup() {
|
|
49
|
+
var _a, _b, _c;
|
|
50
|
+
(_a = this.entitlementsSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
51
|
+
this.entitlementsSubscription = null;
|
|
52
|
+
(_b = this.usageSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
|
|
53
|
+
this.usageSubscription = null;
|
|
54
|
+
(_c = this.packagePublishedSubscription) === null || _c === void 0 ? void 0 : _c.unsubscribe();
|
|
55
|
+
this.packagePublishedSubscription = null;
|
|
56
|
+
this.cacheService.clearCache();
|
|
57
|
+
this.isInitialized = false;
|
|
58
|
+
}
|
|
59
|
+
onEntitlementsUpdated(event) {
|
|
60
|
+
const { customerId, resourceId, accessDeniedReason, entitlements } = event;
|
|
61
|
+
this.loggerService.debug(`Entitlements updated event arrived.`, {
|
|
62
|
+
customerId,
|
|
63
|
+
resourceId,
|
|
64
|
+
accessDeniedReason,
|
|
65
|
+
entitlementsCount: entitlements.length,
|
|
66
|
+
});
|
|
67
|
+
// Check for empty entitlements before mapping/caching
|
|
68
|
+
if (entitlements.length === 0 && !accessDeniedReason) {
|
|
69
|
+
this.loggerService.debug(`entitlements updated event contains no entitlements and no accessDeniedReason.`, {
|
|
70
|
+
customerId,
|
|
71
|
+
resourceId,
|
|
72
|
+
accessDeniedReason,
|
|
73
|
+
});
|
|
74
|
+
// we don't know the reason for empty entitlements, so we invalidate the cache to fetch
|
|
75
|
+
// fresh accessDeniedReason on next request
|
|
76
|
+
this.cacheService.purge({ customerId, resourceId });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const entitlementsTimestamp = this.getEntitlementsUpdatedAtTimestamp({
|
|
80
|
+
entitlements,
|
|
81
|
+
customerId,
|
|
82
|
+
resourceId,
|
|
83
|
+
});
|
|
84
|
+
this.cacheService.setCustomer({
|
|
85
|
+
customerId,
|
|
86
|
+
resourceId,
|
|
87
|
+
entitlements,
|
|
88
|
+
accessDeniedReason,
|
|
89
|
+
entitlementsTimestamp: entitlementsTimestamp.getTime(),
|
|
90
|
+
});
|
|
91
|
+
this.hooks.onEntitlementsUpdated(event);
|
|
92
|
+
}
|
|
93
|
+
onUsageUpdated(event) {
|
|
94
|
+
const { customerId, resourceId, entitlementReference, usage } = event;
|
|
95
|
+
const { currentUsage, usagePeriodStart, usagePeriodEnd, usageUpdatedAt } = usage;
|
|
96
|
+
this.loggerService.debug(`Usage updated event arrived.`, {
|
|
97
|
+
customerId,
|
|
98
|
+
resourceId,
|
|
99
|
+
entitlementType: entitlementReference.type,
|
|
100
|
+
entitlementId: entitlementReference.id,
|
|
101
|
+
currentUsage,
|
|
102
|
+
usagePeriodStart,
|
|
103
|
+
usagePeriodEnd,
|
|
104
|
+
});
|
|
105
|
+
// Typed as a Date by the cache contract; the GraphQL fragment's `any` used to hide that
|
|
106
|
+
// a raw epoch was being passed here.
|
|
107
|
+
const usageTimestamp = new Date(usageUpdatedAt !== null && usageUpdatedAt !== void 0 ? usageUpdatedAt : Date.now());
|
|
108
|
+
this.cacheService.updateUsage({
|
|
109
|
+
customerId,
|
|
110
|
+
resourceId,
|
|
111
|
+
entitlementReference,
|
|
112
|
+
usageTimestamp,
|
|
113
|
+
usage: {
|
|
114
|
+
currentUsage,
|
|
115
|
+
usagePeriodStart,
|
|
116
|
+
usagePeriodEnd,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const updatedEntitlement = this.cacheService.getCustomerEntitlement({
|
|
120
|
+
query: entitlementReference,
|
|
121
|
+
customerId,
|
|
122
|
+
resourceId,
|
|
123
|
+
});
|
|
124
|
+
// Only feature entitlements carry a usage the host can report on
|
|
125
|
+
if (updatedEntitlement.entitlement && (0, cache_core_1.isFeatureEntitlement)(updatedEntitlement.entitlement)) {
|
|
126
|
+
this.hooks.onUsageUpdated(customerId, resourceId !== null && resourceId !== void 0 ? resourceId : null, updatedEntitlement.entitlement);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
isErrorRecoverable(err) {
|
|
130
|
+
const isInvalidAPIKeyError = err.reason === 'Invalid API key';
|
|
131
|
+
return !isInvalidAPIKeyError;
|
|
132
|
+
}
|
|
133
|
+
clearCache() {
|
|
134
|
+
return this.cacheService.clearCache();
|
|
135
|
+
}
|
|
136
|
+
onPackagePublished(event) {
|
|
137
|
+
this.loggerService.debug(`Package published event arrived.`, { data: event.payload });
|
|
138
|
+
if (event.affectsAllCustomers) {
|
|
139
|
+
this.loggerService.log('Clearing cache due to package published event');
|
|
140
|
+
this.clearCache();
|
|
141
|
+
}
|
|
142
|
+
this.hooks.onPackagePublished(event.payload);
|
|
143
|
+
}
|
|
144
|
+
async refetchEntityEntitlementsAfterCacheMiss(params) {
|
|
145
|
+
return this.refetchEntitlements(params);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.InMemoryEntitlementsService = InMemoryEntitlementsService;
|
|
149
|
+
__decorate([
|
|
150
|
+
(0, cache_core_1.ReuseOngoingExecution)(({ customerId, resourceId }) => (0, lodash_1.compact)([customerId, resourceId]).join(':'))
|
|
151
|
+
], InMemoryEntitlementsService.prototype, "refetchEntityEntitlementsAfterCacheMiss", null);
|
|
152
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5NZW1vcnlFbnRpdGxlbWVudHNTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL2luTWVtb3J5RW50aXRsZW1lbnRzU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFDQSwrREFBNEQ7QUFDNUQsa0RBQWtIO0FBRWxILG1DQUFpQztBQVlqQyxNQUFNLDhCQUE4QixHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7QUFFaEQsTUFBYSwyQkFHWCxTQUFRLHlDQUE2QztJQUtyRCxZQUNxQixZQUF5QyxFQUM1RCxlQUFnRSxFQUMvQyxLQUF5RCxFQUMxRSxhQUF5QixFQUN6QixtQkFBMkIsRUFDM0IsU0FBK0IsRUFDL0IsT0FBZ0IsRUFDaEIsWUFBaUM7UUFFakMsS0FBSyxDQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFUeEYsaUJBQVksR0FBWixZQUFZLENBQTZCO1FBRTNDLFVBQUssR0FBTCxLQUFLLENBQW9EO1FBUHBFLDZCQUF3QixHQUFpQyxJQUFJLENBQUM7UUFDOUQsc0JBQWlCLEdBQWlDLElBQUksQ0FBQztRQUN2RCxpQ0FBNEIsR0FBaUMsSUFBSSxDQUFDO0lBYTFFLENBQUM7SUFFUSxJQUFJO1FBQ1gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFZixJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLFNBQVMsQ0FDM0YsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsRUFDNUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FB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
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InMemoryCacheService, CacheInstrumentation, CacheMapper } from '@stigg/cache-core';
|
|
2
|
+
export declare class InMemoryLruCacheService<Input> extends InMemoryCacheService<Input> {
|
|
3
|
+
private static readonly textEncoder;
|
|
4
|
+
static getApproxSizeBytes(obj: any): number;
|
|
5
|
+
constructor(maxSizeBytes: number, instrumentation: CacheInstrumentation, cacheMapper: CacheMapper<Input>);
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemoryLruCacheService = void 0;
|
|
4
|
+
const lru_cache_1 = require("lru-cache");
|
|
5
|
+
const cache_core_1 = require("@stigg/cache-core");
|
|
6
|
+
class InMemoryLruCacheService extends cache_core_1.InMemoryCacheService {
|
|
7
|
+
static getApproxSizeBytes(obj) {
|
|
8
|
+
return InMemoryLruCacheService.textEncoder.encode(typeof obj === 'string' ? obj : JSON.stringify(obj)).length;
|
|
9
|
+
}
|
|
10
|
+
constructor(maxSizeBytes, instrumentation, cacheMapper) {
|
|
11
|
+
const store = new lru_cache_1.LRUCache({
|
|
12
|
+
maxSize: maxSizeBytes,
|
|
13
|
+
sizeCalculation: (value) => InMemoryLruCacheService.getApproxSizeBytes(value),
|
|
14
|
+
});
|
|
15
|
+
super(store, instrumentation, cacheMapper);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.InMemoryLruCacheService = InMemoryLruCacheService;
|
|
19
|
+
InMemoryLruCacheService.textEncoder = new TextEncoder();
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5NZW1vcnlMcnVDYWNoZVNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaW5NZW1vcnlMcnVDYWNoZVNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQXFDO0FBQ3JDLGtEQUF3SDtBQUV4SCxNQUFhLHVCQUErQixTQUFRLGlDQUEyQjtJQUc3RSxNQUFNLENBQUMsa0JBQWtCLENBQUMsR0FBUTtRQUNoQyxPQUFPLHVCQUF1QixDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxHQUFHLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDaEgsQ0FBQztJQUVELFlBQVksWUFBb0IsRUFBRSxlQUFxQyxFQUFFLFdBQStCO1FBQ3RHLE1BQU0sS0FBSyxHQUFHLElBQUksb0JBQVEsQ0FBcUM7WUFDN0QsT0FBTyxFQUFFLFlBQVk7WUFDckIsZUFBZSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7U0FDOUUsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDN0MsQ0FBQzs7QUFiSCwwREFjQztBQWJ5QixtQ0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMifQ==
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare enum InitializationState {
|
|
2
|
+
IN_PROGRESS = "IN_PROGRESS",
|
|
3
|
+
SUCCESS = "READY",
|
|
4
|
+
FAILED = "FAILED"
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* How the tracker reports initialization outcome to the host. node-server-sdk's event emitter
|
|
8
|
+
* implements this, so consumers keep receiving the public `initializeSuccessfully` /
|
|
9
|
+
* `initializeFailed` events.
|
|
10
|
+
*/
|
|
11
|
+
export interface InitializationHooks {
|
|
12
|
+
onInitialized(): void;
|
|
13
|
+
onInitializationFailed(err: any): void;
|
|
14
|
+
}
|
|
15
|
+
export declare class InitializationStateTracker {
|
|
16
|
+
private readonly hooks;
|
|
17
|
+
initializationStatus: InitializationState;
|
|
18
|
+
initFailureError: Error | null;
|
|
19
|
+
private initializationPromise;
|
|
20
|
+
private settle;
|
|
21
|
+
constructor(hooks: InitializationHooks);
|
|
22
|
+
getInitializationPromise(): Promise<void>;
|
|
23
|
+
signalSuccessInit(): void;
|
|
24
|
+
signalFailedInit(err: any): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InitializationStateTracker = exports.InitializationState = void 0;
|
|
4
|
+
var InitializationState;
|
|
5
|
+
(function (InitializationState) {
|
|
6
|
+
InitializationState["IN_PROGRESS"] = "IN_PROGRESS";
|
|
7
|
+
InitializationState["SUCCESS"] = "READY";
|
|
8
|
+
InitializationState["FAILED"] = "FAILED";
|
|
9
|
+
})(InitializationState || (exports.InitializationState = InitializationState = {}));
|
|
10
|
+
class InitializationStateTracker {
|
|
11
|
+
constructor(hooks) {
|
|
12
|
+
this.hooks = hooks;
|
|
13
|
+
this.initializationStatus = InitializationState.IN_PROGRESS;
|
|
14
|
+
this.initFailureError = null;
|
|
15
|
+
this.initializationPromise = null;
|
|
16
|
+
this.settle = null;
|
|
17
|
+
}
|
|
18
|
+
getInitializationPromise() {
|
|
19
|
+
if (this.initializationPromise) {
|
|
20
|
+
return this.initializationPromise;
|
|
21
|
+
}
|
|
22
|
+
if (this.initializationStatus === InitializationState.SUCCESS) {
|
|
23
|
+
return Promise.resolve();
|
|
24
|
+
}
|
|
25
|
+
if (this.initializationStatus === InitializationState.FAILED) {
|
|
26
|
+
return Promise.reject(this.initFailureError);
|
|
27
|
+
}
|
|
28
|
+
this.initializationPromise = new Promise((resolve, reject) => {
|
|
29
|
+
this.settle = { resolve, reject };
|
|
30
|
+
});
|
|
31
|
+
return this.initializationPromise;
|
|
32
|
+
}
|
|
33
|
+
signalSuccessInit() {
|
|
34
|
+
var _a;
|
|
35
|
+
this.initializationStatus = InitializationState.SUCCESS;
|
|
36
|
+
(_a = this.settle) === null || _a === void 0 ? void 0 : _a.resolve();
|
|
37
|
+
this.hooks.onInitialized();
|
|
38
|
+
}
|
|
39
|
+
signalFailedInit(err) {
|
|
40
|
+
var _a;
|
|
41
|
+
// onInitialized() runs host listeners, and one of them throwing lands back here through the
|
|
42
|
+
// caller's catch. Callers have already seen the promise resolve, so this cannot become a failure.
|
|
43
|
+
if (this.initializationStatus === InitializationState.SUCCESS) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.initializationStatus = InitializationState.FAILED;
|
|
47
|
+
this.initFailureError = err;
|
|
48
|
+
(_a = this.settle) === null || _a === void 0 ? void 0 : _a.reject(err);
|
|
49
|
+
this.hooks.onInitializationFailed(err);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.InitializationStateTracker = InitializationStateTracker;
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdGlhbGl6YXRpb25TdGF0ZVRyYWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaW5pdGlhbGl6YXRpb25TdGF0ZVRyYWNrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBWSxtQkFJWDtBQUpELFdBQVksbUJBQW1CO0lBQzdCLGtEQUEyQixDQUFBO0lBQzNCLHdDQUFpQixDQUFBO0lBQ2pCLHdDQUFpQixDQUFBO0FBQ25CLENBQUMsRUFKVyxtQkFBbUIsbUNBQW5CLG1CQUFtQixRQUk5QjtBQVlELE1BQWEsMEJBQTBCO0lBTXJDLFlBQTZCLEtBQTBCO1FBQTFCLFVBQUssR0FBTCxLQUFLLENBQXFCO1FBTHZELHlCQUFvQixHQUFHLG1CQUFtQixDQUFDLFdBQVcsQ0FBQztRQUN2RCxxQkFBZ0IsR0FBaUIsSUFBSSxDQUFDO1FBQzlCLDBCQUFxQixHQUF5QixJQUFJLENBQUM7UUFDbkQsV0FBTSxHQUFpRSxJQUFJLENBQUM7SUFFMUIsQ0FBQztJQUUzRCx3QkFBd0I7UUFDdEIsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvQixPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztRQUNwQyxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLEtBQUssbUJBQW1CLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUQsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzdELE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBRUQsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzNELElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztJQUNwQyxDQUFDO0lBRUQsaUJBQWlCOztRQUNmLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7UUFDeEQsTUFBQSxJQUFJLENBQUMsTUFBTSwwQ0FBRSxPQUFPLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxHQUFROztRQUN2Qiw0RkFBNEY7UUFDNUYsa0dBQWtHO1FBQ2xHLElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzlELE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztRQUN2RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO1FBQzVCLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGO0FBOUNELGdFQThDQyJ9
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { LoggerExtra, SlimLogger } from '@stigg/cache-core';
|
|
2
|
+
export type Extra = LoggerExtra;
|
|
3
|
+
/** Aliases SlimLogger so the services taking a cache-core logger accept this by declaration, not by structural coincidence. */
|
|
4
|
+
export type Logger = SlimLogger;
|
|
5
|
+
export interface LogConfiguration {
|
|
6
|
+
logger: Logger;
|
|
7
|
+
logLevel: LogLevel;
|
|
8
|
+
}
|
|
9
|
+
export declare enum LogLevel {
|
|
10
|
+
ALL = "ALL",
|
|
11
|
+
NONE = "NONE",
|
|
12
|
+
LOG = "LOG",
|
|
13
|
+
ERROR = "ERROR"
|
|
14
|
+
}
|
|
15
|
+
export declare class LoggerService implements Logger {
|
|
16
|
+
private readonly logger;
|
|
17
|
+
private readonly logLevel;
|
|
18
|
+
private readonly prefix;
|
|
19
|
+
private instanceId?;
|
|
20
|
+
constructor(logger: Logger, logLevel: LogLevel, prefix: string);
|
|
21
|
+
error(message: string, error?: Extra): void;
|
|
22
|
+
log(message: string, object?: Extra): void;
|
|
23
|
+
debug(message: string, object?: Extra): void;
|
|
24
|
+
prependPrefix(message: string): string;
|
|
25
|
+
setInstanceId(instanceId: string): void;
|
|
26
|
+
getInstanceId(): string | undefined;
|
|
27
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LoggerService = exports.LogLevel = void 0;
|
|
7
|
+
const includes_1 = __importDefault(require("lodash/includes"));
|
|
8
|
+
var LogLevel;
|
|
9
|
+
(function (LogLevel) {
|
|
10
|
+
LogLevel["ALL"] = "ALL";
|
|
11
|
+
LogLevel["NONE"] = "NONE";
|
|
12
|
+
LogLevel["LOG"] = "LOG";
|
|
13
|
+
LogLevel["ERROR"] = "ERROR";
|
|
14
|
+
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
15
|
+
class LoggerService {
|
|
16
|
+
constructor(logger, logLevel, prefix) {
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.logLevel = logLevel;
|
|
19
|
+
this.prefix = prefix;
|
|
20
|
+
}
|
|
21
|
+
error(message, error) {
|
|
22
|
+
if (this.logLevel !== LogLevel.NONE) {
|
|
23
|
+
const aMessage = this.prependPrefix(message);
|
|
24
|
+
if (error) {
|
|
25
|
+
this.logger.error(aMessage, error);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.logger.error(aMessage);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
log(message, object) {
|
|
33
|
+
if (!(0, includes_1.default)([LogLevel.ERROR, LogLevel.NONE], this.logLevel)) {
|
|
34
|
+
const aMessage = this.prependPrefix(message);
|
|
35
|
+
if (object) {
|
|
36
|
+
this.logger.log(aMessage, object);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.logger.log(aMessage);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
debug(message, object) {
|
|
44
|
+
if ((0, includes_1.default)([LogLevel.LOG, LogLevel.ALL], this.logLevel)) {
|
|
45
|
+
const aMessage = this.prependPrefix(message);
|
|
46
|
+
if (object) {
|
|
47
|
+
this.logger.debug(aMessage, object);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.logger.debug(aMessage);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
prependPrefix(message) {
|
|
55
|
+
return `${this.prefix} [iid:${this.instanceId || '-'}] ${message}`;
|
|
56
|
+
}
|
|
57
|
+
setInstanceId(instanceId) {
|
|
58
|
+
this.instanceId = instanceId;
|
|
59
|
+
}
|
|
60
|
+
getInstanceId() {
|
|
61
|
+
return this.instanceId;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.LoggerService = LoggerService;
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9sb2dnZXJTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLCtEQUF1QztBQWF2QyxJQUFZLFFBS1g7QUFMRCxXQUFZLFFBQVE7SUFDbEIsdUJBQVcsQ0FBQTtJQUNYLHlCQUFhLENBQUE7SUFDYix1QkFBVyxDQUFBO0lBQ1gsMkJBQWUsQ0FBQTtBQUNqQixDQUFDLEVBTFcsUUFBUSx3QkFBUixRQUFRLFFBS25CO0FBRUQsTUFBYSxhQUFhO0lBR3hCLFlBQ21CLE1BQWMsRUFDZCxRQUFrQixFQUNsQixNQUFjO1FBRmQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUM5QixDQUFDO0lBQ0osS0FBSyxDQUFDLE9BQWUsRUFBRSxLQUFhO1FBQ2xDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3QyxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUNWLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyQyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsR0FBRyxDQUFDLE9BQWUsRUFBRSxNQUFjO1FBQ2pDLElBQUksQ0FBQyxJQUFBLGtCQUFRLEVBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM5RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdDLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsT0FBZSxFQUFFLE1BQWM7UUFDbkMsSUFBSSxJQUFBLGtCQUFRLEVBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdDLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM5QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxhQUFhLENBQUMsT0FBZTtRQUMzQixPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sU0FBUyxJQUFJLENBQUMsVUFBVSxJQUFJLEdBQUcsS0FBSyxPQUFPLEVBQUUsQ0FBQztJQUNyRSxDQUFDO0lBRUQsYUFBYSxDQUFDLFVBQWtCO1FBQzlCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7SUFDRCxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7Q0FDRjtBQW5ERCxzQ0FtREMifQ==
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RuntimeErrorHandler } from './runtimeErrorHandler';
|
|
2
|
+
import { EntitlementsService } from './entitlementsService';
|
|
3
|
+
import { RefetchEntityEntitlementsAfterCacheMissParams } from './entitlementsService.utils';
|
|
4
|
+
import { RedisCacheService } from '@stigg/cache-redis-store';
|
|
5
|
+
import { SlimLogger } from '@stigg/cache-core';
|
|
6
|
+
import { EntitlementEvaluator } from '@stigg/entitlements-runtime';
|
|
7
|
+
import { CacheableInput, EntitlementsTransport } from '../types/transport';
|
|
8
|
+
export declare class RedisEntitlementsService<Input extends CacheableInput, TPackagePublished = unknown> extends EntitlementsService<Input, TPackagePublished> {
|
|
9
|
+
protected readonly cacheService: RedisCacheService<Input>;
|
|
10
|
+
protected readonly loggerService: SlimLogger;
|
|
11
|
+
constructor(cacheService: RedisCacheService<Input>, entitlementsApi: EntitlementsTransport<Input, TPackagePublished>, loggerService: SlimLogger, entitlementsTimeout: number, evaluator: EntitlementEvaluator, offline: boolean, errorHandler: RuntimeErrorHandler);
|
|
12
|
+
protected refetchEntityEntitlementsAfterCacheMiss(params: RefetchEntityEntitlementsAfterCacheMissParams): Promise<import("@stigg/cache-core").EntitlementsResponse>;
|
|
13
|
+
clearCache(): Promise<void>;
|
|
14
|
+
init(): void | Promise<void>;
|
|
15
|
+
cleanup(): void | Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RedisEntitlementsService = void 0;
|
|
10
|
+
const entitlementsService_1 = require("./entitlementsService");
|
|
11
|
+
const cache_core_1 = require("@stigg/cache-core");
|
|
12
|
+
const lodash_1 = require("lodash");
|
|
13
|
+
class RedisEntitlementsService extends entitlementsService_1.EntitlementsService {
|
|
14
|
+
constructor(cacheService, entitlementsApi, loggerService, entitlementsTimeout, evaluator, offline, errorHandler) {
|
|
15
|
+
super(entitlementsApi, loggerService, cacheService, entitlementsTimeout, evaluator, offline, errorHandler);
|
|
16
|
+
this.cacheService = cacheService;
|
|
17
|
+
this.loggerService = loggerService;
|
|
18
|
+
this.isInitialized = true; // redis is always considered as initialized
|
|
19
|
+
}
|
|
20
|
+
async refetchEntityEntitlementsAfterCacheMiss(params) {
|
|
21
|
+
if (!this.cacheService.isClientConnected()) {
|
|
22
|
+
throw new Error('Redis is not connected. Cannot refetch entitlements.');
|
|
23
|
+
}
|
|
24
|
+
const { distributedRefetchEntitlementsService } = this.cacheService;
|
|
25
|
+
if (!distributedRefetchEntitlementsService) {
|
|
26
|
+
return this.refetchEntitlements(params);
|
|
27
|
+
}
|
|
28
|
+
const { customerId, resourceId } = params;
|
|
29
|
+
const reloadFromApi = () => this.refetchEntitlements(params);
|
|
30
|
+
const loadFromCache = () => this.cacheService.getCustomerEntitlements({ customerId, resourceId });
|
|
31
|
+
return distributedRefetchEntitlementsService.executeOnceAcrossMultipleProcesses({
|
|
32
|
+
customerId,
|
|
33
|
+
resourceId,
|
|
34
|
+
reloadFromApi,
|
|
35
|
+
loadFromCache,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
clearCache() {
|
|
39
|
+
// Clearing persisted cache is not supported
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
}
|
|
42
|
+
init() {
|
|
43
|
+
// Real time updated via sdk is not supported with persisted cache
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
cleanup() {
|
|
47
|
+
return this.cacheService.cleanup();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.RedisEntitlementsService = RedisEntitlementsService;
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, cache_core_1.ReuseOngoingExecution)(({ customerId, resourceId }) => (0, lodash_1.compact)([customerId, resourceId]).join(':'))
|
|
53
|
+
], RedisEntitlementsService.prototype, "refetchEntityEntitlementsAfterCacheMiss", null);
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkaXNFbnRpdGxlbWVudHNTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL3JlZGlzRW50aXRsZW1lbnRzU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFDQSwrREFBNEQ7QUFHNUQsa0RBQXNFO0FBRXRFLG1DQUFpQztBQUdqQyxNQUFhLHdCQUdYLFNBQVEseUNBQTZDO0lBQ3JELFlBQ3FCLFlBQXNDLEVBQ3pELGVBQWdFLEVBQzdDLGFBQXlCLEVBQzVDLG1CQUEyQixFQUMzQixTQUErQixFQUMvQixPQUFnQixFQUNoQixZQUFpQztRQUVqQyxLQUFLLENBQUMsZUFBZSxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsbUJBQW1CLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztRQVJ4RixpQkFBWSxHQUFaLFlBQVksQ0FBMEI7UUFFdEMsa0JBQWEsR0FBYixhQUFhLENBQVk7UUFPNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsQ0FBQyw0Q0FBNEM7SUFDekUsQ0FBQztJQUt3QixBQUFOLEtBQUssQ0FBQyx1Q0FBdUMsQ0FDOUQsTUFBcUQ7UUFFckQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQzNDLE1BQU0sSUFBSSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBRUQsTUFBTSxFQUFFLHFDQUFxQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNwRSxJQUFJLENBQUMscUNBQXFDLEVBQUUsQ0FBQztZQUMzQyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBRUQsTUFBTSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsR0FBRyxNQUFNLENBQUM7UUFDMUMsTUFBTSxhQUFhLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdELE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsdUJBQXVCLENBQUMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztRQUVsRyxPQUFPLHFDQUFxQyxDQUFDLGtDQUFrQyxDQUFDO1lBQzlFLFVBQVU7WUFDVixVQUFVO1lBQ1YsYUFBYTtZQUNiLGFBQWE7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVEsVUFBVTtRQUNqQiw0Q0FBNEM7UUFDNUMsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVRLElBQUk7UUFDWCxrRUFBa0U7UUFDbEUsT0FBTztJQUNULENBQUM7SUFFUSxPQUFPO1FBQ2QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3JDLENBQUM7Q0FDRjtBQXpERCw0REF5REM7QUFyQzBCO0lBSHhCLElBQUEsa0NBQXFCLEVBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQWlELEVBQUUsRUFBRSxDQUNuRyxJQUFBLGdCQUFPLEVBQUMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQzVDO3VGQXVCQSJ9
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SlimLogger } from '@stigg/cache-core';
|
|
2
|
+
import { ClassifiedError, TransportErrorClassifier } from '../types/errors';
|
|
3
|
+
/** Carries the failure's code and trace so hosts can map it onto their own error vocabulary. */
|
|
4
|
+
export declare class RuntimeError extends Error {
|
|
5
|
+
readonly errorCode?: string | undefined;
|
|
6
|
+
readonly traceId?: string | undefined;
|
|
7
|
+
constructor(message: string, errorCode?: string | undefined, traceId?: string | undefined);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* How a host is told about a transport failure. Exactly one of the two fires per failure —
|
|
11
|
+
* `onUnauthenticated` for an invalid key, `onNetworkRequestFailed` for anything else — so a host
|
|
12
|
+
* that only wants counters never has to wrap anything itself.
|
|
13
|
+
*/
|
|
14
|
+
export interface RuntimeErrorHooks {
|
|
15
|
+
onUnauthenticated(): void;
|
|
16
|
+
onNetworkRequestFailed(error: ClassifiedError): void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The failure contract shared by every host of the runtime: classify once, report once, then either
|
|
20
|
+
* answer with the caller's fallback or rethrow as a `RuntimeError`.
|
|
21
|
+
*/
|
|
22
|
+
export declare class RuntimeErrorHandler {
|
|
23
|
+
private readonly loggerService;
|
|
24
|
+
private readonly hooks;
|
|
25
|
+
private readonly classifier;
|
|
26
|
+
constructor(loggerService: SlimLogger, hooks: RuntimeErrorHooks, classifier: TransportErrorClassifier);
|
|
27
|
+
/**
|
|
28
|
+
* A read never fails the caller: the failure is reported — which is what feeds any host counters —
|
|
29
|
+
* and the caller is answered with its fallback. This is the runtime's never-throw promise, so
|
|
30
|
+
* every host reads through here rather than reimplementing it.
|
|
31
|
+
*/
|
|
32
|
+
readOrFallback<T>(errorMessagePrefix: string, read: () => Promise<T>, fallback: () => T): Promise<T>;
|
|
33
|
+
/** Startup has no fallback answer, so it throws — but reports first, onto a read's own counters. */
|
|
34
|
+
runOrThrow<T>(errorMessagePrefix: string, run: () => Promise<T>): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* An invalid key is reported on its own channel; the message it reads by is fixed here too.
|
|
37
|
+
* Classification and the host's listeners are both fallible, and neither may replace the failure
|
|
38
|
+
* the caller is being told about — so each is tolerated and the classification still stands.
|
|
39
|
+
*/
|
|
40
|
+
private report;
|
|
41
|
+
/** Each reporting channel fails alone, so one bad listener cannot silence the other. */
|
|
42
|
+
private tolerate;
|
|
43
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuntimeErrorHandler = exports.RuntimeError = void 0;
|
|
4
|
+
/** Carries the failure's code and trace so hosts can map it onto their own error vocabulary. */
|
|
5
|
+
class RuntimeError extends Error {
|
|
6
|
+
constructor(message, errorCode, traceId) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.errorCode = errorCode;
|
|
9
|
+
this.traceId = traceId;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.RuntimeError = RuntimeError;
|
|
13
|
+
/**
|
|
14
|
+
* The failure contract shared by every host of the runtime: classify once, report once, then either
|
|
15
|
+
* answer with the caller's fallback or rethrow as a `RuntimeError`.
|
|
16
|
+
*/
|
|
17
|
+
class RuntimeErrorHandler {
|
|
18
|
+
constructor(loggerService, hooks, classifier) {
|
|
19
|
+
this.loggerService = loggerService;
|
|
20
|
+
this.hooks = hooks;
|
|
21
|
+
this.classifier = classifier;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A read never fails the caller: the failure is reported — which is what feeds any host counters —
|
|
25
|
+
* and the caller is answered with its fallback. This is the runtime's never-throw promise, so
|
|
26
|
+
* every host reads through here rather than reimplementing it.
|
|
27
|
+
*/
|
|
28
|
+
async readOrFallback(errorMessagePrefix, read, fallback) {
|
|
29
|
+
try {
|
|
30
|
+
return await read();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
this.report(err);
|
|
34
|
+
this.tolerate(() => this.loggerService.error(`${errorMessagePrefix}: ${toErrorMessage(err)}`, err));
|
|
35
|
+
return fallback();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Startup has no fallback answer, so it throws — but reports first, onto a read's own counters. */
|
|
39
|
+
async runOrThrow(errorMessagePrefix, run) {
|
|
40
|
+
try {
|
|
41
|
+
return await run();
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
const { errorMessage, errorCode, traceId, isTimeout } = this.report(err);
|
|
45
|
+
if (isTimeout) {
|
|
46
|
+
throw new RuntimeError(`${errorMessagePrefix}: Request timed out`, 'RequestTimeout');
|
|
47
|
+
}
|
|
48
|
+
throw new RuntimeError(`${errorMessagePrefix}: ${errorMessage}`, errorCode, traceId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* An invalid key is reported on its own channel; the message it reads by is fixed here too.
|
|
53
|
+
* Classification and the host's listeners are both fallible, and neither may replace the failure
|
|
54
|
+
* the caller is being told about — so each is tolerated and the classification still stands.
|
|
55
|
+
*/
|
|
56
|
+
report(err) {
|
|
57
|
+
let classified = {
|
|
58
|
+
errorMessage: toErrorMessage(err),
|
|
59
|
+
isUnauthenticated: false,
|
|
60
|
+
isTimeout: false,
|
|
61
|
+
};
|
|
62
|
+
this.tolerate(() => {
|
|
63
|
+
classified = this.classifier.classify(err);
|
|
64
|
+
});
|
|
65
|
+
if (classified.isUnauthenticated) {
|
|
66
|
+
this.tolerate(() => this.hooks.onUnauthenticated());
|
|
67
|
+
return Object.assign(Object.assign({}, classified), { errorMessage: 'Authentication failed. Double check your API key.' });
|
|
68
|
+
}
|
|
69
|
+
this.tolerate(() => this.hooks.onNetworkRequestFailed(classified));
|
|
70
|
+
return classified;
|
|
71
|
+
}
|
|
72
|
+
/** Each reporting channel fails alone, so one bad listener cannot silence the other. */
|
|
73
|
+
tolerate(report) {
|
|
74
|
+
try {
|
|
75
|
+
report();
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
// a host listener or the logger itself threw — there is nowhere left to report that
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.RuntimeErrorHandler = RuntimeErrorHandler;
|
|
83
|
+
/** A rejected read can carry anything, and `.message` on a string or on null would throw. */
|
|
84
|
+
function toErrorMessage(err) {
|
|
85
|
+
if (err instanceof Error) {
|
|
86
|
+
return err.message;
|
|
87
|
+
}
|
|
88
|
+
const message = err === null || err === void 0 ? void 0 : err.message;
|
|
89
|
+
return typeof message === 'string' ? message : String(err);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZUVycm9ySGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9ydW50aW1lRXJyb3JIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUdBLGdHQUFnRztBQUNoRyxNQUFhLFlBQWEsU0FBUSxLQUFLO0lBQ3JDLFlBQ0UsT0FBZSxFQUNOLFNBQWtCLEVBQ2xCLE9BQWdCO1FBRXpCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUhOLGNBQVMsR0FBVCxTQUFTLENBQVM7UUFDbEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUczQixDQUFDO0NBQ0Y7QUFSRCxvQ0FRQztBQVlEOzs7R0FHRztBQUNILE1BQWEsbUJBQW1CO0lBQzlCLFlBQ21CLGFBQXlCLEVBQ3pCLEtBQXdCLEVBQ3hCLFVBQW9DO1FBRnBDLGtCQUFhLEdBQWIsYUFBYSxDQUFZO1FBQ3pCLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBQ3hCLGVBQVUsR0FBVixVQUFVLENBQTBCO0lBQ3BELENBQUM7SUFFSjs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBSSxrQkFBMEIsRUFBRSxJQUFzQixFQUFFLFFBQWlCO1FBQzNGLElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUN0QixDQUFDO1FBQUMsT0FBTyxHQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQ2pCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEdBQUcsa0JBQWtCLEtBQUssY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBa0IsQ0FBQyxDQUM5RixDQUFDO1lBQ0YsT0FBTyxRQUFRLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0gsQ0FBQztJQUVELG9HQUFvRztJQUNwRyxLQUFLLENBQUMsVUFBVSxDQUFJLGtCQUEwQixFQUFFLEdBQXFCO1FBQ25FLElBQUksQ0FBQztZQUNILE9BQU8sTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNyQixDQUFDO1FBQUMsT0FBTyxHQUFZLEVBQUUsQ0FBQztZQUN0QixNQUFNLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUV6RSxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLE1BQU0sSUFBSSxZQUFZLENBQUMsR0FBRyxrQkFBa0IscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RixDQUFDO1lBRUQsTUFBTSxJQUFJLFlBQVksQ0FBQyxHQUFHLGtCQUFrQixLQUFLLFlBQVksRUFBRSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN2RixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxNQUFNLENBQUMsR0FBWTtRQUN6QixJQUFJLFVBQVUsR0FBb0I7WUFDaEMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxHQUFHLENBQUM7WUFDakMsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixTQUFTLEVBQUUsS0FBSztTQUNqQixDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDakIsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxVQUFVLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELHVDQUFZLFVBQVUsS0FBRSxZQUFZLEVBQUUsbURBQW1ELElBQUc7UUFDOUYsQ0FBQztRQUVELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ25FLE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFRCx3RkFBd0Y7SUFDaEYsUUFBUSxDQUFDLE1BQWtCO1FBQ2pDLElBQUksQ0FBQztZQUNILE1BQU0sRUFBRSxDQUFDO1FBQ1gsQ0FBQztRQUFDLFdBQU0sQ0FBQztZQUNQLG9GQUFvRjtRQUN0RixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBdkVELGtEQXVFQztBQUVELDZGQUE2RjtBQUM3RixTQUFTLGNBQWMsQ0FBQyxHQUFZO0lBQ2xDLElBQUksR0FBRyxZQUFZLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQztJQUNyQixDQUFDO0lBQ0QsTUFBTSxPQUFPLEdBQUksR0FBZ0QsYUFBaEQsR0FBRyx1QkFBSCxHQUFHLENBQStDLE9BQU8sQ0FBQztJQUMzRSxPQUFPLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDN0QsQ0FBQyJ9
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a transport reports about a failure, in terms the read policy can act on.
|
|
3
|
+
* The wire-level shape of an error — GraphQL error arrays, network envelopes, HTTP
|
|
4
|
+
* responses — is the transport's business.
|
|
5
|
+
*/
|
|
6
|
+
export type ClassifiedError = {
|
|
7
|
+
errorMessage: string;
|
|
8
|
+
errorCode?: string;
|
|
9
|
+
traceId?: string;
|
|
10
|
+
/** Credentials were rejected, so retrying will not help. */
|
|
11
|
+
isUnauthenticated: boolean;
|
|
12
|
+
/** The request exceeded its deadline rather than being refused. */
|
|
13
|
+
isTimeout: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Carried through to the host untouched. The GraphQL transport puts the raw axios
|
|
16
|
+
* request and response here, and those carry the `X-API-KEY` header — so read named
|
|
17
|
+
* fields off them, never log or serialise one wholesale.
|
|
18
|
+
*/
|
|
19
|
+
request?: unknown;
|
|
20
|
+
response?: unknown;
|
|
21
|
+
};
|
|
22
|
+
export interface TransportErrorClassifier {
|
|
23
|
+
classify(err: unknown): ClassifiedError;
|
|
24
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3R5cGVzL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
|