filegrc 0.13.0 → 0.13.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,6 @@
1
1
  {
2
2
  "name": "filegrc",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "Zero-dependency Git-native GRC engine",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,7 +22,9 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "test": "node ../../scripts/run-filegrc-tests.mjs",
25
- "test:fast": "node ../../scripts/run-filegrc-tests.mjs --fast",
25
+ "test:unit": "node ../../scripts/run-filegrc-tests.mjs --tier unit",
26
+ "test:integration": "node ../../scripts/run-filegrc-tests.mjs --tier integration",
27
+ "test:fast": "npm run test:unit",
26
28
  "test:full": "npm test"
27
29
  },
28
30
  "engines": {
@@ -102,17 +102,37 @@ export async function scaffoldCollectionReview(input = process.cwd(), options =
102
102
  const resourceType = requiredType(loaded, options.resourceType);
103
103
  const assessment = assessCollectionReview(loaded, resourceType, { programId: program.id });
104
104
  const allowedDecisions = assessment.configuration.decisions || ["complete"];
105
+ const now = options.now ? new Date(options.now) : new Date();
106
+ if (Number.isNaN(now.getTime())) throw new Error("A valid Collection Review time is required.");
107
+ const priorReview = assessment.review;
108
+ const v4 = modelSupports(loaded.model, "program-scope");
109
+ const priorAuthoritativeSourceId = priorReview?.authoritativeComponentId || priorReview?.authoritativeSystemId || null;
110
+ const priorAuthoritativeSourceActive = priorReview?.decision !== "externally-managed" || loaded.resources.some((record) => (
111
+ record.type === (v4 ? "component" : "system")
112
+ && record.id === priorAuthoritativeSourceId
113
+ && record.status === "active"
114
+ ));
115
+ const priorDecisionStillValid = allowedDecisions.includes(priorReview?.decision)
116
+ && priorAuthoritativeSourceActive
117
+ && (assessment.records.length
118
+ ? priorReview.decision !== "zero-population"
119
+ : priorReview.decision !== "complete");
120
+ const preservedAuthoritativeSourceId = priorDecisionStillValid && priorReview.decision === "externally-managed"
121
+ ? priorAuthoritativeSourceId
122
+ : null;
105
123
  return {
106
124
  resourceType,
107
- decision: assessment.records.length
125
+ decision: priorDecisionStillValid ? priorReview.decision : (assessment.records.length
108
126
  ? "complete"
109
- : allowedDecisions.includes("zero-population") ? "zero-population" : null,
110
- rationale: null,
111
- reviewedByIds: [],
112
- reviewedOn: null,
113
- ...(modelSupports(loaded.model, "program-scope")
114
- ? { authoritativeComponentId: null }
115
- : { authoritativeSystemId: null })
127
+ : allowedDecisions.includes("zero-population") ? "zero-population" : null),
128
+ rationale: priorReview?.rationale || null,
129
+ reviewedByIds: [...(priorReview?.reviewedByIds || [])],
130
+ reviewedOn: priorReview?.reviewedOn
131
+ ? currentCalendarDate(loaded.workspace.timezone, now)
132
+ : null,
133
+ ...(v4
134
+ ? { authoritativeComponentId: preservedAuthoritativeSourceId }
135
+ : { authoritativeSystemId: preservedAuthoritativeSourceId })
116
136
  };
117
137
  }
118
138
 
package/src/files.js CHANGED
@@ -965,14 +965,22 @@ async function updateContentUnlocked(input, dataRelativePath, source, options) {
965
965
  const path = resolveDataPath(loaded.root, dataRelativePath);
966
966
  const previous = await readFile(path, "utf8");
967
967
  assertRevision(previous, options.expectedRevision, "The Markdown file");
968
- const before = await validateWorkspace(loaded);
968
+ const deferValidation = workspaceValidationDeferred();
969
+ const before = deferValidation ? null : await validateWorkspace(loaded);
969
970
  const nextSource = source.endsWith("\n") ? source : `${source}\n`;
970
971
  await writeTextAtomic(path, nextSource);
971
972
  try {
972
- const result = await validateWorkspace(loaded.root);
973
- const introduced = newErrors(result, before);
974
- if (introduced.length) throw new Error(formatWriteFailure(introduced, dataRelativePath));
975
- return { path, dataRelativePath };
973
+ if (!deferValidation) {
974
+ const result = await validateWorkspace(loaded.root);
975
+ const introduced = newErrors(result, before);
976
+ if (introduced.length) throw new Error(formatWriteFailure(introduced, dataRelativePath));
977
+ }
978
+ return {
979
+ path,
980
+ dataRelativePath,
981
+ source: nextSource,
982
+ revision: contentRevision(nextSource)
983
+ };
976
984
  } catch (error) {
977
985
  await writeTextAtomic(path, previous);
978
986
  throw error;