@simplysf/simply-apex 1.6.9 → 1.8.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/README.md +53 -4
- package/lib/commands/simply/apex/execute.d.ts +2 -11
- package/lib/commands/simply/apex/execute.js +16 -19
- package/lib/commands/simply/apex/execute.js.map +1 -1
- package/lib/commands/simply/apex/logs/purge.d.ts +2 -14
- package/lib/commands/simply/apex/logs/purge.js +7 -81
- package/lib/commands/simply/apex/logs/purge.js.map +1 -1
- package/lib/commands/simply/apex/test-suite/generate.d.ts +20 -0
- package/lib/commands/simply/apex/test-suite/generate.js +81 -0
- package/lib/commands/simply/apex/test-suite/generate.js.map +1 -0
- package/lib/commands/simply/apex/trace/setup.d.ts +2 -13
- package/lib/commands/simply/apex/trace/setup.js +47 -87
- package/lib/commands/simply/apex/trace/setup.js.map +1 -1
- package/lib/commands/simply/apex/trace/silence.d.ts +2 -6
- package/lib/commands/simply/apex/trace/silence.js +51 -143
- package/lib/commands/simply/apex/trace/silence.js.map +1 -1
- package/messages/simply.apex.test-suite.generate.md +53 -0
- package/package.json +8 -5
- package/lib/schemas/silence/classesToSilence.d.ts +0 -7
- package/lib/schemas/silence/classesToSilence.js +0 -21
- package/lib/schemas/silence/classesToSilence.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ This package is part of the [`@simplysf/simply`](https://github.com/SimplySF/sim
|
|
|
22
22
|
|
|
23
23
|
- [`sf simply apex execute`](#sf-simply-apex-execute)
|
|
24
24
|
- [`sf simply apex logs purge`](#sf-simply-apex-logs-purge)
|
|
25
|
+
- [`sf simply apex test-suite generate`](#sf-simply-apex-test-suite-generate)
|
|
25
26
|
- [`sf simply apex trace setup`](#sf-simply-apex-trace-setup)
|
|
26
27
|
- [`sf simply apex trace silence`](#sf-simply-apex-trace-silence)
|
|
27
28
|
|
|
@@ -58,7 +59,7 @@ FLAG DESCRIPTIONS
|
|
|
58
59
|
The path to the local .apex file containing the anonymous Apex code to execute.
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
_See code: [lib/commands/simply/apex/execute.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.
|
|
62
|
+
_See code: [lib/commands/simply/apex/execute.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.6.10/packages/simply-apex/lib/commands/simply/apex/execute.js)_
|
|
62
63
|
|
|
63
64
|
## `sf simply apex logs purge`
|
|
64
65
|
|
|
@@ -114,7 +115,55 @@ FLAG DESCRIPTIONS
|
|
|
114
115
|
elapses, then throws.
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
_See code: [lib/commands/simply/apex/logs/purge.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.
|
|
118
|
+
_See code: [lib/commands/simply/apex/logs/purge.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.6.10/packages/simply-apex/lib/commands/simply/apex/logs/purge.js)_
|
|
119
|
+
|
|
120
|
+
## `sf simply apex test-suite generate`
|
|
121
|
+
|
|
122
|
+
Generate an Apex test suite from source.
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
USAGE
|
|
126
|
+
$ sf simply apex test-suite generate -d <value>... -n <value> --output-dir <value> [--json] [--flags-dir <value>]
|
|
127
|
+
|
|
128
|
+
FLAGS
|
|
129
|
+
-d, --source-dir=<value>... (required) Directories to scan for Apex classes
|
|
130
|
+
-n, --name=<value> (required) API name for the test suite
|
|
131
|
+
--output-dir=<value> (required) Output directory
|
|
132
|
+
|
|
133
|
+
GLOBAL FLAGS
|
|
134
|
+
--flags-dir=<value> Import flag values from a directory.
|
|
135
|
+
--json Format output as json.
|
|
136
|
+
|
|
137
|
+
DESCRIPTION
|
|
138
|
+
Generate an Apex test suite from source.
|
|
139
|
+
|
|
140
|
+
Scans one or more source directories for Apex classes, keeps only the ones whose first meaningful line (skipping
|
|
141
|
+
leading blank lines and comments) is an @IsTest annotation, and writes an ApexTestSuite metadata file listing them.
|
|
142
|
+
Every run regenerates the file from scratch based on the current state of --source-dir; an existing file with the same
|
|
143
|
+
name is always overwritten.
|
|
144
|
+
|
|
145
|
+
EXAMPLES
|
|
146
|
+
$ sf simply apex test-suite generate --source-dir force-app/main/default/classes --name My_Suite --output-dir force-app/main/default/testSuites
|
|
147
|
+
|
|
148
|
+
$ sf simply apex test-suite generate --source-dir force-app/main/default/classes --source-dir force-app/extra/classes --name All_Tests --output-dir force-app/main/default/testSuites
|
|
149
|
+
|
|
150
|
+
FLAG DESCRIPTIONS
|
|
151
|
+
-d, --source-dir=<value>... Directories to scan for Apex classes
|
|
152
|
+
|
|
153
|
+
One or more directories to scan, recursively, for Apex classes. Only classes whose first meaningful line is an
|
|
154
|
+
@IsTest annotation are included in the generated suite.
|
|
155
|
+
|
|
156
|
+
-n, --name=<value> API name for the test suite
|
|
157
|
+
|
|
158
|
+
The API name for the generated test suite; also used to derive the output filename, <name>.testSuite-meta.xml.
|
|
159
|
+
|
|
160
|
+
--output-dir=<value> Output directory
|
|
161
|
+
|
|
162
|
+
The directory to write the generated ApexTestSuite metadata file to. Not automatically suffixed with testSuites/ —
|
|
163
|
+
pass that directory explicitly, e.g. force-app/main/default/testSuites.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
_See code: [lib/commands/simply/apex/test-suite/generate.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.6.10/packages/simply-apex/lib/commands/simply/apex/test-suite/generate.js)_
|
|
118
167
|
|
|
119
168
|
## `sf simply apex trace setup`
|
|
120
169
|
|
|
@@ -174,7 +223,7 @@ FLAG DESCRIPTIONS
|
|
|
174
223
|
Defaults to the current date/time.
|
|
175
224
|
```
|
|
176
225
|
|
|
177
|
-
_See code: [lib/commands/simply/apex/trace/setup.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.
|
|
226
|
+
_See code: [lib/commands/simply/apex/trace/setup.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.6.10/packages/simply-apex/lib/commands/simply/apex/trace/setup.js)_
|
|
178
227
|
|
|
179
228
|
## `sf simply apex trace silence`
|
|
180
229
|
|
|
@@ -238,7 +287,7 @@ FLAG DESCRIPTIONS
|
|
|
238
287
|
Adds di_Binding, di_Module, di_PlatformCache, and di_Injector to the classes to silence.
|
|
239
288
|
```
|
|
240
289
|
|
|
241
|
-
_See code: [lib/commands/simply/apex/trace/silence.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.
|
|
290
|
+
_See code: [lib/commands/simply/apex/trace/silence.js](https://github.com/SimplySF/simply-node/blob/@simplysf/simply-apex@1.6.10/packages/simply-apex/lib/commands/simply/apex/trace/silence.js)_
|
|
242
291
|
<!-- commandsstop -->
|
|
243
292
|
|
|
244
293
|
## License
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
-
|
|
3
|
-
export type ApexExecuteResult
|
|
4
|
-
success: boolean;
|
|
5
|
-
compiled: boolean;
|
|
6
|
-
compileProblem: string;
|
|
7
|
-
exceptionMessage: string;
|
|
8
|
-
exceptionStackTrace: string;
|
|
9
|
-
line: number;
|
|
10
|
-
column: number;
|
|
11
|
-
logs?: string;
|
|
12
|
-
};
|
|
2
|
+
import { type ApexExecuteResult } from '@simplysf/simply-apex-core';
|
|
3
|
+
export type { ApexExecuteResult } from '@simplysf/simply-apex-core';
|
|
13
4
|
/**
|
|
14
5
|
* Executes an anonymous block of Apex code from a local .apex file against a target org and
|
|
15
6
|
* reports the compile and execution results, including any debug logs produced.
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import path from 'node:path';
|
|
17
|
-
import { ExecuteService } from '@salesforce/apex-node';
|
|
18
17
|
import { Messages } from '@salesforce/core';
|
|
19
18
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
19
|
+
import { ApexExecuteError, executeApex } from '@simplysf/simply-apex-core';
|
|
20
20
|
import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
|
|
21
21
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
22
22
|
const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.execute');
|
|
@@ -46,26 +46,23 @@ export default class ApexExecute extends SfCommand {
|
|
|
46
46
|
const { flags } = await this.parse(ApexExecute);
|
|
47
47
|
const targetOrgConnection = requireConnection(flags);
|
|
48
48
|
this.spinner.start(`Executing ${path.parse(flags.file).name}`);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const result = {
|
|
53
|
-
success: response.success,
|
|
54
|
-
compiled: response.compiled,
|
|
55
|
-
compileProblem: diagnostic?.compileProblem ?? '',
|
|
56
|
-
exceptionMessage: diagnostic?.exceptionMessage ?? '',
|
|
57
|
-
exceptionStackTrace: diagnostic?.exceptionStackTrace ?? '',
|
|
58
|
-
line: diagnostic?.lineNumber ?? -1,
|
|
59
|
-
column: diagnostic?.columnNumber ?? -1,
|
|
60
|
-
logs: response.logs,
|
|
61
|
-
};
|
|
62
|
-
if (!response.compiled) {
|
|
63
|
-
this.spinner.stop(messages.getMessage('info.failed'));
|
|
64
|
-
throw messages.createError('error.compileFailed', [result.line, result.column, result.compileProblem]);
|
|
49
|
+
let result;
|
|
50
|
+
try {
|
|
51
|
+
result = await executeApex(targetOrgConnection, flags.file);
|
|
65
52
|
}
|
|
66
|
-
|
|
53
|
+
catch (error) {
|
|
67
54
|
this.spinner.stop(messages.getMessage('info.failed'));
|
|
68
|
-
|
|
55
|
+
if (error instanceof ApexExecuteError) {
|
|
56
|
+
if (error.code === 'compile-failed') {
|
|
57
|
+
throw messages.createError('error.compileFailed', [
|
|
58
|
+
error.result.line,
|
|
59
|
+
error.result.column,
|
|
60
|
+
error.result.compileProblem,
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
throw messages.createError('error.executeFailed', [error.result.exceptionMessage]);
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
69
66
|
}
|
|
70
67
|
this.spinner.stop();
|
|
71
68
|
if (result.logs) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../src/commands/simply/apex/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../src/commands/simply/apex/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAA0B,MAAM,4BAA4B,CAAC;AACnG,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,qBAAqB,CAAC,CAAC;AAIvF;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,SAA4B;IAC5D,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;QACjB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;YAC1D,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF;;OAEG;IACI,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAEhD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAErD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAE/D,IAAI,MAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,WAAW,CAAC,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC;YAEtD,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;gBACtC,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;oBACpC,MAAM,QAAQ,CAAC,WAAW,CAAC,qBAAqB,EAAE;wBAChD,KAAK,CAAC,MAAM,CAAC,IAAI;wBACjB,KAAK,CAAC,MAAM,CAAC,MAAM;wBACnB,KAAK,CAAC,MAAM,CAAC,cAAc;qBAC5B,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,QAAQ,CAAC,WAAW,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACrF,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { Duration } from '@salesforce/kit';
|
|
2
2
|
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
3
|
-
|
|
4
|
-
export type ApexLogsPurgeResult
|
|
5
|
-
Id: string;
|
|
6
|
-
Success: boolean;
|
|
7
|
-
Error?: string;
|
|
8
|
-
};
|
|
3
|
+
import { type ApexLogsPurgeResult } from '@simplysf/simply-apex-core';
|
|
4
|
+
export type { ApexLogsPurgeResult } from '@simplysf/simply-apex-core';
|
|
9
5
|
/**
|
|
10
6
|
* Deletes `ApexLog` records from the target org. By default all logs are purged; use `--where`
|
|
11
7
|
* to scope the deletion to a subset of logs.
|
|
@@ -27,12 +23,4 @@ export default class ApexLogsPurge extends SfCommand<ApexLogsPurgeResult[]> {
|
|
|
27
23
|
* filter.
|
|
28
24
|
*/
|
|
29
25
|
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;
|
|
38
26
|
}
|
|
@@ -16,15 +16,10 @@
|
|
|
16
16
|
import { Messages } from '@salesforce/core';
|
|
17
17
|
import { Duration } from '@salesforce/kit';
|
|
18
18
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
19
|
+
import { deleteApexLogsViaBulkApi, deleteApexLogsViaCollections, queryApexLogIdsViaBulkApi, queryApexLogIdsViaRest, } from '@simplysf/simply-apex-core';
|
|
19
20
|
import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
|
|
20
|
-
import { chunk } from '@simplysf/simply-core';
|
|
21
21
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
22
22
|
const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.logs.purge');
|
|
23
|
-
/**
|
|
24
|
-
* Maximum number of `ApexLog` records to delete per SObject Collections call, which is the API's
|
|
25
|
-
* own ceiling and matches jsforce's `MAX_DML_COUNT`.
|
|
26
|
-
*/
|
|
27
|
-
const CHUNK_SIZE = 200;
|
|
28
23
|
/**
|
|
29
24
|
* Deletes `ApexLog` records from the target org. By default all logs are purged; use `--where`
|
|
30
25
|
* to scope the deletion to a subset of logs.
|
|
@@ -70,8 +65,8 @@ export default class ApexLogsPurge extends SfCommand {
|
|
|
70
65
|
}
|
|
71
66
|
this.spinner.start(messages.getMessage('info.queryingLogs'));
|
|
72
67
|
const logIds = useBulkApi
|
|
73
|
-
? await
|
|
74
|
-
: await
|
|
68
|
+
? await queryApexLogIdsViaBulkApi(targetOrgConnection, query, pollTimeout)
|
|
69
|
+
: await queryApexLogIdsViaRest(targetOrgConnection, query);
|
|
75
70
|
this.spinner.stop();
|
|
76
71
|
if (logIds.length === 0) {
|
|
77
72
|
this.info(messages.getMessage('info.noLogsToPurge'));
|
|
@@ -79,8 +74,10 @@ export default class ApexLogsPurge extends SfCommand {
|
|
|
79
74
|
}
|
|
80
75
|
this.spinner.start(messages.getMessage('info.purgingLogs', [logIds.length]));
|
|
81
76
|
const results = useBulkApi
|
|
82
|
-
? await
|
|
83
|
-
: await
|
|
77
|
+
? await deleteApexLogsViaBulkApi(targetOrgConnection, logIds, pollTimeout)
|
|
78
|
+
: await deleteApexLogsViaCollections(targetOrgConnection, logIds, (purged, total) => {
|
|
79
|
+
this.spinner.status = `${purged}/${total}`;
|
|
80
|
+
});
|
|
84
81
|
this.spinner.stop();
|
|
85
82
|
const successCount = results.filter((result) => result.Success).length;
|
|
86
83
|
const failureCount = results.length - successCount;
|
|
@@ -100,76 +97,5 @@ export default class ApexLogsPurge extends SfCommand {
|
|
|
100
97
|
});
|
|
101
98
|
return results;
|
|
102
99
|
}
|
|
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
|
-
];
|
|
174
100
|
}
|
|
175
101
|
//# sourceMappingURL=purge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purge.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/logs/purge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"purge.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/logs/purge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { type ApexTestSuiteGenerateResult } from '@simplysf/simply-apex-core';
|
|
3
|
+
export type { ApexTestSuiteGenerateResult } from '@simplysf/simply-apex-core';
|
|
4
|
+
/**
|
|
5
|
+
* Scans one or more source directories for Apex classes whose first meaningful line is an
|
|
6
|
+
* `@IsTest` annotation, then generates an `ApexTestSuite` metadata file listing them.
|
|
7
|
+
*/
|
|
8
|
+
export default class ApexTestSuiteGenerate extends SfCommand<ApexTestSuiteGenerateResult> {
|
|
9
|
+
static readonly summary: string;
|
|
10
|
+
static readonly description: string;
|
|
11
|
+
static readonly examples: string[];
|
|
12
|
+
static readonly flags: {
|
|
13
|
+
'source-dir': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
'output-dir': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
};
|
|
18
|
+
/** @returns The generated file's path and the test class names it lists. */
|
|
19
|
+
run(): Promise<ApexTestSuiteGenerateResult>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { Messages } from '@salesforce/core';
|
|
17
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
18
|
+
import { ApexTestSuiteError, generateApexTestSuite, } from '@simplysf/simply-apex-core';
|
|
19
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
20
|
+
const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.test-suite.generate');
|
|
21
|
+
/** Maps `ApexTestSuiteError`'s structural codes to this command's own `Messages` catalog. */
|
|
22
|
+
function toCliError(error) {
|
|
23
|
+
switch (error.code) {
|
|
24
|
+
case 'no-test-classes-found':
|
|
25
|
+
return messages.createError('error.noTestClassesFound');
|
|
26
|
+
case 'scan-failed':
|
|
27
|
+
return messages.createError('error.scanFailed', [error.message]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Scans one or more source directories for Apex classes whose first meaningful line is an
|
|
32
|
+
* `@IsTest` annotation, then generates an `ApexTestSuite` metadata file listing them.
|
|
33
|
+
*/
|
|
34
|
+
export default class ApexTestSuiteGenerate extends SfCommand {
|
|
35
|
+
static summary = messages.getMessage('summary');
|
|
36
|
+
static description = messages.getMessage('description');
|
|
37
|
+
static examples = messages.getMessages('examples');
|
|
38
|
+
static flags = {
|
|
39
|
+
...SfCommand.baseFlags,
|
|
40
|
+
'source-dir': Flags.directory({
|
|
41
|
+
summary: messages.getMessage('flags.source-dir.summary'),
|
|
42
|
+
description: messages.getMessage('flags.source-dir.description'),
|
|
43
|
+
char: 'd',
|
|
44
|
+
exists: true,
|
|
45
|
+
multiple: true,
|
|
46
|
+
required: true,
|
|
47
|
+
}),
|
|
48
|
+
name: Flags.string({
|
|
49
|
+
summary: messages.getMessage('flags.name.summary'),
|
|
50
|
+
description: messages.getMessage('flags.name.description'),
|
|
51
|
+
char: 'n',
|
|
52
|
+
required: true,
|
|
53
|
+
}),
|
|
54
|
+
'output-dir': Flags.directory({
|
|
55
|
+
summary: messages.getMessage('flags.output-dir.summary'),
|
|
56
|
+
description: messages.getMessage('flags.output-dir.description'),
|
|
57
|
+
required: true,
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
/** @returns The generated file's path and the test class names it lists. */
|
|
61
|
+
async run() {
|
|
62
|
+
const { flags } = await this.parse(ApexTestSuiteGenerate);
|
|
63
|
+
this.spinner.start(messages.getMessage('info.scanning'));
|
|
64
|
+
let result;
|
|
65
|
+
try {
|
|
66
|
+
result = await generateApexTestSuite(flags['source-dir'], flags['output-dir'], flags.name);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.spinner.stop();
|
|
70
|
+
throw error instanceof ApexTestSuiteError ? toCliError(error) : error;
|
|
71
|
+
}
|
|
72
|
+
this.spinner.stop();
|
|
73
|
+
this.info(messages.getMessage('info.fileGenerated', [result.filePath]));
|
|
74
|
+
this.table({
|
|
75
|
+
data: result.testClassNames.map((className) => ({ class: className })),
|
|
76
|
+
columns: [{ key: 'class', name: 'CLASS' }],
|
|
77
|
+
});
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/test-suite/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GAEtB,MAAM,4BAA4B,CAAC;AAEpC,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,uBAAuB,EAAE,iCAAiC,CAAC,CAAC;AAInG,6FAA6F;AAC7F,SAAS,UAAU,CAAC,KAAyB;IAC3C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,uBAAuB;YAC1B,OAAO,QAAQ,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;QAC1D,KAAK,aAAa;YAChB,OAAO,QAAQ,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,SAAsC;IAChF,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,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,0BAA0B,CAAC;YACxD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,8BAA8B,CAAC;YAChE,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;YAC1D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,0BAA0B,CAAC;YACxD,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,8BAA8B,CAAC;YAChE,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF,4EAA4E;IACrE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;QAEzD,IAAI,MAAmC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,KAAK,YAAY,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACxE,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAEpB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAExE,IAAI,CAAC,KAAK,CAAC;YACT,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACtE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC"}
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
-
|
|
3
|
-
type
|
|
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. */
|
|
8
|
-
export type ApexTraceSetupResult = {
|
|
9
|
-
userId: string;
|
|
10
|
-
debugLevelId: string;
|
|
11
|
-
traceFlagId: string;
|
|
12
|
-
expirationDate: string;
|
|
13
|
-
};
|
|
2
|
+
import { type ApexTraceSetupResult, type OnBehalfOf } from '@simplysf/simply-apex-core';
|
|
3
|
+
export type { ApexTraceSetupResult } from '@simplysf/simply-apex-core';
|
|
14
4
|
/**
|
|
15
5
|
* Creates or updates a DEVELOPER_LOG trace flag for the target user. The target user is the one
|
|
16
6
|
* running the command by default, or the user identified by `--on-behalf-of` if provided. By
|
|
@@ -37,4 +27,3 @@ export default class ApexTraceSetup extends SfCommand<ApexTraceSetupResult> {
|
|
|
37
27
|
*/
|
|
38
28
|
run(): Promise<ApexTraceSetupResult>;
|
|
39
29
|
}
|
|
40
|
-
export {};
|
|
@@ -15,21 +15,27 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { Messages } from '@salesforce/core';
|
|
17
17
|
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
18
|
+
import { ApexTraceSetupError, DATE_TIME_PATTERN, parseOnBehalfOf, setupApexTrace, } from '@simplysf/simply-apex-core';
|
|
18
19
|
import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
|
|
19
|
-
import { escapeSoqlLiteral } from '@simplysf/simply-core';
|
|
20
20
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
21
21
|
const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.trace.setup');
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
/** Maps `ApexTraceSetupError`'s structural codes to this command's own `Messages` catalog. */
|
|
23
|
+
function toCliError(error) {
|
|
24
|
+
switch (error.code) {
|
|
25
|
+
case 'user-not-found':
|
|
26
|
+
return messages.createError('error.userNotFound', error.args);
|
|
27
|
+
case 'ambiguous-on-behalf-of':
|
|
28
|
+
return messages.createError('error.ambiguousOnBehalfOf', error.args);
|
|
29
|
+
case 'debug-level-not-found':
|
|
30
|
+
return messages.createError('error.debugLevelNotFound', error.args);
|
|
31
|
+
case 'debug-level-create-failed':
|
|
32
|
+
return messages.createError('error.debugLevelCreateFailed', error.args);
|
|
33
|
+
case 'trace-flag-create-failed':
|
|
34
|
+
return messages.createError('error.traceFlagCreateFailed', error.args);
|
|
35
|
+
case 'invalid-date-range':
|
|
36
|
+
return messages.createError('error.invalidDateRange', error.args);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
33
39
|
/**
|
|
34
40
|
* Creates or updates a DEVELOPER_LOG trace flag for the target user. The target user is the one
|
|
35
41
|
* running the command by default, or the user identified by `--on-behalf-of` if provided. By
|
|
@@ -47,12 +53,11 @@ export default class ApexTraceSetup extends SfCommand {
|
|
|
47
53
|
'on-behalf-of': Flags.custom({
|
|
48
54
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
49
55
|
parse: async (input) => {
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
56
|
+
const onBehalfOf = parseOnBehalfOf(input);
|
|
57
|
+
if (!onBehalfOf) {
|
|
52
58
|
throw messages.createError('error.invalidOnBehalfOf', [input]);
|
|
53
59
|
}
|
|
54
|
-
|
|
55
|
-
return { field, value };
|
|
60
|
+
return onBehalfOf;
|
|
56
61
|
},
|
|
57
62
|
})({
|
|
58
63
|
summary: messages.getMessage('flags.on-behalf-of.summary'),
|
|
@@ -92,81 +97,36 @@ export default class ApexTraceSetup extends SfCommand {
|
|
|
92
97
|
async run() {
|
|
93
98
|
const { flags } = await this.parse(ApexTraceSetup);
|
|
94
99
|
const targetOrgConnection = requireConnection(flags);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
else if (requestedLogLevel) {
|
|
118
|
-
throw messages.createError('error.debugLevelNotFound', [debugLevelName]);
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
const createResult = await targetOrgConnection.tooling.sobject('DebugLevel').create({
|
|
122
|
-
DeveloperName: DEBUG_LEVEL_NAME,
|
|
123
|
-
MasterLabel: DEBUG_LEVEL_NAME,
|
|
124
|
-
ApexCode: 'FINEST',
|
|
125
|
-
Visualforce: 'FINER',
|
|
126
|
-
});
|
|
127
|
-
if (!createResult.success) {
|
|
128
|
-
throw messages.createError('error.debugLevelCreateFailed', [
|
|
129
|
-
createResult.errors.map((e) => e.message).join(', '),
|
|
130
|
-
]);
|
|
131
|
-
}
|
|
132
|
-
debugLevelId = createResult.id;
|
|
133
|
-
}
|
|
134
|
-
this.spinner.stop();
|
|
135
|
-
this.spinner.start(messages.getMessage('info.configuringTraceFlag'));
|
|
136
|
-
const traceFlagResult = await targetOrgConnection.tooling.query(`SELECT Id FROM TraceFlag WHERE LogType = 'DEVELOPER_LOG' AND TracedEntityId = '${userId}'`);
|
|
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
|
-
}
|
|
142
|
-
let traceFlagId;
|
|
143
|
-
if (traceFlagResult.records.length > 0) {
|
|
144
|
-
traceFlagId = traceFlagResult.records[0].Id;
|
|
145
|
-
await targetOrgConnection.tooling.sobject('TraceFlag').update({
|
|
146
|
-
Id: traceFlagId,
|
|
147
|
-
DebugLevelId: debugLevelId,
|
|
148
|
-
StartDate: startDate,
|
|
149
|
-
ExpirationDate: expirationDate,
|
|
100
|
+
let result;
|
|
101
|
+
try {
|
|
102
|
+
result = await setupApexTrace(targetOrgConnection, {
|
|
103
|
+
onBehalfOf: flags['on-behalf-of'],
|
|
104
|
+
logLevel: flags['log-level'],
|
|
105
|
+
startDate: flags['start-date'],
|
|
106
|
+
endDate: flags['end-date'],
|
|
107
|
+
}, (phase) => {
|
|
108
|
+
switch (phase) {
|
|
109
|
+
case 'finding-user':
|
|
110
|
+
this.spinner.start(messages.getMessage('info.findingUser'));
|
|
111
|
+
break;
|
|
112
|
+
case 'checking-debug-level':
|
|
113
|
+
this.spinner.stop();
|
|
114
|
+
this.spinner.start(messages.getMessage('info.checkingDebugLevel'));
|
|
115
|
+
break;
|
|
116
|
+
case 'configuring-trace-flag':
|
|
117
|
+
this.spinner.stop();
|
|
118
|
+
this.spinner.start(messages.getMessage('info.configuringTraceFlag'));
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
150
121
|
});
|
|
151
122
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
LogType: 'DEVELOPER_LOG',
|
|
156
|
-
DebugLevelId: debugLevelId,
|
|
157
|
-
StartDate: startDate,
|
|
158
|
-
ExpirationDate: expirationDate,
|
|
159
|
-
});
|
|
160
|
-
if (!createResult.success) {
|
|
161
|
-
throw messages.createError('error.traceFlagCreateFailed', [
|
|
162
|
-
createResult.errors.map((e) => e.message).join(', '),
|
|
163
|
-
]);
|
|
164
|
-
}
|
|
165
|
-
traceFlagId = createResult.id;
|
|
123
|
+
catch (error) {
|
|
124
|
+
this.spinner.stop();
|
|
125
|
+
throw error instanceof ApexTraceSetupError ? toCliError(error) : error;
|
|
166
126
|
}
|
|
167
127
|
this.spinner.stop();
|
|
168
|
-
this.info(messages.getMessage('info.complete', [expirationDate]));
|
|
169
|
-
return
|
|
128
|
+
this.info(messages.getMessage('info.complete', [result.expirationDate]));
|
|
129
|
+
return result;
|
|
170
130
|
}
|
|
171
131
|
}
|
|
172
132
|
//# sourceMappingURL=setup.js.map
|
|
@@ -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,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/trace/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
-
|
|
3
|
-
export type ApexTraceSilenceResult
|
|
4
|
-
class: string;
|
|
5
|
-
classId: string;
|
|
6
|
-
traceFlagId: string;
|
|
7
|
-
};
|
|
2
|
+
import { type ApexTraceSilenceResult } from '@simplysf/simply-apex-core';
|
|
3
|
+
export type { ApexTraceSilenceResult } from '@simplysf/simply-apex-core';
|
|
8
4
|
/**
|
|
9
5
|
* Creates or updates a 24-hour CLASS_TRACING trace flag with a fully suppressed (NONE) debug
|
|
10
6
|
* level for each specified Apex class, preventing those classes from generating debug log
|
|
@@ -15,59 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { Messages } from '@salesforce/core';
|
|
17
17
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
18
|
+
import { ApexTraceSilenceError, resolveClasses, silenceApexClasses, } from '@simplysf/simply-apex-core';
|
|
18
19
|
import { requireConnection, targetOrgFlags } from '@simplysf/simply-plugin-kit';
|
|
19
|
-
import { loadJsonConfigSync } from '@simplysf/simply-core';
|
|
20
|
-
import { ClassesToSilenceSchema } from '../../../../schemas/silence/classesToSilence.js';
|
|
21
20
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
22
21
|
const messages = Messages.loadMessages('@simplysf/simply-apex', 'simply.apex.trace.silence');
|
|
23
|
-
/** DeveloperName used for the fully-suppressed (NONE) debug level created for class silencing. */
|
|
24
|
-
const DEBUG_LEVEL_NAME = 'Silence';
|
|
25
|
-
/** How long a configured trace flag stays active before expiring, in milliseconds (24 hours). */
|
|
26
|
-
const TRACE_DURATION_MS = 24 * 60 * 60 * 1000;
|
|
27
|
-
/** Classes silenced by the `--fflib` flag. */
|
|
28
|
-
const FFLIB_CLASSES = ['fflib_SObjectDescribe', 'fflib_SObjectDomain'];
|
|
29
|
-
/** Classes silenced by the `--at4dx` flag. */
|
|
30
|
-
const AT4DX_CLASSES = ['ApplicationSObjectDomain'];
|
|
31
|
-
/** Classes silenced by the `--force-di` flag. */
|
|
32
|
-
const FORCE_DI_CLASSES = ['di_Binding', 'di_Module', 'di_PlatformCache', 'di_Injector'];
|
|
33
|
-
/**
|
|
34
|
-
* Resolve the list of Apex class names to silence from the `--classes` flag (a comma-separated
|
|
35
|
-
* list), the `--classes-file` flag (a JSON config file matching {@link ClassesToSilenceSchema}),
|
|
36
|
-
* and the `--fflib`, `--at4dx`, and `--force-di` preset flags. All sources are combined and
|
|
37
|
-
* deduplicated.
|
|
38
|
-
*
|
|
39
|
-
* @param classesFlag - The raw `--classes` flag value, if provided.
|
|
40
|
-
* @param classesFileFlag - The raw `--classes-file` flag value, if provided.
|
|
41
|
-
* @param presetFlags - Which of the built-in class presets were requested.
|
|
42
|
-
* @returns The resolved, trimmed, deduplicated list of Apex class names.
|
|
43
|
-
* @throws {SfError} If `--classes-file` was provided but fails schema validation.
|
|
44
|
-
*/
|
|
45
|
-
function resolveClasses(classesFlag, classesFileFlag, presetFlags) {
|
|
46
|
-
const classes = [];
|
|
47
|
-
if (classesFlag) {
|
|
48
|
-
classes.push(...classesFlag
|
|
49
|
-
.split(',')
|
|
50
|
-
.map((className) => className.trim())
|
|
51
|
-
.filter(Boolean));
|
|
52
|
-
}
|
|
53
|
-
if (classesFileFlag) {
|
|
54
|
-
const parsed = loadJsonConfigSync(classesFileFlag, ClassesToSilenceSchema);
|
|
55
|
-
if (!parsed.success) {
|
|
56
|
-
throw messages.createError('error.invalidClassesFile', [parsed.message]);
|
|
57
|
-
}
|
|
58
|
-
classes.push(...parsed.data.classes);
|
|
59
|
-
}
|
|
60
|
-
if (presetFlags.fflib) {
|
|
61
|
-
classes.push(...FFLIB_CLASSES);
|
|
62
|
-
}
|
|
63
|
-
if (presetFlags.at4dx) {
|
|
64
|
-
classes.push(...AT4DX_CLASSES);
|
|
65
|
-
}
|
|
66
|
-
if (presetFlags.forceDi) {
|
|
67
|
-
classes.push(...FORCE_DI_CLASSES);
|
|
68
|
-
}
|
|
69
|
-
return [...new Set(classes)];
|
|
70
|
-
}
|
|
71
22
|
/**
|
|
72
23
|
* Creates or updates a 24-hour CLASS_TRACING trace flag with a fully suppressed (NONE) debug
|
|
73
24
|
* level for each specified Apex class, preventing those classes from generating debug log
|
|
@@ -117,118 +68,75 @@ export default class ApexTraceSilence extends SfCommand {
|
|
|
117
68
|
async run() {
|
|
118
69
|
const { flags } = await this.parse(ApexTraceSilence);
|
|
119
70
|
const targetOrgConnection = requireConnection(flags);
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
71
|
+
const classNames = flags.classes
|
|
72
|
+
? flags.classes
|
|
73
|
+
.split(',')
|
|
74
|
+
.map((className) => className.trim())
|
|
75
|
+
.filter(Boolean)
|
|
76
|
+
: [];
|
|
77
|
+
let classes;
|
|
78
|
+
try {
|
|
79
|
+
classes = resolveClasses(classNames, flags['classes-file'], {
|
|
80
|
+
fflib: flags.fflib,
|
|
81
|
+
at4dx: flags.at4dx,
|
|
82
|
+
forceDi: flags['force-di'],
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error instanceof ApexTraceSilenceError && error.code === 'invalid-classes-file') {
|
|
87
|
+
throw messages.createError('error.invalidClassesFile', [error.message]);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
125
91
|
if (classes.length === 0) {
|
|
126
92
|
throw messages.createError('error.noClassesSpecified');
|
|
127
93
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
Visualforce: 'NONE',
|
|
145
|
-
Workflow: 'NONE',
|
|
94
|
+
let outcome;
|
|
95
|
+
try {
|
|
96
|
+
outcome = await silenceApexClasses(targetOrgConnection, classes, (phase) => {
|
|
97
|
+
switch (phase) {
|
|
98
|
+
case 'checking-debug-level':
|
|
99
|
+
this.spinner.start(messages.getMessage('info.checkingDebugLevel'));
|
|
100
|
+
break;
|
|
101
|
+
case 'finding-classes':
|
|
102
|
+
this.spinner.stop();
|
|
103
|
+
this.spinner.start(messages.getMessage('info.findingClasses'));
|
|
104
|
+
break;
|
|
105
|
+
case 'creating-trace-flags':
|
|
106
|
+
this.spinner.stop();
|
|
107
|
+
this.spinner.start(messages.getMessage('info.creatingTraceFlags'));
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
146
110
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
this.spinner.stop();
|
|
114
|
+
if (error instanceof ApexTraceSilenceError && error.code === 'debug-level-create-failed') {
|
|
115
|
+
throw messages.createError('error.debugLevelCreateFailed', [error.message]);
|
|
151
116
|
}
|
|
152
|
-
|
|
117
|
+
throw error;
|
|
153
118
|
}
|
|
154
119
|
this.spinner.stop();
|
|
155
|
-
|
|
156
|
-
const classesClause = classes.map((className) => `'${className}'`).join(',');
|
|
157
|
-
const classResult = await targetOrgConnection.tooling.query(`SELECT Id, Name FROM ApexClass WHERE Name IN (${classesClause})`);
|
|
158
|
-
this.spinner.stop();
|
|
159
|
-
if (classResult.records.length === 0) {
|
|
120
|
+
if (outcome.results.length === 0 && outcome.missingClassNames.length === classes.length) {
|
|
160
121
|
this.warn(messages.getMessage('warning.noClassesFound'));
|
|
161
122
|
return [];
|
|
162
123
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (missingNames.length > 0) {
|
|
166
|
-
this.warn(messages.getMessage('warning.someClassesNotFound', [missingNames.join(', ')]));
|
|
124
|
+
if (outcome.missingClassNames.length > 0) {
|
|
125
|
+
this.warn(messages.getMessage('warning.someClassesNotFound', [outcome.missingClassNames.join(', ')]));
|
|
167
126
|
}
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const expirationDate = expiration.toISOString();
|
|
172
|
-
const classIdsClause = classResult.records.map((record) => `'${record.Id}'`).join(',');
|
|
173
|
-
const existingTraceFlagResult = await targetOrgConnection.tooling.query(`SELECT Id, TracedEntityId FROM TraceFlag WHERE LogType = 'CLASS_TRACING' AND TracedEntityId IN (${classIdsClause})`);
|
|
174
|
-
const existingTraceFlagIdByClassId = new Map(existingTraceFlagResult.records.map((record) => [record.TracedEntityId, record.Id]));
|
|
175
|
-
const results = [];
|
|
176
|
-
this.spinner.start(messages.getMessage('info.creatingTraceFlags'));
|
|
177
|
-
for (const classRecord of classResult.records) {
|
|
178
|
-
const existingTraceFlagId = existingTraceFlagIdByClassId.get(classRecord.Id);
|
|
179
|
-
if (existingTraceFlagId) {
|
|
180
|
-
// eslint-disable-next-line no-await-in-loop
|
|
181
|
-
const updateResult = await targetOrgConnection.tooling.sobject('TraceFlag').update({
|
|
182
|
-
Id: existingTraceFlagId,
|
|
183
|
-
DebugLevelId: debugLevelId,
|
|
184
|
-
StartDate: startDate,
|
|
185
|
-
ExpirationDate: expirationDate,
|
|
186
|
-
});
|
|
187
|
-
if (!updateResult.success) {
|
|
188
|
-
this.warn(messages.getMessage('warning.traceFlagUpdateFailed', [
|
|
189
|
-
classRecord.Name,
|
|
190
|
-
updateResult.errors.map((e) => e.message).join(', '),
|
|
191
|
-
]));
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
results.push({
|
|
195
|
-
class: classRecord.Name,
|
|
196
|
-
classId: classRecord.Id,
|
|
197
|
-
traceFlagId: existingTraceFlagId,
|
|
198
|
-
});
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
// eslint-disable-next-line no-await-in-loop
|
|
202
|
-
const createResult = await targetOrgConnection.tooling.sobject('TraceFlag').create({
|
|
203
|
-
StartDate: startDate,
|
|
204
|
-
ExpirationDate: expirationDate,
|
|
205
|
-
DebugLevelId: debugLevelId,
|
|
206
|
-
TracedEntityId: classRecord.Id,
|
|
207
|
-
LogType: 'CLASS_TRACING',
|
|
208
|
-
});
|
|
209
|
-
if (!createResult.success) {
|
|
210
|
-
this.warn(messages.getMessage('warning.traceFlagCreateFailed', [
|
|
211
|
-
classRecord.Name,
|
|
212
|
-
createResult.errors.map((e) => e.message).join(', '),
|
|
213
|
-
]));
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
results.push({
|
|
217
|
-
class: classRecord.Name,
|
|
218
|
-
classId: classRecord.Id,
|
|
219
|
-
traceFlagId: createResult.id,
|
|
220
|
-
});
|
|
127
|
+
for (const failure of outcome.failures) {
|
|
128
|
+
const key = failure.action === 'update' ? 'warning.traceFlagUpdateFailed' : 'warning.traceFlagCreateFailed';
|
|
129
|
+
this.warn(messages.getMessage(key, [failure.class, failure.error]));
|
|
221
130
|
}
|
|
222
|
-
this.spinner.stop();
|
|
223
131
|
this.table({
|
|
224
|
-
data: results,
|
|
132
|
+
data: outcome.results,
|
|
225
133
|
columns: [
|
|
226
134
|
{ key: 'class', name: 'CLASS' },
|
|
227
135
|
{ key: 'classId', name: 'CLASS ID' },
|
|
228
136
|
{ key: 'traceFlagId', name: 'TRACE FLAG ID' },
|
|
229
137
|
],
|
|
230
138
|
});
|
|
231
|
-
return results;
|
|
139
|
+
return outcome.results;
|
|
232
140
|
}
|
|
233
141
|
}
|
|
234
142
|
//# sourceMappingURL=silence.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"silence.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/trace/silence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"silence.js","sourceRoot":"","sources":["../../../../../src/commands/simply/apex/trace/silence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Generate an Apex test suite from source.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Scans one or more source directories for Apex classes, keeps only the ones whose first meaningful line (skipping leading blank lines and comments) is an @IsTest annotation, and writes an ApexTestSuite metadata file listing them. Every run regenerates the file from scratch based on the current state of --source-dir; an existing file with the same name is always overwritten.
|
|
8
|
+
|
|
9
|
+
# flags.source-dir.summary
|
|
10
|
+
|
|
11
|
+
Directories to scan for Apex classes
|
|
12
|
+
|
|
13
|
+
# flags.source-dir.description
|
|
14
|
+
|
|
15
|
+
One or more directories to scan, recursively, for Apex classes. Only classes whose first meaningful line is an @IsTest annotation are included in the generated suite.
|
|
16
|
+
|
|
17
|
+
# flags.name.summary
|
|
18
|
+
|
|
19
|
+
API name for the test suite
|
|
20
|
+
|
|
21
|
+
# flags.name.description
|
|
22
|
+
|
|
23
|
+
The API name for the generated test suite; also used to derive the output filename, <name>.testSuite-meta.xml.
|
|
24
|
+
|
|
25
|
+
# flags.output-dir.summary
|
|
26
|
+
|
|
27
|
+
Output directory
|
|
28
|
+
|
|
29
|
+
# flags.output-dir.description
|
|
30
|
+
|
|
31
|
+
The directory to write the generated ApexTestSuite metadata file to. Not automatically suffixed with testSuites/ — pass that directory explicitly, e.g. force-app/main/default/testSuites.
|
|
32
|
+
|
|
33
|
+
# examples
|
|
34
|
+
|
|
35
|
+
- <%= config.bin %> <%= command.id %> --source-dir force-app/main/default/classes --name My_Suite --output-dir force-app/main/default/testSuites
|
|
36
|
+
|
|
37
|
+
- <%= config.bin %> <%= command.id %> --source-dir force-app/main/default/classes --source-dir force-app/extra/classes --name All_Tests --output-dir force-app/main/default/testSuites
|
|
38
|
+
|
|
39
|
+
# error.noTestClassesFound
|
|
40
|
+
|
|
41
|
+
No @IsTest-annotated classes were found in the given source director(y/ies).
|
|
42
|
+
|
|
43
|
+
# error.scanFailed
|
|
44
|
+
|
|
45
|
+
Failed to scan the given source director(y/ies): %s
|
|
46
|
+
|
|
47
|
+
# info.scanning
|
|
48
|
+
|
|
49
|
+
Scanning for @IsTest-annotated classes...
|
|
50
|
+
|
|
51
|
+
# info.fileGenerated
|
|
52
|
+
|
|
53
|
+
Test suite successfully generated at %s
|
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.
|
|
4
|
+
"version": "1.8.0",
|
|
5
5
|
"author": "@ClayChipps",
|
|
6
6
|
"homepage": "https://github.com/SimplySF/simply-node",
|
|
7
7
|
"bugs": "https://github.com/SimplySF/simply-node/issues",
|
|
@@ -55,6 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"trace": {
|
|
57
57
|
"description": "Commands for working with Apex trace flags"
|
|
58
|
+
},
|
|
59
|
+
"test-suite": {
|
|
60
|
+
"description": "Commands for working with Apex test suites"
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -65,16 +68,16 @@
|
|
|
65
68
|
},
|
|
66
69
|
"dependencies": {
|
|
67
70
|
"@oclif/core": "^4.11.2",
|
|
68
|
-
"@salesforce/apex-node": "^8.4.39",
|
|
69
71
|
"@salesforce/core": "^8.30.0",
|
|
70
72
|
"@salesforce/kit": "^3.2.6",
|
|
71
73
|
"@salesforce/sf-plugins-core": "^12.2.16",
|
|
74
|
+
"@simplysf/simply-apex-core": "^0.3.0",
|
|
72
75
|
"@simplysf/simply-core": "^1.5.1",
|
|
73
|
-
"@simplysf/simply-plugin-kit": "^1.0.4"
|
|
74
|
-
"zod": "^4.1.12"
|
|
76
|
+
"@simplysf/simply-plugin-kit": "^1.0.4"
|
|
75
77
|
},
|
|
76
78
|
"devDependencies": {
|
|
77
79
|
"@oclif/plugin-command-snapshot": "^5.4.0",
|
|
80
|
+
"@salesforce/apex-node": "^8.4.39",
|
|
78
81
|
"@salesforce/plugin-command-reference": "^3.1.99",
|
|
79
82
|
"@vitest/coverage-v8": "^4.1.10",
|
|
80
83
|
"vitest": "^4.1.10"
|
|
@@ -206,5 +209,5 @@
|
|
|
206
209
|
"output": []
|
|
207
210
|
}
|
|
208
211
|
},
|
|
209
|
-
"gitHead": "
|
|
212
|
+
"gitHead": "2c9a1ffbe2031e3093b8c16150c596cf1394d796"
|
|
210
213
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
/** Schema for the JSON config file that lists which Apex classes to silence debug logs for. */
|
|
3
|
-
export declare const ClassesToSilenceSchema: z.ZodObject<{
|
|
4
|
-
classes: z.ZodArray<z.ZodString>;
|
|
5
|
-
}, z.core.$strip>;
|
|
6
|
-
/** A parsed classes-to-silence config file: a non-empty list of Apex class names. */
|
|
7
|
-
export type ClassesToSilence = z.infer<typeof ClassesToSilenceSchema>;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2026, Clay Chipps.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
/** Schema for the JSON config file that lists which Apex classes to silence debug logs for. */
|
|
18
|
-
export const ClassesToSilenceSchema = z.object({
|
|
19
|
-
classes: z.array(z.string()).min(1),
|
|
20
|
-
});
|
|
21
|
-
//# sourceMappingURL=classesToSilence.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"classesToSilence.js","sourceRoot":"","sources":["../../../src/schemas/silence/classesToSilence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,+FAA+F;AAC/F,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACpC,CAAC,CAAC"}
|