@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,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-scheduling
|
|
3
|
+
description: Cron jobs, intervals, and timeouts with @nestjs/schedule
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task Scheduling
|
|
7
|
+
|
|
8
|
+
Schedule tasks to run at fixed times, recurring intervals, or after delays.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nestjs/schedule
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Module } from '@nestjs/common';
|
|
20
|
+
import { ScheduleModule } from '@nestjs/schedule';
|
|
21
|
+
|
|
22
|
+
@Module({
|
|
23
|
+
imports: [ScheduleModule.forRoot()],
|
|
24
|
+
})
|
|
25
|
+
export class AppModule {}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Cron Jobs
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
32
|
+
import { Cron, CronExpression } from '@nestjs/schedule';
|
|
33
|
+
|
|
34
|
+
@Injectable()
|
|
35
|
+
export class TasksService {
|
|
36
|
+
private readonly logger = new Logger(TasksService.name);
|
|
37
|
+
|
|
38
|
+
// Using cron pattern
|
|
39
|
+
@Cron('45 * * * * *')
|
|
40
|
+
handleCron() {
|
|
41
|
+
this.logger.log('Called at second 45 of every minute');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Using CronExpression enum
|
|
45
|
+
@Cron(CronExpression.EVERY_30_SECONDS)
|
|
46
|
+
handleEvery30Seconds() {
|
|
47
|
+
this.logger.log('Called every 30 seconds');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// With options
|
|
51
|
+
@Cron('0 0 8 * * *', {
|
|
52
|
+
name: 'dailyReport',
|
|
53
|
+
timeZone: 'America/New_York',
|
|
54
|
+
})
|
|
55
|
+
generateDailyReport() {
|
|
56
|
+
this.logger.log('Generating daily report');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Cron Pattern
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
* * * * * *
|
|
65
|
+
| | | | | |
|
|
66
|
+
| | | | | day of week (0-7)
|
|
67
|
+
| | | | month (1-12)
|
|
68
|
+
| | | day of month (1-31)
|
|
69
|
+
| | hours (0-23)
|
|
70
|
+
| minutes (0-59)
|
|
71
|
+
seconds (0-59, optional)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Intervals
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
@Interval(10000)
|
|
78
|
+
handleInterval() {
|
|
79
|
+
this.logger.log('Called every 10 seconds');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Named interval
|
|
83
|
+
@Interval('notifications', 2500)
|
|
84
|
+
handleNotifications() {}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Timeouts
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
@Timeout(5000)
|
|
91
|
+
handleTimeout() {
|
|
92
|
+
this.logger.log('Called once after 5 seconds');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Named timeout
|
|
96
|
+
@Timeout('welcome', 3000)
|
|
97
|
+
sendWelcome() {}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Dynamic API
|
|
101
|
+
|
|
102
|
+
Manage scheduled tasks programmatically:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { Injectable } from '@nestjs/common';
|
|
106
|
+
import { SchedulerRegistry } from '@nestjs/schedule';
|
|
107
|
+
import { CronJob } from 'cron';
|
|
108
|
+
|
|
109
|
+
@Injectable()
|
|
110
|
+
export class TaskService {
|
|
111
|
+
constructor(private schedulerRegistry: SchedulerRegistry) {}
|
|
112
|
+
|
|
113
|
+
// Access existing cron job
|
|
114
|
+
stopCronJob() {
|
|
115
|
+
const job = this.schedulerRegistry.getCronJob('dailyReport');
|
|
116
|
+
job.stop();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Create dynamic cron job
|
|
120
|
+
addCronJob(name: string, cronTime: string) {
|
|
121
|
+
const job = new CronJob(cronTime, () => {
|
|
122
|
+
console.log(`Dynamic job ${name} running`);
|
|
123
|
+
});
|
|
124
|
+
this.schedulerRegistry.addCronJob(name, job);
|
|
125
|
+
job.start();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Delete cron job
|
|
129
|
+
deleteCronJob(name: string) {
|
|
130
|
+
this.schedulerRegistry.deleteCronJob(name);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// List all cron jobs
|
|
134
|
+
getCronJobs() {
|
|
135
|
+
const jobs = this.schedulerRegistry.getCronJobs();
|
|
136
|
+
jobs.forEach((job, key) => {
|
|
137
|
+
console.log(`Job: ${key}, Next: ${job.nextDate().toJSDate()}`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## CronJob Methods
|
|
144
|
+
|
|
145
|
+
| Method | Description |
|
|
146
|
+
|--------|-------------|
|
|
147
|
+
| `stop()` | Stop the job |
|
|
148
|
+
| `start()` | Restart a stopped job |
|
|
149
|
+
| `setTime(time)` | Set new time and restart |
|
|
150
|
+
| `lastDate()` | Last execution date |
|
|
151
|
+
| `nextDate()` | Next scheduled execution |
|
|
152
|
+
|
|
153
|
+
## Cron Options
|
|
154
|
+
|
|
155
|
+
| Option | Description |
|
|
156
|
+
|--------|-------------|
|
|
157
|
+
| `name` | Name for dynamic access |
|
|
158
|
+
| `timeZone` | Timezone for execution |
|
|
159
|
+
| `utcOffset` | UTC offset alternative |
|
|
160
|
+
| `disabled` | Disable job execution |
|
|
161
|
+
| `waitForCompletion` | Wait for current run before next |
|
|
162
|
+
|
|
163
|
+
<!--
|
|
164
|
+
Source references:
|
|
165
|
+
- https://docs.nestjs.com/techniques/task-scheduling
|
|
166
|
+
-->
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: techniques-validation
|
|
3
|
+
description: Data validation using ValidationPipe and class-validator in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Validation
|
|
7
|
+
|
|
8
|
+
NestJS provides `ValidationPipe` for automatic validation of incoming requests using `class-validator` decorators.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm i --save class-validator class-transformer
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Global ValidationPipe
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
async function bootstrap() {
|
|
20
|
+
const app = await NestFactory.create(AppModule);
|
|
21
|
+
app.useGlobalPipes(new ValidationPipe());
|
|
22
|
+
await app.listen(3000);
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## DTO with Validation
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { IsString, IsInt, Min, Max } from 'class-validator';
|
|
30
|
+
|
|
31
|
+
export class CreateCatDto {
|
|
32
|
+
@IsString()
|
|
33
|
+
name: string;
|
|
34
|
+
|
|
35
|
+
@IsInt()
|
|
36
|
+
@Min(0)
|
|
37
|
+
@Max(20)
|
|
38
|
+
age: number;
|
|
39
|
+
|
|
40
|
+
@IsString()
|
|
41
|
+
breed: string;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## ValidationPipe Options
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
app.useGlobalPipes(
|
|
49
|
+
new ValidationPipe({
|
|
50
|
+
whitelist: true,
|
|
51
|
+
forbidNonWhitelisted: true,
|
|
52
|
+
transform: true,
|
|
53
|
+
transformOptions: {
|
|
54
|
+
enableImplicitConversion: true,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Common Options
|
|
61
|
+
|
|
62
|
+
- `whitelist` - Strip non-whitelisted properties
|
|
63
|
+
- `forbidNonWhitelisted` - Throw error on non-whitelisted properties
|
|
64
|
+
- `transform` - Automatically transform payloads to DTO instances
|
|
65
|
+
- `disableErrorMessages` - Disable error messages
|
|
66
|
+
- `validationError.target` - Expose target in ValidationError
|
|
67
|
+
- `stopAtFirstError` - Stop validation on first error
|
|
68
|
+
|
|
69
|
+
## Custom Validators
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { registerDecorator, ValidationOptions } from 'class-validator';
|
|
73
|
+
|
|
74
|
+
export function IsLongerThan(property: string, validationOptions?: ValidationOptions) {
|
|
75
|
+
return function (object: Object, propertyName: string) {
|
|
76
|
+
registerDecorator({
|
|
77
|
+
name: 'isLongerThan',
|
|
78
|
+
target: object.constructor,
|
|
79
|
+
propertyName: propertyName,
|
|
80
|
+
constraints: [property],
|
|
81
|
+
options: validationOptions,
|
|
82
|
+
validator: {
|
|
83
|
+
validate(value: any, args: ValidationArguments) {
|
|
84
|
+
const [relatedPropertyName] = args.constraints;
|
|
85
|
+
const relatedValue = (args.object as any)[relatedPropertyName];
|
|
86
|
+
return typeof value === 'string' && typeof relatedValue === 'string' && value.length > relatedValue.length;
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Validation Groups
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
export class CreateUserDto {
|
|
98
|
+
@IsString({ groups: ['registration'] })
|
|
99
|
+
email: string;
|
|
100
|
+
|
|
101
|
+
@IsString({ groups: ['update'] })
|
|
102
|
+
password: string;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Conditional Validation
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
@ValidateIf((o) => o.type === 'email')
|
|
110
|
+
@IsEmail()
|
|
111
|
+
email: string;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Key Points
|
|
115
|
+
|
|
116
|
+
- Use `ValidationPipe` globally for automatic validation
|
|
117
|
+
- Decorate DTO properties with `class-validator` decorators
|
|
118
|
+
- Enable `transform` to auto-transform payloads
|
|
119
|
+
- Use `whitelist` to strip unknown properties
|
|
120
|
+
- Create custom validators for complex validation
|
|
121
|
+
- Use validation groups for different scenarios
|
|
122
|
+
|
|
123
|
+
<!--
|
|
124
|
+
Source references:
|
|
125
|
+
- https://docs.nestjs.com/techniques/validation
|
|
126
|
+
-->
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: versioning
|
|
3
|
+
description: API versioning strategies in NestJS
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API Versioning
|
|
7
|
+
|
|
8
|
+
NestJS supports four versioning strategies for HTTP applications.
|
|
9
|
+
|
|
10
|
+
## Versioning Types
|
|
11
|
+
|
|
12
|
+
| Type | Description |
|
|
13
|
+
|------|-------------|
|
|
14
|
+
| URI | Version in URL path (`/v1/cats`) |
|
|
15
|
+
| Header | Custom header specifies version |
|
|
16
|
+
| Media Type | `Accept` header with version |
|
|
17
|
+
| Custom | Custom extractor function |
|
|
18
|
+
|
|
19
|
+
## Enable Versioning
|
|
20
|
+
|
|
21
|
+
### URI Versioning (Default)
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// main.ts
|
|
25
|
+
import { VersioningType } from '@nestjs/common';
|
|
26
|
+
|
|
27
|
+
const app = await NestFactory.create(AppModule);
|
|
28
|
+
app.enableVersioning({
|
|
29
|
+
type: VersioningType.URI,
|
|
30
|
+
prefix: 'v', // Optional, default is 'v'
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Header Versioning
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
app.enableVersioning({
|
|
38
|
+
type: VersioningType.HEADER,
|
|
39
|
+
header: 'X-API-Version',
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Media Type Versioning
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
app.enableVersioning({
|
|
47
|
+
type: VersioningType.MEDIA_TYPE,
|
|
48
|
+
key: 'v=', // Accept: application/json;v=1
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Controller Versioning
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
@Controller({ path: 'cats', version: '1' })
|
|
56
|
+
export class CatsControllerV1 {
|
|
57
|
+
@Get()
|
|
58
|
+
findAll() {
|
|
59
|
+
return 'Version 1';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@Controller({ path: 'cats', version: '2' })
|
|
64
|
+
export class CatsControllerV2 {
|
|
65
|
+
@Get()
|
|
66
|
+
findAll() {
|
|
67
|
+
return 'Version 2';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Route Versioning
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
@Controller('cats')
|
|
76
|
+
export class CatsController {
|
|
77
|
+
@Version('1')
|
|
78
|
+
@Get()
|
|
79
|
+
findAllV1() {
|
|
80
|
+
return 'Version 1';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@Version('2')
|
|
84
|
+
@Get()
|
|
85
|
+
findAllV2() {
|
|
86
|
+
return 'Version 2';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Multiple Versions
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
@Controller({ path: 'cats', version: ['1', '2'] })
|
|
95
|
+
export class CatsController {
|
|
96
|
+
@Get()
|
|
97
|
+
findAll() {
|
|
98
|
+
return 'Handles both v1 and v2';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Version Neutral
|
|
104
|
+
|
|
105
|
+
Routes that work regardless of version:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { VERSION_NEUTRAL } from '@nestjs/common';
|
|
109
|
+
|
|
110
|
+
@Controller({ path: 'health', version: VERSION_NEUTRAL })
|
|
111
|
+
export class HealthController {
|
|
112
|
+
@Get()
|
|
113
|
+
check() {
|
|
114
|
+
return { status: 'ok' };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Default Version
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
app.enableVersioning({
|
|
123
|
+
type: VersioningType.URI,
|
|
124
|
+
defaultVersion: '1',
|
|
125
|
+
// Or multiple: defaultVersion: ['1', '2']
|
|
126
|
+
// Or neutral: defaultVersion: VERSION_NEUTRAL
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Middleware Versioning
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
@Module({})
|
|
134
|
+
export class AppModule implements NestModule {
|
|
135
|
+
configure(consumer: MiddlewareConsumer) {
|
|
136
|
+
consumer
|
|
137
|
+
.apply(LoggerMiddleware)
|
|
138
|
+
.forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Key Points
|
|
144
|
+
|
|
145
|
+
- Unversioned routes return 404 when versioning is enabled
|
|
146
|
+
- URI version appears after global prefix
|
|
147
|
+
- Use `VERSION_NEUTRAL` for version-agnostic endpoints
|
|
148
|
+
- Route-level versions override controller-level versions
|
|
149
|
+
|
|
150
|
+
<!--
|
|
151
|
+
Source references:
|
|
152
|
+
- https://docs.nestjs.com/techniques/versioning
|
|
153
|
+
-->
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: websockets-advanced
|
|
3
|
+
description: WebSocket guards, interceptors, pipes, exception filters, and adapters
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WebSocket Advanced Features
|
|
7
|
+
|
|
8
|
+
## Guards
|
|
9
|
+
|
|
10
|
+
Use `WsException` instead of `HttpException` in WebSocket context:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { WsException } from '@nestjs/websockets';
|
|
14
|
+
|
|
15
|
+
@UseGuards(AuthGuard)
|
|
16
|
+
@SubscribeMessage('events')
|
|
17
|
+
handleEvent(client: Socket, data: unknown) {
|
|
18
|
+
if (!data) {
|
|
19
|
+
throw new WsException('Invalid data');
|
|
20
|
+
}
|
|
21
|
+
return { event: 'events', data };
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Exception Filters
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Catch, ArgumentsHost } from '@nestjs/common';
|
|
29
|
+
import { BaseWsExceptionFilter, WsException } from '@nestjs/websockets';
|
|
30
|
+
|
|
31
|
+
@Catch(WsException)
|
|
32
|
+
export class AllExceptionsFilter extends BaseWsExceptionFilter {
|
|
33
|
+
catch(exception: WsException, host: ArgumentsHost) {
|
|
34
|
+
const client = host.switchToWs().getClient<Socket>();
|
|
35
|
+
const error = exception.getError();
|
|
36
|
+
const details = error instanceof Object ? { ...error } : { message: error };
|
|
37
|
+
client.emit('exception', details);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Apply globally:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
app.useGlobalFilters(new AllExceptionsFilter());
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Interceptors
|
|
49
|
+
|
|
50
|
+
Same pattern as HTTP—use `@UseInterceptors()` on gateway or handlers.
|
|
51
|
+
|
|
52
|
+
## Pipes
|
|
53
|
+
|
|
54
|
+
Validation pipes work in WebSocket handlers. Use `@Payload()` with validation:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
@SubscribeMessage('events')
|
|
58
|
+
handleEvent(
|
|
59
|
+
@Payload(new ValidationPipe({ whitelist: true })) data: CreateEventDto,
|
|
60
|
+
) {
|
|
61
|
+
return { event: 'events', data };
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Custom Adapter
|
|
66
|
+
|
|
67
|
+
Use custom WebSocket adapter (e.g., for Redis pub/sub scaling):
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { IoAdapter } from '@nestjs/platform-socket.io';
|
|
71
|
+
|
|
72
|
+
export class RedisIoAdapter extends IoAdapter {
|
|
73
|
+
// Override to use Redis adapter
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const app = await NestFactory.create(AppModule);
|
|
79
|
+
app.useWebSocketAdapter(new RedisIoAdapter(app));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Key Points
|
|
83
|
+
|
|
84
|
+
- `WsException` from `@nestjs/websockets`
|
|
85
|
+
- `BaseWsExceptionFilter` for WebSocket exception handling
|
|
86
|
+
- Guards, interceptors, pipes work same as HTTP
|
|
87
|
+
- Use `@Payload()` for typed message body with validation
|
|
88
|
+
|
|
89
|
+
<!--
|
|
90
|
+
Source references:
|
|
91
|
+
- https://docs.nestjs.com/websockets/guards
|
|
92
|
+
- https://docs.nestjs.com/websockets/exception-filters
|
|
93
|
+
- https://docs.nestjs.com/websockets/interceptors
|
|
94
|
+
- https://docs.nestjs.com/websockets/pipes
|
|
95
|
+
- https://docs.nestjs.com/websockets/adapter
|
|
96
|
+
-->
|