{"_id":"@aialchemy/service-utils","name":"@aialchemy/service-utils","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@aialchemy/service-utils","version":"0.0.1","description":"Reusable Node.js helpers for API services: structured logging, HMAC request signing, Redis session storage, and single-instance process locking.","keywords":["api","utils","logger","winston","hmac","signing","redis","session","process-lock","express"],"homepage":"https://github.com/aialchemylabs/api-service-utils#readme","bugs":{"url":"https://github.com/aialchemylabs/api-service-utils/issues"},"repository":{"type":"git","url":"git+https://github.com/aialchemylabs/api-service-utils.git"},"license":"MIT","author":{"name":"AI Alchemy Labs"},"type":"module","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","sideEffects":false,"peerDependencies":{"express":"^4.0.0 || ^5.0.0","redis":"^4.0.0 || ^5.0.0","winston":"^3.0.0"},"peerDependenciesMeta":{"express":{"optional":true},"redis":{"optional":true},"winston":{"optional":true}},"devDependencies":{"@biomejs/biome":"^2.4.11","@types/express":"^5.0.0","@types/node":"^22.0.0","express":"^5.0.0","redis":"^4.7.0","tsup":"^8.5.1","typescript":"^5.6.0","vitest":"^2.1.0","winston":"^3.15.0"},"engines":{"node":">=22"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","lint":"biome check src/","lint:fix":"biome check --write src/","format":"biome format --write .","test":"vitest run","test:watch":"vitest","clean":"rm -rf dist coverage"},"_id":"@aialchemy/service-utils@0.0.1","_integrity":"sha512-upGn+LjVr5tCbrLsQhpVpa8er5ZjyI/xwCDM4UtZ0VCv4UmN3/rjxuv/5kMB+FKbAMCIJrf+s+a/DQUTlwtdJg==","_resolved":"/tmp/b51842c7e012918827c9bf9e2abb4261/aialchemy-service-utils-0.0.1.tgz","_from":"file:aialchemy-service-utils-0.0.1.tgz","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-upGn+LjVr5tCbrLsQhpVpa8er5ZjyI/xwCDM4UtZ0VCv4UmN3/rjxuv/5kMB+FKbAMCIJrf+s+a/DQUTlwtdJg==","shasum":"26e07879258b854f088b7e5307901fe34943770a","tarball":"https://registry.npmjs.org/@aialchemy/service-utils/-/service-utils-0.0.1.tgz","fileCount":7,"unpackedSize":40432,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDGhQLnSkzgtI1Q5R05e6rrV/8lZH062eCCdzkPSoGSggIhAJwAr5KyxJCvHjYR9okNQ8f906g7qeEcGG+Ha4Abv7a2"}]},"_npmUser":{"name":"srinivas-jay","email":"billing@aialchemy.au"},"directories":{},"maintainers":[{"name":"srinivas-jay","email":"billing@aialchemy.au"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/service-utils_0.0.1_1776075554587_0.9342984685998361"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-13T10:19:14.474Z","0.0.1":"2026-04-13T10:19:14.708Z","modified":"2026-04-13T10:19:14.945Z"},"maintainers":[{"name":"srinivas-jay","email":"billing@aialchemy.au"}],"description":"Reusable Node.js helpers for API services: structured logging, HMAC request signing, Redis session storage, and single-instance process locking.","homepage":"https://github.com/aialchemylabs/api-service-utils#readme","keywords":["api","utils","logger","winston","hmac","signing","redis","session","process-lock","express"],"repository":{"type":"git","url":"git+https://github.com/aialchemylabs/api-service-utils.git"},"author":{"name":"AI Alchemy Labs"},"bugs":{"url":"https://github.com/aialchemylabs/api-service-utils/issues"},"license":"MIT","readme":"# @aialchemy/service-utils\n\nReusable Node.js helpers for API services:\n\n- **Logger** — winston factory with optional file transports and Express middleware\n- **Signing** — HMAC-SHA256 request signing and verification\n- **Redis session** — typed JSON session storage on top of `redis`\n- **Process manager** — single-instance process locking via PID files\n\nESM + CJS, fully typed, zero side effects on import.\n\n## Install\n\n```bash\npnpm add @aialchemy/service-utils\n# or\nnpm install @aialchemy/service-utils\n```\n\nThe package declares optional peer dependencies. Install only what you use:\n\n```bash\npnpm add winston              # for the logger\npnpm add express              # for the Express middleware\npnpm add redis                # for RedisSessionService\n```\n\n## Usage\n\n### Logger\n\n```ts\nimport { createLogger, createRequestLogger, createErrorLogger } from '@aialchemy/service-utils';\nimport express from 'express';\n\nconst logger = createLogger({\n  level: 'info',\n  service: 'orders-api',\n  version: '1.4.2',\n  // file: { dir: 'logs/orders-api' }, // opt-in: file transports\n});\n\nconst app = express();\napp.use(createRequestLogger(logger));\napp.use(createErrorLogger(logger));\n```\n\n### Signing\n\n```ts\nimport { signRequest, verifySignature, generateBodyHash } from '@aialchemy/service-utils';\n\nconst headers = signRequest(process.env.SIGNING_SECRET!, {\n  method: 'POST',\n  path: '/api/orders',\n  body: JSON.stringify({ id: 1 }),\n  client: 'orders-portal',\n  userId: 'user-123',\n});\n\n// On the server:\nconst ok = verifySignature(\n  process.env.SIGNING_SECRET!,\n  headers['X-Signature'],\n  Number(headers['X-Timestamp']),\n  'POST',\n  '/api/orders',\n  generateBodyHash('{\"id\":1}'),\n);\n```\n\n### Redis session\n\n```ts\nimport { RedisSessionService, createLogger } from '@aialchemy/service-utils';\n\nconst logger = createLogger({ service: 'orders-api' });\nconst sessions = new RedisSessionService({ url: process.env.REDIS_URL!, logger });\n\nawait sessions.connect();\nawait sessions.setSession('user:123', { name: 'Ada' }, 3600);\nconst user = await sessions.getSession<{ name: string }>('user:123');\n```\n\n### Process manager\n\n```ts\nimport { initializeProcessManagement } from '@aialchemy/service-utils';\n\ninitializeProcessManagement({\n  serviceName: 'orders-api',\n  lockFilePath: '/tmp/orders-api.lock',\n  metadata: { port: 3000 },\n});\n```\n\n## Development\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, scripts, and conventions.\n\n```bash\npnpm install\npnpm run typecheck\npnpm run lint\npnpm run test\npnpm run build\n```\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n","readmeFilename":"README.md","_rev":"1-7b28ee536446e87737bcb3e6afb483ed"}