@webpieces/core-util 0.3.267 → 0.3.269

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/core-util",
3
- "version": "0.3.267",
3
+ "version": "0.3.269",
4
4
  "description": "Utility functions for WebPieces - works in browser and Node.js",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-util/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @webpieces/core-util\n *\n * Utility functions for WebPieces applications.\n * This package works in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\nexport { toError } from './lib/errorUtils';\nexport { Header } from './Header';\nexport { ContextKey } from './ContextKey';\n\n// Logging (merged from former @webpieces/wp-logging).\n// Pluggable logging interface + a browser-safe console default; apps plug in\n// bunyan/winston/pino/etc. via LogManager.setFactory(...). Browser + Node.\nexport type { Logger, LogLevel } from './logging/Logger';\nexport type { LoggerFactory } from './logging/LoggerFactory';\nexport { ConsoleLogger } from './logging/ConsoleLogger';\nexport { ConsoleLoggerFactory } from './logging/ConsoleLoggerFactory';\nexport { LogManager } from './logging/LogManager';\n\n// HTTP API contract (merged from former @webpieces/http-api).\n// Shared HTTP API definition consumed by both client and server: REST\n// decorators, the HttpError hierarchy, datetime DTOs, platform-header\n// registry/readers, ValidateImplementation, and the test-case recorder\n// contract. Pure definitions — express-free, browser + Node safe.\n\n// API definition decorators\nexport {\n ApiPath,\n Endpoint,\n Authentication,\n AuthenticationConfig,\n // Auth mode decorators (clean service-to-service + user JWT model)\n Public,\n AuthJwt,\n AuthOidc,\n AuthSharedSecret,\n // API kind (RPC vs PubSub/Cloud Tasks) + queue naming\n Rpc,\n PubSub,\n Queue,\n getApiPath,\n getEndpoints,\n isApiPath,\n getAuthMeta,\n getAuthMode,\n assertEveryEndpointHasAuthMode,\n getApiKind,\n assertApiKind,\n assertPubSubConventions,\n getQueueName,\n validateNoConflictingDecorators,\n AuthMeta,\n RouteMetadata,\n METADATA_KEYS,\n} from './http/decorators';\nexport type { AuthMode, ApiKind } from './http/decorators';\n\n// Type validators\nexport { ValidateImplementation } from './http/validators';\n\n// HTTP errors\nexport {\n ProtocolError,\n HttpError,\n HttpNotFoundError,\n EndpointNotFoundError,\n HttpBadRequestError,\n HttpUnauthorizedError,\n HttpForbiddenError,\n HttpTimeoutError,\n HttpBadGatewayError,\n HttpGatewayTimeoutError,\n HttpInternalServerError,\n HttpVendorError,\n HttpUserError,\n // Error subtype constants\n ENTITY_NOT_FOUND,\n WRONG_LOGIN_TYPE,\n WRONG_LOGIN,\n NOT_APPROVED,\n EMAIL_NOT_CONFIRMED,\n WRONG_DOMAIN,\n WRONG_COMPANY,\n NO_REG_CODE,\n} from './http/errors';\n\n// Date/Time DTOs and Utilities (inspired by Java Time / JSR-310)\nexport {\n InstantDto,\n DateDto,\n TimeDto,\n DateTimeDto,\n InstantUtil,\n DateUtil,\n TimeUtil,\n DateTimeUtil,\n} from './http/datetime';\n\n// Platform Headers\nexport { PlatformHeader } from './http/PlatformHeader';\nexport { PlatformHeadersExtension } from './http/PlatformHeadersExtension';\nexport { HeaderRegistry } from './http/HeaderRegistry';\nexport { WebpiecesCoreHeaders } from './http/WebpiecesCoreHeaders';\nexport { HeaderMethods } from './http/HeaderMethods';\nexport { ContextReader } from './http/ContextReader';\nexport { HEADER_TYPES } from './http/HeaderTypes';\n\n// API-call logging helper (uses LogManager above)\nexport { LogApiCall } from './http/LogApiCall';\n\n// Test-case recording contract (impl lives in http-server; hooks in http-client)\nexport { TestCaseRecorder, RecorderKeys } from './http/recorder/TestCaseRecorder';\nexport { RecordedEndpoint, RecordedError, RecordedTestCase } from './http/recorder/RecordedEndpoint';\nexport { DoNotRecord, getDoNotRecordFields } from './http/recorder/DoNotRecord';\nexport { RecordSerializer, SerializedMap, SerializedError } from './http/recorder/RecordSerializer';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-util/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @webpieces/core-util\n *\n * Utility functions for WebPieces applications.\n * This package works in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\nexport { toError } from './lib/errorUtils';\nexport { Header } from './Header';\nexport { ContextKey } from './ContextKey';\n\n// Logging (merged from former @webpieces/wp-logging).\n// Pluggable logging interface + a browser-safe console default; apps plug in\n// bunyan/winston/pino/etc. via LogManager.setLogger(...). Browser + Node.\nexport type { Logger, LogLevel } from './logging/Logger';\nexport type { LoggerFactory } from './logging/LoggerFactory';\nexport { ConsoleLogger } from './logging/ConsoleLogger';\nexport { ConsoleLoggerFactory } from './logging/ConsoleLoggerFactory';\nexport { LogManager } from './logging/LogManager';\n\n// HTTP API contract (merged from former @webpieces/http-api).\n// Shared HTTP API definition consumed by both client and server: REST\n// decorators, the HttpError hierarchy, datetime DTOs, platform-header\n// registry/readers, ValidateImplementation, and the test-case recorder\n// contract. Pure definitions — express-free, browser + Node safe.\n\n// API definition decorators\nexport {\n ApiPath,\n Endpoint,\n Authentication,\n AuthenticationConfig,\n // Auth mode decorators (clean service-to-service + user JWT model)\n Public,\n AuthJwt,\n AuthOidc,\n AuthSharedSecret,\n // API kind (RPC vs PubSub/Cloud Tasks) + queue naming\n Rpc,\n PubSub,\n Queue,\n getApiPath,\n getEndpoints,\n isApiPath,\n getAuthMeta,\n getAuthMode,\n assertEveryEndpointHasAuthMode,\n getApiKind,\n assertApiKind,\n assertPubSubConventions,\n getQueueName,\n validateNoConflictingDecorators,\n AuthMeta,\n RouteMetadata,\n METADATA_KEYS,\n} from './http/decorators';\nexport type { AuthMode, ApiKind } from './http/decorators';\n\n// Type validators\nexport { ValidateImplementation } from './http/validators';\n\n// HTTP errors\nexport {\n ProtocolError,\n HttpError,\n HttpNotFoundError,\n EndpointNotFoundError,\n HttpBadRequestError,\n HttpUnauthorizedError,\n HttpForbiddenError,\n HttpTimeoutError,\n HttpBadGatewayError,\n HttpGatewayTimeoutError,\n HttpInternalServerError,\n HttpVendorError,\n HttpUserError,\n // Error subtype constants\n ENTITY_NOT_FOUND,\n WRONG_LOGIN_TYPE,\n WRONG_LOGIN,\n NOT_APPROVED,\n EMAIL_NOT_CONFIRMED,\n WRONG_DOMAIN,\n WRONG_COMPANY,\n NO_REG_CODE,\n} from './http/errors';\n\n// Date/Time DTOs and Utilities (inspired by Java Time / JSR-310)\nexport {\n InstantDto,\n DateDto,\n TimeDto,\n DateTimeDto,\n InstantUtil,\n DateUtil,\n TimeUtil,\n DateTimeUtil,\n} from './http/datetime';\n\n// Platform Headers\nexport { PlatformHeader } from './http/PlatformHeader';\nexport { PlatformHeadersExtension } from './http/PlatformHeadersExtension';\nexport { HeaderRegistry } from './http/HeaderRegistry';\nexport { WebpiecesCoreHeaders } from './http/WebpiecesCoreHeaders';\nexport { HeaderMethods } from './http/HeaderMethods';\nexport { ContextReader } from './http/ContextReader';\nexport { HEADER_TYPES } from './http/HeaderTypes';\n\n// API-call logging helper (uses LogManager above)\nexport { LogApiCall } from './http/LogApiCall';\n\n// Test-case recording contract (impl lives in http-server; hooks in http-client)\nexport { TestCaseRecorder, RecorderKeys } from './http/recorder/TestCaseRecorder';\nexport { RecordedEndpoint, RecordedError, RecordedTestCase } from './http/recorder/RecordedEndpoint';\nexport { DoNotRecord, getDoNotRecordFields } from './http/recorder/DoNotRecord';\nexport { RecordSerializer, SerializedMap, SerializedError } from './http/recorder/RecordSerializer';\n"]}
