# 404-solution/trunk/contracts/contractFileIO.js

404 Solution, version trunk. 82 lines.

- Page: https://pluginprobe.com/plugins/404-solution/trunk/code/contracts/contractFileIO.js
- Raw: https://pluginprobe.com/plugins/404-solution/trunk/raw/contracts/contractFileIO.js
- Modified: 2026-08-21T22:57:10+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/404-solution/trunk/code/contracts/contractFileIO.js#L10-L20`.

```javascript
/**
 * contractFileIO: filesystem-access layer for the contract validation gate.
 *
 * Pure data-access concern. Reads files and directories from disk and parses
 * their contents. Contains no business/validation logic; callers in
 * validate-contracts.js decide what the read data means for contract validity.
 *
 * Exposes:
 *   fileExists(p)                                  -> boolean
 *   pathExists(p)                                  -> boolean
 *   filesEqual(left, right)                        -> boolean
 *   loadJson(p)                                    -> parsed JSON (throws on bad JSON)
 *   findJsonSchemaFiles(dir)                       -> string[] of *.schema.json paths
 *   fileContainsAnnotation(filePath, id, name?)    -> boolean
 *   fileContainsParityAnnotation(filePath, id)     -> boolean
 */
// 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.

const fs = require("fs");
const path = require("path");

function fileExists(p) {
  try {
    return fs.statSync(p).isFile();
  } catch {
    return false; // allow-silent-catch: stat failure means file does not exist
  }
}

function pathExists(p) {
  try {
    fs.statSync(p);
    return true;
  } catch {
    return false; // allow-silent-catch: stat failure means path is unavailable
  }
}

function filesEqual(left, right) {
  return fs.readFileSync(left).equals(fs.readFileSync(right));
}

function loadJson(p) {
  return JSON.parse(fs.readFileSync(p, "utf8"));
}

function findJsonSchemaFiles(dir) {
  const results = [];
  if (!fs.existsSync(dir)) return results;
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      results.push(...findJsonSchemaFiles(full));
    } else if (entry.name.endsWith(".schema.json")) {
      results.push(full);
    }
  }
  return results;
}

function fileContainsAnnotation(filePath, contractId, annotationName = "contract") {
  const content = fs.readFileSync(filePath, "utf8");
  const pattern = new RegExp(`@${annotationName}\\s+${contractId.replace(/-/g, "\\-")}\\b`);
  return pattern.test(content);
}

function fileContainsParityAnnotation(filePath, contractId) {
  const content = fs.readFileSync(filePath, "utf8");
  const pattern = new RegExp(`@parityTest\\s+${contractId.replace(/-/g, "\\-")}\\b`);
  return pattern.test(content);
}

module.exports = {
  fileExists,
  pathExists,
  filesEqual,
  loadJson,
  findJsonSchemaFiles,
  fileContainsAnnotation,
  fileContainsParityAnnotation,
};

```
