{"_id":"@avanio/express-etag-utils","_rev":"3-adb8ff0ee4f79aedb81da4032bc03f37","name":"@avanio/express-etag-utils","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@avanio/express-etag-utils","version":"0.0.1","keywords":["etag","express"],"author":{"name":"mharj"},"license":"LGPL-2.1-only","_id":"@avanio/express-etag-utils@0.0.1","maintainers":[{"name":"olliglorioso","email":"olli.glorioso@gmail.com"},{"name":"mharj","email":"marko.harjula@gmail.com"}],"homepage":"https://github.com/AvanioOy/express-etag-utils#readme","bugs":{"url":"https://github.com/AvanioOy/express-etag-utils/issues"},"nyc":{"all":true,"include":["src"],"reporter":["text","html"],"extension":[".ts"]},"dist":{"shasum":"dffc332db5b9c983500de07cd92826d3dedcd4d8","tarball":"https://registry.npmjs.org/@avanio/express-etag-utils/-/express-etag-utils-0.0.1.tgz","fileCount":7,"integrity":"sha512-Zp3l0bf86hd1GaliAyDi60NBVT2vbdEorxBxuhKb51iQPkR1rjE04cMyiC33uJdYbUfvUOfdMk6fp5OFXlfHew==","signatures":[{"sig":"MEYCIQDx7z/u18QKwVxjWUfbMZ0YxnptPFBweb1ep56VN42GqAIhAPgBmnLFZ+MStf/CqZTq5Uv/I+W65JdEKvJa9r/S1fjZ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":59010,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjKUNWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoZig//XNbuDeI+pqDXkG5/1fCttYXEpSEuPsw0RuckMbWlAv0eEJKe\r\n4/2fs9VZu2FmqgMWK3ghlmrU+jdEU7YVxZkC4fc+LgzSwmBxPEA3Lor/CjWr\r\n4kjry09mCHhGiFPtCXDEVHeIFewjWjiciL49qghmGXlZt156pRAsYXAbOBWr\r\nRECpT8rp9ZGFba2Ipy1DWzvbLqgi02B7+UIfYltEaCyKXaGCO88PTmCnKIn1\r\nO/oby7IEnhgivpff2/KgPIuyPX7sGveBdGDeVo7klpq8GXKZwQDmBmhSNaHC\r\nwJinokQEbPmZEcjeO5+JOO82mH3Z3iFd/ChHJBRsTeoEAXmDdRCULDtbs37h\r\nrCrVoHVShFUWZcGEs7T8aCrtlVCxkiORrZAQ1zz1rtusqKmToPUOiqUuJXXj\r\n5XrKB6AjKPPKckp0c5xcbgPzBeHVDd5VKCoQvRjZN1152gC0EsgYsfZzwkzZ\r\nG4XexdlvMle1WPgFvGYLRqIQgY0mUh/SVK5zgMoPvOCHRLSeN7uyf7O3Qcy8\r\nPNRoMucdD/wJFCGQYxsgSQhhaSW+QLhvwrs42bX3A2oRgkhhiSEcwx/gSJun\r\nslRYlvPh5DlKGrTjOwbe/oahyzMllorHmdsSSsWl+PGI+k3PEW2SctVRlqTf\r\neMANCyxWsFX2dG1UMWiOT2K5LhMDQrDIsOo=\r\n=RQko\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","mocha":{"exit":true,"require":["ts-node/register","source-map-support/register"],"extension":["ts","js"],"recursive":true,"reporters":["spec","mocha-junit-reporter"]},"types":"./dist\\index.d.ts","gitHead":"5b06ad368898cc25a0faac766e71077dd2075c1d","scripts":{"test":"cross-env TS_NODE_PROJECT='./tsconfig.test.json' nyc mocha","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"mharj","email":"marko.harjula@gmail.com"},"repository":{"url":"git+https://github.com/AvanioOy/express-etag-utils.git","type":"git"},"_npmVersion":"8.0.0","description":"ExpressJS ETag utils","directories":{"test":"test"},"_nodeVersion":"16.11.0","dependencies":{"etag":"^1.8.1"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","mocha":"^10.0.0","eslint":"^8.23.1","express":"^4.18.1","ts-node":"^10.9.1","prettier":"^2.7.1","cross-env":"^7.0.3","typescript":"^4.8.3","@types/chai":"^4.3.3","@types/etag":"^1.8.1","@types/node":"^16.11.59","@types/mocha":"^9.1.1","@types/express":"^4.17.14","source-map-support":"^0.5.21","eslint-plugin-sonarjs":"^0.15.0","eslint-config-prettier":"^8.5.0","eslint-config-standard":"^17.0.0","eslint-plugin-prettier":"^4.2.1","@typescript-eslint/parser":"^5.37.0","@typescript-eslint/eslint-plugin":"^5.37.0"},"peerDependencies":{"express":">=4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-etag-utils_0.0.1_1663648598725_0.4218214055042224","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@avanio/express-etag-utils","version":"0.0.2","description":"ExpressJS ETag utils","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"},"default":"./dist/index.mjs"},"scripts":{"build":"tsdown src/index.ts --format cjs,esm --dts --clean","prepublishOnly":"npm run build","test":"vitest test --typecheck --run --no-isolate --coverage","coverage":"vitest test --run --no-isolate --reporter=dot --coverage --coverage.reporter=lcov","lint":"biome check","validate":"tsc --noEmit --project tsconfig.test.json"},"repository":{"type":"git","url":"git+https://github.com/luolapeikko/express-etag-utils.git"},"keywords":["etag","express"],"author":{"name":"mharj"},"license":"LGPL-2.1-only","bugs":{"url":"https://github.com/luolapeikko/express-etag-utils/issues"},"homepage":"https://github.com/luolapeikko/express-etag-utils#readme","peerDependencies":{"etag":"^1.8.1","express":">=4.0.0"},"devDependencies":{"@biomejs/biome":"^2.4.6","@tsconfig/node24":"^24.0.4","@types/etag":"^1.8.4","@types/express":"^5.0.6","@types/node":"^25.4.0","@vitest/coverage-v8":"^4.0.18","c8":"^11.0.0","express":"^5.2.1","tsdown":"^0.21.2","typescript":"^5.9.3","vitest":"^4.0.18"},"packageManager":"pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be","gitHead":"424a0d12d87fbfccc91b41c12fbe30c52f62ef55","_id":"@avanio/express-etag-utils@0.0.2","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-XzukJgr8NlsKiuIeOKaJR6VgyMiHrVftpxsuamicx0QkLXN3ah2x0t+4Dk1yUNjlS22T32nQEkC0aagIXpSnNg==","shasum":"f2450e195fd48b275fa039e2f5828b19610af050","tarball":"https://registry.npmjs.org/@avanio/express-etag-utils/-/express-etag-utils-0.0.2.tgz","fileCount":7,"unpackedSize":52773,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@avanio%2fexpress-etag-utils@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGWYFp0sYIURoRJKRcvmZUUlj7kKuwtSoADfRyK6AdqlAiEAyOwdKhZbHnUzk7EUjDUMPzEkfw+b+C3wFCt6Yxxqdbw="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:90d2a5d9-32b0-48b5-bc28-24694cdee3f2"}},"directories":{},"maintainers":[{"name":"samutoljamo","email":"samu.toljamo@gmail.com"},{"name":"mharj","email":"marko.harjula@gmail.com"},{"name":"olliglorioso","email":"olli.glorioso@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/express-etag-utils_0.0.2_1773295359804_0.7594221895914008"},"_hasShrinkwrap":false}},"time":{"created":"2022-09-20T04:36:38.649Z","modified":"2026-03-12T06:02:40.244Z","0.0.1":"2022-09-20T04:36:38.931Z","0.0.2":"2026-03-12T06:02:39.949Z"},"bugs":{"url":"https://github.com/luolapeikko/express-etag-utils/issues"},"author":{"name":"mharj"},"license":"LGPL-2.1-only","homepage":"https://github.com/luolapeikko/express-etag-utils#readme","keywords":["etag","express"],"repository":{"type":"git","url":"git+https://github.com/luolapeikko/express-etag-utils.git"},"description":"ExpressJS ETag utils","maintainers":[{"name":"samutoljamo","email":"samu.toljamo@gmail.com"},{"name":"mharj","email":"marko.harjula@gmail.com"},{"name":"olliglorioso","email":"olli.glorioso@gmail.com"}],"readme":"# express-etag-utils\n\nExpressJS ETag utils\n\n## ifNoneMatchHandler: middleware check if current payload is identical with 'if-none-match' header, return 304 (else payload as json with ETag header)\n\n```typescript\nconst payloadCallback: IfNoneMatchHandlerCallback = async (req, res) => {\n    const body = (await Model.find()).map((m) => m.toObject());\n\treturn {\n\t\tbody,\n\t\t// etag: customEtagBuilder(body) // optional, if not set, will be generated from body\n\t};\n};\n\napp.get('/api/endpoint', ifNoneMatchHandler('json', payloadCallback));\n```\n\n## ifMatchHandler: middleware to block if payloadCallback data is already changed based on 'if-match' header\n\n```typescript\nconst payloadCallback: IfMatchHandlerCallback = async (req, res) => {\n\tres.locals.model = await Model.findOne({id: req.params.id});\n\tif (!res.locals.model) {\n\t\tthrow new HttpError(404, 'Not Found');\n\t}\n\treturn {\n\t\tbody: res.locals.model.toObject(),\n\t\t// etag: res.locals.model.customEtagBuild() // optional, if not set, will be generated from body\n\t};\n};\n\napp.put('/api/endpoint/:id', ifMatchHandler(payloadCallback), async (req, res, next) => {\n\tif (!res.locals.model) {\n\t\tthrow new HttpError(404, 'Not Found');\n\t}\n\tObject.assign(res.locals.model, req.body);\n\tif (res.locals.model.isModified()) {\n\t\tawait res.locals.model.save();\n\t}\n\tres.status(200).send('Ok');\n});\n```\n","readmeFilename":"README.md"}