@mitre/inspec-objects 1.0.1 → 2.0.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/.github/dependabot.yml +11 -0
- package/.github/workflows/auto-approve-and-merge.yml +22 -0
- package/.github/workflows/e2e-test.yml +1 -1
- package/.github/workflows/linter.yml +1 -2
- package/README.md +45 -4
- package/lib/index.d.ts +4 -2
- package/lib/index.js +5 -2
- package/lib/objects/control.d.ts +78 -0
- package/lib/objects/control.js +101 -18
- package/lib/objects/profile.d.ts +58 -0
- package/lib/objects/profile.js +60 -1
- package/lib/parsers/json.d.ts +32 -0
- package/lib/parsers/json.js +36 -5
- package/lib/parsers/oval.d.ts +28 -0
- package/lib/parsers/oval.js +45 -5
- package/lib/parsers/xccdf.d.ts +32 -1
- package/lib/parsers/xccdf.js +84 -38
- package/lib/utilities/diff.d.ts +42 -0
- package/lib/utilities/diff.js +51 -12
- package/lib/utilities/diffMarkdown.d.ts +13 -0
- package/lib/utilities/diffMarkdown.js +24 -12
- package/lib/utilities/global.d.ts +53 -0
- package/lib/utilities/global.js +92 -13
- package/lib/utilities/logging.d.ts +1 -1
- package/lib/utilities/logging.js +8 -5
- package/lib/utilities/update.d.ts +60 -1
- package/lib/utilities/update.js +132 -42
- package/lib/utilities/xccdf.d.ts +82 -1
- package/lib/utilities/xccdf.js +113 -22
- package/package.json +17 -17
package/lib/utilities/diff.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.removeNewlines = removeNewlines;
|
|
4
|
+
exports.ignoreFormattingDiff = ignoreFormattingDiff;
|
|
5
|
+
exports.diffProfile = diffProfile;
|
|
4
6
|
const tslib_1 = require("tslib");
|
|
5
7
|
const json_diff_1 = require("json-diff");
|
|
6
8
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
9
|
const update_1 = require("./update");
|
|
8
10
|
const global_1 = require("./global");
|
|
11
|
+
/**
|
|
12
|
+
* Removes newlines from all string values within a nested object.
|
|
13
|
+
*
|
|
14
|
+
* This function recursively traverses the provided object and replaces
|
|
15
|
+
* newline characters (`\n`) in string values with the placeholder `{{{{newlineHERE}}}}`.
|
|
16
|
+
* It also trims any leading or trailing whitespace from the string values.
|
|
17
|
+
*
|
|
18
|
+
* @param control - The object from which to remove newlines. If not provided,
|
|
19
|
+
* an empty object is returned.
|
|
20
|
+
* @returns A new object with newlines removed from all string values.
|
|
21
|
+
*/
|
|
9
22
|
function removeNewlines(control) {
|
|
10
23
|
if (!control) {
|
|
11
24
|
return {};
|
|
@@ -20,16 +33,34 @@ function removeNewlines(control) {
|
|
|
20
33
|
return value;
|
|
21
34
|
});
|
|
22
35
|
}
|
|
23
|
-
|
|
24
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Processes a diff object to ignore formatting differences such as whitespace.
|
|
38
|
+
* Goal is to use a linter for the formatting and compare characters without
|
|
39
|
+
* whitespaces here.
|
|
40
|
+
*
|
|
41
|
+
* The function performs the following:
|
|
42
|
+
* - If the diff value has a `__new` property, it compares the `__new` and
|
|
43
|
+
* `__old` values after removing whitespace. If they are different, it sets
|
|
44
|
+
* the result to the `__new` value.
|
|
45
|
+
* - If the diff value is an array, it maps and filters the array to include
|
|
46
|
+
* only the new values.
|
|
47
|
+
* - If the diff value is an object, it recursively processes the object.
|
|
48
|
+
* - If the key ends with `__deleted`, it ignores the value.
|
|
49
|
+
* - Otherwise, it sets the result to the diff value.
|
|
50
|
+
*
|
|
51
|
+
* @param diffData - The diff object containing differences to process.
|
|
52
|
+
* @returns A new object with formatting differences ignored.
|
|
53
|
+
*
|
|
54
|
+
|
|
55
|
+
*/
|
|
25
56
|
function ignoreFormattingDiff(diffData) {
|
|
26
57
|
return lodash_1.default.transform(diffData, (result, diffValue, key) => {
|
|
27
58
|
if (lodash_1.default.has(diffValue, '__new')) {
|
|
28
59
|
// Remove any trailing space
|
|
29
60
|
if (typeof lodash_1.default.get(diffValue, '__new') === 'string' &&
|
|
30
61
|
typeof lodash_1.default.get(diffValue, '__old') === 'string') {
|
|
31
|
-
if ((0, global_1.removeWhitespace)(lodash_1.default.get(diffValue, '__new')) !==
|
|
32
|
-
(0, global_1.removeWhitespace)(lodash_1.default.get(diffValue, '__old'))) {
|
|
62
|
+
if ((0, global_1.removeWhitespace)(lodash_1.default.get(diffValue, '__new', 'undefined')) !==
|
|
63
|
+
(0, global_1.removeWhitespace)(lodash_1.default.get(diffValue, '__old', 'undefined'))) {
|
|
33
64
|
lodash_1.default.set(result, key, lodash_1.default.get(diffValue, '__new'));
|
|
34
65
|
}
|
|
35
66
|
}
|
|
@@ -53,9 +84,20 @@ function ignoreFormattingDiff(diffData) {
|
|
|
53
84
|
}
|
|
54
85
|
});
|
|
55
86
|
}
|
|
56
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Computes the differences between two profiles and logs the process.
|
|
89
|
+
*
|
|
90
|
+
* @param fromProfile - The original profile to compare from.
|
|
91
|
+
* @param toProfile - The target profile to compare to.
|
|
92
|
+
* @param logger - The logger instance to use for logging information.
|
|
93
|
+
*
|
|
94
|
+
* @returns An object containing two properties:
|
|
95
|
+
* - `ignoreFormattingDiff`: The profile differences ignoring formatting changes.
|
|
96
|
+
* - `rawDiff`: The raw profile differences.
|
|
97
|
+
*/
|
|
57
98
|
function diffProfile(fromProfile, toProfile, logger) {
|
|
58
99
|
var _a;
|
|
100
|
+
logger.info(`Processing diff between: ${fromProfile.name}(v:${fromProfile.version}) and: ${toProfile.name}(v:${toProfile.version})`);
|
|
59
101
|
const profileDiff = {
|
|
60
102
|
addedControlIDs: [],
|
|
61
103
|
removedControlIDs: [],
|
|
@@ -72,9 +114,7 @@ function diffProfile(fromProfile, toProfile, logger) {
|
|
|
72
114
|
addedControls: {},
|
|
73
115
|
changedControls: {},
|
|
74
116
|
};
|
|
75
|
-
const fromControlIDs = fromProfile.controls
|
|
76
|
-
.map((control) => control.id)
|
|
77
|
-
.sort();
|
|
117
|
+
const fromControlIDs = fromProfile.controls.map((control) => control.id).sort();
|
|
78
118
|
const toControlIDs = toProfile.controls.map((control) => control.id).sort();
|
|
79
119
|
// Find new controls
|
|
80
120
|
const controlIDDiff = (_a = (0, json_diff_1.diff)(fromControlIDs, toControlIDs)) === null || _a === void 0 ? void 0 : _a.filter((item) => !(item.length === 1 && item[0] === ' '));
|
|
@@ -95,12 +135,12 @@ function diffProfile(fromProfile, toProfile, logger) {
|
|
|
95
135
|
const controlDiff = lodash_1.default.omit((0, json_diff_1.diff)(existingControl, newControl), 'code__deleted');
|
|
96
136
|
// logger.info("CONTROL DIFF:" + JSON.stringify(controlDiff, null, 2))
|
|
97
137
|
const renamedControlIgnoredFormatting = ignoreFormattingDiff(controlDiff);
|
|
98
|
-
logger.info(JSON.stringify(renamedControlIgnoredFormatting));
|
|
99
138
|
profileDiff.changedControls[newControl.id] = renamedControlIgnoredFormatting;
|
|
100
139
|
profileDiff.changedControlIDs.push(newControl.id);
|
|
101
140
|
originalDiff.changedControls[newControl.id] = controlDiff;
|
|
102
141
|
originalDiff.changedControlIDs.push(newControl.id);
|
|
103
142
|
logger.verbose(`Control ${existingControl.id} has been updated to ${newControl.id}`);
|
|
143
|
+
logger.debug(`Updated control content: ${JSON.stringify(renamedControlIgnoredFormatting)}`);
|
|
104
144
|
}
|
|
105
145
|
else {
|
|
106
146
|
profileDiff.removedControlIDs.push(diffValue[1]);
|
|
@@ -111,7 +151,7 @@ function diffProfile(fromProfile, toProfile, logger) {
|
|
|
111
151
|
logger.error(`Unable to find existing control ${diffValue[1]}`);
|
|
112
152
|
}
|
|
113
153
|
}
|
|
114
|
-
else if (diffValue[0] === '+' && !changedControlIds.includes(diffValue[1].toLowerCase()) && diffValue[1]) {
|
|
154
|
+
else if (diffValue[0] === '+' && !changedControlIds.includes(diffValue[1].toString().toLowerCase()) && diffValue[1]) {
|
|
115
155
|
logger.info(JSON.stringify(diffValue));
|
|
116
156
|
logger.info(JSON.stringify(changedControlIds));
|
|
117
157
|
profileDiff.addedControlIDs.push(diffValue[1]);
|
|
@@ -147,4 +187,3 @@ function diffProfile(fromProfile, toProfile, logger) {
|
|
|
147
187
|
}
|
|
148
188
|
return { ignoreFormattingDiff: profileDiff, rawDiff: originalDiff };
|
|
149
189
|
}
|
|
150
|
-
exports.diffProfile = diffProfile;
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { ProfileDiff } from '../types/diff';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a markdown representation of the differences between two profiles.
|
|
4
|
+
*
|
|
5
|
+
* The function processes the differences to create a renderable data structure
|
|
6
|
+
* that includes added controls, renamed controls, and updated properties such as
|
|
7
|
+
* checks, fixes, impacts, titles, and descriptions. It then uses a mustache template
|
|
8
|
+
* to render the markdown output.
|
|
9
|
+
*
|
|
10
|
+
* @param diff - An object containing the differences between two profiles.
|
|
11
|
+
* @param diff.ignoreFormattingDiff - The profile differences ignoring formatting changes.
|
|
12
|
+
* @param diff.rawDiff - The raw differences between the profiles.
|
|
13
|
+
* @returns A string containing the markdown representation of the differences.
|
|
14
|
+
*/
|
|
2
15
|
export declare function createDiffMarkdown(diff: {
|
|
3
16
|
ignoreFormattingDiff: ProfileDiff;
|
|
4
17
|
rawDiff: any;
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createDiffMarkdown =
|
|
3
|
+
exports.createDiffMarkdown = createDiffMarkdown;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const mustache_1 = tslib_1.__importDefault(require("mustache"));
|
|
6
6
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
7
|
const automatticUpdateTemplate_json_1 = tslib_1.__importDefault(require("../resources/automatticUpdateTemplate.json"));
|
|
8
|
+
/**
|
|
9
|
+
* Generates a markdown representation of the differences between two profiles.
|
|
10
|
+
*
|
|
11
|
+
* The function processes the differences to create a renderable data structure
|
|
12
|
+
* that includes added controls, renamed controls, and updated properties such as
|
|
13
|
+
* checks, fixes, impacts, titles, and descriptions. It then uses a mustache template
|
|
14
|
+
* to render the markdown output.
|
|
15
|
+
*
|
|
16
|
+
* @param diff - An object containing the differences between two profiles.
|
|
17
|
+
* @param diff.ignoreFormattingDiff - The profile differences ignoring formatting changes.
|
|
18
|
+
* @param diff.rawDiff - The raw differences between the profiles.
|
|
19
|
+
* @returns A string containing the markdown representation of the differences.
|
|
20
|
+
*/
|
|
8
21
|
function createDiffMarkdown(diff) {
|
|
9
22
|
const renderableDiffData = {
|
|
10
23
|
addedControls: Object.values(diff.ignoreFormattingDiff.addedControls),
|
|
@@ -26,8 +39,8 @@ function createDiffMarkdown(diff) {
|
|
|
26
39
|
Object.entries(diff.rawDiff.changedControls).forEach(([id, controlDiff]) => {
|
|
27
40
|
var _a, _b;
|
|
28
41
|
if ((_a = controlDiff.descs) === null || _a === void 0 ? void 0 : _a.check) {
|
|
29
|
-
const oldCheck = lodash_1.default.get(controlDiff.descs.check, '__old');
|
|
30
|
-
const newCheck = lodash_1.default.get(controlDiff.descs.check, '__new');
|
|
42
|
+
const oldCheck = lodash_1.default.get(controlDiff.descs.check, '__old', 'undefined');
|
|
43
|
+
const newCheck = lodash_1.default.get(controlDiff.descs.check, '__new', 'undefined');
|
|
31
44
|
if (oldCheck.replace(/\n/g, '').replace(/\W/g, '') !==
|
|
32
45
|
newCheck.replace(/\n/g, '').replace(/\W/g, '')) {
|
|
33
46
|
renderableDiffData.updatedChecks.push({
|
|
@@ -38,8 +51,8 @@ function createDiffMarkdown(diff) {
|
|
|
38
51
|
}
|
|
39
52
|
}
|
|
40
53
|
if ((_b = controlDiff.descs) === null || _b === void 0 ? void 0 : _b.fix) {
|
|
41
|
-
const oldFix = lodash_1.default.get(controlDiff.descs.fix, '__old');
|
|
42
|
-
const newFix = lodash_1.default.get(controlDiff.descs.fix, '__new');
|
|
54
|
+
const oldFix = lodash_1.default.get(controlDiff.descs.fix, '__old', 'undefined');
|
|
55
|
+
const newFix = lodash_1.default.get(controlDiff.descs.fix, '__new', 'undefined');
|
|
43
56
|
if (oldFix.replace(/\n/g, '').replace(/\W/g, '') !==
|
|
44
57
|
newFix.replace(/\n/g, '').replace(/\W/g, '')) {
|
|
45
58
|
renderableDiffData.updatedFixes.push({
|
|
@@ -50,8 +63,8 @@ function createDiffMarkdown(diff) {
|
|
|
50
63
|
}
|
|
51
64
|
}
|
|
52
65
|
if (controlDiff.impact) {
|
|
53
|
-
const oldImpact = lodash_1.default.get(controlDiff.impact, '__old');
|
|
54
|
-
const newImpact = lodash_1.default.get(controlDiff.impact, '__new');
|
|
66
|
+
const oldImpact = lodash_1.default.get(controlDiff.impact, '__old', 'undefined');
|
|
67
|
+
const newImpact = lodash_1.default.get(controlDiff.impact, '__new', 'undefined');
|
|
55
68
|
if (oldImpact !== newImpact) {
|
|
56
69
|
renderableDiffData.updatedImpacts.push({
|
|
57
70
|
id: id,
|
|
@@ -61,8 +74,8 @@ function createDiffMarkdown(diff) {
|
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
76
|
if (controlDiff.title) {
|
|
64
|
-
const oldTitle = lodash_1.default.get(controlDiff.title, '__old');
|
|
65
|
-
const newTitle = lodash_1.default.get(controlDiff.title, '__new');
|
|
77
|
+
const oldTitle = lodash_1.default.get(controlDiff.title, '__old', 'undefined');
|
|
78
|
+
const newTitle = lodash_1.default.get(controlDiff.title, '__new', 'undefined');
|
|
66
79
|
if (oldTitle !== newTitle) {
|
|
67
80
|
renderableDiffData.updatedTitles.push({
|
|
68
81
|
id: id,
|
|
@@ -72,8 +85,8 @@ function createDiffMarkdown(diff) {
|
|
|
72
85
|
}
|
|
73
86
|
}
|
|
74
87
|
if (controlDiff.desc) {
|
|
75
|
-
const oldDesc = lodash_1.default.get(controlDiff.desc, '__old');
|
|
76
|
-
const newDesc = lodash_1.default.get(controlDiff.desc, '__new');
|
|
88
|
+
const oldDesc = lodash_1.default.get(controlDiff.desc, '__old', 'undefined');
|
|
89
|
+
const newDesc = lodash_1.default.get(controlDiff.desc, '__new', 'undefined');
|
|
77
90
|
if (oldDesc !== newDesc) {
|
|
78
91
|
renderableDiffData.updatedDescriptions.push({
|
|
79
92
|
id: id,
|
|
@@ -86,4 +99,3 @@ function createDiffMarkdown(diff) {
|
|
|
86
99
|
// Render output
|
|
87
100
|
return mustache_1.default.render(automatticUpdateTemplate_json_1.default.data, renderableDiffData);
|
|
88
101
|
}
|
|
89
|
-
exports.createDiffMarkdown = createDiffMarkdown;
|
|
@@ -1,7 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps a given string to a specified line length by inserting newline characters.
|
|
3
|
+
*
|
|
4
|
+
* @param s - The string to be wrapped.
|
|
5
|
+
* @param lineLength - The maximum length of each line before wrapping. Defaults to 80.
|
|
6
|
+
* @returns The wrapped string with newline characters inserted at appropriate positions.
|
|
7
|
+
*/
|
|
1
8
|
export declare function wrap(s: string, lineLength?: number): string;
|
|
9
|
+
/**
|
|
10
|
+
* Removes newline characters and excessive whitespace from a given string.
|
|
11
|
+
*
|
|
12
|
+
* This function replaces all newline characters (`\n` and `\\n`) with a single space,
|
|
13
|
+
* and collapses multiple spaces or tabs into a single space.
|
|
14
|
+
*
|
|
15
|
+
* @param s - The input string to be unformatted.
|
|
16
|
+
* @returns The unformatted string with newline characters and excessive whitespace removed.
|
|
17
|
+
*/
|
|
2
18
|
export declare function unformatText(s: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Removes all whitespace characters from the given input string.
|
|
21
|
+
*
|
|
22
|
+
* @param input - The string from which to remove whitespace.
|
|
23
|
+
* @returns A new string with all whitespace characters removed.
|
|
24
|
+
*/
|
|
3
25
|
export declare function removeWhitespace(input: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Escapes quotes in a given string based on the presence of single and double quotes.
|
|
28
|
+
*
|
|
29
|
+
* - If the string contains both single and double quotes, it wraps the string in `%q()` and escapes special case backslashes.
|
|
30
|
+
* - If the string contains only single quotes, it wraps the string in double quotes and escapes double quotes.
|
|
31
|
+
* - If the string contains only double quotes or no quotes, it wraps the string in single quotes and escapes single quotes.
|
|
32
|
+
*
|
|
33
|
+
* @param s - The input string to escape quotes in.
|
|
34
|
+
* @returns The string with appropriately escaped quotes.
|
|
35
|
+
*/
|
|
4
36
|
export declare function escapeQuotes(s: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Replaces all instances of the placeholder `{{{{newlineHERE}}}}` in the given string with newline characters.
|
|
39
|
+
*
|
|
40
|
+
* @param s - The string containing the placeholders to be replaced.
|
|
41
|
+
* @returns The modified string with placeholders replaced by newline characters.
|
|
42
|
+
*/
|
|
5
43
|
export declare function removeNewlinePlaceholders(s: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Retrieves the value from the first path in the provided paths array that exists in the given object.
|
|
46
|
+
*
|
|
47
|
+
* @param object - The object to search for the paths.
|
|
48
|
+
* @param paths - An array of string paths to check in the object.
|
|
49
|
+
* @returns The value from the first existing path in the object as a string.
|
|
50
|
+
* @throws Will throw an error if none of the paths exist in the object.
|
|
51
|
+
*/
|
|
6
52
|
export declare function getFirstPath(object: Record<string, unknown>, paths: string[]): string;
|
|
53
|
+
/**
|
|
54
|
+
* Checks if the given file object has any of the specified paths.
|
|
55
|
+
*
|
|
56
|
+
* @param file - The object to check for the presence of the path(s).
|
|
57
|
+
* @param path - A string or an array of strings representing the path(s) to check.
|
|
58
|
+
* @returns `true` if any of the specified paths exist in the object, otherwise `false`.
|
|
59
|
+
*/
|
|
7
60
|
export declare function hasPath(file: Record<string, unknown>, path: string | string[]): boolean;
|
package/lib/utilities/global.js
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.wrap = wrap;
|
|
4
|
+
exports.unformatText = unformatText;
|
|
5
|
+
exports.removeWhitespace = removeWhitespace;
|
|
6
|
+
exports.escapeQuotes = escapeQuotes;
|
|
7
|
+
exports.removeNewlinePlaceholders = removeNewlinePlaceholders;
|
|
8
|
+
exports.getFirstPath = getFirstPath;
|
|
9
|
+
exports.hasPath = hasPath;
|
|
4
10
|
const tslib_1 = require("tslib");
|
|
5
11
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Wraps a given string to a specified line length by inserting newline characters.
|
|
14
|
+
*
|
|
15
|
+
* @param s - The string to be wrapped.
|
|
16
|
+
* @param lineLength - The maximum length of each line before wrapping. Defaults to 80.
|
|
17
|
+
* @returns The wrapped string with newline characters inserted at appropriate positions.
|
|
18
|
+
*/
|
|
7
19
|
function wrap(s, lineLength = 80) {
|
|
8
20
|
let newString = '';
|
|
9
21
|
let currentLength = 0;
|
|
@@ -34,25 +46,75 @@ function wrap(s, lineLength = 80) {
|
|
|
34
46
|
}
|
|
35
47
|
return newString;
|
|
36
48
|
}
|
|
37
|
-
|
|
38
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Removes newline characters and excessive whitespace from a given string.
|
|
51
|
+
*
|
|
52
|
+
* This function replaces all newline characters (`\n` and `\\n`) with a single space,
|
|
53
|
+
* and collapses multiple spaces or tabs into a single space.
|
|
54
|
+
*
|
|
55
|
+
* @param s - The input string to be unformatted.
|
|
56
|
+
* @returns The unformatted string with newline characters and excessive whitespace removed.
|
|
57
|
+
*/
|
|
39
58
|
function unformatText(s) {
|
|
40
59
|
return s.replace(/\n/g, ' ').replace(/\\n/g, ' ').replace(/( +|\t)/g, ' ');
|
|
41
60
|
}
|
|
42
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Removes all whitespace characters from the given input string.
|
|
63
|
+
*
|
|
64
|
+
* @param input - The string from which to remove whitespace.
|
|
65
|
+
* @returns A new string with all whitespace characters removed.
|
|
66
|
+
*/
|
|
43
67
|
function removeWhitespace(input) {
|
|
44
68
|
return input.replace(/\s/gi, '');
|
|
45
69
|
}
|
|
46
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Escapes backslashes that precede closing parentheses in a given string.
|
|
72
|
+
*
|
|
73
|
+
* This function searches for occurrences of backslashes followed by a closing
|
|
74
|
+
* parenthesis in the input string and replaces each occurrence with two
|
|
75
|
+
* backslashes followed by a closing parenthesis. This effectively escapes
|
|
76
|
+
* the backslashes in such cases.
|
|
77
|
+
*
|
|
78
|
+
* @param s - The input string in which to escape backslashes.
|
|
79
|
+
* @returns A new string with the specified backslashes escaped.
|
|
80
|
+
*/
|
|
47
81
|
const escapeSpecialCaseBackslashes = (s) => {
|
|
48
|
-
return s.replace(/\\\)/g, '\\\\)');
|
|
82
|
+
return s.replace(/\\\)/g, '\\\\)');
|
|
49
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Escapes single quotes and backslashes in a given string.
|
|
86
|
+
*
|
|
87
|
+
* This function replaces all backslashes (`\`) with double backslashes (`\\`)
|
|
88
|
+
* and all single quotes (`'`) with escaped single quotes (`\'`).
|
|
89
|
+
*
|
|
90
|
+
* @param s - The input string to be escaped.
|
|
91
|
+
* @returns The escaped string with single quotes and backslashes properly escaped.
|
|
92
|
+
*/
|
|
50
93
|
const escapeSingleQuotes = (s) => {
|
|
51
|
-
return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
94
|
+
return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
52
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Escapes backslashes and double quotes in a given string.
|
|
98
|
+
*
|
|
99
|
+
* This function replaces all backslashes (`\`) with double backslashes (`\\`)
|
|
100
|
+
* and all double quotes (`"`) with escaped double quotes (`\"`).
|
|
101
|
+
*
|
|
102
|
+
* @param s - The input string to be escaped.
|
|
103
|
+
* @returns The escaped string with backslashes and double quotes properly escaped.
|
|
104
|
+
*/
|
|
53
105
|
const escapeDoubleQuotes = (s) => {
|
|
54
|
-
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
106
|
+
return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
55
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* Escapes quotes in a given string based on the presence of single and double quotes.
|
|
110
|
+
*
|
|
111
|
+
* - If the string contains both single and double quotes, it wraps the string in `%q()` and escapes special case backslashes.
|
|
112
|
+
* - If the string contains only single quotes, it wraps the string in double quotes and escapes double quotes.
|
|
113
|
+
* - If the string contains only double quotes or no quotes, it wraps the string in single quotes and escapes single quotes.
|
|
114
|
+
*
|
|
115
|
+
* @param s - The input string to escape quotes in.
|
|
116
|
+
* @returns The string with appropriately escaped quotes.
|
|
117
|
+
*/
|
|
56
118
|
function escapeQuotes(s) {
|
|
57
119
|
if (s.includes("'") && s.includes('"')) {
|
|
58
120
|
return `%q(${escapeSpecialCaseBackslashes(removeNewlinePlaceholders(s))})`;
|
|
@@ -64,11 +126,23 @@ function escapeQuotes(s) {
|
|
|
64
126
|
return `'${escapeSingleQuotes(removeNewlinePlaceholders(s))}'`;
|
|
65
127
|
}
|
|
66
128
|
}
|
|
67
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Replaces all instances of the placeholder `{{{{newlineHERE}}}}` in the given string with newline characters.
|
|
131
|
+
*
|
|
132
|
+
* @param s - The string containing the placeholders to be replaced.
|
|
133
|
+
* @returns The modified string with placeholders replaced by newline characters.
|
|
134
|
+
*/
|
|
68
135
|
function removeNewlinePlaceholders(s) {
|
|
69
136
|
return s.replace(/\{\{\{\{newlineHERE\}\}\}\}/g, '\n');
|
|
70
137
|
}
|
|
71
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves the value from the first path in the provided paths array that exists in the given object.
|
|
140
|
+
*
|
|
141
|
+
* @param object - The object to search for the paths.
|
|
142
|
+
* @param paths - An array of string paths to check in the object.
|
|
143
|
+
* @returns The value from the first existing path in the object as a string.
|
|
144
|
+
* @throws Will throw an error if none of the paths exist in the object.
|
|
145
|
+
*/
|
|
72
146
|
function getFirstPath(object, paths) {
|
|
73
147
|
const index = lodash_1.default.findIndex(paths, (p) => hasPath(object, p));
|
|
74
148
|
if (index === -1) {
|
|
@@ -78,7 +152,13 @@ function getFirstPath(object, paths) {
|
|
|
78
152
|
return lodash_1.default.get(object, paths[index]);
|
|
79
153
|
}
|
|
80
154
|
}
|
|
81
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Checks if the given file object has any of the specified paths.
|
|
157
|
+
*
|
|
158
|
+
* @param file - The object to check for the presence of the path(s).
|
|
159
|
+
* @param path - A string or an array of strings representing the path(s) to check.
|
|
160
|
+
* @returns `true` if any of the specified paths exist in the object, otherwise `false`.
|
|
161
|
+
*/
|
|
82
162
|
function hasPath(file, path) {
|
|
83
163
|
let pathArray;
|
|
84
164
|
if (typeof path === 'string') {
|
|
@@ -89,4 +169,3 @@ function hasPath(file, path) {
|
|
|
89
169
|
}
|
|
90
170
|
return lodash_1.default.some(pathArray, (p) => lodash_1.default.has(file, p));
|
|
91
171
|
}
|
|
92
|
-
exports.hasPath = hasPath;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import winston from 'winston';
|
|
2
|
-
export declare function createWinstonLogger(level?: string): winston.Logger;
|
|
2
|
+
export declare function createWinstonLogger(mapperName: string, level?: string): winston.Logger;
|
package/lib/utilities/logging.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createWinstonLogger =
|
|
3
|
+
exports.createWinstonLogger = createWinstonLogger;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const winston_1 = tslib_1.__importDefault(require("winston"));
|
|
6
|
-
function createWinstonLogger(level = 'debug') {
|
|
6
|
+
function createWinstonLogger(mapperName, level = 'debug') {
|
|
7
7
|
return winston_1.default.createLogger({
|
|
8
8
|
transports: [new winston_1.default.transports.Console()],
|
|
9
9
|
level: level,
|
|
10
|
-
format: winston_1.default.format.combine(winston_1.default.format.timestamp({
|
|
10
|
+
format: winston_1.default.format.combine(winston_1.default.format.simple(), winston_1.default.format.timestamp({
|
|
11
11
|
format: 'MMM-DD-YYYY HH:mm:ss Z',
|
|
12
|
-
}), winston_1.default.format.printf(
|
|
12
|
+
}), winston_1.default.format.printf(
|
|
13
|
+
// Using the ANSI escape code sequence initiator (\xb[) to change output colors
|
|
14
|
+
// Colors used are: 33m (yellow) and 34m (blue)
|
|
15
|
+
// \x1b[0m : Resets the color settings to the default
|
|
16
|
+
info => `\x1b[33m[${[info.timestamp]} -> ${mapperName}]:\x1b[0m \x1b[34m${info.message}\x1b[0m`)),
|
|
13
17
|
});
|
|
14
18
|
}
|
|
15
|
-
exports.createWinstonLogger = createWinstonLogger;
|
|
@@ -3,7 +3,18 @@ import Control from '../objects/control';
|
|
|
3
3
|
import Profile from '../objects/profile';
|
|
4
4
|
import { ProfileDiff } from '../types/diff';
|
|
5
5
|
import { OvalDefinitionValue } from '../types/oval';
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Represents the return type of an updated profile operation.
|
|
8
|
+
*
|
|
9
|
+
* @typedef UpdatedProfileReturn
|
|
10
|
+
*
|
|
11
|
+
* @property {Profile} profile - The updated profile object.
|
|
12
|
+
* @property {Object} diff - The differences between the original and updated profiles.
|
|
13
|
+
* @property {ProfileDiff} diff.ignoreFormattingDiff - The differences ignoring formatting changes.
|
|
14
|
+
* @property {Record<string, unknown>} diff.rawDiff - The raw differences as a record.
|
|
15
|
+
* @property {string} markdown - The markdown representation of the differences.
|
|
16
|
+
*/
|
|
17
|
+
export type UpdatedProfileReturn = {
|
|
7
18
|
profile: Profile;
|
|
8
19
|
diff: {
|
|
9
20
|
ignoreFormattingDiff: ProfileDiff;
|
|
@@ -11,8 +22,56 @@ export declare type UpdatedProfileReturn = {
|
|
|
11
22
|
};
|
|
12
23
|
markdown: string;
|
|
13
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* This is the most likely thing to break if you are getting code formatting issues.
|
|
27
|
+
*
|
|
28
|
+
* Extracts the `describe` block (what is actually run by inspec for validation)
|
|
29
|
+
* from an InSpec control object, collapsing multi-line strings.
|
|
30
|
+
*
|
|
31
|
+
* @param control - The InSpec control object containing the code to extract the `describe` block from.
|
|
32
|
+
* @returns The extracted `describe` block as a string, or an empty string if the control has no code.
|
|
33
|
+
*/
|
|
14
34
|
export declare function getExistingDescribeFromControl(control: Control): string;
|
|
35
|
+
/**
|
|
36
|
+
* Finds an updated control from a list of updated controls by matching all possible identifiers.
|
|
37
|
+
*
|
|
38
|
+
* This function attempts to find a matching control in the `updatedControls` array by comparing
|
|
39
|
+
* the `id` of the `existingControl` with the `id` of each control in the `updatedControls` array.
|
|
40
|
+
* If no match is found based on `id`, it then tries to match based on legacy identifiers found
|
|
41
|
+
* in the `tags.legacy` property of each control in the `updatedControls` array.
|
|
42
|
+
*
|
|
43
|
+
* @param existingControl - The control to find a match for in the updated controls.
|
|
44
|
+
* @param updatedControls - An array of updated controls to search through.
|
|
45
|
+
* @returns The matching updated control if found, otherwise `undefined`.
|
|
46
|
+
*/
|
|
15
47
|
export declare function findUpdatedControlByAllIdentifiers(existingControl: Control, updatedControls: Control[]): Control | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Updates a given control object with the provided partial update and logs the process.
|
|
50
|
+
*
|
|
51
|
+
* @param {Control} from - The original control object to be updated.
|
|
52
|
+
* @param {Partial<Control>} update - An object containing the properties to update in the original control.
|
|
53
|
+
* @param {winston.Logger} logger - A logger instance to log debug information.
|
|
54
|
+
* @returns {Control} - The updated control object.
|
|
55
|
+
*/
|
|
16
56
|
export declare function updateControl(from: Control, update: Partial<Control>, logger: winston.Logger): Control;
|
|
57
|
+
/**
|
|
58
|
+
* Updates the describe block of a control with the describe block from another control.
|
|
59
|
+
*
|
|
60
|
+
* @param from - The control from which to get the existing describe block.
|
|
61
|
+
* @param update - The partial control data to update.
|
|
62
|
+
* @param logger - The logger instance to use for logging debug information.
|
|
63
|
+
* @returns The updated control with the describe block from the `from` control.
|
|
64
|
+
*/
|
|
65
|
+
export declare function updateControlDescribeBlock(from: Control, update: Partial<Control>, logger: winston.Logger): Control;
|
|
66
|
+
/**
|
|
67
|
+
* Updates a given profile with new metadata and controls from another profile.
|
|
68
|
+
*
|
|
69
|
+
* @param from - The original profile to be updated.
|
|
70
|
+
* @param using - The profile containing the new metadata and controls.
|
|
71
|
+
* @param logger - A winston logger instance for logging debug information.
|
|
72
|
+
* @returns An object containing the updated profile and the diff between the original and updated profiles, excluding markdown.
|
|
73
|
+
*
|
|
74
|
+
* @throws Will throw an error if a new control is added but the control data is not available.
|
|
75
|
+
*/
|
|
17
76
|
export declare function updateProfile(from: Profile, using: Profile, logger: winston.Logger): Omit<UpdatedProfileReturn, 'markdown'>;
|
|
18
77
|
export declare function updateProfileUsingXCCDF(from: Profile, using: string, id: 'group' | 'rule' | 'version' | 'cis', logger: winston.Logger, ovalDefinitions?: Record<string, OvalDefinitionValue>): UpdatedProfileReturn;
|