{"_id":"@bigfootds/bigfootds-service-utils","_rev":"5-d4d352c72e87e1fc2a5c32d03c2aa7dd","name":"@bigfootds/bigfootds-service-utils","dist-tags":{"latest":"1.2.0"},"versions":{"0.1.0":{"name":"@bigfootds/bigfootds-service-utils","version":"0.1.0","keywords":[],"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","_id":"@bigfootds/bigfootds-service-utils@0.1.0","maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"dist":{"shasum":"a29943c6978c76d9b9430d8c661acbc9463bad57","tarball":"https://registry.npmjs.org/@bigfootds/bigfootds-service-utils/-/bigfootds-service-utils-0.1.0.tgz","fileCount":13,"integrity":"sha512-y4D5G3SPp/sKC0SYAPXJzSBESSbc/6qmN/VokilSmHN2LvhPDr8WIBCvjxpMjYfC/xDZ8lxW8/lZdkZe/T74rA==","signatures":[{"sig":"MEQCICypH+98SinxICo1xgP+oCS30QF+ISjSiHVxNn5BFXUpAiBIdlq9I4mDRNpT5wBzGgCbknVrPy+0CerKEnynlZNGvQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34242},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./errors":{"types":"./dist/errors.d.ts","default":"./dist/errors.js","require":"./dist/errors.js"},"./express":{"types":"./dist/express.d.ts","default":"./dist/express.js","require":"./dist/express.js"},"./requestIds":{"types":"./dist/requestIds.d.ts","default":"./dist/requestIds.js","require":"./dist/requestIds.js"},"./package.json":"./package.json","./serviceTokens":{"types":"./dist/serviceTokens.d.ts","default":"./dist/serviceTokens.js","require":"./dist/serviceTokens.js"}},"gitHead":"993c196abcea6e91d9578bee5ae84d7241942866","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json","prepack":"npm run build","prebuild":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""},"_npmUser":{"name":"alexstormwood","email":"alex@bigfootds.com"},"repository":{"url":"git+https://github.com/BigfootDS/pkg-service-utils.git","type":"git"},"_npmVersion":"11.11.0","description":"Reusable service-side utilities for BigfootDS microservices.","directories":{},"_nodeVersion":"25.6.1","dependencies":{"@bigfootds/bigfootds-shared-data":"^2.1.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^6.0.3","@types/node":"^25.9.2"},"_npmOperationalInternal":{"tmp":"tmp/bigfootds-service-utils_0.1.0_1781354387496_0.535887069950348","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@bigfootds/bigfootds-service-utils","version":"1.1.0","keywords":[],"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","_id":"@bigfootds/bigfootds-service-utils@1.1.0","maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"dist":{"shasum":"9514f53a9d7fc06438952a33596b687f99e5ba47","tarball":"https://registry.npmjs.org/@bigfootds/bigfootds-service-utils/-/bigfootds-service-utils-1.1.0.tgz","fileCount":17,"integrity":"sha512-tFUFyIaf9iQ/4X6Ohk9mqY8F5LelhelakFk0bTazr+G8QxJUvY/Dt9OTCeuDsr4zARL/Xmut321o98a+WTVuPA==","signatures":[{"sig":"MEQCIDgagSM6PKgA8+HEH9sUy1wAnl3IzCsEn+f2d7+fjZFdAiBgQ1UZ0dY4SxsBcQdQEOrgTae41CUu5/6ivxTMCf3O8g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bigfootds%2fbigfootds-service-utils@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":57192},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./errors":{"types":"./dist/errors.d.ts","default":"./dist/errors.js","require":"./dist/errors.js"},"./express":{"types":"./dist/express.d.ts","default":"./dist/express.js","require":"./dist/express.js"},"./logging":{"types":"./dist/logging.d.ts","default":"./dist/logging.js","require":"./dist/logging.js"},"./profanity":{"types":"./dist/profanity.d.ts","default":"./dist/profanity.js","require":"./dist/profanity.js"},"./requestIds":{"types":"./dist/requestIds.d.ts","default":"./dist/requestIds.js","require":"./dist/requestIds.js"},"./package.json":"./package.json","./serviceTokens":{"types":"./dist/serviceTokens.d.ts","default":"./dist/serviceTokens.js","require":"./dist/serviceTokens.js"}},"gitHead":"feb4a49b5d8e8878b7c9750304fd26905acc290c","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json","prepack":"npm run build","prebuild":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5cd7ddfc-cb3e-44a1-a1a9-3921b0687e5e"}},"repository":{"url":"git+https://github.com/BigfootDS/pkg-service-utils.git","type":"git"},"_npmVersion":"11.13.0","description":"Reusable service-side utilities for BigfootDS microservices.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"morgan":"^1.11.0","@2toad/profanity":"^3.3.0","@bigfootds/bigfootds-shared-data":"^3.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^6.0.3","@types/node":"^25.9.2","@types/morgan":"^1.9.10"},"_npmOperationalInternal":{"tmp":"tmp/bigfootds-service-utils_1.1.0_1781356507864_0.02733144406096666","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@bigfootds/bigfootds-service-utils","version":"1.1.1","keywords":[],"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","_id":"@bigfootds/bigfootds-service-utils@1.1.1","maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"dist":{"shasum":"ab49a3937fe5d5d2729a0f4939e2c6624e2d860d","tarball":"https://registry.npmjs.org/@bigfootds/bigfootds-service-utils/-/bigfootds-service-utils-1.1.1.tgz","fileCount":17,"integrity":"sha512-7rCG+DQ4U/IsZD+yOpQ6ni7DePGt99GMiQg/psT3Zlo71T/xF0NU2Mfgfq5vfZ1fadhwe8VtcInm0ZRKZpAmUw==","signatures":[{"sig":"MEQCIBUZP8vyraolwdxwbpP23sWRLBGPNGqkWd3xtzz6LxtyAiAzcuY2iHPekBbZOM+o+UdONtFGPCLJ8g/2bfliM3yVJg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bigfootds%2fbigfootds-service-utils@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":57192},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./errors":{"types":"./dist/errors.d.ts","default":"./dist/errors.js","require":"./dist/errors.js"},"./express":{"types":"./dist/express.d.ts","default":"./dist/express.js","require":"./dist/express.js"},"./logging":{"types":"./dist/logging.d.ts","default":"./dist/logging.js","require":"./dist/logging.js"},"./profanity":{"types":"./dist/profanity.d.ts","default":"./dist/profanity.js","require":"./dist/profanity.js"},"./requestIds":{"types":"./dist/requestIds.d.ts","default":"./dist/requestIds.js","require":"./dist/requestIds.js"},"./package.json":"./package.json","./serviceTokens":{"types":"./dist/serviceTokens.d.ts","default":"./dist/serviceTokens.js","require":"./dist/serviceTokens.js"}},"gitHead":"d95bfd288df9cb2233cab4191e7db51478610dc9","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json","prepack":"npm run build","prebuild":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5cd7ddfc-cb3e-44a1-a1a9-3921b0687e5e"}},"repository":{"url":"git+https://github.com/BigfootDS/pkg-service-utils.git","type":"git"},"_npmVersion":"11.16.0","description":"Reusable service-side utilities for BigfootDS microservices.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"morgan":"^1.11.0","@2toad/profanity":"^3.3.0","@bigfootds/bigfootds-shared-data":"^3.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^6.0.3","@types/node":"^25.9.2","@types/morgan":"^1.9.10"},"_npmOperationalInternal":{"tmp":"tmp/bigfootds-service-utils_1.1.1_1786283097371_0.5569974366817743","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@bigfootds/bigfootds-service-utils","version":"1.1.2","keywords":[],"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","_id":"@bigfootds/bigfootds-service-utils@1.1.2","maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"dist":{"shasum":"d0c2ac29ee640a5a752d5e78889c35ded9c555a2","tarball":"https://registry.npmjs.org/@bigfootds/bigfootds-service-utils/-/bigfootds-service-utils-1.1.2.tgz","fileCount":17,"integrity":"sha512-vt7pq1FzNvrwUmV0AzAhUzAlOtdAoMaDrZu97KB8YVkfbdLbxmAVwTmG/LoH7LMoDXCtYZxCWDBA7uaVKQg/9w==","signatures":[{"sig":"MEQCIHplh9gKulsaAJTnSchueapgMdpjoedQhnlvqDK8NtovAiBDIfcwKUF7QO7wVAEx2QOdgL0RCh8b0wapfqpc0kqwSA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bigfootds%2fbigfootds-service-utils@1.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":57192},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js","require":"./dist/index.js"},"./errors":{"types":"./dist/errors.d.ts","default":"./dist/errors.js","require":"./dist/errors.js"},"./express":{"types":"./dist/express.d.ts","default":"./dist/express.js","require":"./dist/express.js"},"./logging":{"types":"./dist/logging.d.ts","default":"./dist/logging.js","require":"./dist/logging.js"},"./profanity":{"types":"./dist/profanity.d.ts","default":"./dist/profanity.js","require":"./dist/profanity.js"},"./requestIds":{"types":"./dist/requestIds.d.ts","default":"./dist/requestIds.js","require":"./dist/requestIds.js"},"./package.json":"./package.json","./serviceTokens":{"types":"./dist/serviceTokens.d.ts","default":"./dist/serviceTokens.js","require":"./dist/serviceTokens.js"}},"gitHead":"c187bd1a6a0202c1b7f3f8712a7e63c5fcb5d66c","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json","prepack":"npm run build","prebuild":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5cd7ddfc-cb3e-44a1-a1a9-3921b0687e5e"}},"repository":{"url":"git+https://github.com/BigfootDS/pkg-service-utils.git","type":"git"},"_npmVersion":"11.17.0","description":"Reusable service-side utilities for BigfootDS microservices.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"morgan":"^1.11.0","@2toad/profanity":"^3.3.0","@bigfootds/bigfootds-shared-data":"^3.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^6.0.3","@types/node":"^25.9.2","@types/morgan":"^1.9.10"},"_npmOperationalInternal":{"tmp":"tmp/bigfootds-service-utils_1.1.2_1786786007137_0.5400801167273654","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bigfootds/bigfootds-service-utils","version":"1.2.0","description":"Reusable service-side utilities for BigfootDS microservices.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","default":"./dist/index.js"},"./requestIds":{"types":"./dist/requestIds.d.ts","require":"./dist/requestIds.js","default":"./dist/requestIds.js"},"./errors":{"types":"./dist/errors.d.ts","require":"./dist/errors.js","default":"./dist/errors.js"},"./serviceTokens":{"types":"./dist/serviceTokens.d.ts","require":"./dist/serviceTokens.js","default":"./dist/serviceTokens.js"},"./express":{"types":"./dist/express.d.ts","require":"./dist/express.js","default":"./dist/express.js"},"./logging":{"types":"./dist/logging.d.ts","require":"./dist/logging.js","default":"./dist/logging.js"},"./profanity":{"types":"./dist/profanity.d.ts","require":"./dist/profanity.js","default":"./dist/profanity.js"},"./package.json":"./package.json"},"scripts":{"prebuild":"node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"","build":"tsc -p tsconfig.json","prepack":"npm run build","test":"npm run build && npm run test:types:express5 && node --test","test:types:express5":"tsc --project tsconfig.express5-consumer.json --noEmit"},"repository":{"type":"git","url":"git+https://github.com/BigfootDS/pkg-service-utils.git"},"keywords":[],"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","dependencies":{"@2toad/profanity":"^3.3.0","@bigfootds/bigfootds-shared-data":"^3.0.0","morgan":"^1.11.0"},"devDependencies":{"@types/express":"^5.0.6","@types/morgan":"^1.9.10","@types/node":"^25.9.2","express":"^5.2.1","typescript":"^6.0.3"},"gitHead":"5ccd0fb890895591e57e49d7d87b6797f337c353","_id":"@bigfootds/bigfootds-service-utils@1.2.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-tXZstB4wTfEuNC8k0AKJ+NOd4/pSaa+6Gxga+d3ZP2N69f9t0cieJGUBkD46Hzl1AvAlTd5HXs6eQJpfKi7UkA==","shasum":"8072217f36a3e29a3516a0d4862a22dd61952baf","tarball":"https://registry.npmjs.org/@bigfootds/bigfootds-service-utils/-/bigfootds-service-utils-1.2.0.tgz","fileCount":17,"unpackedSize":69893,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bigfootds%2fbigfootds-service-utils@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDzDUBi9DTw0SJbLxRjhLQrkFjdfjFfoZAmMIv96AZvMAiAmy6mxQmJqifEWyhNjTiAQV1wOq3SoFl0noiVGzf5oLQ=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5cd7ddfc-cb3e-44a1-a1a9-3921b0687e5e"}},"directories":{},"maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bigfootds-service-utils_1.2.0_1788257580309_0.8466717153569947"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-13T12:39:47.374Z","modified":"2026-09-01T10:13:00.753Z","0.1.0":"2026-06-13T12:39:47.667Z","1.1.0":"2026-06-13T13:15:08.010Z","1.1.1":"2026-08-09T13:44:57.484Z","1.1.2":"2026-08-15T09:26:47.291Z","1.2.0":"2026-09-01T10:13:00.436Z"},"bugs":{"url":"https://github.com/BigfootDS/pkg-service-utils/issues"},"author":{"name":"Alex Stormwood","email":"alex.stormwood@bigfootds.com"},"license":"MIT","homepage":"https://github.com/BigfootDS/pkg-service-utils#readme","keywords":[],"repository":{"type":"git","url":"git+https://github.com/BigfootDS/pkg-service-utils.git"},"description":"Reusable service-side utilities for BigfootDS microservices.","maintainers":[{"name":"alexstormwood","email":"alex@bigfootds.com"}],"readme":"# BigfootDS Service Utils\n\nReusable service-side utilities for BigfootDS microservices.\n\nThis package helps services apply the same request, error, and internal-caller conventions without copying helper code into each service. It is a package, not a service, and it does not own runtime data.\n\n## To-Do List\n\n- [x] Structured JSON-lines request logging\n- [x] Profanity matching/normalisation helpers.\n- [ ] Broad validation helpers\n- [ ] Audit helpers\n- [ ] Admin/operator bulk helpers\n\n\n## Public Package Safety\n\nThis package is publicly published on NPM, so its contents must be safe for public-facing usage.\n\nIt should contain reusable code, public type definitions, and public convention constants only.\n\nDo not put secrets, service-token values, private route policies, private diagnostics, account data, provider payloads, environment-specific URLs, live-ops configuration, audit records, or service-owned runtime data in this package.\n\nService-token helpers accept token values at runtime from the consuming service. Tokens should come from that service's environment or secret manager, never from this package.\n\n## Installation\n\nInstall using the organisatio-scoped name like below: \n\n```sh\nnpm install @bigfootds/bigfootds-service-utils\n```\n\n## Request IDs\n\n```ts\nimport {\n\tresolveRequestIdFromHeaders,\n\twriteRequestIdHeader\n} from \"@bigfootds/bigfootds-service-utils\";\n\nconst metadata = resolveRequestIdFromHeaders(request.headers);\n\nwriteRequestIdHeader(response, metadata.requestId);\n```\n\nInbound `x-request-id` values are accepted only when they are safe ASCII, 8-64 characters long, and contain letters, numbers, `.`, `_`, `:`, or `-`. Missing or unsafe values are replaced with a generated UUID.\n\n## Standard Errors\n\n```ts\nimport {\n\tERROR_CODES\n} from \"@bigfootds/bigfootds-shared-data\";\nimport {\n\tcreateServiceError,\n\tserializeServiceError\n} from \"@bigfootds/bigfootds-service-utils\";\n\nconst error = createServiceError(ERROR_CODES.VALIDATION_FAILED, {\n\tmessage: \"Display name is required.\",\n\tsafeDetails: { field: \"displayName\" },\n\trequestId: \"req_123456\"\n});\n\nconst { httpStatus, body } = serializeServiceError(error);\n```\n\nSerialised errors include stable `error.code` values and safe messages. They do not include stack traces, causes, tokens, or private diagnostics.\n\n## Service Tokens\n\n```ts\nimport {\n\tverifyServiceTokenFromHeaders\n} from \"@bigfootds/bigfootds-service-utils\";\n\nconst result = verifyServiceTokenFromHeaders(request.headers, {\n\tacceptedCallers: [\n\t\t{\n\t\t\tserviceId: \"ms-auth\",\n\t\t\ttoken: process.env.ACCEPT_MS_AUTH_SERVICE_TOKEN ?? \"\"\n\t\t}\n\t],\n\tallowedServiceIds: [\"ms-auth\"]\n});\n\nif (!result.ok) {\n\tconsole.log(result.errorCode);\n}\n```\n\nCallers send tokens with `Authorization: Bearer <token>`. Caller identity comes from the existing `pkg-bigfoot-fetcher` `productName` header. Package-style identities such as `@bigfootds/ms-auth` are normalised to canonical Project IDs such as `ms-auth`.\n\n## Express Adapters\n\nThe Express adapters use structural types, so this package does not require Express as a dependency.\n\n```ts\nimport {\n\trequestIdMiddleware,\n\tserviceTokenMiddleware,\n\tstandardErrorHandler\n} from \"@bigfootds/bigfootds-service-utils\";\n\napp.use(requestIdMiddleware());\n\napp.post(\n\t\"/internal/auth-user-deleted\",\n\tserviceTokenMiddleware({\n\t\tacceptedCallers: [\n\t\t\t{\n\t\t\t\tserviceId: \"ms-auth\",\n\t\t\t\ttoken: process.env.ACCEPT_MS_AUTH_SERVICE_TOKEN ?? \"\"\n\t\t\t}\n\t\t],\n\t\tallowedServiceIds: [\"ms-auth\"]\n\t}),\n\tcontroller\n);\n\napp.use(standardErrorHandler());\n```\n\n## Structured Request Logging\n\nUse the structured logger at the HTTP composition boundary, after the request-ID middleware and before routes. It writes one JSON object to standard output for each completed request, so a log collector can parse it without reading a human-formatted sentence.\n\n```ts\nimport {\n\tcreateStructuredRequestLogger,\n\trequestIdMiddleware\n} from \"@bigfootds/bigfootds-service-utils\";\n\napp.use(requestIdMiddleware());\napp.use(createStructuredRequestLogger({\n\tserviceName: \"ms-userrelations\"\n}));\n```\n\nEvery emitted record has `service`, `environment`, `requestId`, `method`, `path`, `statusCode`, and `responseTimeMs`. It also includes `contentLength`, `callerService`, and a known shared `failureCategory` when those values are available. Route templates are preferred. An unmatched request always uses the fixed `/unmatched` path marker, rather than any raw request path, query string, or fragment.\n\nThe logger never reads or writes request headers, request bodies, response bodies, bearer tokens, or error messages. Its request ID comes only from `requestIdMiddleware`'s canonical `request.bigfootds.requestId`; a misordered or missing request-ID middleware is recorded as `-`, not an inbound header value. A failure category is written only when it is a known `@bigfootds/bigfootds-shared-data` error code. This keeps accidental exception text and secret-derived strings out of request logs.\n\nLogging is disabled by default when `NODE_ENV` is `test`. Services can pass `enabled: false` for tests that construct an app outside that environment. The older `createBigfootDSMorganLogger` export remains available for existing consumers, but new services should use `createStructuredRequestLogger`.\n\n## Express 5 Compatibility\n\nThe Express adapters and structured logger use structural TypeScript types. Express is a development-only dependency here, not a runtime package dependency. `npm test` includes a TypeScript 6 fixture that compiles an Express 5.2 app using request IDs, structured logging, service-token middleware, and the standard error handler.\n\n## Profanity And Restricted Words\n\nRuntime profanity handling lives here, while the static word lists and metadata stay in `@bigfootds/bigfootds-shared-data`.\n\n```ts\nimport {\n\tchatProfanityHandler,\n\tplayerNameProfanityHandler\n} from \"@bigfootds/bigfootds-service-utils\";\n\nconst chatHasProfanity = chatProfanityHandler.exists(\"I like big butts and I cannot lie\");\nconst nameResult = playerNameProfanityHandler.check(\"BigfootDS_Admin\");\n```\n\nUse the lower-level helpers when a service needs direct list matching or normalisation:\n\n```ts\nimport {\n\tfindProfanityListMatches,\n\tnormalizeModerationText\n} from \"@bigfootds/bigfootds-service-utils\";\n\nconst normalised = normalizeModerationText(\"  BigfootDS\\tAdmin  \");\nconst matches = findProfanityListMatches(normalised);\n```\n\n## Package Boundary\n\n`pkg-service-utils` depends on `@bigfootds/bigfootds-shared-data` for stable Project Definitions, error-code metadata, and shared response data shapes.\n\nDo not copy shared data into this package. Do not make `pkg-shared-data` depend on this package.\n\nThe intended dependency direction is:\n\n```text\nmicroservice -> pkg-service-utils -> pkg-shared-data\n```\n","readmeFilename":"README.md"}