nestjs-cls
Version:
A continuation-local storage module compatible with NestJS's dependency injection.
203 lines • 7.61 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClsService = void 0;
const value_from_path_1 = require("../utils/value-from-path");
const cls_constants_1 = require("./cls.constants");
const cls_options_1 = require("./cls.options");
const get_proxy_provider_symbol_1 = require("./proxy-provider/get-proxy-provider-symbol");
class ClsService {
constructor(als) {
this.als = als;
if (!als) {
throw new Error(`Cannot create ClsService because no AsyncLocalStorage instance was provided.\nPlease make sure that ClsService is only provided by the ClsModule and not constructed manually or added to the providers array.`);
}
}
/**
* Set (or overrides) a value on the CLS context.
* @param key the key
* @param value the value to set
*/
set(key, value) {
const store = this.als.getStore();
if (!store) {
throw new Error(`Cannot set the key "${String(key)}". No CLS context available, please make sure that a ClsMiddleware/Guard/Interceptor has set up the context, or wrap any calls that depend on CLS with "ClsService#run"`);
}
if (typeof key === 'symbol') {
store[key] = value;
}
else {
(0, value_from_path_1.setValueFromPath)(store, key, value);
}
}
/**
* Set a value on the CLS context if it doesn't already exist
* @param key the key
* @param value the value to set
* @returns `true` if value vas set, `false` if it existed before
*/
setIfUndefined(key, value) {
if (this.has(key))
return false;
this.set(key, value);
return true;
}
get(key) {
const store = this.als.getStore();
if (!key)
return store;
if (typeof key === 'symbol') {
return store?.[key];
}
return (0, value_from_path_1.getValueFromPath)(store, key);
}
has(key) {
const store = this.als.getStore();
if (typeof key === 'symbol') {
return store?.[key] !== undefined;
}
return (0, value_from_path_1.getValueFromPath)(store, key) !== undefined;
}
/**
* Retrieve the request ID (a shorthand for `cls.get(CLS_ID)`)
* @returns the request ID or undefined
*/
getId() {
const store = this.als.getStore();
return store?.[cls_constants_1.CLS_ID];
}
run(optionsOrCallback, maybeCallback) {
let options;
let callback;
if (typeof optionsOrCallback === 'object') {
options = { ...new cls_options_1.ClsContextOptions(), ...optionsOrCallback };
callback = maybeCallback;
}
else {
options = new cls_options_1.ClsContextOptions();
callback = optionsOrCallback;
}
if (!this.isActive())
return this.runWith({}, callback);
switch (options.ifNested) {
case 'inherit':
return this.runWith({ ...this.get() }, callback);
case 'reuse':
return callback();
case 'override':
return this.runWith({}, callback);
}
}
/**
* Run the callbacks with a new CLS context.
*
* @param store the default context contents
* @param callback function to run
* @returns whatever the callback returns
*/
runWith(store, callback) {
return this.als.run(store ?? {}, callback);
}
enter(maybeOptions) {
if (!this.isActive())
return this.als.enterWith({});
const options = { ...new cls_options_1.ClsContextOptions(), ...maybeOptions };
switch (options.ifNested) {
case 'inherit':
return this.enterWith({ ...this.get() });
case 'reuse':
return;
case 'override':
return this.enterWith({});
}
}
/**
* Run any following code with a shared ClS context
* @param store the default context contents
*/
enterWith(store) {
return this.als.enterWith(store ?? {});
}
/**
* Run the callback outside of a shared CLS context
* @param callback function to run
* @returns whatever the callback returns
*/
exit(callback) {
return this.als.exit(callback);
}
/**
* Whether the current code runs within an active CLS context.
* @returns true if a CLS context is active
*/
isActive() {
return !!this.als.getStore();
}
getProxy(proxyToken) {
return this.get((0, get_proxy_provider_symbol_1.getProxyProviderSymbol)(proxyToken));
}
setProxy(proxyToken, value) {
return this.set((0, get_proxy_provider_symbol_1.getProxyProviderSymbol)(proxyToken), value);
}
/**
* Use to manually trigger resolution of Proxy Providers
* in case `resolveProxyProviders` is not enabled in the enhancer.
*
* @param proxyTokens An optional array of Proxy Provider injection tokens
* to resolve. If not supplied, resolves all registered proxy providers.
*/
async resolveProxyProviders(proxyTokens) {
// Workaround for a circular dep
// TODO: This should be untangled and cleaned up
const { ProxyProviderManager } = await Promise.resolve().then(() => __importStar(require('./proxy-provider/proxy-provider-manager')));
const proxySymbols = proxyTokens
? proxyTokens.map(get_proxy_provider_symbol_1.getProxyProviderSymbol)
: [];
await ProxyProviderManager.resolveProxyProviders(proxySymbols);
}
/**
* @deprecated This method will be removed in a future release and replaced
* with a different mechanism for plugin initialization.
*
* Since the plugin API is still experimental, this method will become a np-op
* and will be eventually removed, possibly in a minor release.
*/
async initializePlugins() {
const { ClsPluginManager } = await Promise.resolve().then(() => __importStar(require('./plugin/cls-plugin-manager')));
await ClsPluginManager.onClsInit();
}
}
exports.ClsService = ClsService;
//# sourceMappingURL=cls.service.js.map