@biggora/claude-plugins 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -4
- package/package.json +1 -1
- package/registry/registry.json +334 -244
- package/specs/coding.md +30 -0
- package/specs/pod.md +2 -0
- package/src/commands/skills/add.js +63 -7
- package/src/commands/skills/list.js +23 -52
- package/src/commands/skills/remove.js +26 -27
- package/src/commands/skills/resolve.js +155 -0
- package/src/commands/skills/update.js +58 -74
- package/src/skills/captcha/README.md +221 -0
- package/src/skills/captcha/SKILL.md +355 -0
- package/src/skills/captcha/references/captcha-types.md +254 -0
- package/src/skills/captcha/references/services.md +172 -0
- package/src/skills/captcha/references/stealth.md +238 -0
- package/src/skills/captcha/scripts/solve_captcha.py +323 -0
- package/src/skills/captcha/scripts/solve_image_grid.py +350 -0
- package/src/skills/google-merchant-api/SKILL.md +581 -0
- package/src/skills/google-merchant-api/references/accounts.md +247 -0
- package/src/skills/google-merchant-api/references/content-api-legacy.md +216 -0
- package/src/skills/google-merchant-api/references/datasources.md +233 -0
- package/src/skills/google-merchant-api/references/inventories.md +201 -0
- package/src/skills/google-merchant-api/references/migration.md +267 -0
- package/src/skills/google-merchant-api/references/products.md +316 -0
- package/src/skills/google-merchant-api/references/promotions.md +201 -0
- package/src/skills/google-merchant-api/references/reports.md +240 -0
- package/src/skills/lv-aggregators-api/SKILL.md +113 -0
- package/src/skills/lv-aggregators-api/references/integration-guide.md +368 -0
- package/src/skills/lv-aggregators-api/references/kurpirkt.md +103 -0
- package/src/skills/lv-aggregators-api/references/salidzini.md +122 -0
- package/src/skills/nest-best-practices/SKILL.md +251 -0
- package/src/skills/nest-best-practices/references/best-practices-request-lifecycle.md +158 -0
- package/src/skills/nest-best-practices/references/cli-monorepo.md +106 -0
- package/src/skills/nest-best-practices/references/cli-overview.md +157 -0
- package/src/skills/nest-best-practices/references/core-controllers.md +165 -0
- package/src/skills/nest-best-practices/references/core-dependency-injection.md +179 -0
- package/src/skills/nest-best-practices/references/core-middleware.md +139 -0
- package/src/skills/nest-best-practices/references/core-modules.md +138 -0
- package/src/skills/nest-best-practices/references/core-providers.md +188 -0
- package/src/skills/nest-best-practices/references/faq-raw-body-hybrid.md +122 -0
- package/src/skills/nest-best-practices/references/fundamentals-circular-dependency.md +89 -0
- package/src/skills/nest-best-practices/references/fundamentals-custom-decorators.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-dynamic-modules.md +125 -0
- package/src/skills/nest-best-practices/references/fundamentals-exception-filters.md +202 -0
- package/src/skills/nest-best-practices/references/fundamentals-execution-context.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-guards.md +136 -0
- package/src/skills/nest-best-practices/references/fundamentals-interceptors.md +187 -0
- package/src/skills/nest-best-practices/references/fundamentals-lazy-loading.md +89 -0
- package/src/skills/nest-best-practices/references/fundamentals-lifecycle-events.md +87 -0
- package/src/skills/nest-best-practices/references/fundamentals-module-reference.md +107 -0
- package/src/skills/nest-best-practices/references/fundamentals-pipes.md +197 -0
- package/src/skills/nest-best-practices/references/fundamentals-provider-scopes.md +92 -0
- package/src/skills/nest-best-practices/references/fundamentals-testing.md +142 -0
- package/src/skills/nest-best-practices/references/graphql-overview.md +233 -0
- package/src/skills/nest-best-practices/references/graphql-resolvers-mutations.md +199 -0
- package/src/skills/nest-best-practices/references/graphql-scalars-unions-enums.md +180 -0
- package/src/skills/nest-best-practices/references/graphql-subscriptions.md +228 -0
- package/src/skills/nest-best-practices/references/microservices-grpc.md +175 -0
- package/src/skills/nest-best-practices/references/microservices-overview.md +221 -0
- package/src/skills/nest-best-practices/references/microservices-transports.md +119 -0
- package/src/skills/nest-best-practices/references/openapi-swagger.md +207 -0
- package/src/skills/nest-best-practices/references/recipes-authentication.md +97 -0
- package/src/skills/nest-best-practices/references/recipes-cqrs.md +176 -0
- package/src/skills/nest-best-practices/references/recipes-crud-generator.md +87 -0
- package/src/skills/nest-best-practices/references/recipes-documentation.md +93 -0
- package/src/skills/nest-best-practices/references/recipes-mongoose.md +153 -0
- package/src/skills/nest-best-practices/references/recipes-prisma.md +98 -0
- package/src/skills/nest-best-practices/references/recipes-terminus.md +148 -0
- package/src/skills/nest-best-practices/references/recipes-typeorm.md +122 -0
- package/src/skills/nest-best-practices/references/security-authorization.md +196 -0
- package/src/skills/nest-best-practices/references/security-cors-helmet-rate-limiting.md +204 -0
- package/src/skills/nest-best-practices/references/security-encryption-hashing.md +93 -0
- package/src/skills/nest-best-practices/references/techniques-caching.md +142 -0
- package/src/skills/nest-best-practices/references/techniques-compression-streaming-sse.md +194 -0
- package/src/skills/nest-best-practices/references/techniques-configuration.md +132 -0
- package/src/skills/nest-best-practices/references/techniques-database.md +153 -0
- package/src/skills/nest-best-practices/references/techniques-events.md +163 -0
- package/src/skills/nest-best-practices/references/techniques-fastify.md +137 -0
- package/src/skills/nest-best-practices/references/techniques-file-upload.md +140 -0
- package/src/skills/nest-best-practices/references/techniques-http-module.md +176 -0
- package/src/skills/nest-best-practices/references/techniques-logging.md +146 -0
- package/src/skills/nest-best-practices/references/techniques-mvc-serve-static.md +132 -0
- package/src/skills/nest-best-practices/references/techniques-queues.md +162 -0
- package/src/skills/nest-best-practices/references/techniques-serialization.md +158 -0
- package/src/skills/nest-best-practices/references/techniques-sessions-cookies.md +167 -0
- package/src/skills/nest-best-practices/references/techniques-task-scheduling.md +166 -0
- package/src/skills/nest-best-practices/references/techniques-validation.md +126 -0
- package/src/skills/nest-best-practices/references/techniques-versioning.md +153 -0
- package/src/skills/nest-best-practices/references/websockets-advanced.md +96 -0
- package/src/skills/nest-best-practices/references/websockets-gateways.md +215 -0
- package/src/skills/tailwindcss-best-practices/SKILL.md +180 -0
- package/src/skills/tailwindcss-best-practices/references/best-practices-utility-patterns.md +87 -0
- package/src/skills/tailwindcss-best-practices/references/core-installation.md +109 -0
- package/src/skills/tailwindcss-best-practices/references/core-preflight.md +200 -0
- package/src/skills/tailwindcss-best-practices/references/core-responsive.md +163 -0
- package/src/skills/tailwindcss-best-practices/references/core-source-detection.md +114 -0
- package/src/skills/tailwindcss-best-practices/references/core-theme.md +108 -0
- package/src/skills/tailwindcss-best-practices/references/core-utility-classes.md +59 -0
- package/src/skills/tailwindcss-best-practices/references/core-variants.md +204 -0
- package/src/skills/tailwindcss-best-practices/references/effects-form-controls.md +76 -0
- package/src/skills/tailwindcss-best-practices/references/effects-mask.md +91 -0
- package/src/skills/tailwindcss-best-practices/references/effects-scroll-snap.md +59 -0
- package/src/skills/tailwindcss-best-practices/references/effects-text-shadow.md +78 -0
- package/src/skills/tailwindcss-best-practices/references/effects-transition-animation.md +80 -0
- package/src/skills/tailwindcss-best-practices/references/effects-visibility-interactivity.md +82 -0
- package/src/skills/tailwindcss-best-practices/references/features-content-detection.md +175 -0
- package/src/skills/tailwindcss-best-practices/references/features-custom-styles.md +203 -0
- package/src/skills/tailwindcss-best-practices/references/features-dark-mode.md +137 -0
- package/src/skills/tailwindcss-best-practices/references/features-functions-directives.md +241 -0
- package/src/skills/tailwindcss-best-practices/references/features-upgrade.md +160 -0
- package/src/skills/tailwindcss-best-practices/references/layout-aspect-ratio.md +39 -0
- package/src/skills/tailwindcss-best-practices/references/layout-columns.md +80 -0
- package/src/skills/tailwindcss-best-practices/references/layout-display.md +110 -0
- package/src/skills/tailwindcss-best-practices/references/layout-flexbox.md +112 -0
- package/src/skills/tailwindcss-best-practices/references/layout-grid.md +87 -0
- package/src/skills/tailwindcss-best-practices/references/layout-height.md +97 -0
- package/src/skills/tailwindcss-best-practices/references/layout-inset.md +103 -0
- package/src/skills/tailwindcss-best-practices/references/layout-logical-properties.md +92 -0
- package/src/skills/tailwindcss-best-practices/references/layout-margin.md +126 -0
- package/src/skills/tailwindcss-best-practices/references/layout-min-max-sizing.md +63 -0
- package/src/skills/tailwindcss-best-practices/references/layout-object-fit-position.md +64 -0
- package/src/skills/tailwindcss-best-practices/references/layout-overflow.md +57 -0
- package/src/skills/tailwindcss-best-practices/references/layout-padding.md +77 -0
- package/src/skills/tailwindcss-best-practices/references/layout-position.md +85 -0
- package/src/skills/tailwindcss-best-practices/references/layout-tables.md +67 -0
- package/src/skills/tailwindcss-best-practices/references/layout-width.md +102 -0
- package/src/skills/tailwindcss-best-practices/references/transform-base.md +68 -0
- package/src/skills/tailwindcss-best-practices/references/transform-rotate.md +70 -0
- package/src/skills/tailwindcss-best-practices/references/transform-scale.md +83 -0
- package/src/skills/tailwindcss-best-practices/references/transform-skew.md +62 -0
- package/src/skills/tailwindcss-best-practices/references/transform-translate.md +77 -0
- package/src/skills/tailwindcss-best-practices/references/typography-font-text.md +142 -0
- package/src/skills/tailwindcss-best-practices/references/typography-list-style.md +65 -0
- package/src/skills/tailwindcss-best-practices/references/typography-text-align.md +60 -0
- package/src/skills/tailwindcss-best-practices/references/visual-background.md +76 -0
- package/src/skills/tailwindcss-best-practices/references/visual-border.md +108 -0
- package/src/skills/tailwindcss-best-practices/references/visual-effects.md +111 -0
- package/src/skills/tailwindcss-best-practices/references/visual-svg.md +82 -0
- package/src/skills/test-mobile-app/SKILL.md +11 -6
- package/src/skills/test-mobile-app/scripts/analyze_apk.py +15 -4
- package/src/skills/test-mobile-app/scripts/check_environment.py +5 -5
- package/src/skills/test-mobile-app/scripts/run_tests.py +1 -1
- package/src/skills/test-web-ui/SKILL.md +264 -84
- package/src/skills/test-web-ui/scripts/discover.py +25 -12
- package/src/skills/test-web-ui/scripts/run_tests.py +3 -2
- package/src/skills/typescript-expert/SKILL.md +145 -0
- package/src/skills/typescript-expert/commands/typescript-fix.md +65 -0
- package/src/skills/typescript-expert/references/advanced-conditional-types.md +190 -0
- package/src/skills/typescript-expert/references/advanced-decorators.md +243 -0
- package/src/skills/typescript-expert/references/advanced-mapped-types.md +223 -0
- package/src/skills/typescript-expert/references/advanced-template-literals.md +209 -0
- package/src/skills/typescript-expert/references/advanced-type-guards.md +308 -0
- package/src/skills/typescript-expert/references/best-practices-patterns.md +313 -0
- package/src/skills/typescript-expert/references/best-practices-performance.md +185 -0
- package/src/skills/typescript-expert/references/best-practices-tsconfig.md +242 -0
- package/src/skills/typescript-expert/references/core-generics.md +246 -0
- package/src/skills/typescript-expert/references/core-interfaces-types.md +231 -0
- package/src/skills/typescript-expert/references/core-type-system.md +261 -0
- package/src/skills/typescript-expert/references/core-utility-types.md +235 -0
- package/src/skills/typescript-expert/references/features-ts5x.md +370 -0
- package/src/skills/vite-best-practices/SKILL.md +115 -0
- package/src/skills/vite-best-practices/references/build-and-ssr.md +255 -0
- package/src/skills/vite-best-practices/references/core-config.md +231 -0
- package/src/skills/vite-best-practices/references/core-features.md +222 -0
- package/src/skills/vite-best-practices/references/core-plugin-api.md +294 -0
- package/src/skills/vite-best-practices/references/environment-api.md +108 -0
- package/src/skills/vite-best-practices/references/rolldown-migration.md +242 -0
- package/codex-cli-workspace/iteration-1/benchmark.json +0 -122
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/outputs/response.md +0 -163
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/grading.json +0 -58
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/outputs/response.md +0 -151
- package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -86
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -58
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
- package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/eval_metadata.json +0 -13
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/grading.json +0 -52
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/outputs/response.md +0 -130
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/grading.json +0 -64
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/outputs/response.md +0 -209
- package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/timing.json +0 -5
- package/codex-cli-workspace/iteration-1/review.html +0 -1325
- package/gemini-cli-workspace/iteration-1/benchmark.json +0 -86
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/outputs/response.md +0 -401
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/outputs/response.md +0 -405
- package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -212
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -427
- package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/eval_metadata.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -171
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -199
- package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-1/review.html +0 -1325
- package/gemini-cli-workspace/iteration-2/benchmark.json +0 -173
- package/gemini-cli-workspace/iteration-2/benchmark.md +0 -28
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/outputs/response.md +0 -195
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/outputs/response.md +0 -377
- package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/eval_metadata.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -127
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/grading.json +0 -37
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
- package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/eval_metadata.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -91
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/grading.json +0 -32
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -112
- package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/timing.json +0 -5
- package/gemini-cli-workspace/iteration-2/eval-viewer.html +0 -1325
- package/screen-recording-workspace/evals.json +0 -41
- package/screen-recording-workspace/iteration-1/benchmark.json +0 -102
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/outputs/demo.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/outputs/demo.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/outputs/region_capture.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/outputs/region_capture.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/eval_metadata.json +0 -31
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/outputs/fallback_recording.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/grading.json +0 -11
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/fallback_recording.mp4 +0 -0
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/record_screen.py +0 -67
- package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/timing.json +0 -5
- package/screen-recording-workspace/iteration-1/review.html +0 -1325
- package/src/skills/codex-cli/evals/evals.json +0 -47
- package/src/skills/gemini-cli/evals/evals.json +0 -46
- package/src/skills/tm-search/evals/evals.json +0 -23
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastify
|
|
3
|
+
description: Using Fastify as the HTTP adapter for better performance
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fastify (Performance)
|
|
7
|
+
|
|
8
|
+
Fastify is a high-performance alternative to Express, achieving nearly 2x better benchmark results.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nestjs/platform-fastify
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { NestFactory } from '@nestjs/core';
|
|
20
|
+
import {
|
|
21
|
+
FastifyAdapter,
|
|
22
|
+
NestFastifyApplication,
|
|
23
|
+
} from '@nestjs/platform-fastify';
|
|
24
|
+
import { AppModule } from './app.module';
|
|
25
|
+
|
|
26
|
+
async function bootstrap() {
|
|
27
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
28
|
+
AppModule,
|
|
29
|
+
new FastifyAdapter(),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Fastify listens only on localhost by default
|
|
33
|
+
await app.listen(3000, '0.0.0.0');
|
|
34
|
+
}
|
|
35
|
+
bootstrap();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Fastify Options
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
new FastifyAdapter({
|
|
42
|
+
logger: true,
|
|
43
|
+
trustProxy: true,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Middleware Differences
|
|
48
|
+
|
|
49
|
+
Fastify middleware receives raw `req` and `res` objects:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { Injectable, NestMiddleware } from '@nestjs/common';
|
|
53
|
+
import { FastifyRequest, FastifyReply } from 'fastify';
|
|
54
|
+
|
|
55
|
+
@Injectable()
|
|
56
|
+
export class LoggerMiddleware implements NestMiddleware {
|
|
57
|
+
use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
|
|
58
|
+
console.log('Request...');
|
|
59
|
+
next();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Redirect Response
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
@Get()
|
|
68
|
+
redirect(@Res() res: FastifyReply) {
|
|
69
|
+
res.status(302).redirect('/login');
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Route Config
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { RouteConfig } from '@nestjs/platform-fastify';
|
|
77
|
+
|
|
78
|
+
@RouteConfig({ output: 'hello world' })
|
|
79
|
+
@Get()
|
|
80
|
+
index(@Req() req: FastifyRequest) {
|
|
81
|
+
return req.routeConfig.output;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Route Constraints
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { RouteConstraints } from '@nestjs/platform-fastify';
|
|
89
|
+
|
|
90
|
+
@RouteConstraints({ version: '1.2.x' })
|
|
91
|
+
@Get()
|
|
92
|
+
newFeature() {
|
|
93
|
+
return 'Works only for version >= 1.2.x';
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Registering Plugins
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import compression from '@fastify/compress';
|
|
101
|
+
import helmet from '@fastify/helmet';
|
|
102
|
+
import fastifyCookie from '@fastify/cookie';
|
|
103
|
+
|
|
104
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
105
|
+
AppModule,
|
|
106
|
+
new FastifyAdapter(),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
await app.register(compression);
|
|
110
|
+
await app.register(helmet);
|
|
111
|
+
await app.register(fastifyCookie, { secret: 'my-secret' });
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Platform-Specific Packages
|
|
115
|
+
|
|
116
|
+
When using Fastify, replace Express packages with Fastify equivalents:
|
|
117
|
+
|
|
118
|
+
| Express | Fastify |
|
|
119
|
+
|---------|---------|
|
|
120
|
+
| `express-session` | `@fastify/secure-session` |
|
|
121
|
+
| `cookie-parser` | `@fastify/cookie` |
|
|
122
|
+
| `compression` | `@fastify/compress` |
|
|
123
|
+
| `helmet` | `@fastify/helmet` |
|
|
124
|
+
| `multer` | Not compatible |
|
|
125
|
+
|
|
126
|
+
## Key Points
|
|
127
|
+
|
|
128
|
+
- Provides significant performance improvements
|
|
129
|
+
- Not all Express middleware is compatible
|
|
130
|
+
- Use `NestFastifyApplication` type for proper typings
|
|
131
|
+
- Default listener is `localhost` only (specify `0.0.0.0` for external access)
|
|
132
|
+
- File upload (multer) is not compatible with Fastify
|
|
133
|
+
|
|
134
|
+
<!--
|
|
135
|
+
Source references:
|
|
136
|
+
- https://docs.nestjs.com/techniques/performance
|
|
137
|
+
-->
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: file-upload
|
|
3
|
+
description: File upload handling with multer integration
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# File Upload
|
|
7
|
+
|
|
8
|
+
NestJS uses [multer](https://github.com/expressjs/multer) middleware for handling `multipart/form-data` file uploads.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i -D @types/multer
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Single File Upload
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Controller, Post, UseInterceptors, UploadedFile } from '@nestjs/common';
|
|
20
|
+
import { FileInterceptor } from '@nestjs/platform-express';
|
|
21
|
+
import { Express } from 'express';
|
|
22
|
+
|
|
23
|
+
@Controller('upload')
|
|
24
|
+
export class UploadController {
|
|
25
|
+
@Post()
|
|
26
|
+
@UseInterceptors(FileInterceptor('file'))
|
|
27
|
+
uploadFile(@UploadedFile() file: Express.Multer.File) {
|
|
28
|
+
console.log(file);
|
|
29
|
+
return { filename: file.originalname };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## File Validation
|
|
35
|
+
|
|
36
|
+
Use `ParseFilePipe` with built-in validators:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
@Post()
|
|
40
|
+
uploadFile(
|
|
41
|
+
@UploadedFile(
|
|
42
|
+
new ParseFilePipe({
|
|
43
|
+
validators: [
|
|
44
|
+
new MaxFileSizeValidator({ maxSize: 1000000 }), // 1MB
|
|
45
|
+
new FileTypeValidator({ fileType: 'image/jpeg' }),
|
|
46
|
+
],
|
|
47
|
+
}),
|
|
48
|
+
)
|
|
49
|
+
file: Express.Multer.File,
|
|
50
|
+
) {
|
|
51
|
+
return { filename: file.originalname };
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Using builder pattern:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
@UploadedFile(
|
|
59
|
+
new ParseFilePipeBuilder()
|
|
60
|
+
.addFileTypeValidator({ fileType: 'jpeg' })
|
|
61
|
+
.addMaxSizeValidator({ maxSize: 1000000 })
|
|
62
|
+
.build({ errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY }),
|
|
63
|
+
)
|
|
64
|
+
file: Express.Multer.File,
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Multiple Files (Same Field)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
@Post('uploads')
|
|
71
|
+
@UseInterceptors(FilesInterceptor('files', 10)) // max 10 files
|
|
72
|
+
uploadFiles(@UploadedFiles() files: Array<Express.Multer.File>) {
|
|
73
|
+
return files.map(f => f.originalname);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Multiple Files (Different Fields)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
@Post('uploads')
|
|
81
|
+
@UseInterceptors(FileFieldsInterceptor([
|
|
82
|
+
{ name: 'avatar', maxCount: 1 },
|
|
83
|
+
{ name: 'background', maxCount: 1 },
|
|
84
|
+
]))
|
|
85
|
+
uploadFiles(
|
|
86
|
+
@UploadedFiles() files: {
|
|
87
|
+
avatar?: Express.Multer.File[],
|
|
88
|
+
background?: Express.Multer.File[]
|
|
89
|
+
},
|
|
90
|
+
) {
|
|
91
|
+
return { avatar: files.avatar?.[0], background: files.background?.[0] };
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Any Files
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
@Post('any')
|
|
99
|
+
@UseInterceptors(AnyFilesInterceptor())
|
|
100
|
+
uploadAny(@UploadedFiles() files: Array<Express.Multer.File>) {
|
|
101
|
+
return files;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Configure Destination
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { MulterModule } from '@nestjs/platform-express';
|
|
109
|
+
|
|
110
|
+
@Module({
|
|
111
|
+
imports: [
|
|
112
|
+
MulterModule.register({ dest: './uploads' }),
|
|
113
|
+
],
|
|
114
|
+
})
|
|
115
|
+
export class UploadModule {}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Async configuration:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
MulterModule.registerAsync({
|
|
122
|
+
imports: [ConfigModule],
|
|
123
|
+
useFactory: async (configService: ConfigService) => ({
|
|
124
|
+
dest: configService.get('UPLOAD_DEST'),
|
|
125
|
+
}),
|
|
126
|
+
inject: [ConfigService],
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Key Points
|
|
131
|
+
|
|
132
|
+
- `FileInterceptor` field name must match form field name
|
|
133
|
+
- Not compatible with Fastify adapter
|
|
134
|
+
- Use `fileIsRequired: false` for optional files
|
|
135
|
+
- Multer only processes `multipart/form-data`
|
|
136
|
+
|
|
137
|
+
<!--
|
|
138
|
+
Source references:
|
|
139
|
+
- https://docs.nestjs.com/techniques/file-upload
|
|
140
|
+
-->
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: http-module
|
|
3
|
+
description: Making HTTP requests with @nestjs/axios
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HTTP Module
|
|
7
|
+
|
|
8
|
+
NestJS wraps Axios for making HTTP requests to external services.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nestjs/axios axios
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Module } from '@nestjs/common';
|
|
20
|
+
import { HttpModule } from '@nestjs/axios';
|
|
21
|
+
|
|
22
|
+
@Module({
|
|
23
|
+
imports: [HttpModule],
|
|
24
|
+
providers: [CatsService],
|
|
25
|
+
})
|
|
26
|
+
export class CatsModule {}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Basic Usage
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { Injectable } from '@nestjs/common';
|
|
33
|
+
import { HttpService } from '@nestjs/axios';
|
|
34
|
+
import { firstValueFrom } from 'rxjs';
|
|
35
|
+
import { AxiosResponse } from 'axios';
|
|
36
|
+
|
|
37
|
+
@Injectable()
|
|
38
|
+
export class CatsService {
|
|
39
|
+
constructor(private readonly httpService: HttpService) {}
|
|
40
|
+
|
|
41
|
+
// Using Observable
|
|
42
|
+
findAll(): Observable<AxiosResponse<Cat[]>> {
|
|
43
|
+
return this.httpService.get('https://api.example.com/cats');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Using Promise
|
|
47
|
+
async findAllAsync(): Promise<Cat[]> {
|
|
48
|
+
const { data } = await firstValueFrom(
|
|
49
|
+
this.httpService.get<Cat[]>('https://api.example.com/cats'),
|
|
50
|
+
);
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## HTTP Methods
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// GET
|
|
60
|
+
this.httpService.get('/users');
|
|
61
|
+
|
|
62
|
+
// POST
|
|
63
|
+
this.httpService.post('/users', { name: 'John' });
|
|
64
|
+
|
|
65
|
+
// PUT
|
|
66
|
+
this.httpService.put('/users/1', { name: 'Jane' });
|
|
67
|
+
|
|
68
|
+
// PATCH
|
|
69
|
+
this.httpService.patch('/users/1', { name: 'Jane' });
|
|
70
|
+
|
|
71
|
+
// DELETE
|
|
72
|
+
this.httpService.delete('/users/1');
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Configuration
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
HttpModule.register({
|
|
79
|
+
timeout: 5000,
|
|
80
|
+
maxRedirects: 5,
|
|
81
|
+
baseURL: 'https://api.example.com',
|
|
82
|
+
headers: {
|
|
83
|
+
'Authorization': 'Bearer token',
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Async Configuration
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
HttpModule.registerAsync({
|
|
92
|
+
imports: [ConfigModule],
|
|
93
|
+
useFactory: async (configService: ConfigService) => ({
|
|
94
|
+
timeout: configService.get('HTTP_TIMEOUT'),
|
|
95
|
+
maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
|
|
96
|
+
baseURL: configService.get('API_URL'),
|
|
97
|
+
}),
|
|
98
|
+
inject: [ConfigService],
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Error Handling
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { catchError, firstValueFrom } from 'rxjs';
|
|
106
|
+
import { AxiosError } from 'axios';
|
|
107
|
+
|
|
108
|
+
async findAll(): Promise<Cat[]> {
|
|
109
|
+
const { data } = await firstValueFrom(
|
|
110
|
+
this.httpService.get<Cat[]>('/cats').pipe(
|
|
111
|
+
catchError((error: AxiosError) => {
|
|
112
|
+
this.logger.error(error.response?.data);
|
|
113
|
+
throw new HttpException(
|
|
114
|
+
'External API error',
|
|
115
|
+
HttpStatus.BAD_GATEWAY,
|
|
116
|
+
);
|
|
117
|
+
}),
|
|
118
|
+
),
|
|
119
|
+
);
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Direct Axios Access
|
|
125
|
+
|
|
126
|
+
Access the underlying Axios instance:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
@Injectable()
|
|
130
|
+
export class CatsService {
|
|
131
|
+
constructor(private readonly httpService: HttpService) {}
|
|
132
|
+
|
|
133
|
+
async findAll(): Promise<Cat[]> {
|
|
134
|
+
const { data } = await this.httpService.axiosRef.get('/cats');
|
|
135
|
+
return data;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Interceptors
|
|
141
|
+
|
|
142
|
+
Add Axios interceptors:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
@Injectable()
|
|
146
|
+
export class CatsService implements OnModuleInit {
|
|
147
|
+
constructor(private readonly httpService: HttpService) {}
|
|
148
|
+
|
|
149
|
+
onModuleInit() {
|
|
150
|
+
this.httpService.axiosRef.interceptors.request.use((config) => {
|
|
151
|
+
config.headers['X-Request-Id'] = uuid();
|
|
152
|
+
return config;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
this.httpService.axiosRef.interceptors.response.use(
|
|
156
|
+
(response) => response,
|
|
157
|
+
(error) => {
|
|
158
|
+
// Log error
|
|
159
|
+
return Promise.reject(error);
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Key Points
|
|
167
|
+
|
|
168
|
+
- Returns RxJS Observables by default
|
|
169
|
+
- Use `firstValueFrom` or `lastValueFrom` for Promises
|
|
170
|
+
- `AxiosResponse` is from `axios` package
|
|
171
|
+
- Configuration passed directly to Axios constructor
|
|
172
|
+
|
|
173
|
+
<!--
|
|
174
|
+
Source references:
|
|
175
|
+
- https://docs.nestjs.com/techniques/http-module
|
|
176
|
+
-->
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: logging
|
|
3
|
+
description: Built-in logger, custom loggers, and JSON logging
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Logging
|
|
7
|
+
|
|
8
|
+
NestJS provides a built-in `Logger` class with customizable behavior.
|
|
9
|
+
|
|
10
|
+
## Basic Usage
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { Logger, Injectable } from '@nestjs/common';
|
|
14
|
+
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class CatsService {
|
|
17
|
+
private readonly logger = new Logger(CatsService.name);
|
|
18
|
+
|
|
19
|
+
findAll() {
|
|
20
|
+
this.logger.log('Finding all cats');
|
|
21
|
+
this.logger.warn('Warning message');
|
|
22
|
+
this.logger.error('Error message', error.stack);
|
|
23
|
+
this.logger.debug('Debug info');
|
|
24
|
+
this.logger.verbose('Verbose output');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configuration Options
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
const app = await NestFactory.create(AppModule, {
|
|
33
|
+
logger: new ConsoleLogger({
|
|
34
|
+
logLevels: ['error', 'warn', 'log'], // Filter log levels
|
|
35
|
+
timestamp: true, // Show timestamps
|
|
36
|
+
json: true, // JSON format output
|
|
37
|
+
colors: false, // Disable colors
|
|
38
|
+
prefix: 'MyApp', // Custom prefix
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Disable logging:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const app = await NestFactory.create(AppModule, { logger: false });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Specific log levels only:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const app = await NestFactory.create(AppModule, {
|
|
53
|
+
logger: ['error', 'warn'],
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## JSON Logging
|
|
58
|
+
|
|
59
|
+
Enable structured JSON logging for production:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const app = await NestFactory.create(AppModule, {
|
|
63
|
+
logger: new ConsoleLogger({ json: true }),
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Output:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"level": "log",
|
|
72
|
+
"pid": 19096,
|
|
73
|
+
"timestamp": 1607370779834,
|
|
74
|
+
"message": "Starting Nest application...",
|
|
75
|
+
"context": "NestFactory"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Custom Logger
|
|
80
|
+
|
|
81
|
+
Implement `LoggerService` interface:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { LoggerService, Injectable } from '@nestjs/common';
|
|
85
|
+
|
|
86
|
+
@Injectable()
|
|
87
|
+
export class MyLogger implements LoggerService {
|
|
88
|
+
log(message: any, ...optionalParams: any[]) {}
|
|
89
|
+
error(message: any, ...optionalParams: any[]) {}
|
|
90
|
+
warn(message: any, ...optionalParams: any[]) {}
|
|
91
|
+
debug?(message: any, ...optionalParams: any[]) {}
|
|
92
|
+
verbose?(message: any, ...optionalParams: any[]) {}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Extend Built-in Logger
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { ConsoleLogger } from '@nestjs/common';
|
|
100
|
+
|
|
101
|
+
export class MyLogger extends ConsoleLogger {
|
|
102
|
+
error(message: any, stack?: string, context?: string) {
|
|
103
|
+
// Custom logic (e.g., send to external service)
|
|
104
|
+
super.error(message, stack, context);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Dependency Injection
|
|
110
|
+
|
|
111
|
+
Use DI for custom logger with configuration:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Create LoggerModule
|
|
115
|
+
@Module({
|
|
116
|
+
providers: [MyLogger],
|
|
117
|
+
exports: [MyLogger],
|
|
118
|
+
})
|
|
119
|
+
export class LoggerModule {}
|
|
120
|
+
|
|
121
|
+
// Use in main.ts
|
|
122
|
+
const app = await NestFactory.create(AppModule, { bufferLogs: true });
|
|
123
|
+
app.useLogger(app.get(MyLogger));
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Transient Logger
|
|
127
|
+
|
|
128
|
+
For unique logger instances per service:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
@Injectable({ scope: Scope.TRANSIENT })
|
|
132
|
+
export class MyLogger extends ConsoleLogger {}
|
|
133
|
+
|
|
134
|
+
// Usage
|
|
135
|
+
@Injectable()
|
|
136
|
+
export class CatsService {
|
|
137
|
+
constructor(private myLogger: MyLogger) {
|
|
138
|
+
this.myLogger.setContext('CatsService');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
<!--
|
|
144
|
+
Source references:
|
|
145
|
+
- https://docs.nestjs.com/techniques/logger
|
|
146
|
+
-->
|