diff --git a/packages/cultnet-ts/.gitignore b/packages/cultnet-ts/.gitignore index fd3ec924..fd7098ff 100644 --- a/packages/cultnet-ts/.gitignore +++ b/packages/cultnet-ts/.gitignore @@ -2,3 +2,6 @@ node_modules/ dist/ dist-test/ *.tgz +# Mirrored from CultLib/contracts/cultnet by tools/generate-swarm-contracts.mjs +# (REC-032). Not tracked: CultLib/contracts/cultnet is the only source. +contracts/ diff --git a/packages/cultnet-ts/package.json b/packages/cultnet-ts/package.json index 0b101282..f94f0bfa 100644 --- a/packages/cultnet-ts/package.json +++ b/packages/cultnet-ts/package.json @@ -17,14 +17,16 @@ } }, "files": [ - "dist" + "dist", + "contracts" ], "scripts": { "contracts:generate": "node tools/generate-swarm-contracts.mjs", "build": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json", + "prepack": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json", "typecheck": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json --pretty false", - "test": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json && node ../../node_modules/typescript/bin/tsc -p tsconfig.test.json && node --test dist-test/packages/cultnet-ts/test/*.test.js", - "test:interop": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json && node ../../node_modules/typescript/bin/tsc -p tsconfig.test.json && node --test --test-force-exit dist-test/packages/cultnet-ts/test/interop/*.test.js" + "test": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json && node ../../node_modules/typescript/bin/tsc -p tsconfig.test.json && node --test dist-test/test/*.test.js", + "test:interop": "node tools/generate-swarm-contracts.mjs && node ../../node_modules/typescript/bin/tsc -p tsconfig.json && node ../../node_modules/typescript/bin/tsc -p tsconfig.test.json && node --test --test-force-exit dist-test/test/interop/*.test.js" }, "keywords": [ "messagepack", diff --git a/packages/cultnet-ts/src/contracts.ts b/packages/cultnet-ts/src/contracts.ts index d44f391f..d90af381 100644 --- a/packages/cultnet-ts/src/contracts.ts +++ b/packages/cultnet-ts/src/contracts.ts @@ -1,38 +1,38 @@ import Ajv2020, { type ValidateFunction } from "ajv/dist/2020"; -import documentRecordSchema from "../../../contracts/cultnet/cultnet.document-record.schema.json"; -import helloSchema from "../../../contracts/cultnet/cultnet.hello.schema.json"; -import loginSchema from "../../../contracts/cultnet/cultnet.login.schema.json"; -import registerSchema from "../../../contracts/cultnet/cultnet.register.schema.json"; -import verifySchema from "../../../contracts/cultnet/cultnet.verify.schema.json"; -import loginSuccessSchema from "../../../contracts/cultnet/cultnet.login-success.schema.json"; -import errorSchema from "../../../contracts/cultnet/cultnet.error.schema.json"; -import sampleChangeNameSchema from "../../../contracts/cultnet/cultnet.sample-change-name.schema.json"; -import sampleChatSchema from "../../../contracts/cultnet/cultnet.sample-chat.schema.json"; -import documentPutSchema from "../../../contracts/cultnet/cultnet.document-put.schema.json"; -import documentDeleteSchema from "../../../contracts/cultnet/cultnet.document-delete.schema.json"; -import rawDocumentRecordSchema from "../../../contracts/cultnet/cultnet.raw-document-record.schema.json"; -import documentPutRawSchema from "../../../contracts/cultnet/cultnet.document-put-raw.schema.json"; -import documentMutationContractSchema from "../../../contracts/cultnet/cultnet.document-mutation-contract.schema.json"; -import transportProfileSchema from "../../../contracts/cultnet/cultnet.transport-profile.schema.json"; -import snapshotRequestSchema from "../../../contracts/cultnet/cultnet.snapshot-request.schema.json"; -import snapshotResponseSchema from "../../../contracts/cultnet/cultnet.snapshot-response.schema.json"; -import snapshotResponseRawSchema from "../../../contracts/cultnet/cultnet.snapshot-response-raw.schema.json"; -import databaseSubscribeSchema from "../../../contracts/cultnet/cultnet.database-subscribe.schema.json"; -import databaseUnsubscribeSchema from "../../../contracts/cultnet/cultnet.database-unsubscribe.schema.json"; -import databaseChangeRawSchema from "../../../contracts/cultnet/cultnet.database-change-raw.schema.json"; -import schemaDescriptorSchema from "../../../contracts/cultnet/cultnet.schema-descriptor.schema.json"; -import schemaCatalogRequestSchema from "../../../contracts/cultnet/cultnet.schema-catalog-request.schema.json"; -import schemaCatalogResponseSchema from "../../../contracts/cultnet/cultnet.schema-catalog-response.schema.json"; -import shardCatalogRequestSchema from "../../../contracts/cultnet/cultnet.shard-catalog-request.schema.json"; -import shardCatalogResponseSchema from "../../../contracts/cultnet/cultnet.shard-catalog-response.schema.json"; -import operationRequestSchema from "../../../contracts/cultnet/cultnet.operation-request.schema.json"; -import operationResponseSchema from "../../../contracts/cultnet/cultnet.operation-response.schema.json"; -import verseCatalogRequestSchema from "../../../contracts/cultnet/cultmesh.verse-catalog-request.schema.json"; -import verseCatalogResponseSchema from "../../../contracts/cultnet/cultmesh.verse-catalog-response.schema.json"; -import sessionOpenSchema from "../../../contracts/cultnet/cultmesh.session-open.schema.json"; -import sessionAcceptedSchema from "../../../contracts/cultnet/cultmesh.session-accepted.schema.json"; -import ghostlightAgentStateSchema from "../../../contracts/cultnet/ghostlight.agent-state.schema.json"; +import documentRecordSchema from "../contracts/cultnet/cultnet.document-record.schema.json"; +import helloSchema from "../contracts/cultnet/cultnet.hello.schema.json"; +import loginSchema from "../contracts/cultnet/cultnet.login.schema.json"; +import registerSchema from "../contracts/cultnet/cultnet.register.schema.json"; +import verifySchema from "../contracts/cultnet/cultnet.verify.schema.json"; +import loginSuccessSchema from "../contracts/cultnet/cultnet.login-success.schema.json"; +import errorSchema from "../contracts/cultnet/cultnet.error.schema.json"; +import sampleChangeNameSchema from "../contracts/cultnet/cultnet.sample-change-name.schema.json"; +import sampleChatSchema from "../contracts/cultnet/cultnet.sample-chat.schema.json"; +import documentPutSchema from "../contracts/cultnet/cultnet.document-put.schema.json"; +import documentDeleteSchema from "../contracts/cultnet/cultnet.document-delete.schema.json"; +import rawDocumentRecordSchema from "../contracts/cultnet/cultnet.raw-document-record.schema.json"; +import documentPutRawSchema from "../contracts/cultnet/cultnet.document-put-raw.schema.json"; +import documentMutationContractSchema from "../contracts/cultnet/cultnet.document-mutation-contract.schema.json"; +import transportProfileSchema from "../contracts/cultnet/cultnet.transport-profile.schema.json"; +import snapshotRequestSchema from "../contracts/cultnet/cultnet.snapshot-request.schema.json"; +import snapshotResponseSchema from "../contracts/cultnet/cultnet.snapshot-response.schema.json"; +import snapshotResponseRawSchema from "../contracts/cultnet/cultnet.snapshot-response-raw.schema.json"; +import databaseSubscribeSchema from "../contracts/cultnet/cultnet.database-subscribe.schema.json"; +import databaseUnsubscribeSchema from "../contracts/cultnet/cultnet.database-unsubscribe.schema.json"; +import databaseChangeRawSchema from "../contracts/cultnet/cultnet.database-change-raw.schema.json"; +import schemaDescriptorSchema from "../contracts/cultnet/cultnet.schema-descriptor.schema.json"; +import schemaCatalogRequestSchema from "../contracts/cultnet/cultnet.schema-catalog-request.schema.json"; +import schemaCatalogResponseSchema from "../contracts/cultnet/cultnet.schema-catalog-response.schema.json"; +import shardCatalogRequestSchema from "../contracts/cultnet/cultnet.shard-catalog-request.schema.json"; +import shardCatalogResponseSchema from "../contracts/cultnet/cultnet.shard-catalog-response.schema.json"; +import operationRequestSchema from "../contracts/cultnet/cultnet.operation-request.schema.json"; +import operationResponseSchema from "../contracts/cultnet/cultnet.operation-response.schema.json"; +import verseCatalogRequestSchema from "../contracts/cultnet/cultmesh.verse-catalog-request.schema.json"; +import verseCatalogResponseSchema from "../contracts/cultnet/cultmesh.verse-catalog-response.schema.json"; +import sessionOpenSchema from "../contracts/cultnet/cultmesh.session-open.schema.json"; +import sessionAcceptedSchema from "../contracts/cultnet/cultmesh.session-accepted.schema.json"; +import ghostlightAgentStateSchema from "../contracts/cultnet/ghostlight.agent-state.schema.json"; export type CultNetWireContract = "cultnet.schema.v0" | "gamecult.networking.v0"; diff --git a/packages/cultnet-ts/src/generated/swarm-contracts.generated.ts b/packages/cultnet-ts/src/generated/swarm-contracts.generated.ts index 84bb09b0..f2dffce2 100644 --- a/packages/cultnet-ts/src/generated/swarm-contracts.generated.ts +++ b/packages/cultnet-ts/src/generated/swarm-contracts.generated.ts @@ -1,5 +1,5 @@ import { defineJsonSchemaContract } from "../json-schema-contract"; -import ghostlightAgentStateGeneratedContractSchema from "../../../../contracts/cultnet/ghostlight.agent-state.schema.json"; +import ghostlightAgentStateGeneratedContractSchema from "../../contracts/cultnet/ghostlight.agent-state.schema.json"; // Generated by tools/generate-swarm-contracts.mjs. Do not hand-edit this file unless you enjoy losing arguments with a machine. diff --git a/packages/cultnet-ts/test/interop/cultnet-interop.test.ts b/packages/cultnet-ts/test/interop/cultnet-interop.test.ts index 07fb268b..51bea1ff 100644 --- a/packages/cultnet-ts/test/interop/cultnet-interop.test.ts +++ b/packages/cultnet-ts/test/interop/cultnet-interop.test.ts @@ -21,7 +21,7 @@ const execFileAsync = promisify(execFile); const cargoCommand = process.env.CARGO ?? (process.platform === "win32" ? join(homedir(), ".cargo", "bin", "cargo.exe") : "cargo"); const dotnetCommand = process.env.DOTNET ?? (process.platform === "win32" ? join("C:", "Program Files", "dotnet", "dotnet.exe") : "dotnet"); const pythonCommand = process.env.PYTHON ?? resolvePythonCommand(); -const cultNetTsRoot = resolve(__dirname, "../../../../.."); +const cultNetTsRoot = resolve(__dirname, "../../.."); const cultLibRoot = findAncestor(cultNetTsRoot, "CultLib.sln") ?? resolve(cultNetTsRoot, "..", "CultLib"); const cultcachePyRoot = resolve(cultLibRoot, "packages", "cultcache-py"); const cultcachePySrc = ["cultcache-py", "cultnet-py", "cultmesh-py"] diff --git a/packages/cultnet-ts/test/runtime-presence-health.test.ts b/packages/cultnet-ts/test/runtime-presence-health.test.ts index 2ceedde3..fa21aeaa 100644 --- a/packages/cultnet-ts/test/runtime-presence-health.test.ts +++ b/packages/cultnet-ts/test/runtime-presence-health.test.ts @@ -26,7 +26,7 @@ import { // are generated output and must have exactly one home. const VECTORS = JSON.parse( readFileSync( - join(__dirname, "..", "..", "..", "..", "test", "fixtures", "runtime-presence-vectors.json"), + join(__dirname, "..", "..", "test", "fixtures", "runtime-presence-vectors.json"), "utf8", ), ) as { proof: string; signed: string }; diff --git a/packages/cultnet-ts/tools/generate-swarm-contracts.mjs b/packages/cultnet-ts/tools/generate-swarm-contracts.mjs index 53ad1e18..dd27ad7c 100644 --- a/packages/cultnet-ts/tools/generate-swarm-contracts.mjs +++ b/packages/cultnet-ts/tools/generate-swarm-contracts.mjs @@ -1,4 +1,4 @@ -import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { cp, mkdir, readFile, rm, writeFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; @@ -6,9 +6,23 @@ import { compile } from "json-schema-to-typescript"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -const repoRoot = path.resolve(__dirname, ".."); -const manifestPath = path.join(repoRoot, "tools", "swarm-contracts.manifest.json"); -const outputPath = path.join(repoRoot, "src", "generated", "swarm-contracts.generated.ts"); +const packageRoot = path.resolve(__dirname, ".."); +const cultLibRoot = path.resolve(packageRoot, "..", ".."); +const manifestPath = path.join(packageRoot, "tools", "swarm-contracts.manifest.json"); +const outputPath = path.join(packageRoot, "src", "generated", "swarm-contracts.generated.ts"); + +// CultLib/contracts/cultnet is the single source of CultNet schema contracts +// (REC-032). cultnet-ts is a standalone npm package (published or vendored by +// Heimdall independent of the CultLib checkout), so it cannot import schemas +// that live outside its own package tree. Mirror the canonical contracts into +// a package-local, gitignored copy every time this generator runs, so `dist` +// and `contracts` both ship self-contained. Wipe first: a stale local file +// left behind after a schema is deleted upstream must not survive as drift. +const sourceContractsDir = path.join(cultLibRoot, "contracts", "cultnet"); +const localContractsDir = path.join(packageRoot, "contracts", "cultnet"); +await rm(localContractsDir, { recursive: true, force: true }); +await mkdir(path.dirname(localContractsDir), { recursive: true }); +await cp(sourceContractsDir, localContractsDir, { recursive: true }); /** * @typedef {{ diff --git a/packages/cultnet-ts/tools/swarm-contracts.manifest.json b/packages/cultnet-ts/tools/swarm-contracts.manifest.json index 49b5073d..f5750740 100644 --- a/packages/cultnet-ts/tools/swarm-contracts.manifest.json +++ b/packages/cultnet-ts/tools/swarm-contracts.manifest.json @@ -1,7 +1,7 @@ { "contracts": [ { - "schemaPath": "../../../contracts/cultnet/ghostlight.agent-state.schema.json", + "schemaPath": "../contracts/cultnet/ghostlight.agent-state.schema.json", "typeName": "GhostlightAgentStateShape", "contractExportName": "ghostlightAgentStateGeneratedContract", "validateExportName": "validateGhostlightAgentStateGenerated", diff --git a/packages/cultnet-ts/tsconfig.test.json b/packages/cultnet-ts/tsconfig.test.json index fc47617c..a73b52c0 100644 --- a/packages/cultnet-ts/tsconfig.test.json +++ b/packages/cultnet-ts/tsconfig.test.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "rootDir": "../..", + "rootDir": ".", "outDir": "dist-test", "declaration": false, "declarationMap": false