@salesforce/source-testkit 0.0.18 → 1.0.2
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/CHANGELOG.md +14 -0
- package/lib/assertions.js +44 -44
- package/lib/executionLog.js +1 -1
- package/lib/fileTracker.js +11 -8
- package/lib/testkit.d.ts +1 -1
- package/lib/testkit.js +43 -38
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.0.2](https://github.com/salesforcecli/source-testkit/compare/v1.0.1...v1.0.2) (2022-06-06)
|
|
6
|
+
|
|
7
|
+
### [1.0.1](https://github.com/salesforcecli/source-testkit/compare/v1.0.0...v1.0.1) (2022-05-31)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- support multiple plugin-config versions ([#78](https://github.com/salesforcecli/source-testkit/issues/78)) ([365831f](https://github.com/salesforcecli/source-testkit/commit/365831f5de5f489d2f2065230e8847de1ecf4f0b))
|
|
12
|
+
|
|
13
|
+
## [1.0.0](https://github.com/salesforcecli/source-testkit/compare/v0.0.18...v1.0.0) (2022-05-31)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- use parking-orbit newer core/sdr ([#77](https://github.com/salesforcecli/source-testkit/issues/77)) ([d9ed642](https://github.com/salesforcecli/source-testkit/commit/d9ed642003bb85407a7b17ffa7b64764eb81b488))
|
|
18
|
+
|
|
5
19
|
### [0.0.18](https://github.com/salesforcecli/source-testkit/compare/v0.0.17...v0.0.18) (2022-03-08)
|
|
6
20
|
|
|
7
21
|
### Features
|
package/lib/assertions.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Assertions = void 0;
|
|
2
4
|
/*
|
|
3
5
|
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* Licensed under the BSD 3-Clause license.
|
|
6
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
|
|
9
|
-
exports.Assertions = void 0;
|
|
10
|
+
const fs = require("fs");
|
|
10
11
|
const path = require("path");
|
|
11
12
|
const chai_1 = require("chai");
|
|
12
13
|
const chaiEach = require("chai-each");
|
|
13
14
|
const fg = require("fast-glob");
|
|
14
|
-
const core_1 = require("@salesforce/core");
|
|
15
15
|
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
16
16
|
const debug_1 = require("debug");
|
|
17
17
|
const fileTracker_1 = require("./fileTracker");
|
|
18
|
-
chai_1.use(chaiEach);
|
|
18
|
+
(0, chai_1.use)(chaiEach);
|
|
19
19
|
/**
|
|
20
20
|
* Assertions is a class that is designed to encapsulate common assertions we want to
|
|
21
21
|
* make during NUT testings
|
|
@@ -31,7 +31,7 @@ class Assertions {
|
|
|
31
31
|
this.projectDir = context.projectDir;
|
|
32
32
|
this.connection = context.connection;
|
|
33
33
|
this.commands = context.commands;
|
|
34
|
-
this.debug = debug_1.debug(`assertions:${context.nut}`);
|
|
34
|
+
this.debug = (0, debug_1.debug)(`assertions:${context.nut}`);
|
|
35
35
|
this.metadataResolver = new source_deploy_retrieve_1.MetadataResolver();
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
@@ -39,14 +39,14 @@ class Assertions {
|
|
|
39
39
|
*/
|
|
40
40
|
fileToBeChanged(file) {
|
|
41
41
|
const fileHistory = this.fileTracker.getLatest(file);
|
|
42
|
-
chai_1.expect(fileHistory === null || fileHistory === void 0 ? void 0 : fileHistory.changedFromPrevious, 'File to be changed').to.be.true;
|
|
42
|
+
(0, chai_1.expect)(fileHistory === null || fileHistory === void 0 ? void 0 : fileHistory.changedFromPrevious, 'File to be changed').to.be.true;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* Expect given file to NOT be changed according to the file history provided by FileTracker
|
|
46
46
|
*/
|
|
47
47
|
fileToNotBeChanged(file) {
|
|
48
48
|
const fileHistory = this.fileTracker.getLatest(file);
|
|
49
|
-
chai_1.expect(fileHistory === null || fileHistory === void 0 ? void 0 : fileHistory.changedFromPrevious, 'File to NOT be changed').to.be.false;
|
|
49
|
+
(0, chai_1.expect)(fileHistory === null || fileHistory === void 0 ? void 0 : fileHistory.changedFromPrevious, 'File to NOT be changed').to.be.false;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Expect all files found by globs to be changed according to the file history provided by FileTracker
|
|
@@ -62,9 +62,9 @@ class Assertions {
|
|
|
62
62
|
.filter((f) => !f.endsWith('.resource'))
|
|
63
63
|
.map((f) => this.fileTracker.getLatest(path.normalize(f)))
|
|
64
64
|
.filter((f) => !!f);
|
|
65
|
-
chai_1.expect(fileHistories, 'file history to exist for tracked files').length.to.be.greaterThan(0);
|
|
65
|
+
(0, chai_1.expect)(fileHistories, 'file history to exist for tracked files').length.to.be.greaterThan(0);
|
|
66
66
|
const allChanged = fileHistories.every((f) => f === null || f === void 0 ? void 0 : f.changedFromPrevious);
|
|
67
|
-
chai_1.expect(allChanged, 'all files to be changed').to.be.true;
|
|
67
|
+
(0, chai_1.expect)(allChanged, 'all files to be changed').to.be.true;
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Expect all files found by globs to NOT be changed according to the file history provided by FileTracker
|
|
@@ -77,9 +77,9 @@ class Assertions {
|
|
|
77
77
|
.filter((f) => !f.endsWith('.resource-meta.xml'))
|
|
78
78
|
.map((f) => this.fileTracker.getLatest(f))
|
|
79
79
|
.filter((f) => !!f);
|
|
80
|
-
chai_1.expect(fileHistories, 'file history to exist for tracked files').length.to.be.greaterThan(0);
|
|
80
|
+
(0, chai_1.expect)(fileHistories, 'file history to exist for tracked files').length.to.be.greaterThan(0);
|
|
81
81
|
const allChanged = fileHistories.every((f) => f === null || f === void 0 ? void 0 : f.changedFromPrevious);
|
|
82
|
-
chai_1.expect(allChanged, 'all files to NOT be changed').to.be.false;
|
|
82
|
+
(0, chai_1.expect)(allChanged, 'all files to NOT be changed').to.be.false;
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* Finds all files in project based on the provided globs and expects them to be updated on the server
|
|
@@ -102,7 +102,7 @@ class Assertions {
|
|
|
102
102
|
// glob will return files with '/' as separators, this won't work on Windows
|
|
103
103
|
const toTrack = all.filter((file) => !ignoreFiles.includes(file)).map((file) => file.replace(/\//g, path.sep));
|
|
104
104
|
result.map((source) => {
|
|
105
|
-
chai_1.expect(toTrack, `toTrack: ${toTrack.join('\n')}, missing file : ${source.filePath}`).to.include(source.filePath);
|
|
105
|
+
(0, chai_1.expect)(toTrack, `toTrack: ${toTrack.join('\n')}, missing file : ${source.filePath}`).to.include(source.filePath);
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
@@ -123,8 +123,8 @@ class Assertions {
|
|
|
123
123
|
*/
|
|
124
124
|
async fileToExist(file) {
|
|
125
125
|
const fullPath = file.startsWith(this.projectDir) ? file : path.join(this.projectDir, file);
|
|
126
|
-
const fileExists =
|
|
127
|
-
chai_1.expect(fileExists, `${fullPath} to exist`).to.be.true;
|
|
126
|
+
const fileExists = fs.existsSync(fullPath);
|
|
127
|
+
(0, chai_1.expect)(fileExists, `${fullPath} to exist`).to.be.true;
|
|
128
128
|
}
|
|
129
129
|
/**
|
|
130
130
|
* Expects given globs to return files
|
|
@@ -132,7 +132,7 @@ class Assertions {
|
|
|
132
132
|
async filesToExist(globs) {
|
|
133
133
|
for (const glob of globs) {
|
|
134
134
|
const results = await this.doGlob([glob]);
|
|
135
|
-
chai_1.expect(results.length, `expect files to be found by glob: ${glob}`).to.be.greaterThan(0);
|
|
135
|
+
(0, chai_1.expect)(results.length, `expect files to be found by glob: ${glob}`).to.be.greaterThan(0);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
@@ -141,7 +141,7 @@ class Assertions {
|
|
|
141
141
|
async filesToNotExist(globs) {
|
|
142
142
|
for (const glob of globs) {
|
|
143
143
|
const results = await this.doGlob([glob], false);
|
|
144
|
-
chai_1.expect(results.length, `expect no files to be found by glob: ${glob}`).to.equal(0);
|
|
144
|
+
(0, chai_1.expect)(results.length, `expect no files to be found by glob: ${glob}`).to.equal(0);
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
@@ -151,7 +151,7 @@ class Assertions {
|
|
|
151
151
|
directory = directory.split(path.sep).join('/');
|
|
152
152
|
const fullGlobs = globs.map((glob) => [directory, glob].join('/'));
|
|
153
153
|
const convertedFiles = await fg(fullGlobs);
|
|
154
|
-
chai_1.expect(convertedFiles.length, 'files to be converted').to.be.greaterThan(0);
|
|
154
|
+
(0, chai_1.expect)(convertedFiles.length, 'files to be converted').to.be.greaterThan(0);
|
|
155
155
|
}
|
|
156
156
|
/**
|
|
157
157
|
* Expects files found by glob to not contain any of the provided strings
|
|
@@ -159,9 +159,9 @@ class Assertions {
|
|
|
159
159
|
async filesToNotContainString(glob, ...strings) {
|
|
160
160
|
const files = await this.doGlob([glob]);
|
|
161
161
|
for (const file of files) {
|
|
162
|
-
const contents = await
|
|
162
|
+
const contents = await fs.promises.readFile(file, 'utf-8');
|
|
163
163
|
for (const str of strings) {
|
|
164
|
-
chai_1.expect(contents, `expect ${file} to not include ${str}`).to.not.include(str);
|
|
164
|
+
(0, chai_1.expect)(contents, `expect ${file} to not include ${str}`).to.not.include(str);
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
}
|
|
@@ -171,9 +171,9 @@ class Assertions {
|
|
|
171
171
|
async filesToContainString(glob, ...strings) {
|
|
172
172
|
const files = await this.doGlob([glob]);
|
|
173
173
|
for (const file of files) {
|
|
174
|
-
const contents = await
|
|
174
|
+
const contents = await fs.promises.readFile(file, 'utf-8');
|
|
175
175
|
for (const str of strings) {
|
|
176
|
-
chai_1.expect(contents, `expect ${file} to not include ${str}`).to.include(str);
|
|
176
|
+
(0, chai_1.expect)(contents, `expect ${file} to not include ${str}`).to.include(str);
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
}
|
|
@@ -197,14 +197,14 @@ class Assertions {
|
|
|
197
197
|
*/
|
|
198
198
|
async directoryToHaveSomeFiles(directory) {
|
|
199
199
|
const fullPath = directory.startsWith(this.projectDir) ? directory : path.join(this.projectDir, directory);
|
|
200
|
-
const fileCount = await fileTracker_1.countFiles([fullPath]);
|
|
201
|
-
chai_1.expect(fileCount, `at least 1 file found in ${directory}`).to.be.greaterThan(0);
|
|
200
|
+
const fileCount = await (0, fileTracker_1.countFiles)([fullPath]);
|
|
201
|
+
(0, chai_1.expect)(fileCount, `at least 1 file found in ${directory}`).to.be.greaterThan(0);
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
204
|
* Expect status to return no results
|
|
205
205
|
*/
|
|
206
206
|
statusToBeEmpty(result) {
|
|
207
|
-
chai_1.expect(result.length, 'status to have no results').to.equal(0);
|
|
207
|
+
(0, chai_1.expect)(result.length, 'status to have no results').to.equal(0);
|
|
208
208
|
}
|
|
209
209
|
/**
|
|
210
210
|
* Expect all given files to have the given state
|
|
@@ -213,36 +213,36 @@ class Assertions {
|
|
|
213
213
|
for (const file of files) {
|
|
214
214
|
this.statusFileToHaveState(result, state, file);
|
|
215
215
|
}
|
|
216
|
-
chai_1.expect(result.length, 'all files to be present in json response').to.equal(files.length);
|
|
216
|
+
(0, chai_1.expect)(result.length, 'all files to be present in json response').to.equal(files.length);
|
|
217
217
|
}
|
|
218
218
|
/**
|
|
219
219
|
* Expect given file to have the given state
|
|
220
220
|
*/
|
|
221
221
|
statusFileToHaveState(result, state, file) {
|
|
222
222
|
const expectedFile = result.find((r) => r.filePath === file);
|
|
223
|
-
chai_1.expect(expectedFile, `${file} to be present in json response`).to.not.be.undefined;
|
|
224
|
-
chai_1.expect(expectedFile === null || expectedFile === void 0 ? void 0 : expectedFile.state, `${file} to have state ${state}`).to.equal(state);
|
|
223
|
+
(0, chai_1.expect)(expectedFile, `${file} to be present in json response`).to.not.be.undefined;
|
|
224
|
+
(0, chai_1.expect)(expectedFile === null || expectedFile === void 0 ? void 0 : expectedFile.state, `${file} to have state ${state}`).to.equal(state);
|
|
225
225
|
}
|
|
226
226
|
/**
|
|
227
227
|
* Expect all given files to have the given state
|
|
228
228
|
*/
|
|
229
229
|
statusToOnlyHaveState(result, state) {
|
|
230
230
|
const allStates = result.every((r) => r.state === state);
|
|
231
|
-
chai_1.expect(allStates, `all files to have ${state}`).to.be.true;
|
|
231
|
+
(0, chai_1.expect)(allStates, `all files to have ${state}`).to.be.true;
|
|
232
232
|
}
|
|
233
233
|
/**
|
|
234
234
|
* Expect all files to have a conflict state
|
|
235
235
|
*/
|
|
236
236
|
statusToOnlyHaveConflicts(result) {
|
|
237
237
|
const allConflicts = result.every((r) => r.state.includes('Conflict'));
|
|
238
|
-
chai_1.expect(allConflicts, 'all results to show conflict state').to.be.true;
|
|
238
|
+
(0, chai_1.expect)(allConflicts, 'all results to show conflict state').to.be.true;
|
|
239
239
|
}
|
|
240
240
|
/**
|
|
241
241
|
* Expect json to have given error name
|
|
242
242
|
*/
|
|
243
243
|
errorToHaveName(result, name) {
|
|
244
|
-
chai_1.expect(result).to.have.property('name');
|
|
245
|
-
chai_1.expect(result.name, `error name to equal ${name}`).to.equal(name);
|
|
244
|
+
(0, chai_1.expect)(result).to.have.property('name');
|
|
245
|
+
(0, chai_1.expect)(result.name, `error name to equal ${name}`).to.equal(name);
|
|
246
246
|
}
|
|
247
247
|
/**
|
|
248
248
|
* Expect no apex tests to be run
|
|
@@ -251,7 +251,7 @@ class Assertions {
|
|
|
251
251
|
const executionTimestamp = this.executionLog.getLatestTimestamp(this.commands.deploy);
|
|
252
252
|
const testResults = await this.retrieveApexTestResults();
|
|
253
253
|
const testsRunAfterTimestamp = testResults.filter((r) => new Date(r.TestTimestamp) > executionTimestamp);
|
|
254
|
-
chai_1.expect(testsRunAfterTimestamp.length, 'no tests to be run during deploy').to.equal(0);
|
|
254
|
+
(0, chai_1.expect)(testsRunAfterTimestamp.length, 'no tests to be run during deploy').to.equal(0);
|
|
255
255
|
}
|
|
256
256
|
/**
|
|
257
257
|
* Expect some apex tests to be run
|
|
@@ -260,7 +260,7 @@ class Assertions {
|
|
|
260
260
|
const executionTimestamp = this.executionLog.getLatestTimestamp(this.commands.deploy);
|
|
261
261
|
const testResults = await this.retrieveApexTestResults();
|
|
262
262
|
const testsRunAfterTimestamp = testResults.filter((r) => new Date(r.TestTimestamp) > executionTimestamp);
|
|
263
|
-
chai_1.expect(testsRunAfterTimestamp.length, 'tests to be run during deploy').to.be.greaterThan(0);
|
|
263
|
+
(0, chai_1.expect)(testsRunAfterTimestamp.length, 'tests to be run during deploy').to.be.greaterThan(0);
|
|
264
264
|
}
|
|
265
265
|
/**
|
|
266
266
|
* Expect apex tests owned by the provided classes to be run
|
|
@@ -273,27 +273,27 @@ class Assertions {
|
|
|
273
273
|
const testsRunAfterTimestamp = testResults.filter((r) => {
|
|
274
274
|
return new Date(r.TestTimestamp) > executionTimestamp && classIds.includes(r.ApexClassId);
|
|
275
275
|
});
|
|
276
|
-
chai_1.expect(testsRunAfterTimestamp.length, 'tests to be run during deploy').to.be.greaterThan(0);
|
|
276
|
+
(0, chai_1.expect)(testsRunAfterTimestamp.length, 'tests to be run during deploy').to.be.greaterThan(0);
|
|
277
277
|
}
|
|
278
278
|
/**
|
|
279
279
|
* Expect result to have given property
|
|
280
280
|
*/
|
|
281
281
|
toHaveProperty(result, prop) {
|
|
282
|
-
chai_1.expect(result).to.have.property(prop);
|
|
282
|
+
(0, chai_1.expect)(result).to.have.property(prop);
|
|
283
283
|
}
|
|
284
284
|
/**
|
|
285
285
|
* Expect result to have given property and for that property to equal the given value
|
|
286
286
|
*/
|
|
287
287
|
toHavePropertyAndValue(result, prop, value) {
|
|
288
|
-
chai_1.expect(result).to.have.property(prop);
|
|
289
|
-
chai_1.expect(result[prop], `${prop} to have value ${value.toString()}`).to.equal(value);
|
|
288
|
+
(0, chai_1.expect)(result).to.have.property(prop);
|
|
289
|
+
(0, chai_1.expect)(result[prop], `${prop} to have value ${value.toString()}`).to.equal(value);
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
292
292
|
* Expect result to have given property and for that property to NOT equal the given value
|
|
293
293
|
*/
|
|
294
294
|
toHavePropertyAndNotValue(result, prop, value) {
|
|
295
|
-
chai_1.expect(result).to.have.property(prop);
|
|
296
|
-
chai_1.expect(result[prop], `${prop} to have value that does not equal ${value.toString()}`).to.not.equal(value);
|
|
295
|
+
(0, chai_1.expect)(result).to.have.property(prop);
|
|
296
|
+
(0, chai_1.expect)(result[prop], `${prop} to have value that does not equal ${value.toString()}`).to.not.equal(value);
|
|
297
297
|
}
|
|
298
298
|
async filesToBeUpdated(globs, ignore = [], command) {
|
|
299
299
|
var _a;
|
|
@@ -302,7 +302,7 @@ class Assertions {
|
|
|
302
302
|
for (const sourceMember of latestSourceMembers) {
|
|
303
303
|
const assertionMessage = `expect RevisionCounter for ${sourceMember.MemberName} (${sourceMember.MemberType}) to be incremented`;
|
|
304
304
|
const preCommandExecution = sourceMembers.find((s) => s.MemberType === sourceMember.MemberType && s.MemberName === sourceMember.MemberName) || { RevisionCounter: 0 };
|
|
305
|
-
chai_1.expect(sourceMember.RevisionCounter, assertionMessage).to.be.greaterThan(preCommandExecution.RevisionCounter);
|
|
305
|
+
(0, chai_1.expect)(sourceMember.RevisionCounter, assertionMessage).to.be.greaterThan(preCommandExecution.RevisionCounter);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
308
|
async filesToNotBeUpdated(globs, ignore = [], command) {
|
|
@@ -313,13 +313,13 @@ class Assertions {
|
|
|
313
313
|
// Not finding any source members based on the globs means that there is no SourceMember for those files
|
|
314
314
|
// which we're assuming means that it hasn't been deployed to the org yet.
|
|
315
315
|
// That's acceptable for this test since we're testing that metadata hasn't been deployed.
|
|
316
|
-
chai_1.expect(latestSourceMembers.length).to.equal(0);
|
|
316
|
+
(0, chai_1.expect)(latestSourceMembers.length).to.equal(0);
|
|
317
317
|
}
|
|
318
318
|
else {
|
|
319
319
|
for (const sourceMember of latestSourceMembers) {
|
|
320
320
|
const assertionMessage = `expect RevisionCounter for ${sourceMember.MemberName} (${sourceMember.MemberType}) to NOT be incremented`;
|
|
321
321
|
const preCommandExecution = sourceMembers.find((s) => s.MemberType === sourceMember.MemberType && s.MemberName === sourceMember.MemberName) || { RevisionCounter: 0 };
|
|
322
|
-
chai_1.expect(sourceMember.RevisionCounter, assertionMessage).to.equal(preCommandExecution.RevisionCounter);
|
|
322
|
+
(0, chai_1.expect)(sourceMember.RevisionCounter, assertionMessage).to.equal(preCommandExecution.RevisionCounter);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
325
|
}
|
|
@@ -331,7 +331,7 @@ class Assertions {
|
|
|
331
331
|
const preCommandExecution = sourceMembers.find((s) => s.MemberType === sourceMember.MemberType && s.MemberName === sourceMember.MemberName) || { RevisionCounter: 0 };
|
|
332
332
|
return sourceMember.RevisionCounter === preCommandExecution.RevisionCounter;
|
|
333
333
|
});
|
|
334
|
-
chai_1.expect(someAreNotUpdated, 'expect some SourceMembers to not be updated').to.be.true;
|
|
334
|
+
(0, chai_1.expect)(someAreNotUpdated, 'expect some SourceMembers to not be updated').to.be.true;
|
|
335
335
|
}
|
|
336
336
|
async retrieveSourceMembers(globs, ignore = []) {
|
|
337
337
|
var _a;
|
|
@@ -395,7 +395,7 @@ class Assertions {
|
|
|
395
395
|
files.push(...globResults);
|
|
396
396
|
}
|
|
397
397
|
if (assert)
|
|
398
|
-
chai_1.expect(files.length, 'globs to return files').to.be.greaterThan(0);
|
|
398
|
+
(0, chai_1.expect)(files.length, 'globs to return files').to.be.greaterThan(0);
|
|
399
399
|
return files;
|
|
400
400
|
}
|
|
401
401
|
}
|
package/lib/executionLog.js
CHANGED
|
@@ -22,7 +22,7 @@ class ExecutionLog {
|
|
|
22
22
|
* Add a command to the execution log
|
|
23
23
|
*/
|
|
24
24
|
async add(cmd) {
|
|
25
|
-
const baseCmd = ts_types_1.ensureString(Object.values(this.context.commands).find((c) => cmd.startsWith(c)) || cmd.split(' -')[0]);
|
|
25
|
+
const baseCmd = (0, ts_types_1.ensureString)(Object.values(this.context.commands).find((c) => cmd.startsWith(c)) || cmd.split(' -')[0]);
|
|
26
26
|
const existingEntries = this.log.get(baseCmd) || [];
|
|
27
27
|
const sourceMembers = baseCmd.includes(this.context.commands.deploy) || baseCmd.includes(this.context.commands.push)
|
|
28
28
|
? await this.querySourceMembers()
|
package/lib/fileTracker.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countFiles = exports.traverseForFiles = exports.FileTracker = void 0;
|
|
2
4
|
/*
|
|
3
5
|
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* Licensed under the BSD 3-Clause license.
|
|
6
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
|
|
9
|
-
exports.countFiles = exports.traverseForFiles = exports.FileTracker = void 0;
|
|
10
|
+
const fs = require("fs");
|
|
10
11
|
const path = require("path");
|
|
11
|
-
const
|
|
12
|
+
const crypto = require("crypto");
|
|
12
13
|
/**
|
|
13
14
|
* This class maintains a map of tracked files. This is particularly useful
|
|
14
15
|
* for determining if files have changed after a command has been executed
|
|
@@ -76,10 +77,12 @@ class FileTracker {
|
|
|
76
77
|
async getContentHash(file) {
|
|
77
78
|
const filePath = this.getFullPath(file);
|
|
78
79
|
try {
|
|
79
|
-
const filestat = await
|
|
80
|
+
const filestat = await fs.promises.stat(filePath);
|
|
80
81
|
const isDirectory = filestat.isDirectory();
|
|
81
|
-
const contents = isDirectory
|
|
82
|
-
|
|
82
|
+
const contents = isDirectory
|
|
83
|
+
? (await fs.promises.readdir(filePath)).toString()
|
|
84
|
+
: await fs.promises.readFile(filePath);
|
|
85
|
+
return crypto.createHash('sha1').update(contents).digest('hex');
|
|
83
86
|
}
|
|
84
87
|
catch {
|
|
85
88
|
return null;
|
|
@@ -94,10 +97,10 @@ exports.FileTracker = FileTracker;
|
|
|
94
97
|
* Returns all files in directory that match the filter
|
|
95
98
|
*/
|
|
96
99
|
async function traverseForFiles(dirPath, regexFilter = /./, allFiles = []) {
|
|
97
|
-
const files = await
|
|
100
|
+
const files = await fs.promises.readdir(dirPath);
|
|
98
101
|
for (const file of files) {
|
|
99
102
|
const filePath = path.join(dirPath, file);
|
|
100
|
-
if (
|
|
103
|
+
if (fs.statSync(filePath).isDirectory()) {
|
|
101
104
|
allFiles = await traverseForFiles(filePath, regexFilter, allFiles);
|
|
102
105
|
}
|
|
103
106
|
else if (regexFilter.test(file)) {
|
package/lib/testkit.d.ts
CHANGED
|
@@ -199,7 +199,7 @@ export declare class SourceTestkit extends AsyncCreatable<SourceTestkit.Options>
|
|
|
199
199
|
*/
|
|
200
200
|
spoofRemoteChange(globs: string[]): Promise<void>;
|
|
201
201
|
/**
|
|
202
|
-
* Returns true if the executable being used belongs to a local
|
|
202
|
+
* Returns true if the executable being used belongs to a local package
|
|
203
203
|
*/
|
|
204
204
|
isLocalExecutable(): boolean;
|
|
205
205
|
/**
|
package/lib/testkit.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.COMMANDS = exports.Executable = exports.SourceTestkit = void 0;
|
|
|
10
10
|
/* eslint-disable no-console */
|
|
11
11
|
const path = require("path");
|
|
12
12
|
const os = require("os");
|
|
13
|
+
const fs = require("fs");
|
|
13
14
|
const fg = require("fast-glob");
|
|
14
15
|
const shelljs_1 = require("shelljs");
|
|
15
16
|
const cli_plugins_testkit_1 = require("@salesforce/cli-plugins-testkit");
|
|
@@ -39,13 +40,14 @@ const fileTracker_1 = require("./fileTracker");
|
|
|
39
40
|
*/
|
|
40
41
|
class SourceTestkit extends kit_1.AsyncCreatable {
|
|
41
42
|
constructor(options) {
|
|
43
|
+
var _a, _b, _c;
|
|
42
44
|
super(options);
|
|
43
|
-
this.executable = options.executable
|
|
45
|
+
this.executable = (_c = (_a = options.executable) !== null && _a !== void 0 ? _a : (_b = (0, shelljs_1.which)('sfdx')) === null || _b === void 0 ? void 0 : _b.stdout) !== null && _c !== void 0 ? _c : 'sfdx';
|
|
44
46
|
this.repository = options.repository;
|
|
45
47
|
this.orgless = !!options.orgless;
|
|
46
48
|
this.setupCommands = options.setupCommands || [];
|
|
47
49
|
this.nut = path.basename(options.nut);
|
|
48
|
-
this.debug = debug_1.debug(`sourceTestkit:${this.nut}`);
|
|
50
|
+
this.debug = (0, debug_1.debug)(`sourceTestkit:${this.nut}`);
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
51
53
|
* Cleans the test session
|
|
@@ -120,7 +122,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
120
122
|
* we can't add plugin-package as a dev plugin yet.
|
|
121
123
|
*/
|
|
122
124
|
installPackage(id) {
|
|
123
|
-
shelljs_1.exec(`sfdx force:package:install --noprompt --package ${id} --wait 5 --json 2> /dev/null`, { silent: true });
|
|
125
|
+
(0, shelljs_1.exec)(`sfdx force:package:install --noprompt --package ${id} --wait 5 --json 2> /dev/null`, { silent: true });
|
|
124
126
|
}
|
|
125
127
|
/**
|
|
126
128
|
* Runs the permset:assign command with the passed in options
|
|
@@ -154,7 +156,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
154
156
|
const files = await this.doGlob(globs);
|
|
155
157
|
const returnValue = {};
|
|
156
158
|
for (const file of files) {
|
|
157
|
-
returnValue[file] = await
|
|
159
|
+
returnValue[file] = await fs.promises.readFile(file, 'utf8');
|
|
158
160
|
}
|
|
159
161
|
return returnValue;
|
|
160
162
|
}
|
|
@@ -163,27 +165,27 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
163
165
|
*/
|
|
164
166
|
async readSourcePathInfos() {
|
|
165
167
|
const sourcePathInfosPath = path.join(this.projectDir, '.sfdx', 'orgs', this.username, 'sourcePathInfos.json');
|
|
166
|
-
return
|
|
168
|
+
return JSON.parse(await fs.promises.readFile(sourcePathInfosPath, 'utf8'));
|
|
167
169
|
}
|
|
168
170
|
/**
|
|
169
171
|
* Read the org's maxRevision.json
|
|
170
172
|
*/
|
|
171
173
|
async readMaxRevision() {
|
|
172
174
|
const maxRevisionPath = path.join(this.projectDir, '.sfdx', 'orgs', this.username, 'maxRevision.json');
|
|
173
|
-
return
|
|
175
|
+
return JSON.parse(await fs.promises.readFile(maxRevisionPath, 'utf8'));
|
|
174
176
|
}
|
|
175
177
|
/**
|
|
176
178
|
* Write the org's maxRevision.json
|
|
177
179
|
*/
|
|
178
180
|
async writeMaxRevision(contents) {
|
|
179
181
|
const maxRevisionPath = path.join(this.projectDir, '.sfdx', 'orgs', this.username, 'maxRevision.json');
|
|
180
|
-
return
|
|
182
|
+
return fs.promises.writeFile(maxRevisionPath, JSON.stringify(contents));
|
|
181
183
|
}
|
|
182
184
|
/**
|
|
183
185
|
* Write file
|
|
184
186
|
*/
|
|
185
187
|
async writeFile(filename, contents) {
|
|
186
|
-
return
|
|
188
|
+
return fs.promises.writeFile(filename, contents);
|
|
187
189
|
}
|
|
188
190
|
/**
|
|
189
191
|
* Create a package.xml
|
|
@@ -196,7 +198,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
196
198
|
</Package>
|
|
197
199
|
`;
|
|
198
200
|
const packageXmlPath = path.join(this.projectDir, 'package.xml');
|
|
199
|
-
await
|
|
201
|
+
await fs.promises.writeFile(packageXmlPath, packageXml);
|
|
200
202
|
return packageXmlPath;
|
|
201
203
|
}
|
|
202
204
|
/**
|
|
@@ -204,14 +206,14 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
204
206
|
*/
|
|
205
207
|
async deleteSourcePathInfos() {
|
|
206
208
|
const sourcePathInfosPath = path.join(this.projectDir, '.sfdx', 'orgs', this.username, 'sourcePathInfos.json');
|
|
207
|
-
return
|
|
209
|
+
return fs.promises.unlink(sourcePathInfosPath);
|
|
208
210
|
}
|
|
209
211
|
/**
|
|
210
212
|
* Delete the org's maxRevision.json
|
|
211
213
|
*/
|
|
212
214
|
async deleteMaxRevision() {
|
|
213
215
|
const maxRevisionPath = path.join(this.projectDir, '.sfdx', 'orgs', this.username, 'maxRevision.json');
|
|
214
|
-
return
|
|
216
|
+
return fs.promises.unlink(maxRevisionPath);
|
|
215
217
|
}
|
|
216
218
|
/**
|
|
217
219
|
* Delete the files found by the given globs
|
|
@@ -219,7 +221,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
219
221
|
async deleteGlobs(globs) {
|
|
220
222
|
const files = await this.doGlob(globs);
|
|
221
223
|
for (const file of files) {
|
|
222
|
-
await
|
|
224
|
+
await fs.promises.unlink(file);
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
/**
|
|
@@ -227,8 +229,8 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
227
229
|
*/
|
|
228
230
|
async deleteAllSourceFiles() {
|
|
229
231
|
for (const pkg of this.packagePaths) {
|
|
230
|
-
await
|
|
231
|
-
await
|
|
232
|
+
await fs.promises.rm(pkg, { recursive: true });
|
|
233
|
+
await fs.promises.mkdir(pkg, { recursive: true });
|
|
232
234
|
}
|
|
233
235
|
}
|
|
234
236
|
/**
|
|
@@ -245,9 +247,9 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
245
247
|
*/
|
|
246
248
|
async modifyLocalFile(file, append = os.EOL) {
|
|
247
249
|
const fullPath = file.startsWith(this.projectDir) ? file : path.join(this.projectDir, file);
|
|
248
|
-
let contents = await
|
|
250
|
+
let contents = await fs.promises.readFile(fullPath, 'utf-8');
|
|
249
251
|
contents += append;
|
|
250
|
-
await
|
|
252
|
+
await fs.promises.writeFile(fullPath, contents);
|
|
251
253
|
await this.fileTracker.update(fullPath, 'modified file');
|
|
252
254
|
}
|
|
253
255
|
/**
|
|
@@ -276,11 +278,11 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
276
278
|
const src = path.join(this.testMetadataFolder, file);
|
|
277
279
|
this.debug(`addTestFiles: ${src} -> ${dest}`);
|
|
278
280
|
try {
|
|
279
|
-
|
|
281
|
+
fs.copyFileSync(src, dest);
|
|
280
282
|
}
|
|
281
283
|
catch {
|
|
282
|
-
await
|
|
283
|
-
|
|
284
|
+
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
|
285
|
+
fs.copyFileSync(src, dest);
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
288
|
await this.trackFiles(this.testMetadataFiles);
|
|
@@ -300,19 +302,19 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
300
302
|
const name = component.name;
|
|
301
303
|
if (!type.includes('CustomLabel')) {
|
|
302
304
|
const maxRevisionKey = parent ? `${type}__${parent}.${name}` : `${type}__${name}`;
|
|
303
|
-
kit_1.set(maxRevision.sourceMembers, `${maxRevisionKey}.lastRetrievedFromServer`, null);
|
|
305
|
+
(0, kit_1.set)(maxRevision.sourceMembers, `${maxRevisionKey}.lastRetrievedFromServer`, null);
|
|
304
306
|
}
|
|
305
307
|
else {
|
|
306
308
|
const labels = Object.keys(maxRevision.sourceMembers).filter((k) => k.startsWith('CustomLabel'));
|
|
307
309
|
labels.forEach((label) => {
|
|
308
|
-
kit_1.set(maxRevision.sourceMembers, `${label}.lastRetrievedFromServer`, null);
|
|
310
|
+
(0, kit_1.set)(maxRevision.sourceMembers, `${label}.lastRetrievedFromServer`, null);
|
|
309
311
|
});
|
|
310
312
|
}
|
|
311
313
|
}
|
|
312
314
|
await this.writeMaxRevision(maxRevision);
|
|
313
315
|
}
|
|
314
316
|
/**
|
|
315
|
-
* Returns true if the executable being used belongs to a local
|
|
317
|
+
* Returns true if the executable being used belongs to a local package
|
|
316
318
|
*/
|
|
317
319
|
isLocalExecutable() {
|
|
318
320
|
return (this.executable.endsWith(SourceTestkit.LocalDevPath) || this.executable.endsWith(SourceTestkit.LocalProdPath));
|
|
@@ -325,12 +327,12 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
325
327
|
* dir, move it, and delete the generated dir.
|
|
326
328
|
*/
|
|
327
329
|
findAndMoveManifest(dir) {
|
|
328
|
-
const manifest = shelljs_1.find(dir).filter((file) => file.endsWith('package.xml'));
|
|
330
|
+
const manifest = (0, shelljs_1.find)(dir).filter((file) => file.endsWith('package.xml'));
|
|
329
331
|
if (!(manifest === null || manifest === void 0 ? void 0 : manifest.length)) {
|
|
330
332
|
throw Error(`Did not find package.xml within ${dir}`);
|
|
331
333
|
}
|
|
332
|
-
shelljs_1.mv(manifest[0], path.join(process.cwd()));
|
|
333
|
-
shelljs_1.rm('-rf', dir);
|
|
334
|
+
(0, shelljs_1.mv)(manifest[0], path.join(process.cwd()));
|
|
335
|
+
(0, shelljs_1.rm)('-rf', dir);
|
|
334
336
|
}
|
|
335
337
|
/**
|
|
336
338
|
* Execute a command using testkit. Adds --json to every command to ensure json output.
|
|
@@ -343,8 +345,8 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
343
345
|
await this.fileTracker.updateAll(`PRE: ${command}`);
|
|
344
346
|
await this.executionLog.add(command);
|
|
345
347
|
const result = this.executableName === Executable.SF
|
|
346
|
-
? cli_plugins_testkit_1.execCmd(command, { ensureExitCode: exitCode, cli: 'sf' })
|
|
347
|
-
: cli_plugins_testkit_1.execCmd(command, { ensureExitCode: exitCode, cli: 'sfdx' });
|
|
348
|
+
? (0, cli_plugins_testkit_1.execCmd)(command, { ensureExitCode: exitCode, cli: 'sf' })
|
|
349
|
+
: (0, cli_plugins_testkit_1.execCmd)(command, { ensureExitCode: exitCode, cli: 'sfdx' });
|
|
348
350
|
await this.fileTracker.updateAll(`POST: ${command}`);
|
|
349
351
|
if (json) {
|
|
350
352
|
const jsonOutput = result.jsonOutput;
|
|
@@ -369,9 +371,9 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
369
371
|
}
|
|
370
372
|
async init() {
|
|
371
373
|
if (!SourceTestkit.Env.getString('TESTKIT_HUB_USERNAME') && !SourceTestkit.Env.getString('TESTKIT_AUTH_URL')) {
|
|
372
|
-
ts_types_1.ensureString(SourceTestkit.Env.getString('TESTKIT_JWT_KEY'));
|
|
373
|
-
ts_types_1.ensureString(SourceTestkit.Env.getString('TESTKIT_JWT_CLIENT_ID'));
|
|
374
|
-
ts_types_1.ensureString(SourceTestkit.Env.getString('TESTKIT_HUB_INSTANCE'));
|
|
374
|
+
(0, ts_types_1.ensureString)(SourceTestkit.Env.getString('TESTKIT_JWT_KEY'));
|
|
375
|
+
(0, ts_types_1.ensureString)(SourceTestkit.Env.getString('TESTKIT_JWT_CLIENT_ID'));
|
|
376
|
+
(0, ts_types_1.ensureString)(SourceTestkit.Env.getString('TESTKIT_HUB_INSTANCE'));
|
|
375
377
|
}
|
|
376
378
|
SourceTestkit.Env.setString('TESTKIT_EXECUTABLE_PATH', this.executable);
|
|
377
379
|
try {
|
|
@@ -380,8 +382,8 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
380
382
|
this.metadataResolver = new source_deploy_retrieve_1.MetadataResolver();
|
|
381
383
|
this.session = await this.createSession();
|
|
382
384
|
this.projectDir = this.session.project.dir;
|
|
383
|
-
const
|
|
384
|
-
this.packages =
|
|
385
|
+
const sfProject = await core_1.SfProject.resolve(this.projectDir);
|
|
386
|
+
this.packages = sfProject.getPackageDirectories();
|
|
385
387
|
this.packageNames = this.packages.map((p) => p.name);
|
|
386
388
|
this.packagePaths = this.packages.map((p) => p.fullPath);
|
|
387
389
|
this.packageGlobs = this.packages.map((p) => `${p.path}/**/*`);
|
|
@@ -397,7 +399,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
397
399
|
this.executionLog = new executionLog_1.ExecutionLog(context);
|
|
398
400
|
this.expect = new assertions_1.Assertions(context, this.executionLog, this.fileTracker);
|
|
399
401
|
this.testMetadataFolder = path.join(__dirname, 'metadata');
|
|
400
|
-
this.testMetadataFiles = (await fileTracker_1.traverseForFiles(this.testMetadataFolder))
|
|
402
|
+
this.testMetadataFiles = (await (0, fileTracker_1.traverseForFiles)(this.testMetadataFolder))
|
|
401
403
|
.filter((f) => !f.endsWith('.DS_Store'))
|
|
402
404
|
.map((f) => f.replace(`${this.testMetadataFolder}${path.sep}`, ''));
|
|
403
405
|
}
|
|
@@ -412,7 +414,7 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
412
414
|
.replace(SourceTestkit.LocalProdPath, '')
|
|
413
415
|
.replace(SourceTestkit.LocalDevPath, '');
|
|
414
416
|
const pkgJsonPath = path.join(npmPackagePath, 'package.json');
|
|
415
|
-
const pkgJson = (await
|
|
417
|
+
const pkgJson = (0, kit_1.parseJsonMap)(await fs.promises.readFile(pkgJsonPath, 'utf8'));
|
|
416
418
|
return pkgJson.oclif.bin;
|
|
417
419
|
}
|
|
418
420
|
else {
|
|
@@ -459,10 +461,13 @@ class SourceTestkit extends kit_1.AsyncCreatable {
|
|
|
459
461
|
});
|
|
460
462
|
}
|
|
461
463
|
async getDefaultUsername() {
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
const
|
|
465
|
-
|
|
464
|
+
var _a, _b;
|
|
465
|
+
const configVar = 'target-org';
|
|
466
|
+
const configResult = (_a = (0, cli_plugins_testkit_1.execCmd)(`config:get ${configVar} --json`).jsonOutput) === null || _a === void 0 ? void 0 : _a.result;
|
|
467
|
+
// depending on which version of config:get the user has available, there may be a name or key
|
|
468
|
+
// eventually, drop the `key` option and the deprecated SfdxPropertyKeys
|
|
469
|
+
const possibleKeys = [configVar, core_1.SfdxPropertyKeys.DEFAULT_USERNAME];
|
|
470
|
+
const username = (_b = configResult === null || configResult === void 0 ? void 0 : configResult.find((r) => (r.key && possibleKeys.includes(r.key)) || (r.name && possibleKeys.includes(r.name)))) === null || _b === void 0 ? void 0 : _b.value;
|
|
466
471
|
return username;
|
|
467
472
|
}
|
|
468
473
|
async createConnection() {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/source-testkit",
|
|
3
3
|
"description": "testkit for running NUTs for source related commands",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -30,39 +30,39 @@
|
|
|
30
30
|
"!lib/**/*.map"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@salesforce/cli-plugins-testkit": "^1.
|
|
34
|
-
"@salesforce/core": "^
|
|
35
|
-
"@salesforce/kit": "^1.
|
|
36
|
-
"@salesforce/source-deploy-retrieve": "^
|
|
37
|
-
"@salesforce/ts-types": "^1.5.
|
|
33
|
+
"@salesforce/cli-plugins-testkit": "^2.1.3",
|
|
34
|
+
"@salesforce/core": "^3.19.4",
|
|
35
|
+
"@salesforce/kit": "^1.5.42",
|
|
36
|
+
"@salesforce/source-deploy-retrieve": "^6.0.2",
|
|
37
|
+
"@salesforce/ts-types": "^1.5.20",
|
|
38
38
|
"archiver": "^5.2.0",
|
|
39
39
|
"chai-each": "^0.0.1",
|
|
40
40
|
"debug": "^4.3.1",
|
|
41
41
|
"shelljs": "^0.8.4",
|
|
42
42
|
"sinon": "^10.0.0",
|
|
43
|
-
"strip-ansi": "^
|
|
43
|
+
"strip-ansi": "^7.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@salesforce/dev-config": "^3.0.0",
|
|
47
|
-
"@salesforce/dev-scripts": "^2.0.
|
|
47
|
+
"@salesforce/dev-scripts": "^2.0.2",
|
|
48
48
|
"@salesforce/prettier-config": "^0.0.2",
|
|
49
49
|
"@salesforce/ts-sinon": "^1.3.5",
|
|
50
50
|
"@types/archiver": "^5.1.0",
|
|
51
51
|
"@types/debug": "^4.1.5",
|
|
52
|
-
"@types/shelljs": "^0.8.
|
|
52
|
+
"@types/shelljs": "^0.8.11",
|
|
53
53
|
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
|
54
54
|
"@typescript-eslint/parser": "^4.15.2",
|
|
55
55
|
"chai": "^4.3.0",
|
|
56
56
|
"copyfiles": "^2.4.1",
|
|
57
57
|
"cz-conventional-changelog": "^3.3.0",
|
|
58
|
-
"eslint": "^7.
|
|
58
|
+
"eslint": "^7.27.0",
|
|
59
59
|
"eslint-config-prettier": "^8.1.0",
|
|
60
60
|
"eslint-config-salesforce": "^0.1.6",
|
|
61
61
|
"eslint-config-salesforce-license": "^0.1.6",
|
|
62
|
-
"eslint-config-salesforce-typescript": "^0.2.
|
|
62
|
+
"eslint-config-salesforce-typescript": "^0.2.8",
|
|
63
63
|
"eslint-plugin-header": "^3.1.1",
|
|
64
|
-
"eslint-plugin-import": "
|
|
65
|
-
"eslint-plugin-jsdoc": "^
|
|
64
|
+
"eslint-plugin-import": "2.24.2",
|
|
65
|
+
"eslint-plugin-jsdoc": "^35.1.2",
|
|
66
66
|
"eslint-plugin-prettier": "^3.3.1",
|
|
67
67
|
"husky": "^7.0.4",
|
|
68
68
|
"mocha": "^9.1.3",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"pretty-quick": "^3.1.0",
|
|
72
72
|
"sinon": "^10.0.0",
|
|
73
73
|
"ts-node": "^10.0.0",
|
|
74
|
-
"typescript": "^4.
|
|
74
|
+
"typescript": "^4.7.2"
|
|
75
75
|
},
|
|
76
76
|
"config": {
|
|
77
77
|
"commitizen": {
|