{"_id":"@bernierllc/nevar-graph-validator","_rev":"2-9f32d9c88a12810b5db710cb1b6f685f","name":"@bernierllc/nevar-graph-validator","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.1":{"name":"@bernierllc/nevar-graph-validator","version":"0.0.1","license":"SEE LICENSE IN README.md","_id":"@bernierllc/nevar-graph-validator@0.0.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"88f406a3dd05d9542eb295d5efe7565f3e57c048","tarball":"https://registry.npmjs.org/@bernierllc/nevar-graph-validator/-/nevar-graph-validator-0.0.1.tgz","fileCount":2,"integrity":"sha512-6htzczkrjazoQeSGXqTDOei2uxTfoOEx+3bbL47dt92TwM4QQ/QkQfLyd4+J48adCGoBPVrxqbqh6JPt3cFVmw==","signatures":[{"sig":"MEUCIQCX3TTe6m+RLJxkKvQJCTJTajzcF0kT2IA33FA94F3TNQIgC5fbWBZvDiZLIZNtTGNeqGcJpXgn9AG2X3TCR6eD6KY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":393},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.12.1","description":"Placeholder for OIDC trusted-publisher bootstrap. Real release follows via GitHub Actions.","directories":{},"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/nevar-graph-validator_0.0.1_1779119029989_0.022504241044265516","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bernierllc/nevar-graph-validator","version":"0.1.2","description":"Static validation for Nevar Graph definitions — DAG acyclicity, port compatibility, edge mapping rules","main":"dist/index.js","types":"dist/index.d.ts","keywords":["nevar","graph","validator","dag","cycle-detection","bernierllc"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","dependencies":{"@bernierllc/nevar-graph-types":"0.1.2","@bernierllc/nevar-types":"0.1.0","@bernierllc/nevar-condition-tree":"0.1.0"},"devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","test":"jest","test:run":"jest","test:coverage":"jest --coverage","lint":"eslint src __tests__ --ext .ts","clean":"rm -rf dist"},"_id":"@bernierllc/nevar-graph-validator@0.1.2","_integrity":"sha512-sYkrSdKmLLsLDYhTCdXiAFCSlIeQRDkzfBISp1FAD45UCgb+ddvIlgn6hPfv/yaPUBHMrC6Iz7p7NDZ2jYHlkw==","_resolved":"/private/var/folders/r0/wspnzd1s18sfjy10ffyv2qxw0000gn/T/3a2ce2a928924c5c93f9eb1d2ef4b8d2/bernierllc-nevar-graph-validator-0.1.2.tgz","_from":"file:bernierllc-nevar-graph-validator-0.1.2.tgz","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-sYkrSdKmLLsLDYhTCdXiAFCSlIeQRDkzfBISp1FAD45UCgb+ddvIlgn6hPfv/yaPUBHMrC6Iz7p7NDZ2jYHlkw==","shasum":"a90475c5ed58985a6001be633c3bd6512ea85d9e","tarball":"https://registry.npmjs.org/@bernierllc/nevar-graph-validator/-/nevar-graph-validator-0.1.2.tgz","fileCount":51,"unpackedSize":256673,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDWXQAXt7Wbe6OANC8rdJswak+Zbb1/AVFlQTjkGWaLiAiEA6v9kIJrSw40iXf6W03RFuXmjB0yQ9JbObMRoqmQzgCk="}]},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nevar-graph-validator_0.1.2_1779127292235_0.4113643466946151"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-18T15:43:49.909Z","modified":"2026-05-18T18:01:32.571Z","0.0.1":"2026-05-18T15:43:50.137Z","0.1.2":"2026-05-18T18:01:32.445Z"},"license":"SEE LICENSE IN LICENSE","description":"Static validation for Nevar Graph definitions — DAG acyclicity, port compatibility, edge mapping rules","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/nevar-graph-validator\n\nStatic validation for Nevar Graph definitions — DAG acyclicity, port compatibility, edge mapping rules, and condition-tree structure.\n\n## Overview\n\nThis package provides `validateGraphDefinition`, the single entry-point for statically checking a `GraphDefinition` before it is stored or executed. It returns a discriminated union result — never throws.\n\n## Installation\n\n```bash\nnpm install @bernierllc/nevar-graph-validator\n```\n\n## Usage\n\n### Basic validation (no registry)\n\n```typescript\nimport { validateGraphDefinition } from '@bernierllc/nevar-graph-validator';\nimport type { GraphDefinition } from '@bernierllc/nevar-graph-types';\n\nconst def: GraphDefinition = { /* ... */ };\n\nconst result = validateGraphDefinition(def);\n\nif (result.ok) {\n  console.log('Graph is valid');\n  if (result.warnings) {\n    console.warn('Warnings:', result.warnings);\n  }\n} else {\n  console.error('Validation failed:', result.errors);\n}\n```\n\n### Strict port-type checking (with registry)\n\nWhen an `ActionTypeRegistry` is provided, edges connecting typed nodes are checked for port-type ID compatibility.\n\n```typescript\nimport { validateGraphDefinition } from '@bernierllc/nevar-graph-validator';\nimport type { ActionTypeRegistry } from '@bernierllc/nevar-graph-validator';\n\nconst registry: ActionTypeRegistry = {\n  get(actionType) {\n    const handlers = {\n      'action:fetch-post': { outputTypeId: 'content-type:blog-post' },\n      'action:publish-post': { inputTypeId: 'content-type:blog-post' },\n    };\n    return handlers[actionType as keyof typeof handlers];\n  },\n};\n\nconst result = validateGraphDefinition(def, { registry });\n```\n\n## API\n\n### `validateGraphDefinition(def, opts?)`\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `def` | `GraphDefinition` | The graph to validate |\n| `opts.registry` | `ActionTypeRegistry` | Optional — enables strict port-type checking |\n\n**Returns**: `ValidationResult` — discriminated union:\n- `{ ok: true; warnings?: string[] }` — valid graph\n- `{ ok: false; errors: GraphValidationError[]; warnings?: string[] }` — invalid graph\n\n### Checks performed (in order)\n\n1. **Reference integrity** — all `rootNodeIds`, `edge.fromNodeId`, and `edge.toNodeId` reference existing nodes\n2. **Acyclicity** — DFS cycle detection; fails fast if references pass but graph has a cycle\n3. **Edge mapping collisions** — two edges mapping to the same `to` field on the same downstream node\n4. **Port-type compatibility** — if registry provided, typed ports must match; untyped = warning only\n5. **Condition tree structure** — `activationCondition` and `edge.condition` trees validated via `nevar-condition-tree`\n\n## Error Classes\n\n| Class | Code | When |\n|-------|------|------|\n| `NevarGraphValidationError` | `NEVAR_GRAPH_VALIDATION_ERROR` | Base class — all validator errors |\n| `NevarGraphCycleError` | `NEVAR_GRAPH_CYCLE_ERROR` | Graph is not a DAG |\n| `NevarGraphPortMismatchError` | `NEVAR_GRAPH_PORT_MISMATCH_ERROR` | Port type IDs don't match on an edge |\n| `NevarGraphEdgeMappingError` | `NEVAR_GRAPH_EDGE_MAPPING_ERROR` | Mapping collision on downstream node |\n\nAll extend `NevarGraphError` from `@bernierllc/nevar-graph-types` and follow the ES2022 `Error.cause` pattern.\n\n```typescript\nimport {\n  NevarGraphCycleError,\n  NevarGraphPortMismatchError,\n  NevarGraphEdgeMappingError,\n} from '@bernierllc/nevar-graph-validator';\n\nconst result = validateGraphDefinition(def);\nif (!result.ok) {\n  for (const error of result.errors) {\n    if (error instanceof NevarGraphCycleError) {\n      console.error('Cycle detected:', error.cycle.join(' → '));\n    }\n    if (error instanceof NevarGraphPortMismatchError) {\n      console.error(`Port mismatch on edge: ${error.fromPortId} → ${error.toPortId}`);\n    }\n  }\n}\n```\n\n## Integrations\n\n### Logger integration\nLogger integration is consumer-driven: `validateGraphDefinition` never throws and never logs — it returns a discriminated `ValidationResult`. Callers should use `@bernierllc/logger` (e.g. `getErrorChain`, `formatErrorChain`) to log the `GraphValidationError[]` array when `result.ok === false`:\n\n```ts\nimport { formatErrorChain } from '@bernierllc/logger';\nimport { validateGraphDefinition } from '@bernierllc/nevar-graph-validator';\n\nconst result = validateGraphDefinition(def);\nif (!result.ok) {\n  for (const err of result.errors) {\n    logger.error('graph validation failed', { chain: formatErrorChain(err) });\n  }\n}\n```\n\n### NeverHub integration\nNeverHub integration is N/A for this validator. It is a pure-function package with no service surface, no network calls, and no runtime dependencies on NeverHub. Service/suite packages that orchestrate validation (e.g. `@bernierllc/nevar-graph-executor`, the `nevar` suite) own NeverHub registration and perform graceful degradation when NeverHub is unavailable.\n\n### Graceful degradation\nGraceful degradation is built in by design: `validateGraphDefinition` never throws — even on malformed input it returns `{ ok: false, errors }`. Optional features degrade safely: omit the `registry` and port-type checks are downgraded to warnings rather than errors. The validator works fully without any optional integrations.\n\n## Related Packages\n\n- `@bernierllc/nevar-graph-types` — shared type definitions (GraphDefinition, PortType, etc.)\n- `@bernierllc/nevar-graph-storage` — storage interface and in-memory adapter\n- `@bernierllc/nevar-graph-executor` — executes validated graphs topologically\n- `@bernierllc/nevar-graph-adapter-prisma` — Prisma/PostgreSQL storage backend\n- `@bernierllc/nevar` — suite re-export (Graph namespace)\n\n## License\n\nCopyright (c) 2025 Bernier LLC. See LICENSE for details.\n","readmeFilename":"README.md","keywords":["nevar","graph","validator","dag","cycle-detection","bernierllc"],"author":{"name":"Bernier LLC"}}