@simplysf/simply-apex 1.1.19 → 1.4.0

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/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  Apache License Version 2.0
2
2
 
3
- Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
3
+ Copyright (c) 2026, Clay Chipps.
4
4
  All rights reserved.
5
5
 
6
6
  Apache License
package/README.md CHANGED
@@ -31,7 +31,7 @@ Execute anonymous Apex code.
31
31
 
32
32
  ```
33
33
  USAGE
34
- $ sf simply apex execute -f <value> -o <value> [--json] [--flags-dir <value>] [--api-version <value>]
34
+ $ sf simply apex execute -o <value> -f <value> [--json] [--flags-dir <value>] [--api-version <value>]
35
35
 
36
36
  FLAGS
37
37
  -f, --file=<value> (required) Path to Apex file
@@ -58,7 +58,7 @@ FLAG DESCRIPTIONS
58
58
  The path to the local .apex file containing the anonymous Apex code to execute.
59
59
  ```
60
60
 
61
- _See code: [lib/commands/simply/apex/execute.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.10/packages/simply-apex/lib/commands/simply/apex/execute.js)_
61
+ _See code: [lib/commands/simply/apex/execute.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.18/packages/simply-apex/lib/commands/simply/apex/execute.js)_
62
62
 
63
63
  ## `sf simply apex logs purge`
64
64
 
@@ -66,13 +66,16 @@ Purge Apex debug logs.
66
66
 
67
67
  ```
68
68
  USAGE
69
- $ sf simply apex logs purge -o <value> [--json] [--flags-dir <value>] [--api-version <value>] [-w <value>]
69
+ $ sf simply apex logs purge -o <value> [--json] [--flags-dir <value>] [--api-version <value>] [-w <value>] [-b] [--wait
70
+ <value>]
70
71
 
71
72
  FLAGS
73
+ -b, --use-bulk-api Use Bulk API v2 to query and delete the logs.
72
74
  -o, --target-org=<value> (required) Username or alias of the target org. Not required if the `target-org`
73
75
  configuration variable is already set.
74
76
  -w, --where=<value> SOQL WHERE clause
75
77
  --api-version=<value> Override the api version used for api requests made by this command
78
+ --wait=<value> Number of minutes to wait for the Bulk API jobs to finish.
76
79
 
77
80
  GLOBAL FLAGS
78
81
  --flags-dir=<value> Import flag values from a directory.
@@ -89,42 +92,70 @@ EXAMPLES
89
92
 
90
93
  $ sf simply apex logs purge --target-org myOrg --where "Status = 'Success'"
91
94
 
95
+ $ sf simply apex logs purge --target-org myOrg --use-bulk-api
96
+
97
+ $ sf simply apex logs purge --target-org myOrg --use-bulk-api --wait 60
98
+
92
99
  FLAG DESCRIPTIONS
100
+ -b, --use-bulk-api Use Bulk API v2 to query and delete the logs.
101
+
102
+ Runs the whole purge as two Bulk API v2 jobs instead of a Tooling API query followed by chunked REST deletes. Bulk
103
+ API processes the deletion asynchronously and does not consume the org's REST API request limit, which suits purges
104
+ of tens of thousands of logs. For small purges the default REST path is faster, since it avoids the overhead of
105
+ creating, uploading, and polling a job.
106
+
93
107
  -w, --where=<value> SOQL WHERE clause
94
108
 
95
109
  A WHERE clause used to filter which ApexLog records are purged (e.g. "Status = 'Success'").
110
+
111
+ --wait=<value> Number of minutes to wait for the Bulk API jobs to finish.
112
+
113
+ Only applies with --use-bulk-api. The command polls the query and delete jobs until they complete or this timeout
114
+ elapses, then throws.
96
115
  ```
97
116
 
98
- _See code: [lib/commands/simply/apex/logs/purge.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.10/packages/simply-apex/lib/commands/simply/apex/logs/purge.js)_
117
+ _See code: [lib/commands/simply/apex/logs/purge.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.18/packages/simply-apex/lib/commands/simply/apex/logs/purge.js)_
99
118
 
100
119
  ## `sf simply apex trace setup`
101
120
 
102
- Configure a debug log trace flag for the current user.
121
+ Configure a debug log trace flag for the current user, or another user.
103
122
 
