{"_id":"@emmett-community/emmett-expressjs-with-openapi","_rev":"8-b3929c9f5580538c118700de99c4c911","name":"@emmett-community/emmett-expressjs-with-openapi","dist-tags":{"latest":"0.8.0"},"versions":{"0.1.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.1.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.1.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"82c204630bfd19f7409eb489a8c8c4e86cce9e19","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.1.0.tgz","fileCount":27,"integrity":"sha512-s0T0YTOiMvt9vxiGxmZ8CfdkbU/JDWwtC95ht3AHQPxe3SP9D47JL8wq19azyuwfrSUFExOhngUSLN/2dYNzcg==","signatures":[{"sig":"MEUCIBctOSA6jifszJfjSYb/568CgBvyXq0RQDa6KPhmisZrAiEA5iL1KHMHk4RoHx5UintkYtG0SGOzudLBa92/pB7yhEI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200121},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"10f54db818157ac2ec9f9311521a796df03bbf95","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"axcosta","email":"axcosta@gmail.com"},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.1.0","description":"Emmett - Event Sourcing development made simple","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","yaml":"^2.8.1","express":"^4.21.2","supertest":"^7.0.0","typescript":"^5.5.4","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0"},"peerDependencies":{"express":"^4.19.2","supertest":"^7.0.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7"},"peerDependenciesMeta":{"express-openapi-validator":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.1.0_1765560156208_0.5807486247054281","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.2.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.2.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"8ed0c86716d4a83e700d70c1123f048823fa68a0","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.2.0.tgz","fileCount":27,"integrity":"sha512-dfA/pKkKVEEpQ63k/q17EOK/iNTxbXU5gGekgh+llZVgzKPHYbkqIe54P6lm46Q+/49sOowuUO+5KA2l5MbT2Q==","signatures":[{"sig":"MEQCIGPD4NAvdKP2KNRr0M96n3JHRV5eDMMEN1SJOWgvL29kAiAxRWcLJYAjw1QehM7oNcpvKez7vyCIUit3tm7UF4UITQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":217531},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"4476f47a6af44645feae40fee2557c579d7f0504","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","supertest":"^7.0.0","typescript":"^5.5.4","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","supertest":"^7.0.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.2.0_1766781034487_0.43616061932093086","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.3.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.3.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"6d3c0fb04aa93f781efb158c1d1a79a7d44d21a8","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.3.0.tgz","fileCount":27,"integrity":"sha512-gZZ5l+Gy1DgmwXvEEKkdBn2HkzRvA5H7pQFkJHBTZdX52hAPmwv6oTG0bKn8Oxq6vwPlPTuqmY+8I4cafcvVWg==","signatures":[{"sig":"MEUCIFXux1F/gyDH9ts8DC38/eA4jGEpn3t0JeG78Y0jt24mAiEAjJAcbvPu+XJQvUgm6i6iMCrFjcuZqx1cnk6jBSmIJMc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":229388},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"384525bae61f6bfe1d2f66553137672ce29dd1d6","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","pino-http":"^9.0.0","supertest":"^7.0.0","typescript":"^5.5.4","pino-pretty":"^13.1.3","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","pino-http":"^9.0.0","supertest":"^7.0.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"pino-http":{"optional":true},"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.3.0_1767028278640_0.43287486506369444","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.4.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.4.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"c42eedb8e4c5f2444e71f2472cf6a07d60a6d80f","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.4.0.tgz","fileCount":31,"integrity":"sha512-tbF0FYK5ugglA2Im8wZZCosFbDbYKz/Wp5QhEnbzzhwS4lo4Lde/Dv9TmCCuj/Xl2rM5LuqK2vtRR5kb+4iWEA==","signatures":[{"sig":"MEQCIGsbIPGOKQC5kJxQzifdmUIy3UlvwGNFMkWyKAZpDTk+AiAckU2gOSMOY05Uzai9zl22WC5RGFp90mFARWf9AfoLJQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":268612},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"b723a88dcbb15c2af4c87b771b12172c9e539f8a","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1","@opentelemetry/api":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","pino-http":"^9.0.0","supertest":"^7.0.0","typescript":"^5.5.4","pino-pretty":"^13.1.3","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","pino-http":"^9.0.0","supertest":"^7.0.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"pino-http":{"optional":true},"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.4.0_1767203234973_0.6087419844383068","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.5.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.5.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"7c35163c3d79bc6d86d689c11a4af054acd64ecd","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.5.0.tgz","fileCount":31,"integrity":"sha512-BnRlBNZmqmohE3RAvqlraSlef5MU9HI64pzgpdwl9dkXmfrfld/47dbcnEORX85XMjdekJVHjBp7dvv8mbp8mg==","signatures":[{"sig":"MEQCIBPWdJmYw79tMFJIYeFlEqbotqJyjRUMNhxcskciYvyrAiB1zhIjzWl7D3ZkjNjYYKe1ixJTa28kBAkJXfWeihzg5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":281884},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"8504b34428db94a0d1673161bf1e6f4618c4b3cb","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1","@opentelemetry/api":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","pino-http":"^9.0.0","supertest":"^7.0.0","typescript":"^5.5.4","pino-pretty":"^13.1.3","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","pino-http":"^9.0.0","supertest":"^7.0.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"pino-http":{"optional":true},"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.5.0_1767228153610_0.8093832737251576","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.6.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.6.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"8dc7107e8b84a4d5991f85d9a171d3657d59c963","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.6.0.tgz","fileCount":31,"integrity":"sha512-fOFDgLq8dafp8UFtrfDm65/tfI8DhuJ6B+ifi5s1CGMY2/zpHrx57V4J6vWjNJaPC5yWX4Bt1j/ZlUa9MkTJMA==","signatures":[{"sig":"MEUCIQD/giRFPWrK/GOnWxvnOS0G9kVgLk2Neii0rtBd4ZnWOgIgb+OIGjQ4gUeqGCgvUNRFLnCadzPhJ3SU/np4GKW09Mw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":286647},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"bc73f51a8f5990f4e16b7d1dbbb1b96365d4eaba","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1","supertest":"^7.0.0","@opentelemetry/api":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","pino-http":"^9.0.0","typescript":"^5.5.4","pino-pretty":"^13.1.3","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","pino-http":"^9.0.0","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"pino-http":{"optional":true},"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.6.0_1767489327827_0.6554646025416702","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.7.0","keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"license":"MIT","_id":"@emmett-community/emmett-expressjs-with-openapi@0.7.0","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"homepage":"https://event-driven-io.github.io/emmett/","bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"dist":{"shasum":"b7c6f020ef3ee6b9467ab46a101718de392e848b","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.7.0.tgz","fileCount":31,"integrity":"sha512-Sx68rbQ2rWCMPSyjrtfB/wRKzUVPPStxceuPNeY/mgN5AXHM8dpNHsw2FLnUgOcMiytb/S1dnXH0p3hUgJ760g==","signatures":[{"sig":"MEUCIQCduVzKaumpHRKE/PNgk+hECFd0s9lJLF1dZKjH0ntoQQIgePz6CaG0K8N4zTzddpCVXPJAUWH6NecUzm2F2UIkoNw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":289049},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"16d3d8a8595cc428cdfa9dd0c37970662badf2e6","scripts":{"test":"run-s test:unit test:int test:e2e","build":"tsup","build:ts":"tsc","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","build:ts:watch":"tsc -b --watch","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"repository":{"url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git","type":"git"},"_npmVersion":"11.6.2","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","directories":{},"_nodeVersion":"24.12.0","dependencies":{"yaml":"^2.8.1","supertest":"^7.0.0","@opentelemetry/api":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.17.0","glob":"^11.0.0","tsup":"^8.2.4","express":"^4.21.2","pino-http":"^9.0.0","typescript":"^5.5.4","pino-pretty":"^13.1.3","npm-run-all2":"^6.2.2","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express-async-errors":"^3.1.1","http-problem-details":"^0.1.7","express-openapi-validator":"^5.6.0","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependencies":{"express":"^4.19.2","pino-http":"^9.0.0","express-async-errors":"^3.1.1","http-problem-details":"^0.1.5","@event-driven-io/emmett":"0.39.1","express-openapi-validator":"^5.3.7","@my-f-startup/firebase-auth-express":"0.1.0"},"peerDependenciesMeta":{"pino-http":{"optional":true},"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/emmett-expressjs-with-openapi_0.7.0_1767563334277_0.8381179789034767","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@emmett-community/emmett-expressjs-with-openapi","version":"0.8.0","license":"MIT","type":"module","description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","scripts":{"build":"tsup","build:ts":"tsc","build:ts:watch":"tsc -b --watch","test":"run-s test:unit test:int test:e2e","test:unit":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/unit/**/*.unit.spec.ts\"","test:int":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/integration/**/*.int.spec.ts\"","test:e2e":"glob -c \"node --import tsx --import tsx/cjs --test\" \"test/e2e/**/*.e2e.spec.ts\"","test:watch":"node --import tsx --import tsx/cjs --test --watch","test:unit:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/unit/**/*.unit.spec.ts\"","test:int:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/integration/**/*.int.spec.ts\"","test:e2e:watch":"glob -c \"node --import tsx --import tsx/cjs --test --watch\" \"test/e2e/**/*.e2e.spec.ts\""},"repository":{"type":"git","url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git"},"keywords":["Event Sourcing"],"author":{"name":"Andre X Costa"},"bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"homepage":"https://event-driven-io.github.io/emmett/","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","peerDependencies":{"@event-driven-io/emmett":"0.39.1","@my-f-startup/firebase-auth-express":"0.1.0","express":"^4.19.2","express-async-errors":"^3.1.1","express-openapi-validator":"^5.3.7","http-problem-details":"^0.1.5","pino-http":"^9.0.0"},"peerDependenciesMeta":{"express-openapi-validator":{"optional":true},"@my-f-startup/firebase-auth-express":{"optional":true},"pino-http":{"optional":true}},"dependencies":{"@opentelemetry/api":"^1.0.0","supertest":"^7.0.0","yaml":"^2.8.1"},"devDependencies":{"@my-f-startup/firebase-auth-express":"0.1.0","@types/express":"^4.17.21","@types/supertest":"^6.0.2","express":"^4.21.2","express-async-errors":"^3.1.1","express-openapi-validator":"^5.6.0","glob":"^11.0.0","http-problem-details":"^0.1.7","npm-run-all2":"^6.2.2","pino-http":"^9.0.0","pino-pretty":"^13.1.3","tsup":"^8.2.4","tsx":"^4.17.0","typescript":"^5.5.4"},"publishConfig":{"access":"public"},"gitHead":"f4655b4d4d4bd096ae092d21f3ca07e350914539","_id":"@emmett-community/emmett-expressjs-with-openapi@0.8.0","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-5rHWY9bMmfNcUPCduwjBxw+41AyrnErX0j8MDO8vEjd+CzqdOQwN9QhT435MEDmbkL3ZKAYmAEa4/RnmLQxPMg==","shasum":"8207c458e2d9c9dc9c755a9d23aa0f522d5703ba","tarball":"https://registry.npmjs.org/@emmett-community/emmett-expressjs-with-openapi/-/emmett-expressjs-with-openapi-0.8.0.tgz","fileCount":31,"unpackedSize":298262,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emmett-community%2femmett-expressjs-with-openapi@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCMEIziZth3Zvm5yEuepDxiBGXjyb8W8/Xhb/lncaR8HwIhAM9JDCTcM1O/tMWMvlwb0pMsqyGSD7OLzrT+loNJvkN8"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3c6de52c-c193-4140-b9ec-8860982c7488"}},"directories":{},"maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/emmett-expressjs-with-openapi_0.8.0_1768480866881_0.216175029951867"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-12T17:22:36.109Z","modified":"2026-01-15T12:41:07.488Z","0.1.0":"2025-12-12T17:22:36.350Z","0.2.0":"2025-12-26T20:30:34.641Z","0.3.0":"2025-12-29T17:11:18.784Z","0.4.0":"2025-12-31T17:47:15.119Z","0.5.0":"2026-01-01T00:42:33.780Z","0.6.0":"2026-01-04T01:15:27.991Z","0.7.0":"2026-01-04T21:48:54.443Z","0.8.0":"2026-01-15T12:41:07.016Z"},"bugs":{"url":"https://github.com/emmett-community/emmett-expressjs-with-openapi/issues"},"author":{"name":"Andre X Costa"},"license":"MIT","homepage":"https://event-driven-io.github.io/emmett/","keywords":["Event Sourcing"],"repository":{"type":"git","url":"git+https://github.com/emmett-community/emmett-expressjs-with-openapi.git"},"description":"Express.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core","maintainers":[{"name":"axcosta","email":"axcosta@gmail.com"}],"readme":"# @emmett-community/emmett-expressjs-with-openapi\n\nExpress.js utilities for Emmett applications that want OpenAPI 3.x validation without pulling the whole Emmett core. This package wires [`express-openapi-validator`](https://github.com/cdimascio/express-openapi-validator) into the Emmett application builder so you can validate requests, responses, security handlers, file uploads, and formats from a single OpenAPI document.\n\n[![npm version](https://img.shields.io/npm/v/@emmett-community/emmett-expressjs-with-openapi.svg)](https://www.npmjs.com/package/@emmett-community/emmett-expressjs-with-openapi) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Build and test](https://github.com/emmett-community/emmett-expressjs-with-openapi/actions/workflows/build_and_test.yml/badge.svg)](https://github.com/emmett-community/emmett-expressjs-with-openapi/actions/workflows/build_and_test.yml)\n\n## Features\n\n- ✅ **OpenAPI 3.x validation** - Validate requests, responses, security, and file uploads.\n- ✅ **Operation handlers** - Auto-wire handlers from `operationId` or `x-eov-operation-handler`.\n- ✅ **Problem Details middleware** - RFC 7807 error responses out of the box.\n- ✅ **ETag helpers** - Built-in optimistic concurrency utilities.\n- ✅ **Testing helpers** - `ApiSpecification` and `ApiE2ESpecification` for tests.\n- ✅ **Optional add-ons** - Firebase Auth security handlers and Pino HTTP logging.\n\n## Why this package?\n\n- Built as a standalone module extracted from the original `@event-driven-io/emmett` repo so it can evolve independently.\n- Keeps the OpenAPI document as the single source of truth across manual routers, validation, and `operationHandlers`.\n- Ships with batteries included: problem-details error handling, helpers for tests, and examples for real-world setups.\n\n## Installation\n\n```bash\nnpm install @emmett-community/emmett-expressjs-with-openapi\nnpm install express-openapi-validator            # optional: OpenAPI validation\nnpm install pino-http                            # optional: HTTP logging\nnpm install @my-f-startup/firebase-auth-express  # optional: Firebase Auth handlers\n```\n\n### Peer Dependencies\n\nRequired:\n\n- `@event-driven-io/emmett` ^0.39.1\n- `express` ^4.19.2\n- `express-async-errors` ^3.1.1\n- `http-problem-details` ^0.1.5\n\nTypeScript types:\n\n- `@types/express` ^4.17.21\n- `@types/supertest` ^6.0.2 (if using testing helpers)\n\nOptional (feature-gated):\n\n- `express-openapi-validator` ^5.3.7 (OpenAPI validation)\n- `pino-http` ^9.0.0 (HTTP logging)\n- `@my-f-startup/firebase-auth-express` 0.1.0 (Firebase Auth handlers)\n- `supertest` ^7.0.0 (required by testing helpers)\n\nVersions follow what is listed in `package.json`.\n\n## Quick start\n\n```typescript\nimport {\n  getApplication,\n  createOpenApiValidatorOptions,\n  startAPI,\n} from '@emmett-community/emmett-expressjs-with-openapi';\n\nconst app = await getApplication({\n  apis: [myApi],\n  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {\n    validateRequests: true,\n    validateResponses: process.env.NODE_ENV === 'development',\n  }),\n});\n\nstartAPI(app, { port: 3000 });\n```\n\n## Configuration\n\n### OpenAPI validation\n\n```typescript\nconst app = await getApplication({\n  apis: [myApi],\n  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {\n    validateRequests: true,\n    validateResponses: true,\n    operationHandlers: './handlers',\n  }),\n});\n```\n\nPrefer to parse the spec once and share it? Load the `.yml` document manually and reuse it for routing, validation, and automatic `operationHandlers`.\n\n```typescript\nimport path from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { parse } from 'yaml';\n\nconst spec = parse(\n  readFileSync(new URL('./openapi.yml', import.meta.url), 'utf-8'),\n);\n\nconst app = await getApplication({\n  apis: [usersApi],\n  openApiValidator: createOpenApiValidatorOptions(spec, {\n    operationHandlers: path.join(path.dirname(import.meta.url), './handlers'),\n  }),\n});\n```\n\nHighlights:\n\n- Enable/disable request or response validation, including per-field tweaks (coercion, unknown query params, removing additional fields, etc.).\n- Register custom security handlers with `validateSecurity.handlers`.\n- Serve the parsed spec via `serveSpec`, configure file upload limits, ignore health-check routes, or validate the spec itself.\n- Reuse `$ref` parsing, custom formats, and file upload middleware exactly as in the upstream validator.\n\n### Logging (optional)\n\nInstall the optional peer to enable HTTP request/response logging:\n\n```bash\nnpm install pino-http\n```\n\n#### Via Code\n\n```typescript\nconst app = await getApplication({\n  pinoHttp: true, // defaults\n  // or:\n  pinoHttp: { autoLogging: false },\n});\n```\n\n#### Via Environment Variables\n\nSet `LOG_HTTP_ENABLED` environment variable to enable HTTP logging:\n\n```bash\nexport LOG_HTTP_ENABLED=true\n```\n\nOptional environment variables:\n- `PINO_HTTP_AUTO_LOGGING`: Set to `false` to disable automatic request/response logging (default: `true`)\n\n```bash\nexport LOG_HTTP_ENABLED=true\nexport PINO_HTTP_AUTO_LOGGING=false\n```\n\nThen in your code:\n\n```typescript\nconst app = await getApplication({});\n```\n\n**Note:** Options passed via code take precedence over environment variables.\n\nSee the full options in the [`pino-http` docs](https://github.com/pinojs/pino-http).\n\n### Firebase Auth (optional)\n\nIf you use Firebase Authentication, install the optional peer and plug it into OpenAPI security handlers:\n\n```bash\nnpm install @my-f-startup/firebase-auth-express\n```\n\n```typescript\nimport admin from 'firebase-admin';\nimport {\n  createFirebaseAuthSecurityHandlers,\n  createOpenApiValidatorOptions,\n  getApplication,\n} from '@emmett-community/emmett-expressjs-with-openapi';\n\nadmin.initializeApp();\n\nconst app = await getApplication({\n  apis: [myApi],\n  openApiValidator: createOpenApiValidatorOptions('./openapi.yaml', {\n    validateSecurity: {\n      handlers: createFirebaseAuthSecurityHandlers(),\n    },\n  }),\n});\n```\n\n`@my-f-startup/firebase-auth-express` relies on `firebase-admin`. Make sure the Admin SDK is installed, initialized, and configured for your environment (credentials or emulator).\n\n## Observability\n\nThis package supports optional logging and tracing.\n\n### Logging\n\nInject a Pino-compatible logger:\n\n```typescript\nimport pino from 'pino';\n\nconst logger = pino();\n\nconst app = await getApplication({\n  observability: { logger },\n});\n\nstartAPI(app, { port: 3000, logger });\n```\n\nNo logs are emitted when logger is not provided.\n\n#### Logger Contract\n\nThis package defines the canonical Logger interface for the Emmett ecosystem. Implementations (Pino, Winston, etc.) MUST adapt to this contract.\n\n```typescript\ninterface Logger {\n  debug(context: Record<string, unknown>, message?: string): void;\n  info(context: Record<string, unknown>, message?: string): void;\n  warn(context: Record<string, unknown>, message?: string): void;\n  error(context: Record<string, unknown>, message?: string): void;\n}\n```\n\n**Semantic Rules:**\n\n- `context` (first parameter): Structured data for the log entry\n- `message` (second parameter): Human-readable message\n- The order is never inverted\n\nPino implements this contract natively. For other loggers like Winston, you need to create an adapter.\n\n> **Note**: The adapter example below is for demonstration purposes only. It is NOT part of the public API and NOT an official recommendation. Users must implement their own adapters for non-Pino loggers.\n\n```typescript\nimport winston from 'winston';\nimport type { Logger } from '@emmett-community/emmett-expressjs-with-openapi';\n\nconst winstonLogger = winston.createLogger({ /* config */ });\n\nconst logger: Logger = {\n  debug(context, message) {\n    winstonLogger.debug(message ?? '', context);\n  },\n  info(context, message) {\n    winstonLogger.info(message ?? '', context);\n  },\n  warn(context, message) {\n    winstonLogger.warn(message ?? '', context);\n  },\n  error(context, message) {\n    winstonLogger.error(message ?? '', context);\n  },\n};\n```\n\n### Tracing\n\nIf your application initializes OpenTelemetry, this package will emit spans automatically. Tracing is passive - spans are no-ops when OpenTelemetry is not configured.\n\n```typescript\nimport { tracedOn, OK } from '@emmett-community/emmett-expressjs-with-openapi';\n\nrouter.post('/carts', tracedOn(async (req) => {\n  // Your handler logic\n  return OK({ body: { success: true } });\n}));\n```\n\nThis package never initializes OpenTelemetry - configure your tracer provider in your application.\n\n## API Reference\n\n### Application\n\n- `getApplication(options)` - Creates and configures the Express app.\n- `startAPI(app, options)` - Starts the HTTP server.\n\n### OpenAPI\n\n- `createOpenApiValidatorOptions(apiSpec, options)` - Helper to assemble OpenAPI validator config.\n- `isOpenApiValidatorAvailable()` - Type guard for optional validator dependency.\n- `createFirebaseAuthSecurityHandlers(options)` - Firebase Auth security handlers.\n- `registerHandlerModule(handlersPath, module)` - Manual registration for operation handlers.\n\n### HTTP helpers\n\n- `send`, `sendCreated`, `sendAccepted`, `sendProblem` - Standard HTTP responses.\n\n### ETag helpers\n\n- `toWeakETag`, `getETagFromIfMatch`, `getETagFromIfNotMatch`, `getETagValueFromIfMatch`, `setETag`.\n\n### Testing helpers\n\n- `ApiSpecification`, `ApiE2ESpecification`\n- `expect`, `expectNewEvents`, `expectResponse`, `expectError`\n\nSee [`docs/openapi-validation.md`](docs/openapi-validation.md) for the full matrix of options and extended examples.\n\n## Testing\n\nThe package includes comprehensive test coverage:\n\n- **Unit tests** (`test/unit/`) - Utilities for ETag handling, error mapping\n- **Integration tests** (`test/integration/`) - Basic routing, OpenAPI validation, operation handlers, optimistic concurrency\n- **E2E tests** (`test/e2e/`) - End-to-end workflows for all features\n\n### Running tests\n\n```bash\n# Unit tests\nnpm run test:unit\n\n# Integration tests\nnpm run test:int\n\n# E2E tests\nnpm run test:e2e\n\n# All tests\nnpm test\n```\n\n## Examples\n\nWorking examples live under `examples/`:\n\n- `examples/shopping-cart` – feature-complete Emmett sample (business logic, memory store/publisher, security handlers, OpenAPI file, unit/int/e2e tests, `.http` scripts).\n- Legacy quick starts:\n  - `examples/basic` – manual routes + validation (minimal scaffolding).\n  - `examples/with-security` – standalone security handler demo.\n  - `examples/operation-handlers` – barebones `operationHandlers` showcase.\n  - `examples/firebase-auth` – Firebase Auth security handlers with operation handlers.\n\n## Documentation\n\n- **Guide:** [`docs/openapi-validation.md`](docs/openapi-validation.md) – authoritative reference for configuration, advanced usage, and troubleshooting.\n- **Emmett docs:** <https://event-driven-io.github.io/emmett/>\n\n## Compatibility\n\n- **Node.js**: tested in CI with 24.x\n- **Emmett**: ^0.39.1\n- **Express**: ^4.19.2\n\n## Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Type-check\nnpm run build:ts\n\n# Run tests\nnpm test\n\n# Run unit tests only\nnpm run test:unit\n\n# Run integration tests\nnpm run test:int\n\n# Run E2E tests\nnpm run test:e2e\n```\n\n## License\n\nMIT\n\n## Related Packages\n\n- [@event-driven-io/emmett](https://github.com/event-driven-io/emmett) - Core Emmett framework\n- [@emmett-community/emmett-google-firestore](https://github.com/emmett-community/emmett-google-firestore) - Firestore event store\n- [@emmett-community/emmett-google-realtime-db](https://github.com/emmett-community/emmett-google-realtime-db) - Realtime Database inline projections\n- [@emmett-community/emmett-google-pubsub](https://github.com/emmett-community/emmett-google-pubsub) - Pub/Sub message bus\n- [@event-driven-io/emmett-mongodb](https://github.com/event-driven-io/emmett/tree/main/src/packages/emmett-mongodb) - MongoDB event store\n\n## Support\n\n- [GitHub Issues](https://github.com/emmett-community/emmett-expressjs-with-openapi/issues)\n- [Emmett Documentation](https://event-driven-io.github.io/emmett/)\n\n---\n\nMade with ❤️ by the Emmett Community\n","readmeFilename":"README.md"}