{"_id":"@b64hub/sfpm-validation","name":"@b64hub/sfpm-validation","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@b64hub/sfpm-validation","version":"0.2.0","description":"Local metadata validation for SFPM","type":"module","keywords":["sfpm","salesforce","apex","typescript"],"author":{"name":"b64"},"license":"MIT","dependencies":{"semver":"^7.7.3","@b64hub/sfpm-core":"^0.2.0","@salesforce/source-deploy-retrieve":"^12.31.7","fs-extra":"^11.3.3"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"devDependencies":{"@types/fs-extra":"^11.0.4","@types/semver":"^7.7.1","vitest":"^4.0.17"},"optionalDependencies":{"@prettier-apex/apex-ast-serializer-linux-x64":"^2.2.6"},"scripts":{"build":"tsc -b","test":"vitest run"},"_id":"@b64hub/sfpm-validation@0.2.0","_integrity":"sha512-Mz6HbNA75dmK99l4+lbFIb4BPCtoH1smFH97kh+f6EjCCclqJpF2Qoni7TPmCr4bRFK7vntFeoawK9+IT3r9Aw==","_resolved":"/private/var/folders/_v/nz569h295px9gvkd08jpnzzr0000gn/T/135dcf7029a59230092d19544e0db485/b64hub-sfpm-validation-0.2.0.tgz","_from":"file:b64hub-sfpm-validation-0.2.0.tgz","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-Mz6HbNA75dmK99l4+lbFIb4BPCtoH1smFH97kh+f6EjCCclqJpF2Qoni7TPmCr4bRFK7vntFeoawK9+IT3r9Aw==","shasum":"cc0489a9cacb6496f5fc3b410eec2a862bfd2f90","tarball":"https://registry.npmjs.org/@b64hub/sfpm-validation/-/sfpm-validation-0.2.0.tgz","fileCount":62,"unpackedSize":107847,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDk1qIAUAa4JON6H7qrOOlo0asF7WXrK+nJZb5raPhD7wIhANAOWMpbRtT5ADy8YdQboEaY8YlWoUEFRnzlwhLQnTFb"}]},"_npmUser":{"name":"nkskaare","email":"nik.skaare@gmail.com"},"directories":{},"maintainers":[{"name":"b64-devs","email":"sebastian.kvalvag@b64.no"},{"name":"nkskaare","email":"nik.skaare@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sfpm-validation_0.2.0_1787306172195_0.7835102237968308"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T09:56:11.999Z","0.2.0":"2026-08-21T09:56:12.379Z","modified":"2026-08-21T09:56:12.668Z"},"maintainers":[{"name":"b64-devs","email":"sebastian.kvalvag@b64.no"},{"name":"nkskaare","email":"nik.skaare@gmail.com"}],"description":"Local metadata validation for SFPM","keywords":["sfpm","salesforce","apex","typescript"],"author":{"name":"b64"},"license":"MIT","readme":"# @b64hub/sfpm-validation\n\nLocal, best-effort validation for Salesforce package builds via the [Nimbus](https://github.com/nimbus-solution/nimbus) local Apex runtime.\n\n**Not a source of truth.** A real org deployment is the only authoritative signal. This package gives fast, cheap, local feedback — nothing more.\n\n---\n\n## Wiring example\n\n```ts\nimport {\n  createNimbusValidator,\n  createNimbusGraphProvider,\n  withNimbusDaemon,\n  buildOwnershipIndex,\n  findPackageBoundaryViolations,\n  type NimbusAdapterConfig,\n  type ValidationContext,\n} from '@b64hub/sfpm-validation';\n\n// 1. Implement Logger and ValidationEventBus structurally (no hard dep on pino)\nconst logger = pinoLogger.child({ component: 'validation' });\nconst eventBus = myOrchestratorEventBus; // must have .emit(event, payload)\n\n// 2. Config — ship with daemon off and autoInstall off\nconst config: NimbusAdapterConfig = {\n  pinnedVersion: '1.2.3',           // pin to the version validated against fixtures\n  supportedVersionRange: '^1.2.0',\n  autoInstall: false,\n  daemon: { enabled: false, autoStart: false, autoStop: true },\n};\n\nconst deps = { logger, eventBus, config };\n\n// 3. Compile / test a single package\nconst validator = createNimbusValidator(deps);\n\nconst ctx: ValidationContext = {\n  packageId: 'my-package',\n  packagePath: '/project/force-app/my-package',\n  projectRoot: '/project',\n  timeoutMs: 60_000,\n};\n\nconst availability = await validator.checkAvailability(ctx);\nif (availability.available && availability.compatible !== false) {\n  const result = await validator.run('compile', ctx);\n  console.log(result.status, result.diagnostics);\n}\n\n// 4. Boundary-check a set of packages (optional, requires nimbus graph)\nconst graphProvider = createNimbusGraphProvider(deps);\nconst ownershipIndex = buildOwnershipIndex(allPackageManifests);\n\nconst violations = await withNimbusDaemon(deps, '/project', () =>\n  findPackageBoundaryViolations(myPkg, ownershipIndex, graphProvider, {\n    projectRoot: '/project',\n    packageId: myPkg.packageId,\n  }),\n);\n```\n\n---\n\n## Default config\n\n```ts\nconst defaultNimbusConfig: NimbusAdapterConfig = {\n  pinnedVersion: '<pin to the version validated against fixtures>',\n  supportedVersionRange: '^<same major.minor>',\n  autoInstall: false,\n  daemon: {\n    enabled: false,   // opt-in per-environment; requires Nimbus Pro license\n    autoStart: false,\n    autoStop: true,\n  },\n};\n```\n\nShip with `daemon.enabled: false` and `autoInstall: false`. Both are safe to flip per-team once daemon subcommands are confirmed with the Nimbus maintainer and Pro licenses are verified (see Open Questions in the implementation plan).\n\n---\n\n## Open questions (block Phase 6/7 ship)\n\n1. Do `nimbus daemon start` / `nimbus daemon status --json` exist as named? Only `daemon stop` is confirmed.\n2. Does a non-zero `daemon start` exit distinguish \"no Pro license\" from other failures?\n3. Does `nimbus graph` support whole-package mode, or only per-class?\n4. What does a **failing** `nimbus test --json` test case look like exactly?\n5. Does `nimbus validate`/`nimbus test` accept the glob pattern style shown (`*`, class name)?\n","readmeFilename":"README.md","_rev":"1-c64a4e4ea6e2ac945e3081c2e661aa67"}