PluginProbe
404 Solution / trunk
404 Solution vtrunk
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / contracts / contractFileIO.js

contractFileIO.js in 404 Solution trunk, at contracts/contractFileIO.js

82 lines 2.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * contractFileIO: filesystem-access layer for the contract validation gate.
3 *
4 * Pure data-access concern. Reads files and directories from disk and parses
5 * their contents. Contains no business/validation logic; callers in
6 * validate-contracts.js decide what the read data means for contract validity.
7 *
8 * Exposes:
9 * fileExists(p) -> boolean
10 * pathExists(p) -> boolean
11 * filesEqual(left, right) -> boolean
12 * loadJson(p) -> parsed JSON (throws on bad JSON)
13 * findJsonSchemaFiles(dir) -> string[] of *.schema.json paths
14 * fileContainsAnnotation(filePath, id, name?) -> boolean
15 * fileContainsParityAnnotation(filePath, id) -> boolean
16 */
17 // allow-no-test-found: file-IO layer of the contract-validation CLI gate; it is the data-access half of validate-contracts.js (its only consumer) and is exercised whenever that gate runs over the real contracts/schemas tree. There is no isolated JS unit spec because it only wraps fs/path reads, with no business logic to assert in isolation.
18
19 const fs = require("fs");
20 const path = require("path");
21
22 function fileExists(p) {
23 try {
24 return fs.statSync(p).isFile();
25 } catch {
26 return false; // allow-silent-catch: stat failure means file does not exist
27 }
28 }
29
30 function pathExists(p) {
31 try {
32 fs.statSync(p);
33 return true;
34 } catch {
35 return false; // allow-silent-catch: stat failure means path is unavailable
36 }
37 }
38
39 function filesEqual(left, right) {
40 return fs.readFileSync(left).equals(fs.readFileSync(right));
41 }
42
43 function loadJson(p) {
44 return JSON.parse(fs.readFileSync(p, "utf8"));
45 }
46
47 function findJsonSchemaFiles(dir) {
48 const results = [];
49 if (!fs.existsSync(dir)) return results;
50 for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
51 const full = path.join(dir, entry.name);
52 if (entry.isDirectory()) {
53 results.push(...findJsonSchemaFiles(full));
54 } else if (entry.name.endsWith(".schema.json")) {
55 results.push(full);
56 }
57 }
58 return results;
59 }
60
61 function fileContainsAnnotation(filePath, contractId, annotationName = "contract") {
62 const content = fs.readFileSync(filePath, "utf8");
63 const pattern = new RegExp(`@${annotationName}\\s+${contractId.replace(/-/g, "\\-")}\\b`);
64 return pattern.test(content);
65 }
66
67 function fileContainsParityAnnotation(filePath, contractId) {
68 const content = fs.readFileSync(filePath, "utf8");
69 const pattern = new RegExp(`@parityTest\\s+${contractId.replace(/-/g, "\\-")}\\b`);
70 return pattern.test(content);
71 }
72
73 module.exports = {
74 fileExists,
75 pathExists,
76 filesEqual,
77 loadJson,
78 findJsonSchemaFiles,
79 fileContainsAnnotation,
80 fileContainsParityAnnotation,
81 };
82