filegrc 0.9.1 → 0.9.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/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import {
|
|
4
|
+
authoritativeSourceRevisionValue,
|
|
4
5
|
collectionRevisionInputs,
|
|
5
6
|
collectionScopeRevisionFacts
|
|
6
7
|
} from "./collection-scope.js";
|
|
@@ -16,15 +17,19 @@ export function collectionRevision(loaded, resourceType, options = {}) {
|
|
|
16
17
|
.map((input) => [input.record.id, input]));
|
|
17
18
|
const authoritativeSource = loaded.resources.find(({ id }) => id === options.authoritativeSourceId);
|
|
18
19
|
if (authoritativeSource) {
|
|
19
|
-
inputs.set(authoritativeSource.id, {
|
|
20
|
+
inputs.set(authoritativeSource.id, {
|
|
21
|
+
record: authoritativeSource,
|
|
22
|
+
value: authoritativeSourceRevisionValue(authoritativeSource),
|
|
23
|
+
includeContent: true
|
|
24
|
+
});
|
|
20
25
|
}
|
|
21
26
|
const records = [...inputs.values()]
|
|
22
|
-
.map(({ record, value }) => ({
|
|
27
|
+
.map(({ record, value, includeContent }) => ({
|
|
23
28
|
id: record.id,
|
|
24
29
|
revision: createHash("sha256")
|
|
25
30
|
.update(JSON.stringify(canonicalRecordValue(loaded.model, record.type, value)))
|
|
26
31
|
.digest("hex"),
|
|
27
|
-
contentRevisions: markdownEntries(loaded.model, record).flatMap(({ path }) => {
|
|
32
|
+
contentRevisions: (includeContent ? markdownEntries(loaded.model, record) : []).flatMap(({ path }) => {
|
|
28
33
|
try {
|
|
29
34
|
const content = readFileSync(resolveDataPath(loaded.root, path), "utf8");
|
|
30
35
|
return [{ path, revision: createHash("sha256").update(content).digest("hex") }];
|
package/src/collection-scope.js
CHANGED
|
@@ -39,7 +39,7 @@ export function scopedCollectionRecords(loaded, resourceType, program) {
|
|
|
39
39
|
export function collectionRevisionInputs(loaded, resourceType, program) {
|
|
40
40
|
const reviewed = scopedCollectionRecords(loaded, resourceType, program);
|
|
41
41
|
if (!modelSupports(loaded.model, "program-scope")) {
|
|
42
|
-
return reviewed.map((record) => ({ record, value: record }));
|
|
42
|
+
return reviewed.map((record) => ({ record, value: record, includeContent: true }));
|
|
43
43
|
}
|
|
44
44
|
const byId = new Map(loaded.resources.map((record) => [record.id, record]));
|
|
45
45
|
const records = new Map(reviewed.map((record) => [record.id, record]));
|
|
@@ -90,7 +90,9 @@ export function collectionRevisionInputs(loaded, resourceType, program) {
|
|
|
90
90
|
record,
|
|
91
91
|
value: reviewedIds.has(record.id)
|
|
92
92
|
? record
|
|
93
|
-
: dependencyRevisionValue(resourceType, record)
|
|
93
|
+
: dependencyRevisionValue(resourceType, record),
|
|
94
|
+
includeContent: reviewedIds.has(record.id)
|
|
95
|
+
|| dependencyContentAffectsRevision(resourceType, record.type)
|
|
94
96
|
}));
|
|
95
97
|
}
|
|
96
98
|
|
|
@@ -138,9 +140,20 @@ export function collectionScopeRevisionFacts(loaded, resourceType, program) {
|
|
|
138
140
|
return common;
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
export function authoritativeSourceRevisionValue(record) {
|
|
144
|
+
return Object.fromEntries(Object.entries(record).filter(([field]) => (
|
|
145
|
+
!authoritativeSourceBookkeepingFields.has(field)
|
|
146
|
+
)));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const authoritativeSourceBookkeepingFields = new Set([
|
|
150
|
+
"tags",
|
|
151
|
+
"statusTransition"
|
|
152
|
+
]);
|
|
153
|
+
|
|
141
154
|
const dependencyFields = {
|
|
142
155
|
framework: {
|
|
143
|
-
system: ["id", "type", "status", "purpose", "servicesProvided", "boundary", "exclusions", "informationTypeIds", "classificationId", "internetExposed"],
|
|
156
|
+
system: ["id", "type", "status", "purpose", "servicesProvided", "boundary", "exclusions", "criticality", "informationTypeIds", "classificationId", "internetExposed", "continuityObjectives"],
|
|
144
157
|
requirement: ["id", "type", "title", "frameworkId", "reference", "description", "parentRequirementId"]
|
|
145
158
|
},
|
|
146
159
|
vendor: {
|
|
@@ -154,22 +167,29 @@ const dependencyFields = {
|
|
|
154
167
|
},
|
|
155
168
|
component: {
|
|
156
169
|
system: ["id", "type", "status", "purpose", "servicesProvided", "boundary", "exclusions", "criticality", "informationTypeIds", "classificationId", "internetExposed", "continuityObjectives"],
|
|
157
|
-
control: ["id", "type", "status", "
|
|
158
|
-
vendor: ["id", "type", "status", "category", "criticality", "description", "
|
|
170
|
+
control: ["id", "type", "status", "systemIds", "componentIds", "evidenceSourceComponentIds"],
|
|
171
|
+
vendor: ["id", "type", "status", "category", "criticality", "description", "startDate", "endDate"],
|
|
159
172
|
classification: ["id", "type", "status", "rank", "description", "handlingRequirements"],
|
|
160
173
|
"information-type": ["id", "type", "status", "classificationId", "description"]
|
|
161
174
|
},
|
|
162
175
|
"complementary-control": {
|
|
163
|
-
system: ["id", "type", "status", "purpose", "servicesProvided", "boundary", "exclusions", "informationTypeIds", "classificationId", "internetExposed"],
|
|
164
|
-
control: ["id", "type", "status", "statement", "activity", "
|
|
176
|
+
system: ["id", "type", "status", "purpose", "servicesProvided", "boundary", "exclusions", "criticality", "informationTypeIds", "classificationId", "internetExposed", "continuityObjectives"],
|
|
177
|
+
control: ["id", "type", "status", "statement", "activity", "systemIds", "componentIds", "evidenceSourceComponentIds"],
|
|
165
178
|
vendor: ["id", "type", "status", "category", "criticality", "description", "standardAgreement", "agreementDocumentId", "startDate", "endDate", "classificationId", "informationTypeIds"],
|
|
166
179
|
requirement: ["id", "type", "title", "frameworkId", "reference", "description", "parentRequirementId"],
|
|
167
180
|
commitment: ["id", "type", "status", "commitmentKind", "statement", "systemIds", "requirementIds", "controlIds", "customerFacing", "effectiveOn"],
|
|
168
181
|
document: ["id", "type", "status", "documentKind", "version", "effectiveOn", "approvedOn", "approvedContentRevisions", "systemIds", "controlIds", "componentIds", "classificationId"],
|
|
169
|
-
component: ["id", "type", "status", "componentKind", "description", "vendorId", "systemUses", "informationUses", "internetExposed"]
|
|
182
|
+
component: ["id", "type", "status", "componentKind", "description", "criticality", "vendorId", "systemUses", "informationUses", "internetExposed", "classificationId", "continuityObjectives"]
|
|
170
183
|
}
|
|
171
184
|
};
|
|
172
185
|
|
|
186
|
+
const dependencyContentTypes = {
|
|
187
|
+
framework: new Set(["system"]),
|
|
188
|
+
vendor: new Set(["document"]),
|
|
189
|
+
component: new Set(["system"]),
|
|
190
|
+
"complementary-control": new Set(["system", "control", "document", "component"])
|
|
191
|
+
};
|
|
192
|
+
|
|
173
193
|
function dependencyRevisionValue(resourceType, record) {
|
|
174
194
|
const fields = dependencyFields[resourceType]?.[record.type];
|
|
175
195
|
if (!fields) return { id: record.id, type: record.type };
|
|
@@ -178,6 +198,10 @@ function dependencyRevisionValue(resourceType, record) {
|
|
|
178
198
|
.map((field) => [field, record[field]]));
|
|
179
199
|
}
|
|
180
200
|
|
|
201
|
+
function dependencyContentAffectsRevision(resourceType, dependencyType) {
|
|
202
|
+
return dependencyContentTypes[resourceType]?.has(dependencyType) || false;
|
|
203
|
+
}
|
|
204
|
+
|
|
181
205
|
function sorted(values) {
|
|
182
206
|
return [...(values || [])].sort();
|
|
183
207
|
}
|