diff --git a/package-lock.json b/package-lock.json index 9789549cf60..9d91054773b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65003,7 +65003,7 @@ }, "packages/common": { "name": "@esri/hub-common", - "version": "15.38.0", + "version": "15.38.1", "license": "Apache-2.0", "dependencies": { "@terraformer/arcgis": "^2.1.2", @@ -65032,7 +65032,7 @@ }, "packages/discussions": { "name": "@esri/hub-discussions", - "version": "29.6.0", + "version": "29.7.0", "license": "Apache-2.0", "dependencies": { "tslib": "^1.13.0" diff --git a/packages/common/src/ArcGISContextManager.ts b/packages/common/src/ArcGISContextManager.ts index 708c9c2c1d4..976ae066fef 100644 --- a/packages/common/src/ArcGISContextManager.ts +++ b/packages/common/src/ArcGISContextManager.ts @@ -80,8 +80,6 @@ export class ArcGISContextManager { private _currentUser: IUser; - private _logLevel: Level = Level.error; - private _serviceStatus: HubServiceStatus; private _featureFlags: IFeatureFlags = {}; @@ -104,10 +102,12 @@ export class ArcGISContextManager { private constructor(opts: IArcGISContextManagerOptions) { // Having a unique id makes debugging easier this.id = new Date().getTime(); + + // TODO: remove all log level logic at next breaking change if (opts.logLevel) { - this._logLevel = opts.logLevel; + Logger.setLogLevel(opts.logLevel); } - Logger.setLogLevel(this._logLevel); + Logger.debug(`ArcGISContextManager:ctor: Creating ${this.id}`); if (opts.properties) { diff --git a/packages/common/src/types/IArcGISContextManagerOptions.ts b/packages/common/src/types/IArcGISContextManagerOptions.ts index c14b67ce39d..5ee24e55e9d 100644 --- a/packages/common/src/types/IArcGISContextManagerOptions.ts +++ b/packages/common/src/types/IArcGISContextManagerOptions.ts @@ -54,9 +54,8 @@ export interface IArcGISContextManagerOptions { properties?: Record; /** + * DEPRECATED: use `globalThis.arcgisHubConfig.logLevel` instead * Logging level - * off > error > warn > info > debug > all - * defaults to 'error' */ logLevel?: Level; diff --git a/packages/common/src/utils/IHubConfig.ts b/packages/common/src/utils/IHubConfig.ts new file mode 100644 index 00000000000..c7f795541c6 --- /dev/null +++ b/packages/common/src/utils/IHubConfig.ts @@ -0,0 +1,25 @@ +import { LogLevel } from "./LogLevel"; + +/** + * Hub.js configuration settings + * + * You can override the default settings by + * initializing the global `arcgisHubConfig` variable + * before using any Hub.js functions, for example: + * ```js + * import { Logger } from '@esri/hub-common'; + * // configure Hub.js + * const logLevel = environment === 'production' ? 'error' : 'debug'; + * globalThis.arcgisHubConfig = { logLevel }; + * // then use Hub.js + * Logger.info('This message will not log on production'); + * ``` + */ +export interface IHubConfig { + /** + * The global log level for Hub.js + * + * Available logging levels are specified in the LogLevel type. The default is 'info'. + */ + logLevel?: LogLevel; +} diff --git a/packages/common/src/utils/LogLevel.ts b/packages/common/src/utils/LogLevel.ts new file mode 100644 index 00000000000..102baa04e7d --- /dev/null +++ b/packages/common/src/utils/LogLevel.ts @@ -0,0 +1,2 @@ +/** The level of console logs that will be issued by Hub.js */ +export type LogLevel = "all" | "debug" | "info" | "warn" | "error" | "off"; diff --git a/packages/common/src/utils/index.ts b/packages/common/src/utils/index.ts index 5f7c00328eb..2f778ae1b96 100644 --- a/packages/common/src/utils/index.ts +++ b/packages/common/src/utils/index.ts @@ -1,3 +1,4 @@ +export * from "./LogLevel"; export * from "./asyncForEach"; export * from "./batch"; export * from "./encoding"; diff --git a/packages/common/src/utils/internal/config.ts b/packages/common/src/utils/internal/config.ts new file mode 100644 index 00000000000..7b05e2870a0 --- /dev/null +++ b/packages/common/src/utils/internal/config.ts @@ -0,0 +1,43 @@ +import { IHubConfig } from "../IHubConfig"; + +// the default settings +const DEFAULT_CONFIG: IHubConfig = { + logLevel: "info", +}; + +// the global variable name that consumers use to override the defaults +const GLOBAL_VARIABLE_NAME = "arcgisHubConfig"; + +// NOTE: we want to move to a config that is read-only +// once it has been initialized from the above global variable +// see https://devtopia.esri.com/dc/hub/issues/10713#issuecomment-5337749 +// but for now we have to support the deprecated Logger.setLogLevel() +// so we need these temporary functions to get/set config settings + +export const _getConfigSetting = (key: keyof IHubConfig) => { + const config = { + ...DEFAULT_CONFIG, + ...(globalThis as any)[GLOBAL_VARIABLE_NAME], + } as IHubConfig; + return config && config[key]; +}; + +export const _setConfigSetting = (key: keyof IHubConfig, value: any) => { + const config = (globalThis as any)[GLOBAL_VARIABLE_NAME] as IHubConfig; + if (!config) { + (globalThis as any)[GLOBAL_VARIABLE_NAME] = {}; + } + (globalThis as any)[GLOBAL_VARIABLE_NAME][key] = value; +}; + +// TODO: once we remove Logger.setLogLevel() we should +// replace the above functions with the following: + +// merge consumer supplied config (if any) with the defaults +// const config = { +// ...DEFAULT_CONFIG, +// ...(globalThis as any)[GLOBAL_VARIABLE_NAME] +// } as IHubConfig; + +// export the settings as immutable consts +// export const logLevel = config.logLevel; diff --git a/packages/common/src/utils/logger.ts b/packages/common/src/utils/logger.ts index e83d676bf50..68ebdce32dc 100644 --- a/packages/common/src/utils/logger.ts +++ b/packages/common/src/utils/logger.ts @@ -1,5 +1,8 @@ /* tslint:disable no-console */ +import { _setConfigSetting, _getConfigSetting } from "./internal/config"; +// TODO: stop exporting this at the next breaking change +// only exporting for backward compatibility /** * Enum for Logger Levels */ @@ -9,12 +12,12 @@ export enum Level { info, warn, error, - off + off, } /** * ```js - * import { Logger, Level } from '@esri/hub-common' + * import { Logger } from '@esri/hub-common' * ``` * Functions share the console interface * ```js @@ -22,7 +25,7 @@ export enum Level { * Logger.warn('Watch out!', { threat: 'Charizard' }); * // etc, etc * ``` - * Available logging levels are specified in the Level enum. The hierarchy is as follows: + * Available logging levels are specified in the LogLevel type. The hierarchy is as follows: * ``` * off > error > warn > info > debug > all * ``` @@ -32,20 +35,17 @@ export enum Level { * Logger.info('This message won't log'); * Logger.error('But this one will!'); * ``` - * Logger's default level is 'off', so set desired level before use - * ```js - * Logger.setLogLevel(Level.all); - * ``` */ export class Logger { - private static logLevel = Level.off; - + // TODO: remove this at next breaking change /** + * DEPRECATED: configure log level with `globalThis.arcgisHubConfig.logLevel` instead * Sets the global log level * @param {Level} level */ public static setLogLevel(level: Level) { - this.logLevel = level; + const levelName = Level[level]; + _setConfigSetting("logLevel", levelName); } /** @@ -104,6 +104,8 @@ export class Logger { } private static isLevelPermitted(level: Level) { - return this.logLevel <= level; + const configuredLevel = + Level[_getConfigSetting("logLevel") as keyof typeof Level]; + return configuredLevel <= level; } }