#!/usr/bin/env node "use strict"; const fs = require("fs"); const path = require("path"); const repoRoot = path.resolve(__dirname, ".."); const catalogPath = path.join(repoRoot, "docs", "language", "STDLIB_API.md"); const catalog = fs.readFileSync(catalogPath, "utf8"); function fail(message) { console.error(`stdlib API tier check failed: ${message}`); process.exit(1); } function requireText(text, message) { if (!catalog.includes(text)) { fail(message); } } function moduleSection(moduleName) { const marker = `### std.${moduleName}\n`; const start = catalog.indexOf(marker); if (start < 0) { fail(`missing std.${moduleName} module section`); } const next = catalog.indexOf("\n### std.", start + marker.length); return next < 0 ? catalog.slice(start) : catalog.slice(start, next); } function requireModuleTier(moduleName, expectedTier) { const section = moduleSection(moduleName); if (!section.includes(`- Tiers: \`${expectedTier}\``)) { fail(`std.${moduleName} is not marked as ${expectedTier}`); } } function requireHelperTier(moduleName, helperName, expectedTier) { const section = moduleSection(moduleName); const helperPattern = new RegExp(`^- \`${expectedTier}\` \`${helperName} `, "m"); if (!helperPattern.test(section)) { fail(`std.${moduleName}.${helperName} is not marked as ${expectedTier}`); } } if (/experimental`: not used|experimental not used/i.test(catalog)) { fail("catalog still contains stale wording that says experimental is unused"); } requireText("- `beta-supported`:", "missing beta-supported tier definition"); requireText("- `experimental`:", "missing experimental tier definition"); requireText("- `internal`:", "missing internal tier definition"); requireText("- `experimental` helper signatures:", "missing experimental summary count"); requireText("Concrete `std.vec_*` modules are beta-supported as concrete helper families only; this does not freeze a generic collection API.", "missing concrete vector boundary"); if (!/^- `experimental` `[^`]+`/m.test(catalog)) { fail("catalog does not list any experimental helper signatures"); } for (const moduleName of ["json", "net", "random", "time"]) { requireModuleTier(moduleName, "experimental"); } for (const helperName of [ "open_text_read_result", "read_open_text_result", "close_result", "read_text_via_handle_result", "close_ok", ]) { requireHelperTier("fs", helperName, "experimental"); } for (const moduleName of ["vec_bool", "vec_f64", "vec_i32", "vec_i64", "vec_string"]) { const section = moduleSection(moduleName); if (!section.includes("- Note: concrete-only vector helper family; no generic collection freeze.")) { fail(`std.${moduleName} is missing the concrete vector boundary note`); } }