@naniteninja/cyrano-contracts
v1.2.1
Published
Shared types, enums, interfaces, and schemas for the Cyrano ecosystem
Readme
@naniteninja/cyrano-contracts
Shared TypeScript contracts for the Cyrano ecosystem — the single source of truth (SSOT) for types, enums, interfaces, constants, and JSON schemas used across:
- cyranoserver (NestJS backend)
- cyrano (Angular/Ionic frontend)
- dashboard-components-lib (Angular component library)
- Cyrano-Android-Blackbox (Python blackbox service)
Centralizing contracts here prevents drift between services (e.g. mismatched socket event names or payload shapes) and gives every consumer the same compiled types and declaration files.
Quick start
Install
Local development (sibling repos in the same workspace):
npm install file:../cyrano-contractsPublished package (when available on npm):
npm install @naniteninja/cyrano-contractsBuild
npm install
npm run buildUsage
Import from the root barrel or subpath exports:
import { ChatSocketEndpoints, WIRE_PROTOCOL_VERSION } from '@naniteninja/cyrano-contracts';
import type { IMessage, ISendMessageChatPayload } from '@naniteninja/cyrano-contracts';
import { MatcherStatuses } from '@naniteninja/cyrano-contracts/enums';
import type { IGatewayRequest } from '@naniteninja/cyrano-contracts/interfaces';JSON schemas are shipped as source files and can be imported directly:
import chatPayloadSchema from '@naniteninja/cyrano-contracts/schemas/chat-payload.schema.json';Directory structure
cyrano-contracts/
├── src/
│ ├── enums/ # String enums (socket endpoints, statuses, flags, …)
│ ├── interfaces/ # Payload and domain interfaces (I-prefixed)
│ ├── types/ # Type aliases and unions
│ ├── constants/ # Shared constants (e.g. WIRE_PROTOCOL_VERSION)
│ ├── schemas/ # JSON Schema files for runtime validation
│ ├── __tests__/ # Contract export and alignment tests
│ └── index.ts # Root barrel export
├── scripts/
│ └── generate-python.ts # TS → Python Pydantic codegen
├── generated/python/ # Auto-generated Python output (gitignored)
└── dist/ # Compiled CJS, ESM, and .d.ts (gitignored)Subpath exports
| Export path | Contents |
|---|---|
| @naniteninja/cyrano-contracts | Enums, interfaces, types, constants |
| @naniteninja/cyrano-contracts/enums | Enums only |
| @naniteninja/cyrano-contracts/interfaces | Interfaces only |
| @naniteninja/cyrano-contracts/types | Type aliases only |
| @naniteninja/cyrano-contracts/constants | Constants only |
| @naniteninja/cyrano-contracts/schemas/* | JSON Schema files |
Adding new contracts
Add the definition in the appropriate folder:
- Socket event names →
src/enums/<name>.enum.ts - Request/response payloads →
src/interfaces/<name>.interface.ts - Shared literals/unions →
src/types/index.ts - Runtime validation →
src/schemas/<name>.schema.json
- Socket event names →
Export from the barrel — add a re-export line to the folder's
index.ts(e.g.src/enums/index.ts,src/interfaces/index.ts).Update tests — extend
src/__tests__/contracts.spec.tsif you add enums or interfaces that must remain part of the public surface.Regenerate Python (if Blackbox needs the new types):
npm run generate:pythonCopy or sync
generated/python/into the Blackbox repo as needed.Build and verify:
npm run build npm test
Conventions
- Interfaces use an
Iprefix (IMessage,IGatewayRequest). - Enums use PascalCase names with matching PascalCase string values (e.g.
ChatSocketEndpoints.SendMessageChat = 'SendMessageChat'). - Prefer extending existing enums/interfaces over duplicating shapes in consumer repos.
- Bump
WIRE_PROTOCOL_VERSIONinsrc/constants/index.tswhen making breaking payload changes.
Wire serialization
Date-typed fields are domain types; over JSON (HTTP/Socket.IO) they serialize as ISO-8601 strings. Parse at the ingress boundary in each consumer — do not change contract types to string. See docs/WIRE_SERIALIZATION.md.
Python code generation
The Blackbox service runs Python; TypeScript interfaces and enums are mirrored via a codegen script:
npm run generate:pythonThis writes Pydantic v2 models to generated/python/:
enums.py— fromsrc/enums/models.py— fromsrc/interfaces/constants.py— fromsrc/constants/__init__.py— package barrel
The output directory is gitignored. After generation, copy the files into Cyrano-Android-Blackbox (e.g. cyrano_contracts/) and commit there.
Publishing and versioning
The package is published as @naniteninja/cyrano-contracts (scoped, private/unlicensed).
Version bumps
Follow semver:
- Patch — documentation, non-breaking fixes
- Minor — new enums/interfaces/schemas (backward compatible)
- Major — removed or renamed exports, breaking payload or enum value changes
Update version in package.json, then rebuild. The prepublishOnly script runs npm run build automatically before publish.
Publish
npm run build
npm test
npm publish --access restrictedEnsure you are authenticated to the npm registry that hosts @naniteninja packages.
Local linking
Sibling repos currently consume the package via a file dependency:
"@naniteninja/cyrano-contracts": "file:../cyrano-contracts"After changing contracts locally, run npm run build in this repo, then reinstall or rebuild the consuming project.
Scripts
| Script | Description |
|---|---|
| npm run build | Compile ESM, CJS, and declaration files to dist/ |
| npm run build:types | Emit declaration files only |
| npm run generate:python | Generate Python models in generated/python/ |
| npm test | Run Jest contract tests |
| npm run lint | ESLint (requires eslint to be configured) |
