chore: establish hwlab l0 contract skeleton
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env node
|
||||
import assert from "node:assert/strict";
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import {
|
||||
ENVIRONMENT_DEV,
|
||||
SERVICE_IDS,
|
||||
TABLES,
|
||||
validateRequest,
|
||||
validateResponse
|
||||
} from "../internal/protocol/index.mjs";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
||||
async function parseJSONFiles(dir) {
|
||||
const entries = await readdir(path.join(repoRoot, dir), { withFileTypes: true });
|
||||
const parsed = [];
|
||||
for (const entry of entries) {
|
||||
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
||||
continue;
|
||||
}
|
||||
const relativePath = path.join(dir, entry.name);
|
||||
const raw = await readFile(path.join(repoRoot, relativePath), "utf8");
|
||||
const doc = JSON.parse(raw);
|
||||
assert.ok(doc.$schema, `${relativePath} missing $schema`);
|
||||
assert.ok(doc.$id, `${relativePath} missing $id`);
|
||||
parsed.push({ relativePath, doc });
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function assertUnique(name, values) {
|
||||
assert.equal(new Set(values).size, values.length, `${name} must be unique`);
|
||||
}
|
||||
|
||||
function assertCommonSchema(commonSchema) {
|
||||
const schemaServiceIds = commonSchema.$defs.serviceId.enum;
|
||||
assert.deepEqual(schemaServiceIds, SERVICE_IDS, "common service ids must match runtime constants");
|
||||
assert.deepEqual(commonSchema.$defs.environment.enum, [ENVIRONMENT_DEV]);
|
||||
}
|
||||
|
||||
function assertDeploySchema(deploySchema) {
|
||||
const serviceIds = deploySchema.$defs.service.properties.serviceId.enum;
|
||||
assert.deepEqual(serviceIds, SERVICE_IDS, "deploy service ids must match runtime constants");
|
||||
assert.equal(deploySchema.properties.endpoint.const, "http://74.48.78.17:6667");
|
||||
}
|
||||
|
||||
function assertEnvelopeValidation() {
|
||||
validateRequest({
|
||||
jsonrpc: "2.0",
|
||||
id: "req_01J00000000000000000000000",
|
||||
method: "hardware.operation.request",
|
||||
params: {
|
||||
projectId: "prj_01J00000000000000000000000"
|
||||
},
|
||||
meta: {
|
||||
traceId: "trc_01J00000000000000000000000",
|
||||
serviceId: "hwlab-cloud-api",
|
||||
environment: "dev"
|
||||
}
|
||||
});
|
||||
|
||||
validateResponse({
|
||||
jsonrpc: "2.0",
|
||||
id: "req_01J00000000000000000000000",
|
||||
result: {
|
||||
accepted: true
|
||||
},
|
||||
meta: {
|
||||
traceId: "trc_01J00000000000000000000000",
|
||||
serviceId: "hwlab-agent-mgr",
|
||||
environment: "dev"
|
||||
}
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() =>
|
||||
validateResponse({
|
||||
jsonrpc: "2.0",
|
||||
id: "req_01J00000000000000000000000",
|
||||
result: {},
|
||||
error: { code: -32000, message: "bad" },
|
||||
meta: {
|
||||
traceId: "trc_01J00000000000000000000000",
|
||||
serviceId: "hwlab-agent-mgr",
|
||||
environment: "dev"
|
||||
}
|
||||
}),
|
||||
/exactly one/
|
||||
);
|
||||
}
|
||||
|
||||
const schemas = await parseJSONFiles("protocol/schemas");
|
||||
const deploySchemas = await parseJSONFiles("deploy");
|
||||
const docsByName = new Map([...schemas, ...deploySchemas].map((item) => [path.basename(item.relativePath), item.doc]));
|
||||
|
||||
assert.ok(schemas.length >= 13, "expected protocol schemas");
|
||||
assert.ok(TABLES.includes("patch_panel_status"), "frozen tables must include patch_panel_status");
|
||||
assertUnique("service ids", SERVICE_IDS);
|
||||
assertUnique("tables", TABLES);
|
||||
assertCommonSchema(docsByName.get("common.json"));
|
||||
assertDeploySchema(docsByName.get("deploy.schema.json"));
|
||||
assertEnvelopeValidation();
|
||||
|
||||
console.log(`validated ${schemas.length + deploySchemas.length} JSON files and ${SERVICE_IDS.length} service ids`);
|
||||
Reference in New Issue
Block a user