@@ -1,11 +1,11 @@
1
- import { Logger, LogArg } from './Logger';
1
+ import { Logger } from './Logger';
2
2
  /**
3
3
  * ConsoleLogger - the default, browser-safe {@link Logger} implementation.
4
4
  *
5
5
  * Backed purely by `console.*` (no Node imports), so it works unchanged in the
6
6
  * browser (Angular/React) and in Node. Each line is prefixed with the logger
7
- * name so multi-source logs stay greppable; callers that pass their own tag
8
- * (e.g. `[API-SVR-req] ...`) keep it inside the message.
7
+ * name so multi-source logs stay greppable. An optional `Error` is forwarded to
8
+ * `console.*` as a second argument so its stack trace is rendered.
9
9
  *
10
10
  * Level → console method mapping:
11
11
  * - trace/debug → console.debug
@@ -15,11 +15,18 @@ import { Logger, LogArg } from './Logger';
15
15
  */
16
16
  export declare class ConsoleLogger implements Logger {
17
17
  private readonly name;
18
- constructor(name: string);
18
+ private readonly bootstrapPrefix;
19
+ /**
20
+ * @param name logger name (slf4j-style; usually the class/module)
21
+ * @param bootstrapPrefix prepended to every line while no real backend has
22
+ * been installed (see {@link ConsoleLoggerFactory}); empty once one is.
23
+ */
24
+ constructor(name: string, bootstrapPrefix?: string);
19
25
  private prefix;
20
- trace(message: string, ...args: LogArg[]): void;
21
- debug(message: string, ...args: LogArg[]): void;
22
- info(message: string, ...args: LogArg[]): void;
23
- warn(message: string, ...args: LogArg[]): void;
24
- error(message: string, ...args: LogArg[]): void;
26
+ private errArg;
27
+ trace(message: string, err?: Error): void;
28
+ debug(message: string, err?: Error): void;
29
+ info(message: string, err?: Error): void;
30
+ warn(message: string, err?: Error): void;
31
+ error(message: string, err?: Error): void;
25
32
  }
@@ -6,8 +6,8 @@ exports.ConsoleLogger = void 0;
6
6
  *
7
7
  * Backed purely by `console.*` (no Node imports), so it works unchanged in the
8
8
  * browser (Angular/React) and in Node. Each line is prefixed with the logger
9
- * name so multi-source logs stay greppable; callers that pass their own tag
10
- * (e.g. `[API-SVR-req] ...`) keep it inside the message.
9
+ * name so multi-source logs stay greppable. An optional `Error` is forwarded to
10
+ * `console.*` as a second argument so its stack trace is rendered.
11
11
  *
12
12
  * Level → console method mapping:
13
13
  * - trace/debug → console.debug
@@ -17,26 +17,36 @@ exports.ConsoleLogger = void 0;
17
17
  */
18
18
  class ConsoleLogger {
19
19
  name;
20
- constructor(name) {
20
+ bootstrapPrefix;
21
+ /**
22
+ * @param name logger name (slf4j-style; usually the class/module)
23
+ * @param bootstrapPrefix prepended to every line while no real backend has
24
+ * been installed (see {@link ConsoleLoggerFactory}); empty once one is.
25
+ */
26
+ constructor(name, bootstrapPrefix = '') {
21
27
  this.name = name;
28
+ this.bootstrapPrefix = bootstrapPrefix;
22
29
  }
23
30
  prefix() {
24
- return `[${this.name}]`;
31
+ return `${this.bootstrapPrefix}[${this.name}]`;
25
32
  }
26
- trace(message, ...args) {
27
- console.debug(`${this.prefix()} ${message}`, ...args);
33
+ errArg(err) {
34
+ return err ? [err] : [];
28
35
  }
29
- debug(message, ...args) {
30
- console.debug(`${this.prefix()} ${message}`, ...args);
36
+ trace(message, err) {
37
+ console.debug(`${this.prefix()} ${message}`, ...this.errArg(err));
31
38
  }
32
- info(message, ...args) {
33
- console.log(`${this.prefix()} ${message}`, ...args);
39
+ debug(message, err) {
40
+ console.debug(`${this.prefix()} ${message}`, ...this.errArg(err));
34
41
  }
35
- warn(message, ...args) {
36
- console.warn(`${this.prefix()} ${message}`, ...args);
42
+ info(message, err) {
43
+ console.log(`${this.prefix()} ${message}`, ...this.errArg(err));
37
44
  }
38
- error(message, ...args) {
39
- console.error(`${this.prefix()} ${message}`, ...args);
45
+ warn(message, err) {
46
+ console.warn(`${this.prefix()} ${message}`, ...this.errArg(err));
47
+ }
48
+ error(message, err) {
49
+ console.error(`${this.prefix()} ${message}`, ...this.errArg(err));
40
50
  }
41
51
  }
42
52
  exports.ConsoleLogger = ConsoleLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleLogger.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/ConsoleLogger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAa;IACL,IAAI,CAAS;IAE9B,YAAY,IAAY;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAEO,MAAM;QACV,OAAO,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAc;QACpC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAc;QACpC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAc;QACnC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAc;QACnC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAc;QACpC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;CACJ;AA9BD,sCA8BC","sourcesContent":["import { Logger, LogArg } from './Logger';\n\n/**\n * ConsoleLogger - the default, browser-safe {@link Logger} implementation.\n *\n * Backed purely by `console.*` (no Node imports), so it works unchanged in the\n * browser (Angular/React) and in Node. Each line is prefixed with the logger\n * name so multi-source logs stay greppable; callers that pass their own tag\n * (e.g. `[API-SVR-req] ...`) keep it inside the message.\n *\n * Level → console method mapping:\n * - trace/debug → console.debug\n * - info → console.log (stdout, matching conventional server logging)\n * - warn → console.warn\n * - error → console.error\n */\nexport class ConsoleLogger implements Logger {\n private readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n private prefix(): string {\n return `[${this.name}]`;\n }\n\n trace(message: string, ...args: LogArg[]): void {\n console.debug(`${this.prefix()} ${message}`, ...args);\n }\n\n debug(message: string, ...args: LogArg[]): void {\n console.debug(`${this.prefix()} ${message}`, ...args);\n }\n\n info(message: string, ...args: LogArg[]): void {\n console.log(`${this.prefix()} ${message}`, ...args);\n }\n\n warn(message: string, ...args: LogArg[]): void {\n console.warn(`${this.prefix()} ${message}`, ...args);\n }\n\n error(message: string, ...args: LogArg[]): void {\n console.error(`${this.prefix()} ${message}`, ...args);\n }\n}\n"]}
1
+ {"version":3,"file":"ConsoleLogger.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/ConsoleLogger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;GAaG;AACH,MAAa,aAAa;IACL,IAAI,CAAS;IACb,eAAe,CAAS;IAEzC;;;;OAIG;IACH,YAAY,IAAY,EAAE,eAAe,GAAG,EAAE;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IAC3C,CAAC;IAEO,MAAM;QACV,OAAO,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;IACnD,CAAC;IAEO,MAAM,CAAC,GAAW;QACtB,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;CACJ;AAzCD,sCAyCC","sourcesContent":["import { Logger } from './Logger';\n\n/**\n * ConsoleLogger - the default, browser-safe {@link Logger} implementation.\n *\n * Backed purely by `console.*` (no Node imports), so it works unchanged in the\n * browser (Angular/React) and in Node. Each line is prefixed with the logger\n * name so multi-source logs stay greppable. An optional `Error` is forwarded to\n * `console.*` as a second argument so its stack trace is rendered.\n *\n * Level → console method mapping:\n * - trace/debug → console.debug\n * - info → console.log (stdout, matching conventional server logging)\n * - warn → console.warn\n * - error → console.error\n */\nexport class ConsoleLogger implements Logger {\n private readonly name: string;\n private readonly bootstrapPrefix: string;\n\n /**\n * @param name logger name (slf4j-style; usually the class/module)\n * @param bootstrapPrefix prepended to every line while no real backend has\n * been installed (see {@link ConsoleLoggerFactory}); empty once one is.\n */\n constructor(name: string, bootstrapPrefix = '') {\n this.name = name;\n this.bootstrapPrefix = bootstrapPrefix;\n }\n\n private prefix(): string {\n return `${this.bootstrapPrefix}[${this.name}]`;\n }\n\n private errArg(err?: Error): Error[] {\n return err ? [err] : [];\n }\n\n trace(message: string, err?: Error): void {\n console.debug(`${this.prefix()} ${message}`, ...this.errArg(err));\n }\n\n debug(message: string, err?: Error): void {\n console.debug(`${this.prefix()} ${message}`, ...this.errArg(err));\n }\n\n info(message: string, err?: Error): void {\n console.log(`${this.prefix()} ${message}`, ...this.errArg(err));\n }\n\n warn(message: string, err?: Error): void {\n console.warn(`${this.prefix()} ${message}`, ...this.errArg(err));\n }\n\n error(message: string, err?: Error): void {\n console.error(`${this.prefix()} ${message}`, ...this.errArg(err));\n }\n}\n"]}
@@ -5,9 +5,16 @@ import { LoggerFactory } from './LoggerFactory';
5
5
  *
6
6
  * Produces (and caches per name) {@link ConsoleLogger}s. This is what
7
7
  * {@link LogManager} uses until an app installs a different backend
8
- * (bunyan/winston/pino/...) via {@link LogManager.setFactory}.
8
+ * (bunyan/winston/pino/...) via {@link LogManager.setLogger}.
9
+ *
10
+ * When constructed with `isBootstrap = true` (the framework default before any
11
+ * app calls `setLogger`), every line is prefixed with an AWAITING banner so it's
12
+ * obvious no real backend was wired. An app that genuinely wants console logging
13
+ * installs `new ConsoleLoggerFactory()` (isBootstrap defaults to false → no banner).
9
14
  */
10
15
  export declare class ConsoleLoggerFactory implements LoggerFactory {
11
16
  private readonly loggers;
17
+ private readonly bootstrapPrefix;
18
+ constructor(isBootstrap?: boolean);
12
19
  getLogger(name: string): Logger;
13
20
  }
@@ -7,14 +7,25 @@ const ConsoleLogger_1 = require("./ConsoleLogger");
7
7
  *
8
8
  * Produces (and caches per name) {@link ConsoleLogger}s. This is what
9
9
  * {@link LogManager} uses until an app installs a different backend
10
- * (bunyan/winston/pino/...) via {@link LogManager.setFactory}.
10
+ * (bunyan/winston/pino/...) via {@link LogManager.setLogger}.
11
+ *
12
+ * When constructed with `isBootstrap = true` (the framework default before any
13
+ * app calls `setLogger`), every line is prefixed with an AWAITING banner so it's
14
+ * obvious no real backend was wired. An app that genuinely wants console logging
15
+ * installs `new ConsoleLoggerFactory()` (isBootstrap defaults to false → no banner).
11
16
  */
12
17
  class ConsoleLoggerFactory {
13
18
  loggers = new Map();
19
+ bootstrapPrefix;
20
+ constructor(isBootstrap = false) {
21
+ this.bootstrapPrefix = isBootstrap
22
+ ? '[AWAITING LogManager.setLogger(...) — see .webpieces/instruct-ai/webpieces.logging.md] '
23
+ : '';
24
+ }
14
25
  getLogger(name) {
15
26
  let logger = this.loggers.get(name);
16
27
  if (!logger) {
17
- logger = new ConsoleLogger_1.ConsoleLogger(name);
28
+ logger = new ConsoleLogger_1.ConsoleLogger(name, this.bootstrapPrefix);
18
29
  this.loggers.set(name, logger);
19
30
  }
20
31
  return logger;
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleLoggerFactory.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/ConsoleLoggerFactory.ts"],"names":[],"mappings":";;;AAEA,mDAAgD;AAEhD;;;;;;GAMG;AACH,MAAa,oBAAoB;IACZ,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAErD,SAAS,CAAC,IAAY;QAClB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,IAAI,6BAAa,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAXD,oDAWC","sourcesContent":["import { Logger } from './Logger';\nimport { LoggerFactory } from './LoggerFactory';\nimport { ConsoleLogger } from './ConsoleLogger';\n\n/**\n * ConsoleLoggerFactory - the default {@link LoggerFactory}, browser-safe.\n *\n * Produces (and caches per name) {@link ConsoleLogger}s. This is what\n * {@link LogManager} uses until an app installs a different backend\n * (bunyan/winston/pino/...) via {@link LogManager.setFactory}.\n */\nexport class ConsoleLoggerFactory implements LoggerFactory {\n private readonly loggers = new Map<string, Logger>();\n\n getLogger(name: string): Logger {\n let logger = this.loggers.get(name);\n if (!logger) {\n logger = new ConsoleLogger(name);\n this.loggers.set(name, logger);\n }\n return logger;\n }\n}\n"]}
1
+ {"version":3,"file":"ConsoleLoggerFactory.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/ConsoleLoggerFactory.ts"],"names":[],"mappings":";;;AAEA,mDAAgD;AAEhD;;;;;;;;;;;GAWG;AACH,MAAa,oBAAoB;IACZ,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IACpC,eAAe,CAAS;IAEzC,YAAY,WAAW,GAAG,KAAK;QAC3B,IAAI,CAAC,eAAe,GAAG,WAAW;YAC9B,CAAC,CAAC,yFAAyF;YAC3F,CAAC,CAAC,EAAE,CAAC;IACb,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,IAAI,6BAAa,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YACvD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AAlBD,oDAkBC","sourcesContent":["import { Logger } from './Logger';\nimport { LoggerFactory } from './LoggerFactory';\nimport { ConsoleLogger } from './ConsoleLogger';\n\n/**\n * ConsoleLoggerFactory - the default {@link LoggerFactory}, browser-safe.\n *\n * Produces (and caches per name) {@link ConsoleLogger}s. This is what\n * {@link LogManager} uses until an app installs a different backend\n * (bunyan/winston/pino/...) via {@link LogManager.setLogger}.\n *\n * When constructed with `isBootstrap = true` (the framework default before any\n * app calls `setLogger`), every line is prefixed with an AWAITING banner so it's\n * obvious no real backend was wired. An app that genuinely wants console logging\n * installs `new ConsoleLoggerFactory()` (isBootstrap defaults to false → no banner).\n */\nexport class ConsoleLoggerFactory implements LoggerFactory {\n private readonly loggers = new Map<string, Logger>();\n private readonly bootstrapPrefix: string;\n\n constructor(isBootstrap = false) {\n this.bootstrapPrefix = isBootstrap\n ? '[AWAITING LogManager.setLogger(...) — see .webpieces/instruct-ai/webpieces.logging.md] '\n : '';\n }\n\n getLogger(name: string): Logger {\n let logger = this.loggers.get(name);\n if (!logger) {\n logger = new ConsoleLogger(name, this.bootstrapPrefix);\n this.loggers.set(name, logger);\n }\n return logger;\n }\n}\n"]}
@@ -7,30 +7,34 @@ import { LoggerFactory } from './LoggerFactory';
7
7
  *
8
8
  * ```ts
9
9
  * const log = LogManager.getLogger('MyClass');
10
- * log.info('hello', { some: 'context' });
10
+ * log.info('did the thing');
11
+ * log.error('it failed', err); // err?: Error — the ONLY extra arg
11
12
  * ```
12
13
  *
13
14
  * and never knows which backend is behind it. Apps choose their backend ONCE at
14
15
  * startup by installing a {@link LoggerFactory}:
15
16
  *
16
17
  * ```ts
17
- * LogManager.setFactory(new BunyanLoggerFactory(...)); // node-only app
18
+ * LogManager.setLogger(new BunyanLoggerFactory(...)); // node-only app
18
19
  * ```
19
20
  *
20
- * Until a factory is installed, logging goes to the browser-safe
21
- * {@link ConsoleLoggerFactory}, so libraries can log at import time without any
22
- * app wiring. This is a data-less coordination holder (all static), which is why
23
- * it is a class with static members rather than an instance.
21
+ * Until one is installed, logging goes to a bootstrap {@link ConsoleLoggerFactory}
22
+ * that prefixes every line with an AWAITING banner (so a forgotten `setLogger` is
23
+ * obvious). See `.webpieces/instruct-ai/webpieces.logging.md`.
24
24
  */
25
25
  export declare class LogManager {
26
26
  private static factory;
27
+ private static readonly deferred;
27
28
  /**
28
- * Install the process-wide logging backend. Call once at app startup, before
29
- * other modules fetch their loggers, so early loggers use the chosen backend.
29
+ * Install the process-wide logging backend. Call once at app startup. Loggers
30
+ * already handed out via {@link getLogger} switch to it immediately (they are
31
+ * deferred facades), so import-time loggers are covered too.
30
32
  */
31
- static setFactory(factory: LoggerFactory): void;
32
- /** Get a named logger from the currently installed factory. */
33
+ static setLogger(factory: LoggerFactory): void;
34
+ /** Get a named logger (a stable deferred facade over the current backend). */
33
35
  static getLogger(name: string): Logger;
34
36
  /** The currently installed factory (mainly for tests / diagnostics). */
35
37
  static getFactory(): LoggerFactory;
38
+ /** Internal: resolve the concrete backend logger for a name (used by DeferredLogger). */
39
+ static resolveBackend(name: string): Logger;
36
40
  }
@@ -2,6 +2,35 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LogManager = void 0;
4
4
  const ConsoleLoggerFactory_1 = require("./ConsoleLoggerFactory");
5
+ /**
6
+ * A stable per-name facade that re-resolves the currently installed factory on
7
+ * EVERY call. This is why a module-scope `const log = LogManager.getLogger('X')`
8
+ * captured at import time (before the app runs) still starts using the real
9
+ * backend the instant `LogManager.setLogger(...)` installs it — and the bootstrap
10
+ * AWAITING banner disappears. Backends cache their concrete logger per name, so
11
+ * this indirection is a cheap Map lookup.
12
+ */
13
+ class DeferredLogger {
14
+ name;
15
+ constructor(name) {
16
+ this.name = name;
17
+ }
18
+ trace(message, err) {
19
+ LogManager.resolveBackend(this.name).trace(message, err);
20
+ }
21
+ debug(message, err) {
22
+ LogManager.resolveBackend(this.name).debug(message, err);
23
+ }
24
+ info(message, err) {
25
+ LogManager.resolveBackend(this.name).info(message, err);
26
+ }
27
+ warn(message, err) {
28
+ LogManager.resolveBackend(this.name).warn(message, err);
29
+ }
30
+ error(message, err) {
31
+ LogManager.resolveBackend(this.name).error(message, err);
32
+ }
33
+ }
5
34
  /**
6
35
  * LogManager - the global, slf4j-style entry point for logging.
7
36
  *
@@ -9,38 +38,49 @@ const ConsoleLoggerFactory_1 = require("./ConsoleLoggerFactory");
9
38
  *
10
39
  * ```ts
11
40
  * const log = LogManager.getLogger('MyClass');
12
- * log.info('hello', { some: 'context' });
41
+ * log.info('did the thing');
42
+ * log.error('it failed', err); // err?: Error — the ONLY extra arg
13
43
  * ```
14
44
  *
15
45
  * and never knows which backend is behind it. Apps choose their backend ONCE at
16
46
  * startup by installing a {@link LoggerFactory}:
17
47
  *
18
48
  * ```ts
19
- * LogManager.setFactory(new BunyanLoggerFactory(...)); // node-only app
49
+ * LogManager.setLogger(new BunyanLoggerFactory(...)); // node-only app
20
50
  * ```
21
51
  *
22
- * Until a factory is installed, logging goes to the browser-safe
23
- * {@link ConsoleLoggerFactory}, so libraries can log at import time without any
24
- * app wiring. This is a data-less coordination holder (all static), which is why
25
- * it is a class with static members rather than an instance.
52
+ * Until one is installed, logging goes to a bootstrap {@link ConsoleLoggerFactory}
53
+ * that prefixes every line with an AWAITING banner (so a forgotten `setLogger` is
54
+ * obvious). See `.webpieces/instruct-ai/webpieces.logging.md`.
26
55
  */
27
56
  class LogManager {
28
- static factory = new ConsoleLoggerFactory_1.ConsoleLoggerFactory();
57
+ static factory = new ConsoleLoggerFactory_1.ConsoleLoggerFactory(true);
58
+ static deferred = new Map();
29
59
  /**
30
- * Install the process-wide logging backend. Call once at app startup, before
31
- * other modules fetch their loggers, so early loggers use the chosen backend.
60
+ * Install the process-wide logging backend. Call once at app startup. Loggers
61
+ * already handed out via {@link getLogger} switch to it immediately (they are
62
+ * deferred facades), so import-time loggers are covered too.
32
63
  */
33
- static setFactory(factory) {
64
+ static setLogger(factory) {
34
65
  LogManager.factory = factory;
35
66
  }
36
- /** Get a named logger from the currently installed factory. */
67
+ /** Get a named logger (a stable deferred facade over the current backend). */
37
68
  static getLogger(name) {
38
- return LogManager.factory.getLogger(name);
69
+ let logger = LogManager.deferred.get(name);
70
+ if (!logger) {
71
+ logger = new DeferredLogger(name);
72
+ LogManager.deferred.set(name, logger);
73
+ }
74
+ return logger;
39
75
  }
40
76
  /** The currently installed factory (mainly for tests / diagnostics). */
41
77
  static getFactory() {
42
78
  return LogManager.factory;
43
79
  }
80
+ /** Internal: resolve the concrete backend logger for a name (used by DeferredLogger). */
81
+ static resolveBackend(name) {
82
+ return LogManager.factory.getLogger(name);
83
+ }
44
84
  }
45
85
  exports.LogManager = LogManager;
46
86
  //# sourceMappingURL=LogManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LogManager.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/LogManager.ts"],"names":[],"mappings":";;;AAEA,iEAA8D;AAE9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAa,UAAU;IACX,MAAM,CAAC,OAAO,GAAkB,IAAI,2CAAoB,EAAE,CAAC;IAEnE;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,OAAsB;QACpC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IACjC,CAAC;IAED,+DAA+D;IAC/D,MAAM,CAAC,SAAS,CAAC,IAAY;QACzB,OAAO,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,UAAU;QACb,OAAO,UAAU,CAAC,OAAO,CAAC;IAC9B,CAAC;;AAnBL,gCAoBC","sourcesContent":["import { Logger } from './Logger';\nimport { LoggerFactory } from './LoggerFactory';\nimport { ConsoleLoggerFactory } from './ConsoleLoggerFactory';\n\n/**\n * LogManager - the global, slf4j-style entry point for logging.\n *\n * Every call site in the codebase does:\n *\n * ```ts\n * const log = LogManager.getLogger('MyClass');\n * log.info('hello', { some: 'context' });\n * ```\n *\n * and never knows which backend is behind it. Apps choose their backend ONCE at\n * startup by installing a {@link LoggerFactory}:\n *\n * ```ts\n * LogManager.setFactory(new BunyanLoggerFactory(...)); // node-only app\n * ```\n *\n * Until a factory is installed, logging goes to the browser-safe\n * {@link ConsoleLoggerFactory}, so libraries can log at import time without any\n * app wiring. This is a data-less coordination holder (all static), which is why\n * it is a class with static members rather than an instance.\n */\nexport class LogManager {\n private static factory: LoggerFactory = new ConsoleLoggerFactory();\n\n /**\n * Install the process-wide logging backend. Call once at app startup, before\n * other modules fetch their loggers, so early loggers use the chosen backend.\n */\n static setFactory(factory: LoggerFactory): void {\n LogManager.factory = factory;\n }\n\n /** Get a named logger from the currently installed factory. */\n static getLogger(name: string): Logger {\n return LogManager.factory.getLogger(name);\n }\n\n /** The currently installed factory (mainly for tests / diagnostics). */\n static getFactory(): LoggerFactory {\n return LogManager.factory;\n }\n}\n"]}
1
+ {"version":3,"file":"LogManager.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/LogManager.ts"],"names":[],"mappings":";;;AAEA,iEAA8D;AAE9D;;;;;;;GAOG;AACH,MAAM,cAAc;IACa;IAA7B,YAA6B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE7C,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAW;QAC7B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAW;QAC9B,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAa,UAAU;IACX,MAAM,CAAC,OAAO,GAAkB,IAAI,2CAAoB,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAU,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE7D;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,OAAsB;QACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IACjC,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,SAAS,CAAC,IAAY;QACzB,IAAI,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;YAClC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,wEAAwE;IACxE,MAAM,CAAC,UAAU;QACb,OAAO,UAAU,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED,yFAAyF;IACzF,MAAM,CAAC,cAAc,CAAC,IAAY;QAC9B,OAAO,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;;AA/BL,gCAgCC","sourcesContent":["import { Logger } from './Logger';\nimport { LoggerFactory } from './LoggerFactory';\nimport { ConsoleLoggerFactory } from './ConsoleLoggerFactory';\n\n/**\n * A stable per-name facade that re-resolves the currently installed factory on\n * EVERY call. This is why a module-scope `const log = LogManager.getLogger('X')`\n * captured at import time (before the app runs) still starts using the real\n * backend the instant `LogManager.setLogger(...)` installs it — and the bootstrap\n * AWAITING banner disappears. Backends cache their concrete logger per name, so\n * this indirection is a cheap Map lookup.\n */\nclass DeferredLogger implements Logger {\n constructor(private readonly name: string) {}\n\n trace(message: string, err?: Error): void {\n LogManager.resolveBackend(this.name).trace(message, err);\n }\n\n debug(message: string, err?: Error): void {\n LogManager.resolveBackend(this.name).debug(message, err);\n }\n\n info(message: string, err?: Error): void {\n LogManager.resolveBackend(this.name).info(message, err);\n }\n\n warn(message: string, err?: Error): void {\n LogManager.resolveBackend(this.name).warn(message, err);\n }\n\n error(message: string, err?: Error): void {\n LogManager.resolveBackend(this.name).error(message, err);\n }\n}\n\n/**\n * LogManager - the global, slf4j-style entry point for logging.\n *\n * Every call site in the codebase does:\n *\n * ```ts\n * const log = LogManager.getLogger('MyClass');\n * log.info('did the thing');\n * log.error('it failed', err); // err?: Error — the ONLY extra arg\n * ```\n *\n * and never knows which backend is behind it. Apps choose their backend ONCE at\n * startup by installing a {@link LoggerFactory}:\n *\n * ```ts\n * LogManager.setLogger(new BunyanLoggerFactory(...)); // node-only app\n * ```\n *\n * Until one is installed, logging goes to a bootstrap {@link ConsoleLoggerFactory}\n * that prefixes every line with an AWAITING banner (so a forgotten `setLogger` is\n * obvious). See `.webpieces/instruct-ai/webpieces.logging.md`.\n */\nexport class LogManager {\n private static factory: LoggerFactory = new ConsoleLoggerFactory(true);\n private static readonly deferred = new Map<string, Logger>();\n\n /**\n * Install the process-wide logging backend. Call once at app startup. Loggers\n * already handed out via {@link getLogger} switch to it immediately (they are\n * deferred facades), so import-time loggers are covered too.\n */\n static setLogger(factory: LoggerFactory): void {\n LogManager.factory = factory;\n }\n\n /** Get a named logger (a stable deferred facade over the current backend). */\n static getLogger(name: string): Logger {\n let logger = LogManager.deferred.get(name);\n if (!logger) {\n logger = new DeferredLogger(name);\n LogManager.deferred.set(name, logger);\n }\n return logger;\n }\n\n /** The currently installed factory (mainly for tests / diagnostics). */\n static getFactory(): LoggerFactory {\n return LogManager.factory;\n }\n\n /** Internal: resolve the concrete backend logger for a name (used by DeferredLogger). */\n static resolveBackend(name: string): Logger {\n return LogManager.factory.getLogger(name);\n }\n}\n"]}
@@ -5,12 +5,6 @@
5
5
  * can be plugged in behind the {@link Logger} interface.
6
6
  */
7
7
  export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
8
- /**
9
- * A single structured log argument. A logger legitimately accepts arbitrary
10
- * values (objects, errors, primitives) and lets the backend decide how to
11
- * render them — mirroring `console.*`/bunyan/winston signatures.
12
- */
13
- export type LogArg = unknown;
14
8
  /**
15
9
  * Logger - the pluggable logging contract for WebPieces.
16
10
  *
@@ -23,14 +17,17 @@ export type LogArg = unknown;
23
17
  * React. Node-only backends (bunyan, file writers, ...) are wired in by
24
18
  * `framework:express` apps at startup, never in browser-safe libraries.
25
19
  *
26
- * Each method takes a message plus optional structured args (objects, errors,
27
- * numbers) that the backend decides how to rendermatching `console.*` and
28
- * bunyan/winston signatures.
20
+ * KISS by design: every method takes ONLY a message plus an OPTIONAL `Error`.
21
+ * There is deliberately no structured-fields / varargs argumentso nobody can
22
+ * pass request ids, tenant ids, or other platform-header values into a log line.
23
+ * Those are already emitted automatically by the framework (see
24
+ * `HeaderMethods.buildSecureMapForLogs`); duplicating them here is impossible.
25
+ * See `.webpieces/instruct-ai/webpieces.logging.md`.
29
26
  */
30
27
  export interface Logger {
31
- trace(message: string, ...args: LogArg[]): void;
32
- debug(message: string, ...args: LogArg[]): void;
33
- info(message: string, ...args: LogArg[]): void;
34
- warn(message: string, ...args: LogArg[]): void;
35
- error(message: string, ...args: LogArg[]): void;
28
+ trace(message: string, err?: Error): void;
29
+ debug(message: string, err?: Error): void;
30
+ info(message: string, err?: Error): void;
31
+ warn(message: string, err?: Error): void;
32
+ error(message: string, err?: Error): void;
36
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/Logger.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Log severity levels, ordered lowest → highest.\n *\n * Mirrors the common slf4j/bunyan/winston vocabulary so any of those backends\n * can be plugged in behind the {@link Logger} interface.\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * A single structured log argument. A logger legitimately accepts arbitrary\n * values (objects, errors, primitives) and lets the backend decide how to\n * render them — mirroring `console.*`/bunyan/winston signatures.\n */\n// webpieces-disable no-any-unknown -- a logger must accept arbitrary values to render; this is the one intentional widening\nexport type LogArg = unknown;\n\n/**\n * Logger - the pluggable logging contract for WebPieces.\n *\n * This is a BUSINESS-LOGIC interface (methods with behavior), so per the\n * webpieces guidelines it is an `interface`, not a class. Different projects\n * plug in different backends (bunyan, winston, pino, browser console, a\n * file writer, ...) by supplying an implementation via a {@link LoggerFactory}.\n *\n * Implementations MUST stay browser-safe if they are to be used from Angular /\n * React. Node-only backends (bunyan, file writers, ...) are wired in by\n * `framework:express` apps at startup, never in browser-safe libraries.\n *\n * Each method takes a message plus optional structured args (objects, errors,\n * numbers) that the backend decides how to render matching `console.*` and\n * bunyan/winston signatures.\n */\nexport interface Logger {\n trace(message: string, ...args: LogArg[]): void;\n debug(message: string, ...args: LogArg[]): void;\n info(message: string, ...args: LogArg[]): void;\n warn(message: string, ...args: LogArg[]): void;\n error(message: string, ...args: LogArg[]): void;\n}\n"]}
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/Logger.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Log severity levels, ordered lowest → highest.\n *\n * Mirrors the common slf4j/bunyan/winston vocabulary so any of those backends\n * can be plugged in behind the {@link Logger} interface.\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Logger - the pluggable logging contract for WebPieces.\n *\n * This is a BUSINESS-LOGIC interface (methods with behavior), so per the\n * webpieces guidelines it is an `interface`, not a class. Different projects\n * plug in different backends (bunyan, winston, pino, browser console, a\n * file writer, ...) by supplying an implementation via a {@link LoggerFactory}.\n *\n * Implementations MUST stay browser-safe if they are to be used from Angular /\n * React. Node-only backends (bunyan, file writers, ...) are wired in by\n * `framework:express` apps at startup, never in browser-safe libraries.\n *\n * KISS by design: every method takes ONLY a message plus an OPTIONAL `Error`.\n * There is deliberately no structured-fields / varargs argument — so nobody can\n * pass request ids, tenant ids, or other platform-header values into a log line.\n * Those are already emitted automatically by the framework (see\n * `HeaderMethods.buildSecureMapForLogs`); duplicating them here is impossible.\n * See `.webpieces/instruct-ai/webpieces.logging.md`.\n */\nexport interface Logger {\n trace(message: string, err?: Error): void;\n debug(message: string, err?: Error): void;\n info(message: string, err?: Error): void;\n warn(message: string, err?: Error): void;\n error(message: string, err?: Error): void;\n}\n"]}
@@ -4,7 +4,7 @@ import { Logger } from './Logger';
4
4
  *
5
5
  * BUSINESS-LOGIC interface (a method with behavior). An app selects its logging
6
6
  * backend by installing one implementation of this factory globally via
7
- * {@link LogManager.setFactory}. Everything else in the codebase asks
7
+ * {@link LogManager.setLogger}. Everything else in the codebase asks
8
8
  * {@link LogManager.getLogger} for a named logger and never knows which backend
9
9
  * is behind it.
10
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"LoggerFactory.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/LoggerFactory.ts"],"names":[],"mappings":"","sourcesContent":["import { Logger } from './Logger';\n\n/**\n * LoggerFactory - the pluggable seam that produces named {@link Logger}s.\n *\n * BUSINESS-LOGIC interface (a method with behavior). An app selects its logging\n * backend by installing one implementation of this factory globally via\n * {@link LogManager.setFactory}. Everything else in the codebase asks\n * {@link LogManager.getLogger} for a named logger and never knows which backend\n * is behind it.\n *\n * `name` is conventionally the class or module name (slf4j style), e.g.\n * `LogManager.getLogger('LogApiCall')`.\n */\nexport interface LoggerFactory {\n getLogger(name: string): Logger;\n}\n"]}
1
+ {"version":3,"file":"LoggerFactory.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/logging/LoggerFactory.ts"],"names":[],"mappings":"","sourcesContent":["import { Logger } from './Logger';\n\n/**\n * LoggerFactory - the pluggable seam that produces named {@link Logger}s.\n *\n * BUSINESS-LOGIC interface (a method with behavior). An app selects its logging\n * backend by installing one implementation of this factory globally via\n * {@link LogManager.setLogger}. Everything else in the codebase asks\n * {@link LogManager.getLogger} for a named logger and never knows which backend\n * is behind it.\n *\n * `name` is conventionally the class or module name (slf4j style), e.g.\n * `LogManager.getLogger('LogApiCall')`.\n */\nexport interface LoggerFactory {\n getLogger(name: string): Logger;\n}\n"]}