UNPKG

nestjs-cls

Version:

A continuation-local storage module compatible with NestJS's dependency injection.

203 lines 7.61 kB
"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