104
123
  ```
105
124
  USAGE
106
- $ sf simply apex trace setup -o <value> [--json] [--flags-dir <value>] [--api-version <value>]
125
+ $ sf simply apex trace setup -o <value> [--json] [--flags-dir <value>] [--api-version <value>] [--on-behalf-of
126
+ <value>]
107
127
 
108
128
  FLAGS
109
- -o, --target-org=<value> (required) Username or alias of the target org. Not required if the `target-org`
110
- configuration variable is already set.
111
- --api-version=<value> Override the api version used for api requests made by this command
129
+ -o, --target-org=<value> (required) Username or alias of the target org. Not required if the `target-org`
130
+ configuration variable is already set.
131
+ --api-version=<value> Override the api version used for api requests made by this command
132
+ --on-behalf-of=<value> Configure the trace flag for another user, identified by a "Field:Value" pair.
112
133
 
113
134
  GLOBAL FLAGS
114
135
  --flags-dir=<value> Import flag values from a directory.
115
136
  --json Format output as json.
116
137
 
117
138
  DESCRIPTION
118
- Configure a debug log trace flag for the current user.
139
+ Configure a debug log trace flag for the current user, or another user.
119
140
 
120
141
  Creates or updates a 24-hour DEVELOPER_LOG trace flag for the user running the command, using a FINEST/FINER debug
121
- level suitable for the Apex Replay Debugger.
142
+ level suitable for the Apex Replay Debugger. Use --on-behalf-of to configure the trace flag for a different user
143
+ instead.
122
144
 
123
145
  EXAMPLES
124
146
  $ sf simply apex trace setup --target-org myOrg
147
+
148
+ $ sf simply apex trace setup --target-org myOrg --on-behalf-of Username:someuser@example.com
149
+
150
+ $ sf simply apex trace setup --target-org myOrg --on-behalf-of FederationIdentifier:123456
151
+
152
+ FLAG DESCRIPTIONS
153
+ --on-behalf-of=<value> Configure the trace flag for another user, identified by a "Field:Value" pair.
154
+
155
+ Any unique User field can be used, for example "Username:someuser@example.com" or "FederationIdentifier:123456".
125
156
  ```
126
157
 
127
- _See code: [lib/commands/simply/apex/trace/setup.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.10/packages/simply-apex/lib/commands/simply/apex/trace/setup.js)_
158
+ _See code: [lib/commands/simply/apex/trace/setup.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.18/packages/simply-apex/lib/commands/simply/apex/trace/setup.js)_
128
159
 
129
160
  ## `sf simply apex trace silence`
130
161
 
@@ -168,21 +199,9 @@ FLAG DESCRIPTIONS
168
199
  silence.
