Skip to content

refactor: deduplicate framework options and useLogger#148

Merged
HugoRCD merged 3 commits intomainfrom
refactor/deduplicate-framework-options
Mar 7, 2026
Merged

refactor: deduplicate framework options and useLogger#148
HugoRCD merged 3 commits intomainfrom
refactor/deduplicate-framework-options

Conversation

@HugoRCD
Copy link
Owner

@HugoRCD HugoRCD commented Mar 7, 2026

Summary

  • Extract BaseEvlogOptions in shared/middleware.ts — the 7 framework options interfaces (Express, Fastify, NestJS, Elysia, SvelteKit, Hono, Next.js) now extends BaseEvlogOptions instead of redeclaring the same 6 fields with identical JSDoc
  • Extract createLoggerStorage() factory in shared/storage.ts — the AsyncLocalStorage + useLogger() pattern was copy-pasted in 5 frameworks, now it's a single factory (Elysia keeps its own useLogger due to the activeLoggers check)
  • Net result: +113 / -314 lines, zero behavior change

…ions

Extract BaseEvlogOptions in shared/middleware.ts and createLoggerStorage
factory in shared/storage.ts to eliminate ~170 lines of copy-pasted types,
JSDoc, and AsyncLocalStorage boilerplate across 7 framework integrations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
evlog-docs Ready Ready Preview, Comment, Open in v0 Mar 7, 2026 5:31pm

@github-actions
Copy link
Contributor

github-actions bot commented Mar 7, 2026

Thank you for following the naming conventions! 🙏

Update the template to use BaseEvlogOptions and createLoggerStorage
instead of the old copy-paste pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace `interface Evlog*Options extends BaseEvlogOptions {}` with
`type Evlog*Options = BaseEvlogOptions` to satisfy
@typescript-eslint/no-empty-object-type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@HugoRCD HugoRCD changed the title refactor: deduplicate framework options and useLogger refactor: deduplicate framework options and useLogger Mar 7, 2026
@HugoRCD HugoRCD merged commit a72f75a into main Mar 7, 2026
12 checks passed
@HugoRCD HugoRCD deleted the refactor/deduplicate-framework-options branch March 7, 2026 17:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the evlog framework adapters to reduce duplication by extracting shared option types and a shared AsyncLocalStorage/useLogger() factory into packages/evlog/src/shared/.

Changes:

  • Introduces BaseEvlogOptions (shared user-facing options) and updates framework option interfaces to extend it.
  • Adds createLoggerStorage() to centralize the AsyncLocalStorage + useLogger() pattern, used by Express/Fastify/NestJS/SvelteKit.
  • Updates the framework integration skill guide to reflect the new shared utilities.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/evlog/src/sveltekit/index.ts Switches SvelteKit adapter to BaseEvlogOptions + createLoggerStorage and re-exports useLogger.
packages/evlog/src/shared/storage.ts Adds shared factory for request-scoped storage and useLogger() accessor.
packages/evlog/src/shared/middleware.ts Extracts BaseEvlogOptions and makes MiddlewareLoggerOptions extend it.
packages/evlog/src/next/types.ts Refactors Next options type to extend BaseEvlogOptions.
packages/evlog/src/nestjs/index.ts Switches NestJS adapter to BaseEvlogOptions + createLoggerStorage and re-exports useLogger.
packages/evlog/src/hono/index.ts Refactors Hono options type to extend BaseEvlogOptions.
packages/evlog/src/fastify/index.ts Switches Fastify adapter to BaseEvlogOptions + createLoggerStorage and re-exports useLogger.
packages/evlog/src/express/index.ts Switches Express adapter to BaseEvlogOptions + createLoggerStorage and re-exports useLogger.
packages/evlog/src/elysia/index.ts Refactors Elysia options type to extend BaseEvlogOptions (keeps custom useLogger).
.agents/skills/create-framework-integration/SKILL.md Updates integration template/docs for the new shared types and storage factory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +11 to +13
export type EvlogExpressOptions = BaseEvlogOptions

export { useLogger }
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor removes the exported useLogger() JSDoc/examples from the Express entrypoint (it is now a re-exported destructured value). That’s a user-facing docs/IntelliSense regression; consider reintroducing an exported wrapper/alias with JSDoc in this module while delegating to the factory implementation.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
export type EvlogNestJSOptions = BaseEvlogOptions

export { useLogger }
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor removes the exported useLogger() JSDoc/examples from the NestJS entrypoint (it is now a re-exported destructured value). That’s a user-facing docs/IntelliSense regression; consider reintroducing an exported wrapper/alias with JSDoc in this module while delegating to the factory implementation.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
export type EvlogSvelteKitOptions = BaseEvlogOptions

export { useLogger }
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor removes the exported useLogger() JSDoc/examples from the SvelteKit entrypoint (it is now a re-exported destructured value). That’s a user-facing docs/IntelliSense regression; consider reintroducing an exported wrapper/alias with JSDoc in this module while delegating to the factory implementation.

Copilot uses AI. Check for mistakes.
Comment on lines 1 to +3
import type { FastifyPluginCallback } from 'fastify'
import type { DrainContext, EnrichContext, RequestLogger, RouteConfig, TailSamplingContext } from '../types'
import { createMiddlewareLogger } from '../shared/middleware'
import type { RequestLogger } from '../types'
import { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RequestLogger is imported but no longer referenced in this file (FastifyRequest.log is typed as any, and useLogger/storage typing moved to createLoggerStorage). This will be flagged as an unused import by typical ESLint/TS configs; please remove the import (or reintroduce a typed usage) to keep lint/typecheck clean.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +13
const { storage, useLogger } = createLoggerStorage(
'plugin context. Make sure app.register(evlog) is called before your routes.',
)

export type EvlogFastifyOptions = BaseEvlogOptions

export { useLogger }
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This refactor removes the exported useLogger() JSDoc/examples from the Fastify entrypoint (it is now a re-exported destructured value). That’s a user-facing docs/IntelliSense regression; consider reintroducing an exported wrapper/alias with JSDoc in this module while delegating to the factory implementation.

Suggested change
const { storage, useLogger } = createLoggerStorage(
'plugin context. Make sure app.register(evlog) is called before your routes.',
)
export type EvlogFastifyOptions = BaseEvlogOptions
export { useLogger }
const { storage, useLogger: internalUseLogger } = createLoggerStorage(
'plugin context. Make sure app.register(evlog) is called before your routes.',
)
export type EvlogFastifyOptions = BaseEvlogOptions
/**
* Get the current request-scoped evlog logger within a Fastify request.
*
* This must be called inside a request lifecycle where the `evlog` Fastify
* plugin has been registered and the request is currently being handled.
*
* @example
* ```ts
* import { evlog, useLogger } from 'evlog/fastify'
*
* app.register(evlog)
*
* app.get('/hello', async (request, reply) => {
* const log = useLogger()
* log.info({ path: request.url }, 'Handling request')
* return { ok: true }
* })
* ```
*/
export function useLogger() {
return internalUseLogger()
}

Copilot uses AI. Check for mistakes.
HugoRCD added a commit that referenced this pull request Mar 7, 2026
Add JSDoc to the shared useLogger function in createLoggerStorage so
IntelliSense documentation propagates through re-exports. Remove unused
RequestLogger import from fastify/index.ts.

Addresses review feedback from #148.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants