@xonovex/skills 0.1.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/.claude-plugin/plugin.json +21 -0
- package/commands/code-align.md +108 -0
- package/commands/code-harden.md +74 -0
- package/commands/code-simplify.md +145 -0
- package/commands/git-commit.md +146 -0
- package/commands/insights-extract.md +109 -0
- package/commands/insights-integrate.md +100 -0
- package/commands/plan-continue.md +167 -0
- package/commands/plan-create.md +107 -0
- package/commands/plan-research.md +113 -0
- package/commands/plan-subplans-create.md +111 -0
- package/commands/plan-tdd-create.md +128 -0
- package/commands/plan-update.md +99 -0
- package/commands/plan-validate.md +100 -0
- package/commands/plan-worktree-abandon.md +104 -0
- package/commands/plan-worktree-create.md +92 -0
- package/commands/plan-worktree-merge.md +132 -0
- package/package.json +44 -0
- package/skills/astro-guidelines/SKILL.md +23 -0
- package/skills/astro-guidelines/reference/accessibility.md +31 -0
- package/skills/astro-guidelines/reference/components.md +42 -0
- package/skills/astro-guidelines/reference/content-collections.md +32 -0
- package/skills/astro-guidelines/reference/islands-architecture.md +26 -0
- package/skills/astro-guidelines/reference/project-structure.md +32 -0
- package/skills/c99-game-opinionated-guidelines/SKILL.md +43 -0
- package/skills/c99-game-opinionated-guidelines/reference/builder-pattern.md +29 -0
- package/skills/c99-game-opinionated-guidelines/reference/coordinate-system.md +27 -0
- package/skills/c99-game-opinionated-guidelines/reference/geometry-pipeline.md +29 -0
- package/skills/c99-game-opinionated-guidelines/reference/math-types.md +31 -0
- package/skills/c99-game-opinionated-guidelines/reference/mesh-types.md +32 -0
- package/skills/c99-game-opinionated-guidelines/reference/physics-patterns.md +28 -0
- package/skills/c99-game-opinionated-guidelines/reference/spatial-structures.md +26 -0
- package/skills/c99-game-opinionated-guidelines/reference/tagged-unions.md +40 -0
- package/skills/c99-game-opinionated-guidelines/reference/vertex-packing.md +38 -0
- package/skills/c99-guidelines/SKILL.md +29 -0
- package/skills/c99-guidelines/reference/compound-literals.md +33 -0
- package/skills/c99-guidelines/reference/const-correctness.md +32 -0
- package/skills/c99-guidelines/reference/designated-initializers.md +32 -0
- package/skills/c99-guidelines/reference/error-handling.md +49 -0
- package/skills/c99-guidelines/reference/inline-functions.md +37 -0
- package/skills/c99-guidelines/reference/memory-management.md +35 -0
- package/skills/c99-opinionated-guidelines/SKILL.md +44 -0
- package/skills/c99-opinionated-guidelines/reference/alignment.md +50 -0
- package/skills/c99-opinionated-guidelines/reference/caller-owns-memory.md +38 -0
- package/skills/c99-opinionated-guidelines/reference/compound-literals.md +33 -0
- package/skills/c99-opinionated-guidelines/reference/const-correctness.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/data-oriented-design.md +42 -0
- package/skills/c99-opinionated-guidelines/reference/designated-initializers.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/error-handling.md +49 -0
- package/skills/c99-opinionated-guidelines/reference/file-naming.md +33 -0
- package/skills/c99-opinionated-guidelines/reference/implementation-variants.md +35 -0
- package/skills/c99-opinionated-guidelines/reference/inline-functions.md +37 -0
- package/skills/c99-opinionated-guidelines/reference/memory-management.md +35 -0
- package/skills/c99-opinionated-guidelines/reference/safety-validations.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/testing-patterns.md +39 -0
- package/skills/cmake-guidelines/SKILL.md +31 -0
- package/skills/cmake-guidelines/reference/compile-options.md +34 -0
- package/skills/cmake-guidelines/reference/fetchcontent.md +32 -0
- package/skills/cmake-guidelines/reference/find-package.md +29 -0
- package/skills/cmake-guidelines/reference/generator-expressions.md +34 -0
- package/skills/cmake-guidelines/reference/installation.md +38 -0
- package/skills/cmake-guidelines/reference/project-structure.md +40 -0
- package/skills/cmake-guidelines/reference/target-types.md +37 -0
- package/skills/cmake-guidelines/reference/testing.md +30 -0
- package/skills/cmake-guidelines/reference/visibility-specifiers.md +32 -0
- package/skills/content-guidelines/SKILL.md +36 -0
- package/skills/content-guidelines/reference/humanize.md +30 -0
- package/skills/content-guidelines/reference/news.md +28 -0
- package/skills/content-guidelines/reference/travelguide.md +31 -0
- package/skills/docker-guidelines/SKILL.md +23 -0
- package/skills/docker-guidelines/reference/docker-compose.md +40 -0
- package/skills/docker-guidelines/reference/layer-caching.md +25 -0
- package/skills/docker-guidelines/reference/multi-stage-builds.md +37 -0
- package/skills/docker-guidelines/reference/production-config.md +32 -0
- package/skills/docker-guidelines/reference/security.md +27 -0
- package/skills/express.js-guidelines/SKILL.md +32 -0
- package/skills/express.js-guidelines/reference/app-setup.md +39 -0
- package/skills/express.js-guidelines/reference/authentication.md +39 -0
- package/skills/express.js-guidelines/reference/controllers.md +49 -0
- package/skills/express.js-guidelines/reference/error-handling.md +54 -0
- package/skills/express.js-guidelines/reference/project-structure.md +29 -0
- package/skills/express.js-guidelines/reference/responses.md +30 -0
- package/skills/express.js-guidelines/reference/routes.md +29 -0
- package/skills/express.js-guidelines/reference/testing.md +39 -0
- package/skills/express.js-guidelines/reference/validation.md +41 -0
- package/skills/general-fp-guidelines/SKILL.md +28 -0
- package/skills/general-oop-guidelines/SKILL.md +28 -0
- package/skills/git-guidelines/SKILL.md +46 -0
- package/skills/git-guidelines/reference/commit.md +32 -0
- package/skills/git-guidelines/reference/merge-resolve.md +38 -0
- package/skills/git-guidelines/reference/worktree-abandon.md +48 -0
- package/skills/git-guidelines/reference/worktree-cleanup.md +40 -0
- package/skills/git-guidelines/reference/worktree-commit.md +46 -0
- package/skills/git-guidelines/reference/worktree-create.md +42 -0
- package/skills/git-guidelines/reference/worktree-merge.md +45 -0
- package/skills/git-guidelines/reference/worktree-validate.md +44 -0
- package/skills/hono-guidelines/SKILL.md +49 -0
- package/skills/hono-guidelines/reference/application-structure.md +53 -0
- package/skills/hono-guidelines/reference/context-storage.md +46 -0
- package/skills/hono-guidelines/reference/cookie-handling.md +63 -0
- package/skills/hono-guidelines/reference/error-handling.md +69 -0
- package/skills/hono-guidelines/reference/middleware-combine.md +47 -0
- package/skills/hono-guidelines/reference/middleware-patterns.md +58 -0
- package/skills/hono-guidelines/reference/platform-runtime.md +41 -0
- package/skills/hono-guidelines/reference/security-middleware.md +60 -0
- package/skills/hono-guidelines/reference/validation-type-safety.md +43 -0
- package/skills/hono-guidelines/reference/websocket-support.md +59 -0
- package/skills/hono-opinionated-guidelines/SKILL.md +49 -0
- package/skills/hono-opinionated-guidelines/reference/application-structure.md +53 -0
- package/skills/hono-opinionated-guidelines/reference/body-limit.md +57 -0
- package/skills/hono-opinionated-guidelines/reference/context-storage.md +46 -0
- package/skills/hono-opinionated-guidelines/reference/controllers.md +38 -0
- package/skills/hono-opinionated-guidelines/reference/cookie-handling.md +63 -0
- package/skills/hono-opinionated-guidelines/reference/error-handling.md +69 -0
- package/skills/hono-opinionated-guidelines/reference/middleware-combine.md +47 -0
- package/skills/hono-opinionated-guidelines/reference/middleware-patterns.md +58 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-explicit-status-codes.md +61 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-inline-handlers.md +56 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-router-hierarchy.md +64 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-spec-generation.md +57 -0
- package/skills/hono-opinionated-guidelines/reference/platform-runtime.md +41 -0
- package/skills/hono-opinionated-guidelines/reference/router-selection.md +34 -0
- package/skills/hono-opinionated-guidelines/reference/security-middleware.md +60 -0
- package/skills/hono-opinionated-guidelines/reference/validation-type-safety.md +43 -0
- package/skills/hono-opinionated-guidelines/reference/websocket-support.md +59 -0
- package/skills/insights-guidelines/SKILL.md +28 -0
- package/skills/insights-guidelines/reference/insights-extract.md +31 -0
- package/skills/insights-guidelines/reference/insights-integrate.md +35 -0
- package/skills/instruction-guidelines/SKILL.md +26 -0
- package/skills/instruction-guidelines/reference/assimilate.md +38 -0
- package/skills/instruction-guidelines/reference/simplify.md +46 -0
- package/skills/instruction-guidelines/reference/sync.md +41 -0
- package/skills/kubernetes-guidelines/SKILL.md +28 -0
- package/skills/kubernetes-guidelines/reference/configmaps-secrets.md +34 -0
- package/skills/kubernetes-guidelines/reference/deployments.md +55 -0
- package/skills/kubernetes-guidelines/reference/kustomize.md +41 -0
- package/skills/kubernetes-guidelines/reference/network-policies.md +53 -0
- package/skills/kubernetes-guidelines/reference/services.md +36 -0
- package/skills/kubernetes-guidelines/reference/validation.md +32 -0
- package/skills/lua-guidelines/SKILL.md +29 -0
- package/skills/lua-guidelines/reference/coroutines.md +66 -0
- package/skills/lua-guidelines/reference/error-handling.md +41 -0
- package/skills/lua-guidelines/reference/idiomatic-patterns.md +40 -0
- package/skills/lua-guidelines/reference/input-validation.md +42 -0
- package/skills/lua-guidelines/reference/local-variables.md +33 -0
- package/skills/lua-guidelines/reference/metatables.md +52 -0
- package/skills/lua-guidelines/reference/module-pattern.md +37 -0
- package/skills/lua-guidelines/reference/string-concatenation.md +31 -0
- package/skills/lua-opinionated-guidelines/SKILL.md +32 -0
- package/skills/lua-opinionated-guidelines/reference/cache-lookups.md +43 -0
- package/skills/lua-opinionated-guidelines/reference/coroutines.md +66 -0
- package/skills/lua-opinionated-guidelines/reference/error-handling.md +41 -0
- package/skills/lua-opinionated-guidelines/reference/idiomatic-patterns.md +40 -0
- package/skills/lua-opinionated-guidelines/reference/input-validation.md +42 -0
- package/skills/lua-opinionated-guidelines/reference/jit-friendly-tables.md +57 -0
- package/skills/lua-opinionated-guidelines/reference/local-variables.md +33 -0
- package/skills/lua-opinionated-guidelines/reference/metatables.md +52 -0
- package/skills/lua-opinionated-guidelines/reference/module-pattern.md +37 -0
- package/skills/lua-opinionated-guidelines/reference/string-concatenation.md +31 -0
- package/skills/moon-guidelines/SKILL.md +30 -0
- package/skills/moon-guidelines/reference/docker-multistage.md +42 -0
- package/skills/moon-guidelines/reference/project-constraints.md +25 -0
- package/skills/moon-guidelines/reference/query-language.md +27 -0
- package/skills/moon-guidelines/reference/tag-based-filtering.md +28 -0
- package/skills/moon-guidelines/reference/task-configuration.md +38 -0
- package/skills/moon-guidelines/reference/task-inheritance.md +30 -0
- package/skills/motion-react-guidelines/SKILL.md +66 -0
- package/skills/motion-react-guidelines/reference/3d-effects.md +35 -0
- package/skills/motion-react-guidelines/reference/entrance.md +36 -0
- package/skills/motion-react-guidelines/reference/exit.md +35 -0
- package/skills/motion-react-guidelines/reference/gestures.md +23 -0
- package/skills/motion-react-guidelines/reference/layout.md +39 -0
- package/skills/motion-react-guidelines/reference/motion-values.md +33 -0
- package/skills/motion-react-guidelines/reference/performance.md +32 -0
- package/skills/motion-react-guidelines/reference/scroll.md +38 -0
- package/skills/motion-react-guidelines/reference/spring-physics.md +40 -0
- package/skills/motion-react-guidelines/reference/stagger.md +34 -0
- package/skills/motion-react-guidelines/reference/svg-path.md +33 -0
- package/skills/motion-react-guidelines/reference/text-effects.md +39 -0
- package/skills/plan-guidelines/SKILL.md +56 -0
- package/skills/plan-guidelines/reference/code-align.md +23 -0
- package/skills/plan-guidelines/reference/code-barrels-remove.md +24 -0
- package/skills/plan-guidelines/reference/code-comments-remove.md +28 -0
- package/skills/plan-guidelines/reference/code-harden.md +30 -0
- package/skills/plan-guidelines/reference/code-shared-extract.md +25 -0
- package/skills/plan-guidelines/reference/code-simplify.md +33 -0
- package/skills/plan-guidelines/reference/code-template-extract.md +34 -0
- package/skills/plan-guidelines/reference/code-template-scaffold.md +36 -0
- package/skills/plan-guidelines/reference/general-research.md +35 -0
- package/skills/plan-guidelines/reference/plan-create.md +37 -0
- package/skills/plan-guidelines/reference/plan-tdd-create.md +44 -0
- package/skills/plan-guidelines/reference/todos.md +39 -0
- package/skills/presentation-guidelines/SKILL.md +25 -0
- package/skills/presentation-guidelines/reference/presentation-create.md +41 -0
- package/skills/presentation-guidelines/reference/presentation-motion-scaffold.md +38 -0
- package/skills/python-guidelines/SKILL.md +32 -0
- package/skills/python-guidelines/reference/async-await-patterns.md +62 -0
- package/skills/python-guidelines/reference/caching-functions.md +47 -0
- package/skills/python-guidelines/reference/dataclasses-type-hints.md +63 -0
- package/skills/python-guidelines/reference/exception-handling.md +72 -0
- package/skills/python-guidelines/reference/generators-comprehensions.md +54 -0
- package/skills/python-guidelines/reference/pathlib-file-ops.md +60 -0
- package/skills/python-guidelines/reference/resource-management.md +58 -0
- package/skills/python-guidelines/reference/string-formatting.md +41 -0
- package/skills/python-guidelines/reference/type-checking.md +47 -0
- package/skills/react-guidelines/SKILL.md +105 -0
- package/skills/react-guidelines/reference/accessibility.md +31 -0
- package/skills/react-guidelines/reference/activity-effect-event.md +42 -0
- package/skills/react-guidelines/reference/component-design.md +57 -0
- package/skills/react-guidelines/reference/hooks.md +39 -0
- package/skills/react-guidelines/reference/migration-anti-patterns.md +33 -0
- package/skills/react-guidelines/reference/migration-deprecations.md +109 -0
- package/skills/react-guidelines/reference/migration-paradigm-shifts.md +33 -0
- package/skills/react-guidelines/reference/migration-typescript.md +95 -0
- package/skills/react-guidelines/reference/new-hooks.md +94 -0
- package/skills/react-guidelines/reference/performance-optimization.md +41 -0
- package/skills/react-guidelines/reference/react-compiler.md +34 -0
- package/skills/react-guidelines/reference/server-components.md +99 -0
- package/skills/react-guidelines/reference/state-management.md +72 -0
- package/skills/react-guidelines/reference/suspense-streaming.md +36 -0
- package/skills/remotion-guidelines/SKILL.md +67 -0
- package/skills/remotion-guidelines/reference/animations.md +121 -0
- package/skills/remotion-guidelines/reference/assets.md +21 -0
- package/skills/remotion-guidelines/reference/captions.md +33 -0
- package/skills/remotion-guidelines/reference/charts.md +35 -0
- package/skills/remotion-guidelines/reference/compositions.md +40 -0
- package/skills/remotion-guidelines/reference/dom-measurement.md +82 -0
- package/skills/remotion-guidelines/reference/gifs.md +33 -0
- package/skills/remotion-guidelines/reference/lottie.md +41 -0
- package/skills/remotion-guidelines/reference/maps.md +26 -0
- package/skills/remotion-guidelines/reference/media.md +39 -0
- package/skills/remotion-guidelines/reference/mediabunny.md +28 -0
- package/skills/remotion-guidelines/reference/sequencing.md +44 -0
- package/skills/remotion-guidelines/reference/text.md +24 -0
- package/skills/remotion-guidelines/reference/three-d.md +33 -0
- package/skills/remotion-guidelines/reference/timing.md +22 -0
- package/skills/remotion-guidelines/reference/transitions.md +52 -0
- package/skills/shell-scripting-guidelines/SKILL.md +31 -0
- package/skills/shell-scripting-guidelines/reference/argument-parsing.md +67 -0
- package/skills/shell-scripting-guidelines/reference/common-patterns.md +46 -0
- package/skills/shell-scripting-guidelines/reference/error-handling.md +62 -0
- package/skills/shell-scripting-guidelines/reference/functions.md +66 -0
- package/skills/shell-scripting-guidelines/reference/idempotency.md +57 -0
- package/skills/shell-scripting-guidelines/reference/parameter-expansion.md +38 -0
- package/skills/shell-scripting-guidelines/reference/posix-compatibility.md +53 -0
- package/skills/shell-scripting-guidelines/reference/quoting.md +42 -0
- package/skills/shell-scripting-guidelines/reference/script-template.md +70 -0
- package/skills/shell-scripting-guidelines/reference/strict-mode.md +41 -0
- package/skills/shell-scripting-guidelines/reference/validation.md +30 -0
- package/skills/skill-guidelines/SKILL.md +33 -0
- package/skills/skill-guidelines/reference/assimilate.md +51 -0
- package/skills/skill-guidelines/reference/create.md +48 -0
- package/skills/skill-guidelines/reference/extract.md +48 -0
- package/skills/skill-guidelines/reference/simplify.md +56 -0
- package/skills/sql-postgresql-guidelines/SKILL.md +31 -0
- package/skills/sql-postgresql-guidelines/reference/constraints.md +47 -0
- package/skills/sql-postgresql-guidelines/reference/cte-patterns.md +42 -0
- package/skills/sql-postgresql-guidelines/reference/data-types.md +46 -0
- package/skills/sql-postgresql-guidelines/reference/indexing.md +45 -0
- package/skills/sql-postgresql-guidelines/reference/jsonb.md +54 -0
- package/skills/sql-postgresql-guidelines/reference/performance.md +46 -0
- package/skills/sql-postgresql-guidelines/reference/role-based-access.md +47 -0
- package/skills/sql-postgresql-guidelines/reference/row-level-security.md +66 -0
- package/skills/strudel-guidelines/SKILL.md +52 -0
- package/skills/strudel-guidelines/reference/arrangement.md +24 -0
- package/skills/strudel-guidelines/reference/conditionals.md +22 -0
- package/skills/strudel-guidelines/reference/effects.md +22 -0
- package/skills/strudel-guidelines/reference/genre-ambient.md +26 -0
- package/skills/strudel-guidelines/reference/genre-harsh.md +21 -0
- package/skills/strudel-guidelines/reference/genre-trance.md +23 -0
- package/skills/strudel-guidelines/reference/layering.md +22 -0
- package/skills/strudel-guidelines/reference/mini-notation.md +74 -0
- package/skills/strudel-guidelines/reference/modulation.md +22 -0
- package/skills/strudel-guidelines/reference/scales-harmony.md +20 -0
- package/skills/strudel-guidelines/reference/sounds.md +89 -0
- package/skills/strudel-guidelines/reference/tempo-timing.md +23 -0
- package/skills/terraform-guidelines/SKILL.md +28 -0
- package/skills/terraform-guidelines/reference/advanced-patterns.md +88 -0
- package/skills/terraform-guidelines/reference/locals.md +53 -0
- package/skills/terraform-guidelines/reference/module-definition.md +81 -0
- package/skills/terraform-guidelines/reference/module-structure.md +51 -0
- package/skills/terraform-guidelines/reference/remote-state.md +38 -0
- package/skills/terraform-guidelines/reference/root-module.md +71 -0
- package/skills/terraform-guidelines/reference/typed-variables.md +90 -0
- package/skills/threejs-guidelines/SKILL.md +38 -0
- package/skills/threejs-guidelines/reference/animation.md +26 -0
- package/skills/threejs-guidelines/reference/cameras-controls.md +26 -0
- package/skills/threejs-guidelines/reference/geometry.md +22 -0
- package/skills/threejs-guidelines/reference/interaction.md +25 -0
- package/skills/threejs-guidelines/reference/lighting-shadows.md +31 -0
- package/skills/threejs-guidelines/reference/loaders.md +29 -0
- package/skills/threejs-guidelines/reference/materials.md +25 -0
- package/skills/threejs-guidelines/reference/math.md +27 -0
- package/skills/threejs-guidelines/reference/node-materials.md +32 -0
- package/skills/threejs-guidelines/reference/patterns.md +29 -0
- package/skills/threejs-guidelines/reference/performance.md +24 -0
- package/skills/threejs-guidelines/reference/physics-vr.md +36 -0
- package/skills/threejs-guidelines/reference/postprocessing.md +26 -0
- package/skills/threejs-guidelines/reference/scene-fundamentals.md +26 -0
- package/skills/threejs-guidelines/reference/shaders.md +28 -0
- package/skills/threejs-guidelines/reference/textures.md +21 -0
- package/skills/threejs-guidelines/reference/webgpu.md +34 -0
- package/skills/typescript-guidelines/SKILL.md +37 -0
- package/skills/typescript-guidelines/reference/async-without-await.md +32 -0
- package/skills/typescript-guidelines/reference/avoid-barrel-exports.md +25 -0
- package/skills/typescript-guidelines/reference/avoid-eslint-disable.md +28 -0
- package/skills/typescript-guidelines/reference/avoid-reexports.md +26 -0
- package/skills/typescript-guidelines/reference/env-access-bracket-notation.md +29 -0
- package/skills/typescript-guidelines/reference/numeric-separator-enforcement.md +30 -0
- package/skills/typescript-guidelines/reference/template-literals-require-string-conversion.md +26 -0
- package/skills/typescript-guidelines/reference/unbound-method-references.md +32 -0
- package/skills/typescript-guidelines/reference/unnecessary-async-keywords.md +37 -0
- package/skills/typescript-to-lua-guidelines/SKILL.md +33 -0
- package/skills/typescript-to-lua-guidelines/reference/avoiding-heavy-features.md +41 -0
- package/skills/typescript-to-lua-guidelines/reference/coroutine-patterns.md +49 -0
- package/skills/typescript-to-lua-guidelines/reference/function-patterns.md +59 -0
- package/skills/typescript-to-lua-guidelines/reference/lua-interop.md +49 -0
- package/skills/typescript-to-lua-guidelines/reference/module-organization.md +42 -0
- package/skills/typescript-to-lua-guidelines/reference/multi-return-functions.md +47 -0
- package/skills/typescript-to-lua-guidelines/reference/namespaces-vs-classes.md +52 -0
- package/skills/typescript-to-lua-guidelines/reference/performance-tips.md +68 -0
- package/skills/typescript-to-lua-guidelines/reference/stable-tables.md +60 -0
- package/skills/typescript-to-lua-guidelines/reference/tsconfig.md +46 -0
- package/skills/typescript-to-lua-guidelines/reference/tstl-decorators.md +61 -0
- package/skills/typescript-to-lua-guidelines/reference/type-safety.md +79 -0
- package/skills/vitest-guidelines/SKILL.md +32 -0
- package/skills/vitest-guidelines/reference/cors-preflight-status-code.md +34 -0
- package/skills/vitest-guidelines/reference/http-testing.md +57 -0
- package/skills/vitest-guidelines/reference/json-response-type-safety.md +40 -0
- package/skills/vitest-guidelines/reference/mock-patterns.md +53 -0
- package/skills/vitest-guidelines/reference/project-references-path-resolution.md +36 -0
- package/skills/vitest-guidelines/reference/test-organization.md +25 -0
- package/skills/vitest-guidelines/reference/timestamp-testing.md +55 -0
- package/skills/vitest-guidelines/reference/type-safety.md +55 -0
- package/skills/vitest-guidelines/reference/typescript-config.md +43 -0
- package/skills/zod-guidelines/SKILL.md +33 -0
- package/skills/zod-guidelines/reference/default-values-output-type.md +63 -0
- package/skills/zod-guidelines/reference/migration-string-validators.md +38 -0
- package/skills/zod-guidelines/reference/migration-v4.md +46 -0
- package/skills/zod-guidelines/reference/schema-organization.md +73 -0
- package/skills/zod-guidelines/reference/validation-patterns.md +37 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# http-testing: HTTP Testing Patterns
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use correct HTTP status codes in test assertions (204 for OPTIONS/DELETE, 201 for creation, 200 for GET).
|
|
4
|
+
|
|
5
|
+
**Rationale:** Correct status codes ensure tests align with HTTP standards and detect real failures.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// CORS Preflight
|
|
11
|
+
it("should handle CORS preflight", async () => {
|
|
12
|
+
const res = await app.request("/api/users", {
|
|
13
|
+
method: "OPTIONS",
|
|
14
|
+
headers: {
|
|
15
|
+
Origin: "https://example.com",
|
|
16
|
+
"Access-Control-Request-Method": "POST",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
expect(res.status).toBe(204); // ✅ Correct for OPTIONS
|
|
21
|
+
expect(res.headers.get("Access-Control-Allow-Origin")).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Status Code Assertions
|
|
25
|
+
it("should create resource", async () => {
|
|
26
|
+
const res = await app.request("/api/users", {method: "POST", body: data});
|
|
27
|
+
expect(res.status).toBe(201); // ✅ Created
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("should get resource", async () => {
|
|
31
|
+
const res = await app.request("/api/users/123");
|
|
32
|
+
expect(res.status).toBe(200); // ✅ OK with body
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should delete resource", async () => {
|
|
36
|
+
const res = await app.request("/api/users/123", {method: "DELETE"});
|
|
37
|
+
expect(res.status).toBe(204); // ✅ No Content
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("should validate input", async () => {
|
|
41
|
+
const res = await app.request("/api/users", {method: "POST", body: invalid});
|
|
42
|
+
expect(res.status).toBe(400); // ✅ Bad Request
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should handle missing resource", async () => {
|
|
46
|
+
const res = await app.request("/api/users/999");
|
|
47
|
+
expect(res.status).toBe(404); // ✅ Not Found
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Techniques:**
|
|
52
|
+
- Use 204 for OPTIONS preflight requests (CORS)
|
|
53
|
+
- Use 204 for successful DELETE operations without response body
|
|
54
|
+
- Use 201 for resource creation (POST that creates new resource)
|
|
55
|
+
- Use 200 for successful operations with response body
|
|
56
|
+
- Use 400 for validation failures and bad requests
|
|
57
|
+
- Use 404 for missing resources
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# json-response-type-safety: JSON Response Type Safety in Tests
|
|
2
|
+
|
|
3
|
+
**Guideline:** Define response interfaces and cast JSON results to maintain type safety in tests.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Type casting prevents unsafe assignment errors and enables IDE autocomplete and refactoring.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// Define interfaces at file top
|
|
11
|
+
interface User {
|
|
12
|
+
id: string;
|
|
13
|
+
email: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ErrorResponse {
|
|
17
|
+
title: string;
|
|
18
|
+
status: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Use in tests
|
|
22
|
+
it("should return user", async () => {
|
|
23
|
+
const res = await app.request("/api/users/123");
|
|
24
|
+
const json = (await res.json()) as User;
|
|
25
|
+
expect(json.id).toBe("123"); // ✅ Type-safe
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should return error", async () => {
|
|
29
|
+
const res = await app.request("/api/users/invalid");
|
|
30
|
+
const json = (await res.json()) as ErrorResponse;
|
|
31
|
+
expect(json.status).toBe(404); // ✅ Type-safe
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Techniques:**
|
|
36
|
+
- Create test-specific interfaces at the top of test files
|
|
37
|
+
- Use type assertion: `const json = (await res.json()) as ExpectedType`
|
|
38
|
+
- Reuse interfaces across multiple tests
|
|
39
|
+
- Match interface properties to actual API response shape
|
|
40
|
+
- Cast before property access to avoid unsafe-assignment ESLint errors
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# mock-patterns: Simple Type Casting for Vitest Mocks
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use simple type casting for Vitest mocks instead of complex generic typing.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Simple casting is more maintainable and readable than complex generic typing.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import {expect, it, vi} from "vitest";
|
|
11
|
+
|
|
12
|
+
interface User {
|
|
13
|
+
id: string;
|
|
14
|
+
email: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ✅ Simple - easy to read and maintain
|
|
18
|
+
it("should call user service", async () => {
|
|
19
|
+
const mockUser: User = {id: "123", email: "test@example.com"};
|
|
20
|
+
const getUserFn = vi.fn();
|
|
21
|
+
getUserFn.mockResolvedValue(mockUser);
|
|
22
|
+
|
|
23
|
+
const result = await getUserFn("123");
|
|
24
|
+
expect(result).toEqual(mockUser);
|
|
25
|
+
expect(getUserFn).toHaveBeenCalledWith("123");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ✅ Good - type cast when needed
|
|
29
|
+
it("should handle error", async () => {
|
|
30
|
+
const getUserFn = vi.fn();
|
|
31
|
+
(getUserFn as ReturnType<typeof vi.fn>).mockRejectedValue(
|
|
32
|
+
new Error("Not found"),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
await expect(getUserFn("999")).rejects.toThrow("Not found");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// ✅ Good - simple sync mock
|
|
39
|
+
it("should transform data", () => {
|
|
40
|
+
const transformFn = vi.fn();
|
|
41
|
+
transformFn.mockReturnValue({transformed: true});
|
|
42
|
+
|
|
43
|
+
const result = transformFn({input: "data"});
|
|
44
|
+
expect(result.transformed).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Techniques:**
|
|
49
|
+
- Create mocks with `vi.fn()` without complex generics
|
|
50
|
+
- Use type casting when setting return values
|
|
51
|
+
- Let TypeScript infer types from usage
|
|
52
|
+
- Only add types when necessary for test assertions
|
|
53
|
+
- Prefer simple casting over advanced mock type patterns
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# project-references-path-resolution: Path Resolution in TypeScript Project References
|
|
2
|
+
|
|
3
|
+
**Guideline:** Verify directory structure before configuring project references; calculate relative paths carefully from current package to target.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Incorrect paths cause "File not found" errors and build failures in CI/CD pipelines.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Verify structure
|
|
11
|
+
$ ls packages/
|
|
12
|
+
templates/ shared/ apps/
|
|
13
|
+
|
|
14
|
+
# Calculate path: packages/templates/my-template → packages/shared/shared-core
|
|
15
|
+
# Up 2 levels (..), down through shared/, then shared-core/
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
// Correct reference
|
|
20
|
+
{"references": [{"path": "../../shared/shared-core"}]}
|
|
21
|
+
|
|
22
|
+
// Wrong - goes up 3 levels
|
|
23
|
+
// {"path": "../../../shared/shared-core"} ❌
|
|
24
|
+
|
|
25
|
+
// Wrong - missing "shared" directory
|
|
26
|
+
// {"path": "../../shared-core"} ❌
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Techniques:**
|
|
30
|
+
- ls verification: Use `ls` to check actual directory structure before configuring
|
|
31
|
+
- Relative paths: Calculate from current package up (..) then down to target
|
|
32
|
+
- tsc --build: Test with TypeScript build to verify paths resolve
|
|
33
|
+
- Error messages: Read build errors to identify which paths failed
|
|
34
|
+
- Monorepo structure: Understand packages/, apps/, shared/ hierarchy
|
|
35
|
+
- Counting levels: Each up (..) represents one directory level
|
|
36
|
+
- Off-by-one errors: Most common mistake - verify counting twice
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# test-organization: Test Directory Structure and Suite Organization
|
|
2
|
+
|
|
3
|
+
**Guideline:** Organize tests by endpoint/feature with nested describe blocks and clear directory structure.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Well-organized tests are easy to navigate, maintain, and update.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
test/
|
|
11
|
+
├── app.test.ts # Application-level tests
|
|
12
|
+
├── health.test.ts # Health check endpoints
|
|
13
|
+
└── api/
|
|
14
|
+
├── users.test.ts # User CRUD operations
|
|
15
|
+
└── auth.test.ts # Authentication flows
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Techniques:**
|
|
19
|
+
- Create `test/` directory at package root
|
|
20
|
+
- Mirror API structure in test files (e.g., `test/api/users.test.ts`)
|
|
21
|
+
- Use nested `describe` blocks for endpoint grouping
|
|
22
|
+
- Name test files after features: `{feature}.test.ts`
|
|
23
|
+
- Group related tests in inner `describe` blocks
|
|
24
|
+
- Use descriptive `it` statements that explain expected behavior
|
|
25
|
+
- Test both success and error cases for each endpoint
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# timestamp-testing: Avoiding Flaky Timestamp Comparisons
|
|
2
|
+
|
|
3
|
+
**Guideline:** Don't compare timestamps from rapid operations; they may complete in the same millisecond.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Fast operations can complete within milliseconds, making timestamp comparisons flaky and unreliable.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Preferred - verify existence and type
|
|
11
|
+
it("should update timestamp", async () => {
|
|
12
|
+
const created = await createUser();
|
|
13
|
+
const updated = await updateUser(created.id);
|
|
14
|
+
|
|
15
|
+
expect(updated.updatedAt).toBeDefined();
|
|
16
|
+
expect(typeof updated.updatedAt).toBe("string");
|
|
17
|
+
expect(new Date(updated.updatedAt)).toBeInstanceOf(Date);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// ✅ Alternative - add explicit delay
|
|
21
|
+
it("should update timestamp with delay", async () => {
|
|
22
|
+
const created = await createUser();
|
|
23
|
+
await new Promise((resolve) => setTimeout(resolve, 10)); // 10ms delay
|
|
24
|
+
const updated = await updateUser(created.id);
|
|
25
|
+
|
|
26
|
+
expect(updated.updatedAt).not.toBe(created.updatedAt);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// ✅ Good - verify timestamp is after a known point
|
|
30
|
+
it("should have recent timestamp", async () => {
|
|
31
|
+
const before = new Date().toISOString();
|
|
32
|
+
const created = await createUser();
|
|
33
|
+
|
|
34
|
+
expect(created.createdAt >= before).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// ✅ Good - verify timestamp changed (with reasonable buffer)
|
|
38
|
+
it("should update timestamp", async () => {
|
|
39
|
+
const created = await createUser();
|
|
40
|
+
const createdTime = new Date(created.createdAt).getTime();
|
|
41
|
+
|
|
42
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
43
|
+
const updated = await updateUser(created.id);
|
|
44
|
+
const updatedTime = new Date(updated.updatedAt).getTime();
|
|
45
|
+
|
|
46
|
+
expect(updatedTime).toBeGreaterThan(createdTime);
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Techniques:**
|
|
51
|
+
- Verify timestamp exists and is correct type (preferred approach)
|
|
52
|
+
- Add explicit delay (10-50ms) before second operation if comparison needed
|
|
53
|
+
- Use timestamp ranges (before/after) instead of exact equality
|
|
54
|
+
- Verify timestamp format/structure instead of comparing values
|
|
55
|
+
- Mock time if deterministic testing is required
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# type-safety: Type Safety in Tests
|
|
2
|
+
|
|
3
|
+
**Guideline:** Always define interfaces for response shapes and cast JSON parsing results to maintain type safety.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Type assertions enable IDE autocomplete and prevent unsafe assignment errors.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import {describe, expect, it} from "vitest";
|
|
11
|
+
|
|
12
|
+
// Define reusable interfaces at the top
|
|
13
|
+
interface User {
|
|
14
|
+
id: string;
|
|
15
|
+
email: string;
|
|
16
|
+
name: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ErrorResponse {
|
|
21
|
+
title: string;
|
|
22
|
+
status: number;
|
|
23
|
+
issues?: {path: string[]; message: string}[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe("Users API", () => {
|
|
27
|
+
it("should create user", async () => {
|
|
28
|
+
const res = await app.request("/api/users", {
|
|
29
|
+
method: "POST",
|
|
30
|
+
body: JSON.stringify({email: "test@example.com"}),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const json = (await res.json()) as User;
|
|
34
|
+
expect(json.email).toBe("test@example.com"); // Type-safe!
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("should validate email", async () => {
|
|
38
|
+
const res = await app.request("/api/users", {
|
|
39
|
+
method: "POST",
|
|
40
|
+
body: JSON.stringify({email: "invalid"}),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const json = (await res.json()) as ErrorResponse;
|
|
44
|
+
expect(json.status).toBe(400);
|
|
45
|
+
expect(json.issues).toBeDefined(); // Type-safe!
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Techniques:**
|
|
51
|
+
- Define interfaces for expected response shapes at the top of test files
|
|
52
|
+
- Cast all JSON parsing results: `const json = (await res.json()) as ResponseType`
|
|
53
|
+
- Create reusable interfaces for common response types (User, ErrorResponse, etc.)
|
|
54
|
+
- Use the same interfaces across multiple tests in the same file
|
|
55
|
+
- Match interface properties to actual API response shapes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# typescript-config: TypeScript Project Configuration for Tests
|
|
2
|
+
|
|
3
|
+
**Guideline:** Verify directory structure before configuring TypeScript project references and test inclusion in tsconfig.json.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Incorrect configuration causes compilation failures and broken builds in CI/CD.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
// For packages/templates/X referencing packages/shared/Y
|
|
11
|
+
{
|
|
12
|
+
"extends": "../../tsconfig.base.json",
|
|
13
|
+
"compilerOptions": {
|
|
14
|
+
"rootDir": "src",
|
|
15
|
+
"outDir": "dist"
|
|
16
|
+
},
|
|
17
|
+
"references": [
|
|
18
|
+
{
|
|
19
|
+
"path": "../../shared/shared-core" // ✅ Correct - verified with ls
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "../../shared/shared-types"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"include": [
|
|
26
|
+
"src", // ✅ Source files
|
|
27
|
+
"test", // ✅ Test files
|
|
28
|
+
"vitest.config.ts" // ✅ Vitest config
|
|
29
|
+
],
|
|
30
|
+
"exclude": [
|
|
31
|
+
"dist", // ✅ Build output
|
|
32
|
+
"node_modules" // ✅ Dependencies
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Techniques:**
|
|
38
|
+
- Check actual directory structure with `ls` or file explorer before configuring
|
|
39
|
+
- Calculate relative paths from current package to referenced packages
|
|
40
|
+
- Add project references with correct relative paths
|
|
41
|
+
- Include test directories in `include` array (e.g., "test")
|
|
42
|
+
- Exclude build artifacts and node_modules from compilation
|
|
43
|
+
- Test compilation with `tsc --build` to verify paths resolve
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zod-guidelines
|
|
3
|
+
description: >-
|
|
4
|
+
Trigger on `.ts` files with Zod imports or validation patterns. Use when working with Zod 4.0+ for runtime validation. Apply for API validation, schema composition, type inference, default values. Keywords: Zod, z.uuid(), z.email(), z.iso.datetime(), schema composition, safeParse, z.infer, defaults, validation patterns.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Zod Coding Guidelines
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Zod ≥ 4.0
|
|
12
|
+
|
|
13
|
+
## Essentials
|
|
14
|
+
|
|
15
|
+
- **Use v4 validators** - `z.uuid()`, `z.email()`, `z.iso.datetime()` (not `z.string().uuid()`)
|
|
16
|
+
- **Name schemas PascalCase** - Derive with `.omit()`, `.extend()`, `.pick()`, `.merge()`, see [reference/schema-organization.md](reference/schema-organization.md)
|
|
17
|
+
- **Validate at boundaries** - Use `.safeParse()` for I/O, `.pipe()` for transforms, see [reference/validation-patterns.md](reference/validation-patterns.md)
|
|
18
|
+
- **Infer types from schemas** - `z.infer<typeof Schema>` for TypeScript types, see [reference/validation-patterns.md](reference/validation-patterns.md)
|
|
19
|
+
- **Module-level schemas** - Define for reuse, keep close to usage, see [reference/schema-organization.md](reference/schema-organization.md)
|
|
20
|
+
- **Match default output types** - Defaults must align with transformations, see [reference/default-values-output-type.md](reference/default-values-output-type.md)
|
|
21
|
+
|
|
22
|
+
## Progressive Disclosure
|
|
23
|
+
|
|
24
|
+
### Guidelines
|
|
25
|
+
|
|
26
|
+
- Read [reference/schema-organization.md](reference/schema-organization.md) - When organizing schemas across modules or files
|
|
27
|
+
- Read [reference/validation-patterns.md](reference/validation-patterns.md) - When choosing between safeParse, parse, or pipe
|
|
28
|
+
- Read [reference/default-values-output-type.md](reference/default-values-output-type.md) - When default values cause type mismatches
|
|
29
|
+
|
|
30
|
+
### Migration from Zod v3
|
|
31
|
+
|
|
32
|
+
- Read [reference/migration-v4.md](reference/migration-v4.md) - When migrating from Zod v3 or using deprecated validators
|
|
33
|
+
- Read [reference/migration-string-validators.md](reference/migration-string-validators.md) - When replacing z.string().uuid() patterns
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# default-values-output-type: Default Values Must Match Output Type
|
|
2
|
+
|
|
3
|
+
**Guideline:** When using `.transform()` or `.pipe()`, ensure `.default()` matches the final output type, not the input type.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Zod v4 requires defaults to match the transformed output type; mismatched types cause TypeScript errors and prevent proper type narrowing.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Correct - default matches output type (number)
|
|
11
|
+
const PaginationSchema = z.object({
|
|
12
|
+
page: z
|
|
13
|
+
.string()
|
|
14
|
+
.regex(/^\d+$/)
|
|
15
|
+
.transform(Number)
|
|
16
|
+
.pipe(z.number().int().min(1))
|
|
17
|
+
.default(1), // Number, matches output type
|
|
18
|
+
|
|
19
|
+
limit: z
|
|
20
|
+
.string()
|
|
21
|
+
.regex(/^\d+$/)
|
|
22
|
+
.transform(Number)
|
|
23
|
+
.pipe(z.number().int().min(1).max(100))
|
|
24
|
+
.default(10), // Number, matches output type
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
type Pagination = z.infer<typeof PaginationSchema>;
|
|
28
|
+
// Result: {page: number, limit: number}
|
|
29
|
+
|
|
30
|
+
// ✅ Boolean transformation
|
|
31
|
+
const ConfigSchema = z.object({
|
|
32
|
+
debug: z
|
|
33
|
+
.string()
|
|
34
|
+
.transform((val) => val === "true")
|
|
35
|
+
.pipe(z.boolean())
|
|
36
|
+
.default(false), // Boolean, matches output type
|
|
37
|
+
|
|
38
|
+
verbose: z
|
|
39
|
+
.string()
|
|
40
|
+
.transform((val) => val === "1")
|
|
41
|
+
.pipe(z.boolean())
|
|
42
|
+
.default(true), // Boolean, matches output type
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// ✅ Complex transformation
|
|
46
|
+
const PortSchema = z
|
|
47
|
+
.string()
|
|
48
|
+
.transform(Number)
|
|
49
|
+
.pipe(z.number().int().min(1024).max(65535))
|
|
50
|
+
.default(3000); // Number, matches output type
|
|
51
|
+
|
|
52
|
+
type Port = z.infer<typeof PortSchema>;
|
|
53
|
+
// Result: number
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Techniques:**
|
|
57
|
+
- Match defaults to final output type, not input type
|
|
58
|
+
- With `.transform(Number)`, use `.default(1)` not `.default("1")`
|
|
59
|
+
- With `.transform(Boolean)`, use `.default(true)` not `.default("true")`
|
|
60
|
+
- Check TypeScript compilation errors for type mismatches
|
|
61
|
+
- Determine output type by tracing through transformation chain
|
|
62
|
+
- Use `z.infer<typeof Schema>` to verify final types
|
|
63
|
+
- Test with `safeParse()` to catch runtime type issues
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# string-validation-method-changes: String Validation Method Changes
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use standalone validators `z.uuid()` and `z.iso.datetime()` instead of deprecated string refinements `z.string().uuid()` and `z.string().datetime()`.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Zod v4 deprecated string refinements; standalone methods are more efficient and prevent ESLint deprecation warnings.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Correct - Zod v4 standalone validators
|
|
11
|
+
const EventSchema = z.object({
|
|
12
|
+
id: z.uuid(), // Standalone UUID validator
|
|
13
|
+
eventId: z.uuid(), // Use for any UUID field
|
|
14
|
+
scheduledAt: z.iso.datetime(), // Standalone datetime validator
|
|
15
|
+
createdAt: z.iso.datetime(), // Use for any ISO datetime
|
|
16
|
+
updatedAt: z.iso.datetime(),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Infer type
|
|
20
|
+
type Event = z.infer<typeof EventSchema>;
|
|
21
|
+
// Result: {id: string, eventId: string, scheduledAt: string, ...}
|
|
22
|
+
|
|
23
|
+
// Validation
|
|
24
|
+
const result = EventSchema.safeParse(data);
|
|
25
|
+
if (result.success) {
|
|
26
|
+
console.log(result.data.id); // Type-safe access
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Techniques:**
|
|
31
|
+
- Replace `z.string().uuid()` with `z.uuid()`
|
|
32
|
+
- Replace `z.string().email()` with `z.email()`
|
|
33
|
+
- Replace `z.string().url()` with `z.url()`
|
|
34
|
+
- Replace `z.string().datetime()` with `z.iso.datetime()`
|
|
35
|
+
- Replace `z.string().date()` with `z.iso.date()`
|
|
36
|
+
- Replace `z.string().time()` with `z.iso.time()`
|
|
37
|
+
- Run linter to verify no deprecation warnings
|
|
38
|
+
- Test validation to ensure behavior unchanged
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# v4-migration: Zod v4 Migration Guide
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use Zod v4 standalone validators like `z.uuid()`, `z.email()`, and `z.iso.datetime()` instead of deprecated v3 string refinement methods.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Zod v4 changed from string refinements to standalone validators that are more efficient, type-safe, and avoid ESLint deprecation warnings.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Correct (v4) - standalone validators
|
|
11
|
+
const UserSchema = z.object({
|
|
12
|
+
id: z.uuid(), // Not z.string().uuid()
|
|
13
|
+
email: z.email(), // Not z.string().email()
|
|
14
|
+
website: z.url(), // Not z.string().url()
|
|
15
|
+
createdAt: z.iso.datetime(), // Not z.string().datetime()
|
|
16
|
+
birthDate: z.iso.date(), // Not z.string().date()
|
|
17
|
+
checkInTime: z.iso.time(), // Not z.string().time()
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Enum usage (unchanged)
|
|
21
|
+
enum Status {
|
|
22
|
+
Active = "active",
|
|
23
|
+
Inactive = "inactive",
|
|
24
|
+
}
|
|
25
|
+
const StatusSchema = z.enum(Status);
|
|
26
|
+
|
|
27
|
+
// String literal unions (unchanged)
|
|
28
|
+
const RoleSchema = z.enum(["admin", "user", "guest"]);
|
|
29
|
+
|
|
30
|
+
// Default values with transformations
|
|
31
|
+
const ConfigSchema = z.object({
|
|
32
|
+
port: z.string().transform(Number).pipe(z.number()).default(3000), // ✅ Default matches output type (number)
|
|
33
|
+
|
|
34
|
+
timeout: z.string().transform(Number).pipe(z.number()).default(5000), // ✅ Not .default("5000")
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Techniques:**
|
|
39
|
+
- Replace `z.string().uuid()` with `z.uuid()`
|
|
40
|
+
- Replace `z.string().email()` with `z.email()`
|
|
41
|
+
- Replace `z.string().url()` with `z.url()`
|
|
42
|
+
- Replace `z.string().datetime()` with `z.iso.datetime()`
|
|
43
|
+
- Replace `z.string().date()` with `z.iso.date()`
|
|
44
|
+
- Replace `z.string().time()` with `z.iso.time()`
|
|
45
|
+
- Update defaults to match output types with transformations
|
|
46
|
+
- Run linter to verify no deprecation warnings
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# schema-organization: Schema Organization Patterns
|
|
2
|
+
|
|
3
|
+
**Guideline:** Name schemas with PascalCase suffix, compose with `.merge()`, `.pick()`, `.partial()`, and always infer types using `z.infer<typeof Schema>`.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Schema-first design provides single source of truth for types and validation, enabling reusable composition and reducing duplication.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// ✅ Base schema with common fields
|
|
11
|
+
const BaseEntitySchema = z.object({
|
|
12
|
+
id: z.uuid(),
|
|
13
|
+
createdAt: z.iso.datetime(),
|
|
14
|
+
updatedAt: z.iso.datetime(),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// ✅ Extend with .merge()
|
|
18
|
+
export const UserSchema = BaseEntitySchema.merge(
|
|
19
|
+
z.object({
|
|
20
|
+
email: z.email(),
|
|
21
|
+
name: z.string().min(1).max(100),
|
|
22
|
+
role: z.enum(["admin", "user", "guest"]),
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// ✅ Infer type from schema
|
|
27
|
+
export type User = z.infer<typeof UserSchema>;
|
|
28
|
+
|
|
29
|
+
// ✅ Create input schemas with .pick()
|
|
30
|
+
export const CreateUserSchema = UserSchema.pick({
|
|
31
|
+
email: true,
|
|
32
|
+
name: true,
|
|
33
|
+
role: true,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export type CreateUser = z.infer<typeof CreateUserSchema>;
|
|
37
|
+
|
|
38
|
+
// ✅ Make fields optional with .partial()
|
|
39
|
+
export const UpdateUserSchema = UserSchema.pick({
|
|
40
|
+
email: true,
|
|
41
|
+
name: true,
|
|
42
|
+
role: true,
|
|
43
|
+
}).partial();
|
|
44
|
+
|
|
45
|
+
export type UpdateUser = z.infer<typeof UpdateUserSchema>;
|
|
46
|
+
|
|
47
|
+
// ✅ Simplified view with .pick()
|
|
48
|
+
export const UserSummarySchema = UserSchema.pick({
|
|
49
|
+
id: true,
|
|
50
|
+
email: true,
|
|
51
|
+
name: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export type UserSummary = z.infer<typeof UserSummarySchema>;
|
|
55
|
+
|
|
56
|
+
// Usage in API
|
|
57
|
+
async function createUser(input: unknown): Promise<User> {
|
|
58
|
+
const data = CreateUserSchema.parse(input);
|
|
59
|
+
// data is type-safe: CreateUser
|
|
60
|
+
const user = await db.users.create(data);
|
|
61
|
+
return UserSchema.parse(user);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Techniques:**
|
|
66
|
+
- Name all schemas with PascalCase + "Schema" suffix
|
|
67
|
+
- Define schemas at module level for reuse
|
|
68
|
+
- Always infer types: `type User = z.infer<typeof UserSchema>`
|
|
69
|
+
- Use `.merge()` to combine schemas
|
|
70
|
+
- Use `.pick()` to select specific fields
|
|
71
|
+
- Use `.partial()` to make fields optional
|
|
72
|
+
- Create base schemas for common patterns
|
|
73
|
+
- Keep schemas close to their usage
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# validation-patterns: Validation Patterns
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use `.safeParse()` for external input; `.parse()` for controlled data; `.pipe()` for type-safe transformations.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Runtime type safety ensures external input never crashes your application.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// API input with safeParse
|
|
11
|
+
const result = CreateUserSchema.safeParse(req.body);
|
|
12
|
+
if (!result.success) {
|
|
13
|
+
return res.status(400).json({error: result.error.issues});
|
|
14
|
+
}
|
|
15
|
+
const user = await createUser(result.data);
|
|
16
|
+
|
|
17
|
+
// Query transformation with pipe
|
|
18
|
+
const PaginationSchema = z.object({
|
|
19
|
+
page: z.string().regex(/^\d+$/).transform(Number)
|
|
20
|
+
.pipe(z.number().int().min(1)).default(1),
|
|
21
|
+
limit: z.string().regex(/^\d+$/).transform(Number)
|
|
22
|
+
.pipe(z.number().int().min(1).max(100)).default(10),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Controlled data (safe to use parse)
|
|
26
|
+
const validated = InternalSchema.parse(data);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Techniques:**
|
|
30
|
+
- `.safeParse()`: Use for external input (API, user, services); never throws
|
|
31
|
+
- `.parse()`: Use only for controlled data; throws on validation failure
|
|
32
|
+
- Check `result.success`: Always verify before accessing `result.data`
|
|
33
|
+
- `.transform()`: Apply type conversion before pipe validation
|
|
34
|
+
- `.pipe()`: Chain type-safe transformations for multi-step validation
|
|
35
|
+
- `.default()`: Provide fallback values for optional fields
|
|
36
|
+
- Error handling: Always `.safeParse()` untrusted input, never `.parse()`
|
|
37
|
+
- Error context: Preserve error details in API responses
|