169
200
  ```
170
201
 
171
- _See code: [lib/commands/simply/apex/trace/silence.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.10/packages/simply-apex/lib/commands/simply/apex/trace/silence.js)_
202
+ _See code: [lib/commands/simply/apex/trace/silence.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.1.18/packages/simply-apex/lib/commands/simply/apex/trace/silence.js)_
172
203
  <!-- commandsstop -->
173
204
 
174
- ## Configuration Files
175
-
176
- ### `sf simply apex trace silence --classes-file`
177
-
178
- The `--classes-file` flag on `sf simply apex trace silence` takes the path to a JSON file listing which Apex classes to silence:
179
-
180
- ```json
181
- {
182
- "classes": ["AccountTriggerHandler", "NoisyBatchClass"]
183
- }
184
- ```
205
+ ## License
185
206
 
186
- | Field | Type | Required | Description |
187
- | --------- | ---------- | -------- | -------------------------------------------------------------------------- |
188
- | `classes` | `string[]` | Yes | One or more Apex class API names to silence. Must have at least one entry. |
207
+ Licensed under the [Apache-2.0](https://raw.githubusercontent.com/SimplySF/simply-node/main/LICENSE.txt) license.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,3 +1,4 @@
1
+ import { Duration } from '@salesforce/kit';
1
2
  import { SfCommand } from '@salesforce/sf-plugins-core';
2
3
  /** Outcome of deleting a single `ApexLog` record. */
3
4
  export type ApexLogsPurgeResult = {
@@ -15,6 +16,8 @@ export default class ApexLogsPurge extends SfCommand<ApexLogsPurgeResult[]> {
15
16
  static readonly examples: string[];
16
17
  static readonly flags: {
17
18
  where: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ 'use-bulk-api': import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
+ wait: import("@oclif/core/interfaces").OptionFlag<Duration, import("@oclif/core/interfaces").CustomOptions>;
18
21
  'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined>;
19
22
  'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org>;
20
23
  'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -24,4 +27,12 @@ export default class ApexLogsPurge extends SfCommand<ApexLogsPurgeResult[]> {
24
27
  * filter.
25
28
  */
26
29
  run(): Promise<ApexLogsPurgeResult[]>;
30
+ /**
31
+ * Deletes through the core connection's SObject Collections resource, 200 records per call.
32
+ *
33
+ * Deliberately not `.tooling`: `ApexLog` is exposed on both APIs, but only core REST implements
34
+ * the Collections resource a bulk delete needs. `/tooling/composite/sobjects` does not exist and
35
+ * answers 404 "The requested resource does not exist".
36
+ */
37
+ private deleteViaCollections;
27
38
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { Messages } from '@salesforce/core';
17
+ import { Duration } from '@salesforce/kit';
17
18
  import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
18
19
  import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
19
20
  import { chunk } from '@simplysf/simply-core';
@@ -40,6 +41,19 @@ export default class ApexLogsPurge extends SfCommand {
40
41
  description: messages.getMessage('flags.where.description'),
41
42
  char: 'w',
42
43
  }),
44
+ 'use-bulk-api': Flags.boolean({
45
+ summary: messages.getMessage('flags.use-bulk-api.summary'),
46
+ description: messages.getMessage('flags.use-bulk-api.description'),
47
+ char: 'b',
48
+ default: false,
49
+ }),
50
+ wait: Flags.duration({
51
+ unit: 'minutes',
52
+ summary: messages.getMessage('flags.wait.summary'),
53
+ description: messages.getMessage('flags.wait.description'),
54
+ // jsforce defaults bulk polling to 30 seconds, which no real purge finishes within.
55
+ default: Duration.minutes(30),
56
+ }),
43
57
  };
44
58
  /**
45
59
  * @returns The delete outcome for every `ApexLog` record matched by the (optional) `--where`
@@ -48,39 +62,25 @@ export default class ApexLogsPurge extends SfCommand {
48
62
  async run() {
49
63
  const { flags } = await this.parse(ApexLogsPurge);
50
64
  const targetOrgConnection = requireConnection(flags);
65
+ const useBulkApi = flags['use-bulk-api'];
66
+ const pollTimeout = flags.wait.milliseconds;
51
67
  let query = 'SELECT Id FROM ApexLog';
52
68
  if (flags.where) {
53
69
  query += ` WHERE ${flags.where}`;
54
70
  }
55
71
  this.spinner.start(messages.getMessage('info.queryingLogs'));
56
- const queryResult = await targetOrgConnection.tooling.query(query);
72
+ const logIds = useBulkApi
73
+ ? await queryLogIdsViaBulkApi(targetOrgConnection, query, pollTimeout)
74
+ : await queryLogIdsViaRest(targetOrgConnection, query);
57
75
  this.spinner.stop();
58
- if (queryResult.records.length === 0) {
76
+ if (logIds.length === 0) {
59
77
  this.info(messages.getMessage('info.noLogsToPurge'));
60
78
  return [];
61
79
  }
62
- const logIds = queryResult.records.map((record) => record.Id);
63
- const results = [];
64
80
  this.spinner.start(messages.getMessage('info.purgingLogs', [logIds.length]));
65
- let purged = 0;
66
- for (const idChunk of chunk(logIds, CHUNK_SIZE)) {
67
- purged += idChunk.length;
68
- this.spinner.status = `${purged}/${logIds.length}`;
69
- // Deleted through the core connection, not `.tooling`. ApexLog is exposed on both APIs, but
70
- // only core REST implements the SObject Collections resource that a bulk delete needs;
71
- // `/tooling/composite/sobjects` does not exist and answers 404 "The requested resource does
72
- // not exist". The records were queried via the Tooling API, which returns the same IDs.
73
- // eslint-disable-next-line no-await-in-loop -- batches are sequential so the spinner tracks real progress
74
- const deleteResults = await targetOrgConnection.delete('ApexLog', idChunk);
75
- const deleteResultsArray = Array.isArray(deleteResults) ? deleteResults : [deleteResults];
76
- deleteResultsArray.forEach((deleteResult, index) => {
77
- results.push({
78
- Id: deleteResult.id ?? idChunk[index] ?? 'unknown',
79
- Success: deleteResult.success,
80
- Error: deleteResult.success ? undefined : deleteResult.errors.map((e) => e.message).join(', '),
81
- });
82
- });
83
- }
81
+ const results = useBulkApi
82
+ ? await deleteViaBulkApi(targetOrgConnection, logIds, pollTimeout)
83
+ : await this.deleteViaCollections(targetOrgConnection, logIds);
84
84
  this.spinner.stop();
85
85
  const successCount = results.filter((result) => result.Success).length;
86
86
  const failureCount = results.length - successCount;
@@ -100,5 +100,76 @@ export default class ApexLogsPurge extends SfCommand {
100
100
  });
101
101
  return results;
102
102
  }
103
+ /**
104
+ * Deletes through the core connection's SObject Collections resource, 200 records per call.
105
+ *
106
+ * Deliberately not `.tooling`: `ApexLog` is exposed on both APIs, but only core REST implements
107
+ * the Collections resource a bulk delete needs. `/tooling/composite/sobjects` does not exist and
108
+ * answers 404 "The requested resource does not exist".
109
+ */
110
+ async deleteViaCollections(connection, logIds) {
111
+ const results = [];
112
+ let purged = 0;
113
+ for (const idChunk of chunk(logIds, CHUNK_SIZE)) {
114
+ purged += idChunk.length;
115
+ this.spinner.status = `${purged}/${logIds.length}`;
116
+ // eslint-disable-next-line no-await-in-loop -- batches are sequential so the spinner tracks real progress
117
+ const deleteResults = await connection.delete('ApexLog', idChunk);
118
+ const deleteResultsArray = Array.isArray(deleteResults) ? deleteResults : [deleteResults];
119
+ deleteResultsArray.forEach((deleteResult, index) => {
120
+ results.push({
121
+ Id: deleteResult.id ?? idChunk[index] ?? 'unknown',
122
+ Success: deleteResult.success,
123
+ Error: deleteResult.success ? undefined : deleteResult.errors.map((e) => e.message).join(', '),
124
+ });
125
+ });
126
+ }
127
+ return results;
128
+ }
129
+ }
130
+ /** Collects matching log IDs through the Tooling API, which returns them in a single response. */
131
+ async function queryLogIdsViaRest(connection, query) {
132
+ const queryResult = await connection.tooling.query(query);
133
+ return queryResult.records.map((record) => record.Id);
134
+ }
135
+ /**
136
+ * Collects matching log IDs through a Bulk API v2 query job. The job streams CSV back, so the IDs
137
+ * are gathered from the record stream rather than a single response body.
138
+ */
139
+ async function queryLogIdsViaBulkApi(connection, query, pollTimeout) {
140
+ const recordStream = await connection.bulk2.query(query, { pollTimeout });
141
+ const logIds = [];
142
+ for await (const record of recordStream) {
143
+ const { Id: id } = record;
144
+ if (id) {
145
+ logIds.push(id);
146
+ }
147
+ }
148
+ return logIds;
149
+ }
150
+ /**
151
+ * Deletes through a Bulk API v2 ingest job. The whole set goes up as one job rather than in
152
+ * 200-record chunks, and the org processes it asynchronously without spending REST request limit.
153
+ */
154
+ async function deleteViaBulkApi(connection, logIds, pollTimeout) {
155
+ const { successfulResults, failedResults } = await connection.bulk2.loadAndWaitForResults({
156
+ object: 'ApexLog',
157
+ operation: 'delete',
158
+ input: logIds.map((Id) => ({ Id })),
159
+ pollTimeout,
160
+ });
161
+ return [
162
+ ...successfulResults.map((result) => ({ Id: result.sf__Id, Success: true })),
163
+ ...failedResults.map((result) => {
164
+ // A failed row reports an empty (not absent) `sf__Id`; the submitted `Id` column is echoed
165
+ // back alongside it, so prefer that to keep every failure traceable to a specific log.
166
+ const submittedId = result.Id;
167
+ return {
168
+ Id: result.sf__Id.length > 0 ? result.sf__Id : (submittedId ?? 'unknown'),
169
+ Success: false,
170
+ Error: result.sf__Error,
171
+ };
172
+ }),
173
+ ];
103
174
  }
104
175
  //# sourceMappingURL=purge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"purge.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/logs/purge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"purge.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/logs/purge.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,10 @@
1
1
  import { SfCommand } from '@salesforce/sf-plugins-core';
2
- /** IDs of the debug level and trace flag configured for the running user, and when it expires. */
2
+ /** A `Field:Value` pair identifying the user to configure the trace flag for. */
3
+ type OnBehalfOf = {
4
+ field: string;
5
+ value: string;
6
+ };
7
+ /** IDs of the debug level and trace flag configured for the target user, and when it expires. */
3
8
  export type ApexTraceSetupResult = {
4
9
  userId: string;
5
10
  debugLevelId: string;
@@ -7,14 +12,21 @@ export type ApexTraceSetupResult = {
7
12
  expirationDate: string;
8
13
  };
9
14
  /**
10
- * Creates or updates a 24-hour DEVELOPER_LOG trace flag for the user running the command, using
11
- * a FINEST/FINER debug level suitable for the Apex Replay Debugger.
15
+ * Creates or updates a DEVELOPER_LOG trace flag for the target user. The target user is the one
16
+ * running the command by default, or the user identified by `--on-behalf-of` if provided. By
17
+ * default the trace flag uses the FINEST/FINER `ReplayDebuggerLevels` debug level suitable for
18
+ * the Apex Replay Debugger and runs for 24 hours starting now; `--log-level`, `--start-date`, and
19
+ * `--end-date` override those defaults.
12
20
  */
13
21
  export default class ApexTraceSetup extends SfCommand<ApexTraceSetupResult> {
14
22
  static readonly summary: string;
15
23
  static readonly description: string;
16
24
  static readonly examples: string[];
17
25
  static readonly flags: {
26
+ 'on-behalf-of': import("@oclif/core/interfaces").OptionFlag<OnBehalfOf | undefined, import("@oclif/core/interfaces").CustomOptions>;
27
+ 'log-level': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
28
+ 'start-date': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
29
+ 'end-date': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
30
  'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined>;
19
31
  'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org>;
20
32
  'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -25,3 +37,4 @@ export default class ApexTraceSetup extends SfCommand<ApexTraceSetupResult> {
25
37
  */
26
38
  run(): Promise<ApexTraceSetupResult>;
27
39
  }
40
+ export {};
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,17 +14,28 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { Messages } from '@salesforce/core';
17
- import { SfCommand } from '@salesforce/sf-plugins-core';
17
+ import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
18
18
  import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
19
+ import { escapeSoqlLiteral } from '@simplysf/simply-core';
19
20
  Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
20
21
  const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.trace.setup');
21
22
  /** DeveloperName used for the FINEST/FINER debug level created for the Apex Replay Debugger. */
22
23
  const DEBUG_LEVEL_NAME = 'ReplayDebuggerLevels';
23
24
  /** How long a configured trace flag stays active before expiring, in milliseconds (24 hours). */
24
25
  const TRACE_DURATION_MS = 24 * 60 * 60 * 1000;
26
+ /** Matches the ISO 8601 date-time format required by the `--start-date`/`--end-date` flags. */
27
+ const DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
25
28
  /**
26
- * Creates or updates a 24-hour DEVELOPER_LOG trace flag for the user running the command, using
27
- * a FINEST/FINER debug level suitable for the Apex Replay Debugger.
29
+ * Matches `Field:Value` for `--on-behalf-of`. The field name is restricted to safe SOQL
30
+ * identifier characters since, unlike the value, it can't be quoted/escaped in the query.
31
+ */
32
+ const ON_BEHALF_OF_PATTERN = /^([A-Za-z_][A-Za-z0-9_]*):(.+)$/;
33
+ /**
34
+ * Creates or updates a DEVELOPER_LOG trace flag for the target user. The target user is the one
35
+ * running the command by default, or the user identified by `--on-behalf-of` if provided. By
36
+ * default the trace flag uses the FINEST/FINER `ReplayDebuggerLevels` debug level suitable for
37
+ * the Apex Replay Debugger and runs for 24 hours starting now; `--log-level`, `--start-date`, and
38
+ * `--end-date` override those defaults.
28
39
  */
29
40
  export default class ApexTraceSetup extends SfCommand {
30
41
  static summary = messages.getMessage('summary');
@@ -33,6 +44,46 @@ export default class ApexTraceSetup extends SfCommand {
33
44
  static flags = {
34
45
  ...SfCommand.baseFlags,
35
46
  ...targetOrgFlags,
47
+ 'on-behalf-of': Flags.custom({
48
+ // eslint-disable-next-line @typescript-eslint/require-await
49
+ parse: async (input) => {
50
+ const match = ON_BEHALF_OF_PATTERN.exec(input);
51
+ if (!match) {
52
+ throw messages.createError('error.invalidOnBehalfOf', [input]);
53
+ }
54
+ const [, field, value] = match;
55
+ return { field, value };
56
+ },
57
+ })({
58
+ summary: messages.getMessage('flags.on-behalf-of.summary'),
59
+ description: messages.getMessage('flags.on-behalf-of.description'),
60
+ }),
61
+ 'log-level': Flags.string({
62
+ summary: messages.getMessage('flags.log-level.summary'),
63
+ description: messages.getMessage('flags.log-level.description'),
64
+ }),
65
+ 'start-date': Flags.string({
66
+ summary: messages.getMessage('flags.start-date.summary'),
67
+ description: messages.getMessage('flags.start-date.description'),
68
+ // eslint-disable-next-line @typescript-eslint/require-await
69
+ parse: async (input) => {
70
+ if (!DATE_TIME_PATTERN.test(input)) {
71
+ throw messages.createError('error.invalidDateTime', ['start-date', input]);
72
+ }
73
+ return input;
74
+ },
75
+ }),
76
+ 'end-date': Flags.string({
77
+ summary: messages.getMessage('flags.end-date.summary'),
78
+ description: messages.getMessage('flags.end-date.description'),
79
+ // eslint-disable-next-line @typescript-eslint/require-await
80
+ parse: async (input) => {
81
+ if (!DATE_TIME_PATTERN.test(input)) {
82
+ throw messages.createError('error.invalidDateTime', ['end-date', input]);
83
+ }
84
+ return input;
85
+ },
86
+ }),
36
87
  };
37
88
  /**
38
89
  * @returns The IDs of the debug level and trace flag that were created or updated, and the
@@ -41,20 +92,31 @@ export default class ApexTraceSetup extends SfCommand {
41
92
  async run() {
42
93
  const { flags } = await this.parse(ApexTraceSetup);
43
94
  const targetOrgConnection = requireConnection(flags);
95
+ const onBehalfOf = flags['on-behalf-of'];
96
+ const userFilterField = onBehalfOf?.field ?? 'Username';
97
+ const userFilterValue = onBehalfOf?.value ?? targetOrgConnection.getUsername() ?? '';
98
+ const userIdentifier = onBehalfOf ? `${onBehalfOf.field}:${onBehalfOf.value}` : userFilterValue;
44
99
  this.spinner.start(messages.getMessage('info.findingUser'));
45
- const username = targetOrgConnection.getUsername() ?? '';
46
- const userQueryResult = await targetOrgConnection.query(`SELECT Id FROM User WHERE Username = '${username}'`);
100
+ const userQueryResult = await targetOrgConnection.query(`SELECT Id FROM User WHERE ${userFilterField} = '${escapeSoqlLiteral(userFilterValue)}' LIMIT 2`);
47
101
  if (userQueryResult.records.length === 0) {
48
- throw messages.createError('error.userNotFound', [username]);
102
+ throw messages.createError('error.userNotFound', [userIdentifier]);
103
+ }
104
+ if (userQueryResult.records.length > 1) {
105
+ throw messages.createError('error.ambiguousOnBehalfOf', [userIdentifier]);
49
106
  }
50
107
  const userId = userQueryResult.records[0].Id;
51
108
  this.spinner.stop();
109
+ const requestedLogLevel = flags['log-level'];
110
+ const debugLevelName = requestedLogLevel ?? DEBUG_LEVEL_NAME;
52
111
  this.spinner.start(messages.getMessage('info.checkingDebugLevel'));
53
- const debugLevelResult = await targetOrgConnection.tooling.query(`SELECT Id FROM DebugLevel WHERE DeveloperName = '${DEBUG_LEVEL_NAME}'`);
112
+ const debugLevelResult = await targetOrgConnection.tooling.query(`SELECT Id FROM DebugLevel WHERE DeveloperName = '${debugLevelName}'`);
54
113
  let debugLevelId;
55
114
  if (debugLevelResult.records.length > 0) {
56
115
  debugLevelId = debugLevelResult.records[0].Id;
57
116
  }
117
+ else if (requestedLogLevel) {
118
+ throw messages.createError('error.debugLevelNotFound', [debugLevelName]);
119
+ }
58
120
  else {
59
121
  const createResult = await targetOrgConnection.tooling.sobject('DebugLevel').create({
60
122
  DeveloperName: DEBUG_LEVEL_NAME,
@@ -72,10 +134,11 @@ export default class ApexTraceSetup extends SfCommand {
72
134
  this.spinner.stop();
73
135
  this.spinner.start(messages.getMessage('info.configuringTraceFlag'));
74
136
  const traceFlagResult = await targetOrgConnection.tooling.query(`SELECT Id FROM TraceFlag WHERE LogType = 'DEVELOPER_LOG' AND TracedEntityId = '${userId}'`);
75
- const now = new Date();
76
- const expiration = new Date(now.getTime() + TRACE_DURATION_MS);
77
- const startDate = now.toISOString();
78
- const expirationDate = expiration.toISOString();
137
+ const startDate = flags['start-date'] ?? new Date().toISOString();
138
+ const expirationDate = flags['end-date'] ?? new Date(new Date(startDate).getTime() + TRACE_DURATION_MS).toISOString();
139
+ if (new Date(expirationDate).getTime() <= new Date(startDate).getTime()) {
140
+ throw messages.createError('error.invalidDateRange', [expirationDate, startDate]);
141
+ }
79
142
  let traceFlagId;
80
143
  if (traceFlagResult.records.length > 0) {
81
144
  traceFlagId = traceFlagResult.records[0].Id;
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/trace/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAEhF,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,uBAAuB,EAAE,yBAAyB,CAAC,CAAC;AAE3F,gGAAgG;AAChG,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAChD,iGAAiG;AACjG,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAU9C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,SAA+B;IAClE,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAE5D,MAAM,CAAU,KAAK,GAAG;QAC7B,GAAG,SAAS,CAAC,SAAS;QACtB,GAAG,cAAc;KAClB,CAAC;IAEF;;;OAGG;IACI,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAEnD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAErD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,KAAK,CACrD,yCAAyC,QAAQ,GAAG,CACrD,CAAC;QAEF,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,QAAQ,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACnE,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAC9D,oDAAoD,gBAAgB,GAAG,CACxE,CAAC;QAEF,IAAI,YAAoB,CAAC;QAEzB,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,YAAY,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;gBAClF,aAAa,EAAE,gBAAgB;gBAC/B,WAAW,EAAE,gBAAgB;gBAC7B,QAAQ,EAAE,QAAQ;gBAClB,WAAW,EAAE,OAAO;aACrB,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1B,MAAM,QAAQ,CAAC,WAAW,CAAC,8BAA8B,EAAE;oBACzD,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;iBACrD,CAAC,CAAC;YACL,CAAC;YAED,YAAY,GAAG,YAAY,CAAC,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrE,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAC7D,kFAAkF,MAAM,GAAG,CAC5F,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,iBAAiB,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,cAAc,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAEhD,IAAI,WAAmB,CAAC;QAExB,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvC,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;gBAC5D,EAAE,EAAE,WAAW;gBACf,YAAY,EAAE,YAAY;gBAC1B,SAAS,EAAE,SAAS;gBACpB,cAAc,EAAE,cAAc;aAC/B,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;gBACjF,cAAc,EAAE,MAAM;gBACtB,OAAO,EAAE,eAAe;gBACxB,YAAY,EAAE,YAAY;gBAC1B,SAAS,EAAE,SAAS;gBACpB,cAAc,EAAE,cAAc;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1B,MAAM,QAAQ,CAAC,WAAW,CAAC,6BAA6B,EAAE;oBACxD,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;iBACrD,CAAC,CAAC;YACL,CAAC;YAED,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QAElE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;IAC/D,CAAC"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/trace/setup.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
2
+ * Copyright (c) 2026, Clay Chipps.
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,32 @@ SOQL WHERE clause
14
14
 
15
15
  A WHERE clause used to filter which ApexLog records are purged (e.g. "Status = 'Success'").
16
16
 
17
+ # flags.use-bulk-api.summary
18
+
19
+ Use Bulk API v2 to query and delete the logs.
20
+
21
+ # flags.use-bulk-api.description
22
+
23
+ Runs the whole purge as two Bulk API v2 jobs instead of a Tooling API query followed by chunked REST deletes. Bulk API processes the deletion asynchronously and does not consume the org's REST API request limit, which suits purges of tens of thousands of logs. For small purges the default REST path is faster, since it avoids the overhead of creating, uploading, and polling a job.
24
+
25
+ # flags.wait.summary
26
+
27
+ Number of minutes to wait for the Bulk API jobs to finish.
28
+
29
+ # flags.wait.description
30
+
31
+ Only applies with --use-bulk-api. The command polls the query and delete jobs until they complete or this timeout elapses, then throws.
32
+
17
33
  # examples
18
34
 
19
35
  - <%= config.bin %> <%= command.id %> --target-org myOrg
20
36
 
21
37
  - <%= config.bin %> <%= command.id %> --target-org myOrg --where "Status = 'Success'"
22
38
 
39
+ - <%= config.bin %> <%= command.id %> --target-org myOrg --use-bulk-api
40
+
41
+ - <%= config.bin %> <%= command.id %> --target-org myOrg --use-bulk-api --wait 60
42
+
23
43
  # info.queryingLogs
24
44
 
25
45
  Querying Apex logs...
@@ -1,18 +1,76 @@
1
1
  # summary
2
2
 
3
- Configure a debug log trace flag for the current user.
3
+ Configure a debug log trace flag for the current user, or another user.
4
4
 
5
5
  # description
6
6
 
7
- Creates or updates a 24-hour DEVELOPER_LOG trace flag for the user running the command, using a FINEST/FINER debug level suitable for the Apex Replay Debugger.
7
+ Creates or updates a DEVELOPER_LOG trace flag for the target user, using the FINEST/FINER "ReplayDebuggerLevels" debug level suitable for the Apex Replay Debugger and running for 24 hours starting now, by default. Use --on-behalf-of to configure the trace flag for a different user instead; --log-level, --start-date, and --end-date override the other defaults.
8
+
9
+ # flags.on-behalf-of.summary
10
+
11
+ Configure the trace flag for another user, identified by a "Field:Value" pair.
12
+
13
+ # flags.on-behalf-of.description
14
+
15
+ Any unique User field can be used, for example "Username:someuser@example.com" or "FederationIdentifier:123456".
16
+
17
+ # flags.log-level.summary
18
+
19
+ Developer name of an existing debug level to use for the trace flag.
20
+
21
+ # flags.log-level.description
22
+
23
+ Must already exist in the org; it's looked up but never created or modified. Defaults to the "ReplayDebuggerLevels" debug level, which is created automatically if it doesn't exist.
24
+
25
+ # flags.start-date.summary
26
+
27
+ Start date/time of the trace flag, as an ISO 8601 date-time.
28
+
29
+ # flags.start-date.description
30
+
31
+ Defaults to the current date/time.
32
+
33
+ # flags.end-date.summary
34
+
35
+ Expiration date/time of the trace flag, as an ISO 8601 date-time.
36
+
37
+ # flags.end-date.description
38
+
39
+ Defaults to 24 hours after the start date/time.
8
40
 
9
41
  # examples
10
42
 
11
43
  - <%= config.bin %> <%= command.id %> --target-org myOrg
12
44
 
45
+ - <%= config.bin %> <%= command.id %> --target-org myOrg --on-behalf-of Username:someuser@example.com
46
+
47
+ - <%= config.bin %> <%= command.id %> --target-org myOrg --on-behalf-of FederationIdentifier:123456
48
+
49
+ - <%= config.bin %> <%= command.id %> --target-org myOrg --log-level MyCustomDebugLevel --start-date 2026-08-18T09:00:00Z --end-date 2026-08-19T09:00:00Z
50
+
51
+ # error.invalidOnBehalfOf
52
+
53
+ Invalid --on-behalf-of value: %s. Expected a "Field:Value" pair, for example "Username:someuser@example.com".
54
+
13
55
  # error.userNotFound
14
56
 
15
- User not found for username: %s
57
+ User not found for %s
58
+
59
+ # error.ambiguousOnBehalfOf
60
+
61
+ Multiple users found for %s. Use a field/value pair that uniquely identifies one user.
62
+
63
+ # error.debugLevelNotFound
64
+
65
+ No debug level found with developer name: %s
66
+
67
+ # error.invalidDateTime
68
+
69
+ Invalid value for --%s: "%s". Expected an ISO 8601 date-time (e.g., 2026-08-18T14:30:00Z).
70
+
71
+ # error.invalidDateRange
72
+
73
+ --end-date (%s) must be after --start-date (%s).
16
74
 
17
75
  # error.debugLevelCreateFailed
18
76
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplysf/simply-apex",
3
3
  "description": "Utilities for working with Apex",
4
- "version": "1.1.19",
4
+ "version": "1.4.0",
5
5
  "author": "@ClayChipps",
6
6
  "homepage": "https://github.com/SimplySF/simply-node",
7
7
  "bugs": "https://github.com/SimplySF/simply-node/issues",
@@ -69,8 +69,8 @@
69
69
  "@salesforce/core": "^8.30.0",
70
70
  "@salesforce/kit": "^3.2.6",
71
71
  "@salesforce/sf-plugins-core": "^12.2.16",
72
- "@simplysf/simply-core": "^1.1.13",
73
- "@simplysf/simply-plugin-kit": "^1.0.1",
72
+ "@simplysf/simply-core": "^1.1.17",
73
+ "@simplysf/simply-plugin-kit": "^1.0.4",
74
74
  "zod": "^4.1.12"
75
75
  },
76
76
  "devDependencies": {
@@ -92,7 +92,7 @@
92
92
  "readme": "oclif readme --no-aliases",
93
93
  "test": "wireit",
94
94
  "test:coverage": "vitest run --coverage --project simply-apex",
95
- "test:nuts": "vitest run --config vitest.nuts.config.ts --project simply-apex",
95
+ "test:nuts": "vitest run --config ../../vitest.nuts.config.ts --project simply-apex",
96
96
  "test:only": "wireit",
97
97
  "test:watch": "vitest watch --project simply-apex"
98
98
  },
@@ -217,5 +217,5 @@
217
217
  "output": []
218
218
  }
219
219
  },
220
- "gitHead": "b6604fc398051fa2f92ad8223dd8e214ba9e4988"
220
+ "gitHead": "c1134ddedb7cd88cfdd28e5e9596c2d28028b2f3"
221
221
  }