@salesforce/core 4.3.11 → 5.0.1-v5-beta.1

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.
Files changed (51) hide show
  1. package/lib/config/config.js +1 -1
  2. package/lib/config/configFile.d.ts +1 -1
  3. package/lib/config/configFile.js +1 -1
  4. package/lib/crypto/crypto.js +1 -1
  5. package/lib/crypto/keyChain.js +1 -1
  6. package/lib/deviceOauthService.js +1 -1
  7. package/lib/exported.d.ts +1 -1
  8. package/lib/exported.js +1 -1
  9. package/lib/global.d.ts +0 -4
  10. package/lib/global.js +0 -6
  11. package/lib/lifecycleEvents.d.ts +1 -1
  12. package/lib/lifecycleEvents.js +9 -4
  13. package/lib/logger/cleanup.d.ts +11 -0
  14. package/lib/logger/cleanup.js +57 -0
  15. package/lib/logger/filters.d.ts +7 -0
  16. package/lib/logger/filters.js +69 -0
  17. package/lib/{logger.d.ts → logger/logger.d.ts} +34 -155
  18. package/lib/logger/logger.js +399 -0
  19. package/lib/logger/memoryLogger.d.ts +10 -0
  20. package/lib/logger/memoryLogger.js +30 -0
  21. package/lib/logger/transformStream.d.ts +3 -0
  22. package/lib/logger/transformStream.js +57 -0
  23. package/lib/org/authInfo.js +1 -1
  24. package/lib/org/authRemover.js +1 -1
  25. package/lib/org/connection.js +2 -2
  26. package/lib/org/org.js +27 -22
  27. package/lib/org/permissionSetAssignment.js +1 -1
  28. package/lib/org/scratchOrgCreate.js +1 -1
  29. package/lib/org/scratchOrgErrorCodes.js +1 -1
  30. package/lib/org/scratchOrgInfoApi.js +1 -1
  31. package/lib/org/scratchOrgLifecycleEvents.js +2 -3
  32. package/lib/org/scratchOrgSettingsGenerator.js +1 -1
  33. package/lib/org/user.js +1 -1
  34. package/lib/schema/printer.d.ts +1 -1
  35. package/lib/schema/validator.d.ts +1 -1
  36. package/lib/stateAggregator/accessors/orgAccessor.js +1 -1
  37. package/lib/status/myDomainResolver.js +1 -1
  38. package/lib/status/pollingClient.d.ts +1 -1
  39. package/lib/status/pollingClient.js +1 -1
  40. package/lib/status/streamingClient.js +1 -1
  41. package/lib/testSetup.d.ts +1 -1
  42. package/lib/testSetup.js +2 -2
  43. package/lib/util/sfdc.d.ts +2 -0
  44. package/lib/util/sfdc.js +4 -2
  45. package/lib/util/sfdcUrl.js +1 -1
  46. package/lib/util/unwrapArray.d.ts +1 -0
  47. package/lib/util/unwrapArray.js +17 -0
  48. package/lib/util/zipWriter.js +1 -1
  49. package/lib/webOAuthServer.js +1 -1
  50. package/package.json +5 -5
  51. package/lib/logger.js +0 -737
@@ -12,7 +12,7 @@ const fs = require("fs");
12
12
  const kit_1 = require("@salesforce/kit");
13
13
  const ts_types_1 = require("@salesforce/ts-types");
14
14
  const global_1 = require("../global");
15
- const logger_1 = require("../logger");
15
+ const logger_1 = require("../logger/logger");
16
16
  const messages_1 = require("../messages");
17
17
  const sfdc_1 = require("../util/sfdc");
18
18
  const sfdcUrl_1 = require("../util/sfdcUrl");
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { Stats as fsStats } from 'fs';
3
- import { Logger } from '../logger';
3
+ import { Logger } from '../logger/logger';
4
4
  import { BaseConfigStore, ConfigContents } from './configStore';
5
5
  /**
6
6
  * Represents a json config file used to manage settings and state. Global config
@@ -14,7 +14,7 @@ const path_1 = require("path");
14
14
  const ts_types_1 = require("@salesforce/ts-types");
15
15
  const kit_1 = require("@salesforce/kit");
16
16
  const global_1 = require("../global");
17
- const logger_1 = require("../logger");
17
+ const logger_1 = require("../logger/logger");
18
18
  const sfError_1 = require("../sfError");
19
19
  const internal_1 = require("../util/internal");
20
20
  const configStore_1 = require("./configStore");
@@ -13,7 +13,7 @@ const os = require("os");
13
13
  const path_1 = require("path");
14
14
  const ts_types_1 = require("@salesforce/ts-types");
15
15
  const kit_1 = require("@salesforce/kit");
16
- const logger_1 = require("../logger");
16
+ const logger_1 = require("../logger/logger");
17
17
  const messages_1 = require("../messages");
18
18
  const cache_1 = require("../util/cache");
19
19
  const global_1 = require("../global");
@@ -8,7 +8,7 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.retrieveKeychain = void 0;
10
10
  const kit_1 = require("@salesforce/kit");
11
- const logger_1 = require("../logger");
11
+ const logger_1 = require("../logger/logger");
12
12
  const messages_1 = require("../messages");
13
13
  const keyChainImpl_1 = require("./keyChainImpl");
14
14
  const messages = new messages_1.Messages('@salesforce/core', 'encryption', new Map([["invalidEncryptedFormatError", "The encrypted data is not properly formatted."], ["invalidEncryptedFormatError.actions", ["If attempting to create a scratch org then re-authorize. Otherwise create a new scratch org."]], ["authDecryptError", "Failed to decipher auth data. reason: %s."], ["unsupportedOperatingSystemError", "Unsupported Operating System: %s"], ["missingCredentialProgramError", "Unable to find required security software: %s"], ["credentialProgramAccessError", "Unable to execute security software: %s"], ["passwordRetryError", "Failed to get the password after %i retries."], ["passwordRequiredError", "A password is required."], ["keyChainServiceRequiredError", "Unable to get or set a keychain value without a service name."], ["keyChainAccountRequiredError", "Unable to get or set a keychain value without an account name."], ["keyChainUserCanceledError", "User canceled authentication."], ["keychainPasswordCreationError", "Failed to create a password in the keychain."], ["genericKeychainServiceError", "The service and account specified in %s do not match the version of the toolbelt."], ["genericKeychainServiceError.actions", ["Check your toolbelt version and re-auth."]], ["genericKeychainInvalidPermsError", "Invalid file permissions for secret file"], ["genericKeychainInvalidPermsError.actions", ["Ensure the file %s has the file permission octal value of %s."]], ["passwordNotFoundError", "Could not find password.\n%s"], ["passwordNotFoundError.actions", ["Ensure a valid password is returned with the following command: [%s]"]], ["setCredentialError", "Command failed with response:\n%s"], ["setCredentialError.actions", ["Determine why this command failed to set an encryption key for user %s: [%s]."]], ["macKeychainOutOfSync", "We\u2019ve encountered an error with the Mac keychain being out of sync with your `sfdx` credentials. To fix the problem, sync your credentials by authenticating into your org again using the auth commands."]]));
@@ -13,7 +13,7 @@ const transport_1 = require("jsforce/lib/transport");
13
13
  const kit_1 = require("@salesforce/kit");
14
14
  const ts_types_1 = require("@salesforce/ts-types");
15
15
  const FormData = require("form-data");
16
- const logger_1 = require("./logger");
16
+ const logger_1 = require("./logger/logger");
17
17
  const org_1 = require("./org");
18
18
  const sfError_1 = require("./sfError");
19
19
  const messages_1 = require("./messages");
package/lib/exported.d.ts CHANGED
@@ -17,7 +17,7 @@ export { Lifecycle } from './lifecycleEvents';
17
17
  export { WebOAuthServer } from './webOAuthServer';
18
18
  export { SfdcUrl } from './util/sfdcUrl';
19
19
  export { getJwtAudienceUrl } from './util/getJwtAudienceUrl';
20
- export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptions, LoggerStream, Logger, } from './logger';
20
+ export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptions, Logger } from './logger/logger';
21
21
  export { Messages, StructuredMessage } from './messages';
22
22
  export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, ResumeSandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
23
23
  export { OrgConfigProperties, ORG_CONFIG_ALLOWED_PROPERTIES } from './org/orgConfigProperties';
package/lib/exported.js CHANGED
@@ -66,7 +66,7 @@ var sfdcUrl_1 = require("./util/sfdcUrl");
66
66
  Object.defineProperty(exports, "SfdcUrl", { enumerable: true, get: function () { return sfdcUrl_1.SfdcUrl; } });
67
67
  var getJwtAudienceUrl_1 = require("./util/getJwtAudienceUrl");
68
68
  Object.defineProperty(exports, "getJwtAudienceUrl", { enumerable: true, get: function () { return getJwtAudienceUrl_1.getJwtAudienceUrl; } });
69
- var logger_1 = require("./logger");
69
+ var logger_1 = require("./logger/logger");
70
70
  Object.defineProperty(exports, "LoggerLevel", { enumerable: true, get: function () { return logger_1.LoggerLevel; } });
71
71
  Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
72
72
  var messages_2 = require("./messages");
package/lib/global.d.ts CHANGED
@@ -48,10 +48,6 @@ export declare class Global {
48
48
  * The full system path to the preferred global state folder
49
49
  */
50
50
  static get DIR(): string;
51
- /**
52
- * The full system path to the global log file.
53
- */
54
- static readonly LOG_FILE_PATH: string;
55
51
  /**
56
52
  * Gets the current mode environment variable as a {@link Mode} instance.
57
53
  *
package/lib/global.js CHANGED
@@ -101,10 +101,4 @@ Global.SF_STATE_FOLDER = '.sf';
101
101
  * The preferred global folder in which state is stored.
102
102
  */
103
103
  Global.STATE_FOLDER = Global.SFDX_STATE_FOLDER;
104
- /**
105
- * The full system path to the global log file.
106
- */
107
- // member ordering conflicts with the TS use-before-declaration error
108
- // eslint-disable-next-line @typescript-eslint/member-ordering
109
- Global.LOG_FILE_PATH = path.join(Global.SF_DIR, 'sf.log');
110
104
  //# sourceMappingURL=global.js.map
@@ -25,7 +25,7 @@ export declare class Lifecycle {
25
25
  private readonly listeners;
26
26
  static readonly telemetryEventName = "telemetry";
27
27
  static readonly warningEventName = "warning";
28
- private debug;
28
+ private logger?;
29
29
  private constructor();
30
30
  /**
31
31
  * return the package.json version of the sfdx-core library.
@@ -7,12 +7,12 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.Lifecycle = void 0;
10
- const Debug = require("debug");
11
10
  const semver_1 = require("semver");
12
11
  // needed for TS to not put everything inside /lib/src
13
12
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
14
13
  // @ts-ignore
15
14
  const pjson = require("../package.json");
15
+ const logger_1 = require("./logger/logger");
16
16
  /**
17
17
  * An asynchronous event listener and emitter that follows the singleton pattern. The singleton pattern allows lifecycle
18
18
  * events to be emitted from deep within a library and still be consumed by any other library or tool. It allows other
@@ -37,7 +37,6 @@ const pjson = require("../package.json");
37
37
  class Lifecycle {
38
38
  constructor(listeners = {}) {
39
39
  this.listeners = listeners;
40
- this.debug = Debug(`sfdx:${this.constructor.name}`);
41
40
  }
42
41
  /**
43
42
  * return the package.json version of the sfdx-core library.
@@ -138,7 +137,10 @@ class Lifecycle {
138
137
  on(eventName, cb) {
139
138
  const listeners = this.getListeners(eventName);
140
139
  if (listeners.length !== 0) {
141
- this.debug(`${listeners.length + 1} lifecycle events with the name ${eventName} have now been registered. When this event is emitted all ${listeners.length + 1} listeners will fire.`);
140
+ if (!this.logger) {
141
+ this.logger = logger_1.Logger.childFromRoot('Lifecycle');
142
+ }
143
+ this.logger.debug(`${listeners.length + 1} lifecycle events with the name ${eventName} have now been registered. When this event is emitted all ${listeners.length + 1} listeners will fire.`);
142
144
  }
143
145
  listeners.push(cb);
144
146
  this.listeners[eventName] = listeners;
@@ -173,7 +175,10 @@ class Lifecycle {
173
175
  async emit(eventName, data) {
174
176
  const listeners = this.getListeners(eventName);
175
177
  if (listeners.length === 0 && eventName !== Lifecycle.warningEventName) {
176
- this.debug(`A lifecycle event with the name ${eventName} does not exist. An event must be registered before it can be emitted.`);
178
+ if (!this.logger) {
179
+ this.logger = logger_1.Logger.childFromRoot('Lifecycle');
180
+ }
181
+ this.logger.debug(`A lifecycle event with the name ${eventName} does not exist. An event must be registered before it can be emitted.`);
177
182
  }
178
183
  else {
179
184
  for (const cb of listeners) {
@@ -0,0 +1,11 @@
1
+ /**
2
+ * New logger (Summer 2023) changes how file rotation works. Each day, the logger writes to a new file
3
+ * To get old files cleaned up, this can be called when a new root logger is instantiated
4
+ * based on CLEAN_ODDS, it could exit OR delete some old log files
5
+ *
6
+ * to start this without waiting, use void cleanup()
7
+ *
8
+ * accepts params to override the default behavior (used to cleanup huge log file during perf tests)
9
+ */
10
+ export declare const cleanup: (maxMs?: number, force?: boolean) => Promise<void>;
11
+ export declare const getOldLogFiles: (files: string[], maxMs?: number) => string[];
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOldLogFiles = exports.cleanup = void 0;
4
+ /*
5
+ * Copyright (c) 2023, salesforce.com, inc.
6
+ * All rights reserved.
7
+ * Licensed under the BSD 3-Clause license.
8
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
9
+ */
10
+ const fs = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ const global_1 = require("../global");
13
+ const logger_1 = require("./logger");
14
+ /**
15
+ * the odds of running are 1 in CLEAN_ODDS
16
+ * ex: CLEAN_ODDS=100 implies 1 in 100
17
+ * ex: CLEAN_ODDS=100 implies 1 in 1 (run every time)
18
+ * */
19
+ const CLEAN_ODDS = 100;
20
+ const MAX_FILE_AGE_DAYS = 7;
21
+ const MAX_FILE_AGE_MS = 1000 * 60 * 60 * 24 * MAX_FILE_AGE_DAYS;
22
+ const shouldClean = Math.random() * CLEAN_ODDS > CLEAN_ODDS - 1;
23
+ /**
24
+ * New logger (Summer 2023) changes how file rotation works. Each day, the logger writes to a new file
25
+ * To get old files cleaned up, this can be called when a new root logger is instantiated
26
+ * based on CLEAN_ODDS, it could exit OR delete some old log files
27
+ *
28
+ * to start this without waiting, use void cleanup()
29
+ *
30
+ * accepts params to override the default behavior (used to cleanup huge log file during perf tests)
31
+ */
32
+ const cleanup = async (maxMs = MAX_FILE_AGE_MS, force = false) => {
33
+ if (shouldClean || force) {
34
+ try {
35
+ const filesToConsider = await fs.promises // get the files in that dir
36
+ .readdir(global_1.Global.SF_DIR);
37
+ const filesToDelete = (0, exports.getOldLogFiles)(filesToConsider, maxMs);
38
+ await Promise.all(filesToDelete.map((f) => fs.promises.unlink((0, node_path_1.join)(global_1.Global.SF_DIR, f))));
39
+ }
40
+ catch (e) {
41
+ // we never, ever, ever throw since we're not awaiting this promise, so just log a warning
42
+ (await logger_1.Logger.child('cleanup')).warn('Failed to cleanup old log files', e);
43
+ }
44
+ }
45
+ };
46
+ exports.cleanup = cleanup;
47
+ const getOldLogFiles = (files, maxMs = MAX_FILE_AGE_MS) => files
48
+ .filter((f) => f.endsWith('.log'))
49
+ // map of filename and the date sf-YYYY-MM-DD.log => YYYY-MM-DD
50
+ .map((f) => ({ file: f, date: f.match(/sf-(\d{4}-\d{2}-\d{2}).*\.log/)?.[1] }))
51
+ .filter(hasDate)
52
+ .map((f) => ({ file: f.file, date: new Date(f.date) }))
53
+ .filter((f) => f.date < new Date(Date.now() - maxMs))
54
+ .map((f) => f.file);
55
+ exports.getOldLogFiles = getOldLogFiles;
56
+ const hasDate = (f) => typeof f === 'object' && f !== null && 'date' in f && typeof f.date === 'string';
57
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1,7 @@
1
+ export declare const HIDDEN = "HIDDEN";
2
+ /**
3
+ *
4
+ * @param args you *probably are passing this an object, but it can handle any type
5
+ * @returns
6
+ */
7
+ export declare const filterSecrets: (...args: unknown[]) => unknown;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterSecrets = exports.HIDDEN = void 0;
4
+ /*
5
+ * Copyright (c) 2023, salesforce.com, inc.
6
+ * All rights reserved.
7
+ * Licensed under the BSD 3-Clause license.
8
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
9
+ */
10
+ const ts_types_1 = require("@salesforce/ts-types");
11
+ const sfdc_1 = require("../util/sfdc");
12
+ exports.HIDDEN = 'HIDDEN';
13
+ // Match all json attribute values case insensitive: ex. {" Access*^&(*()^* Token " : " 45143075913458901348905 \n\t" ...}
14
+ const buildTokens = (expElement) => new RegExp(`(['"][^'"]*${expElement}[^'"]*['"]\\s*:\\s*)['"][^'"]*['"]`, 'gi');
15
+ // Match all key value attribute case insensitive: ex. {" key\t" : ' access_token ' , " value " : " dsafgasr431 " ....}
16
+ const buildKeyRegex = (expElement) => RegExp(`(['"]\\s*key\\s*['"]\\s*:)\\s*['"]\\s*${expElement}\\s*['"]\\s*.\\s*['"]\\s*value\\s*['"]\\s*:\\s*['"]\\s*[^'"]*['"]`, 'gi');
17
+ // This will redact values when the keys match certain patterns
18
+ const FILTERED_KEYS = [
19
+ { name: 'sid' },
20
+ { name: 'Authorization' },
21
+ // Any json attribute that contains the words "refresh" and "token" will have the attribute/value hidden
22
+ { name: 'refresh_token', regex: 'refresh[^\'"]*token' },
23
+ { name: 'clientsecret' },
24
+ ];
25
+ const FILTERED_KEYS_FOR_PROCESSING = FILTERED_KEYS.map((key) => ({
26
+ ...key,
27
+ regexTokens: buildTokens(key.regex ?? key.name),
28
+ hiddenAttrMessage: `"<${key.name} - ${exports.HIDDEN}>"`,
29
+ keyRegex: buildKeyRegex(key.regex ?? key.name),
30
+ }));
31
+ const compose = (...fns) => fns.reduce((prevFn, nextFn) => (value) => prevFn(nextFn(value)));
32
+ const replacementFunctions = FILTERED_KEYS_FOR_PROCESSING.flatMap((key) => [
33
+ // two functions to run across each key
34
+ (input) => input.replace(key.regexTokens, `$1${key.hiddenAttrMessage}`),
35
+ (input) => input.replace(key.keyRegex, `$1${key.hiddenAttrMessage}`),
36
+ ]).concat([
37
+ // plus any "generalized" functions that are matching contents regardless of keys
38
+ // use these for secrets with known patterns
39
+ (input) => input
40
+ .replace(new RegExp(sfdc_1.accessTokenRegex, 'g'), '<REDACTED ACCESS TOKEN>')
41
+ .replace(new RegExp(sfdc_1.sfdxAuthUrlRegex, 'g'), '<REDACTED AUTH URL TOKEN>'),
42
+ ]);
43
+ const fullReplacementChain = compose(...replacementFunctions);
44
+ /**
45
+ *
46
+ * @param args you *probably are passing this an object, but it can handle any type
47
+ * @returns
48
+ */
49
+ const filterSecrets = (...args) => args.map((arg) => {
50
+ if (!arg) {
51
+ return arg;
52
+ }
53
+ if ((0, ts_types_1.isArray)(arg)) {
54
+ return (0, exports.filterSecrets)(...arg);
55
+ }
56
+ // Normalize all objects into a string. This includes errors.
57
+ if (arg instanceof Buffer) {
58
+ return '<Buffer>';
59
+ }
60
+ if ((0, ts_types_1.isObject)(arg)) {
61
+ return JSON.parse(fullReplacementChain(JSON.stringify(arg)));
62
+ }
63
+ if ((0, ts_types_1.isString)(arg)) {
64
+ return fullReplacementChain(arg);
65
+ }
66
+ return '';
67
+ });
68
+ exports.filterSecrets = filterSecrets;
69
+ //# sourceMappingURL=filters.js.map
@@ -1,20 +1,4 @@
1
- /// <reference types="node" />
2
- import { Writable } from 'stream';
3
- /**
4
- * A Bunyan `Serializer` function.
5
- *
6
- * @param input The input to be serialized.
7
- * **See** {@link https://github.com/forcedotcom/node-bunyan#serializers|Bunyan Serializers API}
8
- */
9
- export type Serializer = (input: unknown) => unknown;
10
- /**
11
- * A collection of named `Serializer`s.
12
- *
13
- * **See** {@link https://github.com/forcedotcom/node-bunyan#serializers|Bunyan Serializers API}
14
- */
15
- export interface Serializers {
16
- [key: string]: Serializer;
17
- }
1
+ import { Logger as PinoLogger } from 'pino';
18
2
  /**
19
3
  * The common set of `Logger` options.
20
4
  */
@@ -23,35 +7,21 @@ export interface LoggerOptions {
23
7
  * The logger name.
24
8
  */
25
9
  name: string;
26
- /**
27
- * The logger format type. Current options include LogFmt or JSON (default).
28
- */
29
- format?: LoggerFormat;
30
- /**
31
- * The logger's serializers.
32
- */
33
- serializers?: Serializers;
34
- /**
35
- * Whether or not to log source file, line, and function information.
36
- */
37
- src?: boolean;
38
10
  /**
39
11
  * The desired log level.
40
12
  */
41
13
  level?: LoggerLevelValue;
42
14
  /**
43
- * A stream to write to.
15
+ * Create a logger with the fields set
44
16
  */
45
- stream?: Writable;
46
- /**
47
- * An array of streams to write to.
48
- */
49
- streams?: LoggerStream[];
17
+ fields?: Fields;
18
+ /** log to memory instead of to a file. Intended for Unit Testing */
19
+ useMemoryLogger?: boolean;
50
20
  }
51
21
  /**
52
22
  * Standard `Logger` levels.
53
23
  *
54
- * **See** {@link https://github.com/forcedotcom/node-bunyan#levels|Bunyan Levels}
24
+ * **See** {@link https://getpino.io/#/docs/api?id=logger-level |Logger Levels}
55
25
  */
56
26
  export declare enum LoggerLevel {
57
27
  TRACE = 10,
@@ -61,57 +31,18 @@ export declare enum LoggerLevel {
61
31
  ERROR = 50,
62
32
  FATAL = 60
63
33
  }
64
- /**
65
- * `Logger` format types.
66
- */
67
- export declare enum LoggerFormat {
68
- JSON = 0,
69
- LOGFMT = 1
70
- }
71
- /**
72
- * A Bunyan stream configuration.
73
- *
74
- * @see {@link https://github.com/forcedotcom/node-bunyan#streams|Bunyan Streams}
75
- */
76
- export interface LoggerStream {
77
- [key: string]: any;
78
- /**
79
- * The type of stream -- may be inferred from other properties.
80
- */
81
- type?: string;
82
- /**
83
- * The desired log level for the stream.
84
- */
85
- level?: LoggerLevelValue;
86
- /**
87
- * The stream to write to. Mutually exclusive with `path`.
88
- */
89
- stream?: Writable;
90
- /**
91
- * The name of the stream.
92
- */
93
- name?: string;
94
- /**
95
- * A log file path to write to. Mutually exclusive with `stream`.
96
- */
97
- path?: string;
98
- }
99
34
  /**
100
35
  * Any numeric `Logger` level.
101
36
  */
102
37
  export type LoggerLevelValue = LoggerLevel | number;
103
38
  /**
104
- * A collection of named `FieldValue`s.
105
- *
106
- * **See** {@link https://github.com/forcedotcom/node-bunyan#log-record-fields|Bunyan Log Record Fields}
39
+ * An object
107
40
  */
108
- export interface Fields {
109
- [key: string]: FieldValue;
110
- }
41
+ export type Fields = Record<string, unknown>;
111
42
  /**
112
43
  * All possible field value types.
113
44
  */
114
- export type FieldValue = string | number | boolean;
45
+ export type FieldValue = string | number | boolean | Fields;
115
46
  /**
116
47
  * Log line interface
117
48
  */
@@ -126,8 +57,8 @@ export interface LogLine {
126
57
  v: number;
127
58
  }
128
59
  /**
129
- * A logging abstraction powered by {@link https://github.com/forcedotcom/node-bunyan|Bunyan} that provides both a default
130
- * logger configuration that will log to `sfdx.log`, and a way to create custom loggers based on the same foundation.
60
+ * A logging abstraction powered by {@link https://github.com/pinojs/pino | Pino} that provides both a default
61
+ * logger configuration that will log to the default path, and a way to create custom loggers based on the same foundation.
131
62
  *
132
63
  * ```
133
64
  * // Gets the root sfdx logger
@@ -141,8 +72,17 @@ export interface LogLine {
141
72
  *
142
73
  * // Creates a child of a custom logger unaffiliated with the root logger with custom fields applied
143
74
  * const myCustomChildLogger = myCustomLogger.child('myCustomChild', {tag: 'value'});
75
+ *
76
+ * // get a raw pino logger from the root instance of Logger
77
+ * // you can use these to avoid constructing another Logger wrapper class and to get better type support
78
+ * const logger = Logger.getRawRootLogger().child({name: 'foo', otherProp: 'bar'});
79
+ * logger.info({some: 'stuff'}, 'a message');
80
+ *
81
+ *
82
+ * // get a raw pino logger from the current instance
83
+ * const childLogger = await Logger.child('myRootChild', {tag: 'value'});
84
+ * const logger = childLogger.getRawLogger();
144
85
  * ```
145
- * **See** https://github.com/forcedotcom/node-bunyan
146
86
  *
147
87
  * **See** https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_dev_cli_log_messages.htm
148
88
  */
@@ -161,25 +101,9 @@ export declare class Logger {
161
101
  * **See** {@link LoggerLevel}
162
102
  */
163
103
  static readonly LEVEL_NAMES: string[];
164
- private static readonly lifecycle;
165
104
  private static rootLogger?;
166
- /**
167
- * The default rotation period for logs. Example '1d' will rotate logs daily (at midnight).
168
- * See 'period' docs here: https://github.com/forcedotcom/node-bunyan#stream-type-rotating-file
169
- */
170
- readonly logRotationPeriod: string;
171
- /**
172
- * The number of backup rotated log files to keep.
173
- * Example: '3' will have the base sf.log file, and the past 3 (period) log files.
174
- * See 'count' docs here: https://github.com/forcedotcom/node-bunyan#stream-type-rotating-file
175
- */
176
- readonly logRotationCount: number;
177
- /**
178
- * Whether debug is enabled for this Logger.
179
- */
180
- debugEnabled: boolean;
181
- private bunyan;
182
- private readonly format;
105
+ private pinoLogger;
106
+ private memoryLogger?;
183
107
  /**
184
108
  * Constructs a new `Logger`.
185
109
  *
@@ -190,11 +114,13 @@ export declare class Logger {
190
114
  */
191
115
  constructor(optionsOrName: LoggerOptions | string);
192
116
  /**
193
- * Gets the root logger with the default level, file stream, and DEBUG enabled.
117
+ *
118
+ * Gets the root logger. It's a singleton
119
+ * See also getRawLogger if you don't need the root logger
194
120
  */
195
121
  static root(): Promise<Logger>;
196
122
  /**
197
- * Gets the root logger with the default level, file stream, and DEBUG enabled.
123
+ * Gets the root logger. It's a singleton
198
124
  */
199
125
  static getRoot(): Logger;
200
126
  /**
@@ -204,14 +130,14 @@ export declare class Logger {
204
130
  */
205
131
  static destroyRoot(): void;
206
132
  /**
207
- * Create a child of the root logger, inheriting this instance's configuration such as `level`, `streams`, etc.
133
+ * Create a child of the root logger, inheriting this instance's configuration such as `level`, transports, etc.
208
134
  *
209
135
  * @param name The name of the child logger.
210
136
  * @param fields Additional fields included in all log lines.
211
137
  */
212
138
  static child(name: string, fields?: Fields): Promise<Logger>;
213
139
  /**
214
- * Create a child of the root logger, inheriting this instance's configuration such as `level`, `streams`, etc.
140
+ * Create a child of the root logger, inheriting this instance's configuration such as `level`, transports, etc.
215
141
  *
216
142
  * @param name The name of the child logger.
217
143
  * @param fields Additional fields included in all log lines.
@@ -226,25 +152,10 @@ export declare class Logger {
226
152
  * @see {@Link LoggerLevel}
227
153
  */
228
154
  static getLevelByName(levelName: string): LoggerLevelValue;
229
- /**
230
- * Adds a stream.
231
- *
232
- * @param stream The stream configuration to add.
233
- * @param defaultLevel The default level of the stream.
234
- */
235
- addStream(stream: LoggerStream, defaultLevel?: LoggerLevelValue): void;
236
- /**
237
- * Adds a file stream to this logger. Resolved or rejected upon completion of the addition.
238
- *
239
- * @param logFile The path to the log file. If it doesn't exist it will be created.
240
- */
241
- addLogFileStream(logFile: string): Promise<void>;
242
- /**
243
- * Adds a file stream to this logger. Resolved or rejected upon completion of the addition.
244
- *
245
- * @param logFile The path to the log file. If it doesn't exist it will be created.
246
- */
247
- addLogFileStreamSync(logFile: string): void;
155
+ /** get the bare (pino) logger instead of using the class hierarchy */
156
+ static getRawRootLogger(): PinoLogger;
157
+ /** get the bare (pino) logger instead of using the class hierarchy */
158
+ getRawLogger(): PinoLogger;
248
159
  /**
249
160
  * Gets the name of this logger.
250
161
  */
@@ -275,10 +186,6 @@ export declare class Logger {
275
186
  * ```
276
187
  */
277
188
  setLevel(level?: LoggerLevelValue): Logger;
278
- /**
279
- * Gets the underlying Bunyan logger.
280
- */
281
- getBunyanLogger(): any;
282
189
  /**
283
190
  * Compares the requested log level with the current log level. Returns true if
284
191
  * the requested log level is greater than or equal to the current log level.
@@ -286,13 +193,6 @@ export declare class Logger {
286
193
  * @param level The requested log level to compare against the currently set log level.
287
194
  */
288
195
  shouldLog(level: LoggerLevelValue): boolean;
289
- /**
290
- * Use in-memory logging for this logger instance instead of any parent streams. Useful for testing.
291
- * For convenience this object is returned.
292
- *
293
- * **WARNING: This cannot be undone for this logger instance.**
294
- */
295
- useMemoryLogging(): Logger;
296
196
  /**
297
197
  * Gets an array of log line objects. Each element is an object that corresponds to a log line.
298
198
  */
@@ -301,22 +201,10 @@ export declare class Logger {
301
201
  * Reads a text blob of all the log lines contained in memory or the log file.
302
202
  */
303
203
  readLogContentsAsText(): string;
304
- /**
305
- * Adds a filter to be applied to all logged messages.
306
- *
307
- * @param filter A function with signature `(...args: any[]) => any[]` that transforms log message arguments.
308
- */
309
- addFilter(filter: (...args: unknown[]) => unknown): void;
310
- /**
311
- * Close the logger, including any streams, and remove all listeners.
312
- *
313
- * @param fn A function with signature `(stream: LoggerStream) => void` to call for each stream with the stream as an arg.
314
- */
315
- close(fn?: (stream: LoggerStream) => void): void;
316
204
  /**
317
205
  * Create a child logger, typically to add a few log record fields. For convenience this object is returned.
318
206
  *
319
- * @param name The name of the child logger that is emitted w/ log line as `log:<name>`.
207
+ * @param name The name of the child logger that is emitted w/ log line. Will be prefixed with the parent logger name and `:`
320
208
  * @param fields Additional fields included in all log lines for the child logger.
321
209
  */
322
210
  child(name: string, fields?: Fields): Logger;
@@ -369,13 +257,4 @@ export declare class Logger {
369
257
  * @param args Any number of arguments to be logged.
370
258
  */
371
259
  fatal(...args: unknown[]): Logger;
372
- /**
373
- * Enables logging to stdout when the DEBUG environment variable is used. It uses the logger
374
- * name as the debug name, so you can do DEBUG=<logger-name> to filter the results to your logger.
375
- */
376
- enableDEBUG(): void;
377
- private applyFilters;
378
- private uncaughtExceptionHandler;
379
- private exitHandler;
380
- private createLogFmtFormatterStream;
381
260
  }