@codyswann/lisa 1.47.1 → 1.48.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/all/copy-overwrite/.claude/rules/lisa.md +23 -10
- package/all/copy-overwrite/.claude/settings.json +10 -252
- package/all/deletions.json +67 -1
- package/cdk/copy-overwrite/.claude/settings.json +80 -0
- package/cdk/create-only/.github/workflows/ci.yml +1 -1
- package/cdk/create-only/.github/workflows/deploy.yml +1 -1
- package/dist/core/lisa.d.ts +14 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +47 -0
- package/dist/core/lisa.js.map +1 -1
- package/expo/copy-overwrite/.claude/settings.json +80 -0
- package/expo/copy-overwrite/eslint.expo.ts +2 -2
- package/expo/create-only/.github/workflows/ci.yml +1 -1
- package/expo/create-only/.github/workflows/deploy.yml +1 -1
- package/expo/deletions.json +33 -0
- package/expo/package-lisa/package.lisa.json +2 -2
- package/nestjs/copy-overwrite/.claude/settings.json +80 -0
- package/nestjs/create-only/.github/workflows/ci.yml +1 -1
- package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
- package/nestjs/deletions.json +8 -0
- package/package.json +8 -4
- package/rails/copy-overwrite/.claude/settings.json +80 -0
- package/rails/create-only/.github/workflows/ci.yml +1 -1
- package/rails/deletions.json +11 -1
- package/typescript/copy-overwrite/.claude/settings.json +13 -253
- package/typescript/copy-overwrite/eslint.typescript.ts +1 -1
- package/typescript/create-only/.github/workflows/ci.yml +1 -1
- package/typescript/deletions.json +12 -1
- package/typescript/package-lisa/package.lisa.json +1 -1
- package/all/copy-overwrite/.claude/agents/agent-architect.md +0 -310
- package/all/copy-overwrite/.claude/agents/architecture-specialist.md +0 -53
- package/all/copy-overwrite/.claude/agents/debug-specialist.md +0 -204
- package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +0 -183
- package/all/copy-overwrite/.claude/agents/hooks-expert.md +0 -74
- package/all/copy-overwrite/.claude/agents/implementer.md +0 -54
- package/all/copy-overwrite/.claude/agents/learner.md +0 -44
- package/all/copy-overwrite/.claude/agents/performance-specialist.md +0 -95
- package/all/copy-overwrite/.claude/agents/product-specialist.md +0 -72
- package/all/copy-overwrite/.claude/agents/quality-specialist.md +0 -55
- package/all/copy-overwrite/.claude/agents/security-specialist.md +0 -58
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +0 -246
- package/all/copy-overwrite/.claude/agents/slash-command-architect.md +0 -87
- package/all/copy-overwrite/.claude/agents/test-specialist.md +0 -64
- package/all/copy-overwrite/.claude/agents/verification-specialist.md +0 -189
- package/all/copy-overwrite/.claude/agents/web-search-researcher.md +0 -112
- package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +0 -7
- package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-and-verify.md +0 -7
- package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-deploy-and-verify.md +0 -7
- package/all/copy-overwrite/.claude/commands/git/commit.md +0 -7
- package/all/copy-overwrite/.claude/commands/git/prune.md +0 -6
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +0 -7
- package/all/copy-overwrite/.claude/commands/jira/create.md +0 -7
- package/all/copy-overwrite/.claude/commands/jira/sync.md +0 -7
- package/all/copy-overwrite/.claude/commands/jira/verify.md +0 -7
- package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +0 -7
- package/all/copy-overwrite/.claude/commands/plan/add-test-coverage.md +0 -7
- package/all/copy-overwrite/.claude/commands/plan/create.md +0 -6
- package/all/copy-overwrite/.claude/commands/plan/execute.md +0 -7
- package/all/copy-overwrite/.claude/commands/plan/fix-linter-error.md +0 -7
- package/all/copy-overwrite/.claude/commands/plan/local-code-review.md +0 -6
- package/all/copy-overwrite/.claude/commands/plan/lower-code-complexity.md +0 -6
- package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines-per-function.md +0 -7
- package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines.md +0 -7
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +0 -7
- package/all/copy-overwrite/.claude/commands/security/zap-scan.md +0 -6
- package/all/copy-overwrite/.claude/commands/sonarqube/check.md +0 -6
- package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +0 -6
- package/all/copy-overwrite/.claude/commands/tasks/load.md +0 -7
- package/all/copy-overwrite/.claude/commands/tasks/sync.md +0 -7
- package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +0 -61
- package/all/copy-overwrite/.claude/hooks/debug-hook.sh +0 -47
- package/all/copy-overwrite/.claude/hooks/enforce-plan-rules.sh +0 -15
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +0 -183
- package/all/copy-overwrite/.claude/hooks/setup-jira-cli.sh +0 -52
- package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +0 -107
- package/all/copy-overwrite/.claude/hooks/ticket-sync-reminder.sh +0 -23
- package/all/copy-overwrite/.claude/hooks/track-plan-sessions.sh +0 -164
- package/all/copy-overwrite/.claude/hooks/verify-completion.sh +0 -77
- package/all/copy-overwrite/.claude/rules/coding-philosophy.md +0 -428
- package/all/copy-overwrite/.claude/rules/verfication.md +0 -596
- package/all/copy-overwrite/.claude/skills/agent-design-best-practices/SKILL.md +0 -219
- package/all/copy-overwrite/.claude/skills/git-commit/SKILL.md +0 -48
- package/all/copy-overwrite/.claude/skills/git-commit-and-submit-pr/SKILL.md +0 -8
- package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-and-verify/SKILL.md +0 -7
- package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-deploy-and-verify/SKILL.md +0 -7
- package/all/copy-overwrite/.claude/skills/git-prune/SKILL.md +0 -35
- package/all/copy-overwrite/.claude/skills/git-submit-pr/SKILL.md +0 -44
- package/all/copy-overwrite/.claude/skills/jira-create/SKILL.md +0 -41
- package/all/copy-overwrite/.claude/skills/jira-sync/SKILL.md +0 -63
- package/all/copy-overwrite/.claude/skills/jira-verify/SKILL.md +0 -29
- package/all/copy-overwrite/.claude/skills/lisa-review-implementation/SKILL.md +0 -209
- package/all/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -44
- package/all/copy-overwrite/.claude/skills/plan-execute/SKILL.md +0 -89
- package/all/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
- package/all/copy-overwrite/.claude/skills/plan-local-code-review/SKILL.md +0 -88
- package/all/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -44
- package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -45
- package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
- package/all/copy-overwrite/.claude/skills/pull-request-review/SKILL.md +0 -68
- package/all/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
- package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +0 -202
- package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +0 -210
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +0 -305
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +0 -112
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +0 -67
- package/all/copy-overwrite/.claude/skills/sonarqube-check/SKILL.md +0 -11
- package/all/copy-overwrite/.claude/skills/sonarqube-fix/SKILL.md +0 -8
- package/all/copy-overwrite/.claude/skills/tasks-load/SKILL.md +0 -88
- package/all/copy-overwrite/.claude/skills/tasks-sync/SKILL.md +0 -108
- package/eslint-plugin-code-organization/README.md +0 -149
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
- package/eslint-plugin-code-organization/index.js +0 -28
- package/eslint-plugin-code-organization/package.json +0 -10
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
- package/expo/copy-overwrite/.claude/agents/ops-specialist.md +0 -124
- package/expo/copy-overwrite/.claude/rules/expo-verification.md +0 -261
- package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +0 -238
- package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +0 -360
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +0 -360
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +0 -417
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +0 -257
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +0 -233
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +0 -329
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +0 -299
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +0 -749
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +0 -318
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +0 -200
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +0 -209
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +0 -268
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +0 -619
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +0 -340
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +0 -276
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +0 -416
- package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +0 -202
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +0 -445
- package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +0 -309
- package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +0 -417
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +0 -431
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +0 -290
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +0 -171
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +0 -411
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +0 -343
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +0 -307
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +0 -300
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +0 -315
- package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +0 -362
- package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +0 -505
- package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +0 -711
- package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +0 -446
- package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +0 -124
- package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +0 -211
- package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +0 -119
- package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +0 -119
- package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +0 -99
- package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +0 -165
- package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +0 -166
- package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +0 -101
- package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +0 -56
- package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +0 -223
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +0 -314
- package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +0 -420
- package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +0 -556
- package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +0 -590
- package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +0 -291
- package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +0 -234
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +0 -89
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +0 -201
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +0 -294
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +0 -37
- package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +0 -10
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +0 -235
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +0 -96
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +0 -183
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +0 -243
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -192
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +0 -31
- package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +0 -10
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +0 -56
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +0 -60
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +0 -176
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +0 -527
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +0 -483
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +0 -257
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +0 -413
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +0 -513
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +0 -536
- package/nestjs/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +0 -275
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +0 -487
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +0 -450
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +0 -536
- package/rails/copy-overwrite/.claude/skills/action-controller-best-practices/SKILL.md +0 -374
- package/rails/copy-overwrite/.claude/skills/action-view-best-practices/SKILL.md +0 -335
- package/rails/copy-overwrite/.claude/skills/active-record-model-best-practices/SKILL.md +0 -166
- package/rails/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -45
- package/rails/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
- package/rails/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -48
- package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -46
- package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +0 -76
- package/typescript/copy-overwrite/.claude/hooks/install-pkgs.sh +0 -64
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +0 -81
- package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +0 -68
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +0 -432
- package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +0 -149
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +0 -28
- package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +0 -10
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
# Types and Scalars
|
|
2
|
-
|
|
3
|
-
Guide to defining GraphQL types, scalars, enums, interfaces, and unions in NestJS.
|
|
4
|
-
|
|
5
|
-
## Object Types
|
|
6
|
-
|
|
7
|
-
### Basic Object Type
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import { Field, ID, ObjectType } from "@nestjs/graphql";
|
|
11
|
-
|
|
12
|
-
@ObjectType({ description: "A user account in the system" })
|
|
13
|
-
export class User {
|
|
14
|
-
@Field(() => ID, { description: "Unique identifier" })
|
|
15
|
-
id: string;
|
|
16
|
-
|
|
17
|
-
@Field(() => String, { description: "Email address" })
|
|
18
|
-
email: string;
|
|
19
|
-
|
|
20
|
-
@Field(() => String, { nullable: true, description: "Display name" })
|
|
21
|
-
displayName?: string;
|
|
22
|
-
|
|
23
|
-
@Field(() => Boolean, { description: "Whether email is verified" })
|
|
24
|
-
isVerified: boolean;
|
|
25
|
-
|
|
26
|
-
@Field(() => Date, { description: "Account creation date" })
|
|
27
|
-
createdAt: Date;
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### Object Type with Relations
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
@ObjectType({ description: "A blog post" })
|
|
35
|
-
export class Post {
|
|
36
|
-
@Field(() => ID)
|
|
37
|
-
id: string;
|
|
38
|
-
|
|
39
|
-
@Field(() => String)
|
|
40
|
-
title: string;
|
|
41
|
-
|
|
42
|
-
@Field(() => User, { description: "Post author" })
|
|
43
|
-
author: User;
|
|
44
|
-
|
|
45
|
-
@Field(() => [Comment], { description: "Post comments" })
|
|
46
|
-
comments: Comment[];
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Input Types
|
|
51
|
-
|
|
52
|
-
### Basic Input Type
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { Field, InputType } from "@nestjs/graphql";
|
|
56
|
-
|
|
57
|
-
@InputType({ description: "Input for creating a user" })
|
|
58
|
-
export class CreateUserInput {
|
|
59
|
-
@Field(() => String, { description: "User's email" })
|
|
60
|
-
email: string;
|
|
61
|
-
|
|
62
|
-
@Field(() => String, { description: "User's password" })
|
|
63
|
-
password: string;
|
|
64
|
-
|
|
65
|
-
@Field(() => String, { nullable: true, description: "Optional display name" })
|
|
66
|
-
displayName?: string;
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Update Input Type
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
@InputType({ description: "Input for updating a user" })
|
|
74
|
-
export class UpdateUserInput {
|
|
75
|
-
@Field(() => String, { nullable: true })
|
|
76
|
-
displayName?: string;
|
|
77
|
-
|
|
78
|
-
@Field(() => String, { nullable: true })
|
|
79
|
-
avatarUrl?: string;
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Mapped Types
|
|
84
|
-
|
|
85
|
-
NestJS provides utility functions to create derived types from existing ones.
|
|
86
|
-
|
|
87
|
-
### PartialType
|
|
88
|
-
|
|
89
|
-
Makes all fields optional:
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
92
|
-
import { PartialType } from "@nestjs/graphql";
|
|
93
|
-
|
|
94
|
-
@InputType()
|
|
95
|
-
export class UpdateUserInput extends PartialType(CreateUserInput) {}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### PickType
|
|
99
|
-
|
|
100
|
-
Select specific fields:
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
import { PickType } from "@nestjs/graphql";
|
|
104
|
-
|
|
105
|
-
@InputType()
|
|
106
|
-
export class UpdateEmailInput extends PickType(CreateUserInput, ["email"] as const) {}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### OmitType
|
|
110
|
-
|
|
111
|
-
Exclude specific fields:
|
|
112
|
-
|
|
113
|
-
```typescript
|
|
114
|
-
import { OmitType } from "@nestjs/graphql";
|
|
115
|
-
|
|
116
|
-
@InputType()
|
|
117
|
-
export class UpdateUserInput extends OmitType(CreateUserInput, ["password"] as const) {}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### IntersectionType
|
|
121
|
-
|
|
122
|
-
Combine multiple types:
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
import { IntersectionType } from "@nestjs/graphql";
|
|
126
|
-
|
|
127
|
-
@InputType()
|
|
128
|
-
export class CreateUserWithPrefsInput extends IntersectionType(
|
|
129
|
-
CreateUserInput,
|
|
130
|
-
UserPreferencesInput
|
|
131
|
-
) {}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Composition
|
|
135
|
-
|
|
136
|
-
Combine multiple utilities:
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
@InputType()
|
|
140
|
-
export class UpdateUserInput extends PartialType(
|
|
141
|
-
OmitType(CreateUserInput, ["password"] as const)
|
|
142
|
-
) {}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Enums
|
|
146
|
-
|
|
147
|
-
### Defining Enums
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { registerEnumType } from "@nestjs/graphql";
|
|
151
|
-
|
|
152
|
-
export enum UserRole {
|
|
153
|
-
ADMIN = "ADMIN",
|
|
154
|
-
MODERATOR = "MODERATOR",
|
|
155
|
-
USER = "USER",
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
registerEnumType(UserRole, {
|
|
159
|
-
name: "UserRole",
|
|
160
|
-
description: "Available user roles in the system",
|
|
161
|
-
valuesMap: {
|
|
162
|
-
ADMIN: { description: "Full system access" },
|
|
163
|
-
MODERATOR: { description: "Content moderation access" },
|
|
164
|
-
USER: { description: "Standard user access" },
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Using Enums in Types
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
@ObjectType()
|
|
173
|
-
export class User {
|
|
174
|
-
@Field(() => UserRole, { description: "User's role" })
|
|
175
|
-
role: UserRole;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
@InputType()
|
|
179
|
-
export class CreateUserInput {
|
|
180
|
-
@Field(() => UserRole, { defaultValue: UserRole.USER })
|
|
181
|
-
role: UserRole;
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Interfaces
|
|
186
|
-
|
|
187
|
-
### Defining Interfaces
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
import { Field, ID, InterfaceType } from "@nestjs/graphql";
|
|
191
|
-
|
|
192
|
-
@InterfaceType({ description: "Base interface for all nodes" })
|
|
193
|
-
export abstract class Node {
|
|
194
|
-
@Field(() => ID)
|
|
195
|
-
id: string;
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Implementing Interfaces
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
@ObjectType({ implements: () => [Node] })
|
|
203
|
-
export class User extends Node {
|
|
204
|
-
@Field(() => String)
|
|
205
|
-
email: string;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
@ObjectType({ implements: () => [Node] })
|
|
209
|
-
export class Post extends Node {
|
|
210
|
-
@Field(() => String)
|
|
211
|
-
title: string;
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Resolving Interface Types
|
|
216
|
-
|
|
217
|
-
```typescript
|
|
218
|
-
@InterfaceType({
|
|
219
|
-
resolveType: (value) => {
|
|
220
|
-
if ("email" in value) return User;
|
|
221
|
-
if ("title" in value) return Post;
|
|
222
|
-
return null;
|
|
223
|
-
},
|
|
224
|
-
})
|
|
225
|
-
export abstract class Node {
|
|
226
|
-
@Field(() => ID)
|
|
227
|
-
id: string;
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
## Unions
|
|
232
|
-
|
|
233
|
-
### Defining Unions
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
import { createUnionType } from "@nestjs/graphql";
|
|
237
|
-
|
|
238
|
-
export const SearchResult = createUnionType({
|
|
239
|
-
name: "SearchResult",
|
|
240
|
-
description: "Possible search result types",
|
|
241
|
-
types: () => [User, Post, Comment] as const,
|
|
242
|
-
resolveType: (value) => {
|
|
243
|
-
if ("email" in value) return User;
|
|
244
|
-
if ("title" in value) return Post;
|
|
245
|
-
if ("body" in value) return Comment;
|
|
246
|
-
return null;
|
|
247
|
-
},
|
|
248
|
-
});
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### Using Unions
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
@Query(() => [SearchResult], { description: "Search across all content" })
|
|
255
|
-
async search(@Args("query") query: string): Promise<typeof SearchResult[]> {
|
|
256
|
-
const users = await this.userService.search(query);
|
|
257
|
-
const posts = await this.postService.search(query);
|
|
258
|
-
return [...users, ...posts];
|
|
259
|
-
}
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
## Custom Scalars
|
|
263
|
-
|
|
264
|
-
### Built-in Scalars
|
|
265
|
-
|
|
266
|
-
NestJS/GraphQL includes these scalars by default:
|
|
267
|
-
- `ID` - Unique identifier
|
|
268
|
-
- `String` - UTF-8 string
|
|
269
|
-
- `Boolean` - true/false
|
|
270
|
-
- `Int` - 32-bit integer
|
|
271
|
-
- `Float` - Double-precision float
|
|
272
|
-
|
|
273
|
-
### Date Scalar
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
import { Scalar, CustomScalar } from "@nestjs/graphql";
|
|
277
|
-
import { Kind, ValueNode } from "graphql";
|
|
278
|
-
|
|
279
|
-
@Scalar("Date", () => Date)
|
|
280
|
-
export class DateScalar implements CustomScalar<number, Date> {
|
|
281
|
-
description = "Date custom scalar type";
|
|
282
|
-
|
|
283
|
-
parseValue(value: number): Date {
|
|
284
|
-
return new Date(value);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
serialize(value: Date): number {
|
|
288
|
-
return value.getTime();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
parseLiteral(ast: ValueNode): Date {
|
|
292
|
-
if (ast.kind === Kind.INT) {
|
|
293
|
-
return new Date(parseInt(ast.value, 10));
|
|
294
|
-
}
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### JSON Scalar
|
|
301
|
-
|
|
302
|
-
```typescript
|
|
303
|
-
import { Scalar, CustomScalar } from "@nestjs/graphql";
|
|
304
|
-
import { Kind, ValueNode } from "graphql";
|
|
305
|
-
|
|
306
|
-
@Scalar("JSON")
|
|
307
|
-
export class JSONScalar implements CustomScalar<string, object> {
|
|
308
|
-
description = "JSON custom scalar type";
|
|
309
|
-
|
|
310
|
-
parseValue(value: string): object {
|
|
311
|
-
return JSON.parse(value);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
serialize(value: object): string {
|
|
315
|
-
return JSON.stringify(value);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
parseLiteral(ast: ValueNode): object {
|
|
319
|
-
if (ast.kind === Kind.STRING) {
|
|
320
|
-
return JSON.parse(ast.value);
|
|
321
|
-
}
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### Registering Scalars
|
|
328
|
-
|
|
329
|
-
```typescript
|
|
330
|
-
@Module({
|
|
331
|
-
providers: [DateScalar, JSONScalar],
|
|
332
|
-
})
|
|
333
|
-
export class CommonModule {}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### Using graphql-scalars Library
|
|
337
|
-
|
|
338
|
-
```typescript
|
|
339
|
-
import { GraphQLDateTime, GraphQLJSON } from "graphql-scalars";
|
|
340
|
-
|
|
341
|
-
GraphQLModule.forRoot<ApolloDriverConfig>({
|
|
342
|
-
resolvers: {
|
|
343
|
-
DateTime: GraphQLDateTime,
|
|
344
|
-
JSON: GraphQLJSON,
|
|
345
|
-
},
|
|
346
|
-
})
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## Field Options
|
|
350
|
-
|
|
351
|
-
### Common Field Options
|
|
352
|
-
|
|
353
|
-
```typescript
|
|
354
|
-
@Field(() => String, {
|
|
355
|
-
// Description shown in schema
|
|
356
|
-
description: "User's email address",
|
|
357
|
-
|
|
358
|
-
// Allow null values
|
|
359
|
-
nullable: true,
|
|
360
|
-
|
|
361
|
-
// Deprecation notice
|
|
362
|
-
deprecationReason: "Use `primaryEmail` instead",
|
|
363
|
-
|
|
364
|
-
// Query complexity cost
|
|
365
|
-
complexity: 1,
|
|
366
|
-
|
|
367
|
-
// Default value for input fields
|
|
368
|
-
defaultValue: "default",
|
|
369
|
-
|
|
370
|
-
// Custom name in schema
|
|
371
|
-
name: "emailAddress",
|
|
372
|
-
})
|
|
373
|
-
email: string;
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
### Array Fields
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
// Non-nullable array with non-nullable items: [String!]!
|
|
380
|
-
@Field(() => [String])
|
|
381
|
-
tags: string[];
|
|
382
|
-
|
|
383
|
-
// Nullable array items: [String]!
|
|
384
|
-
@Field(() => [String], { nullable: "items" })
|
|
385
|
-
tags: (string | null)[];
|
|
386
|
-
|
|
387
|
-
// Nullable array: [String!]
|
|
388
|
-
@Field(() => [String], { nullable: true })
|
|
389
|
-
tags?: string[];
|
|
390
|
-
|
|
391
|
-
// Both nullable: [String]
|
|
392
|
-
@Field(() => [String], { nullable: "itemsAndList" })
|
|
393
|
-
tags?: (string | null)[] | null;
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
## Type Composition Patterns
|
|
397
|
-
|
|
398
|
-
### Base Entity Type
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
@ObjectType({ isAbstract: true })
|
|
402
|
-
export abstract class BaseEntity {
|
|
403
|
-
@Field(() => ID)
|
|
404
|
-
id: string;
|
|
405
|
-
|
|
406
|
-
@Field(() => Date)
|
|
407
|
-
createdAt: Date;
|
|
408
|
-
|
|
409
|
-
@Field(() => Date)
|
|
410
|
-
updatedAt: Date;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
@ObjectType()
|
|
414
|
-
export class User extends BaseEntity {
|
|
415
|
-
@Field()
|
|
416
|
-
email: string;
|
|
417
|
-
}
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
### Pagination Types
|
|
421
|
-
|
|
422
|
-
```typescript
|
|
423
|
-
@ObjectType()
|
|
424
|
-
export class PageInfo {
|
|
425
|
-
@Field(() => Boolean)
|
|
426
|
-
hasNextPage: boolean;
|
|
427
|
-
|
|
428
|
-
@Field(() => Boolean)
|
|
429
|
-
hasPreviousPage: boolean;
|
|
430
|
-
|
|
431
|
-
@Field(() => String, { nullable: true })
|
|
432
|
-
startCursor?: string;
|
|
433
|
-
|
|
434
|
-
@Field(() => String, { nullable: true })
|
|
435
|
-
endCursor?: string;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
@ObjectType()
|
|
439
|
-
export class UserEdge {
|
|
440
|
-
@Field(() => User)
|
|
441
|
-
node: User;
|
|
442
|
-
|
|
443
|
-
@Field(() => String)
|
|
444
|
-
cursor: string;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
@ObjectType()
|
|
448
|
-
export class UserConnection {
|
|
449
|
-
@Field(() => [UserEdge])
|
|
450
|
-
edges: UserEdge[];
|
|
451
|
-
|
|
452
|
-
@Field(() => PageInfo)
|
|
453
|
-
pageInfo: PageInfo;
|
|
454
|
-
|
|
455
|
-
@Field(() => Int)
|
|
456
|
-
totalCount: number;
|
|
457
|
-
}
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
## Best Practices
|
|
461
|
-
|
|
462
|
-
### 1. Always Add Descriptions
|
|
463
|
-
|
|
464
|
-
Every type, field, and enum value should have a description:
|
|
465
|
-
|
|
466
|
-
```typescript
|
|
467
|
-
@ObjectType({ description: "A user account in the system" })
|
|
468
|
-
export class User {
|
|
469
|
-
@Field(() => ID, { description: "Unique identifier (UUID v4)" })
|
|
470
|
-
id: string;
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### 2. Use Explicit Types
|
|
475
|
-
|
|
476
|
-
Always specify the GraphQL type explicitly:
|
|
477
|
-
|
|
478
|
-
```typescript
|
|
479
|
-
// Good
|
|
480
|
-
@Field(() => Int)
|
|
481
|
-
age: number;
|
|
482
|
-
|
|
483
|
-
// Bad - GraphQL can't infer Int vs Float
|
|
484
|
-
@Field()
|
|
485
|
-
age: number;
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
### 3. Separate Input and Output Types
|
|
489
|
-
|
|
490
|
-
Don't reuse ObjectTypes as InputTypes:
|
|
491
|
-
|
|
492
|
-
```typescript
|
|
493
|
-
// Good
|
|
494
|
-
@ObjectType()
|
|
495
|
-
export class User { }
|
|
496
|
-
|
|
497
|
-
@InputType()
|
|
498
|
-
export class CreateUserInput { }
|
|
499
|
-
|
|
500
|
-
// Bad
|
|
501
|
-
@ObjectType()
|
|
502
|
-
@InputType("UserInput")
|
|
503
|
-
export class User { }
|
|
504
|
-
```
|
|
505
|
-
|
|
506
|
-
### 4. Use Mapped Types for Updates
|
|
507
|
-
|
|
508
|
-
```typescript
|
|
509
|
-
@InputType()
|
|
510
|
-
export class UpdateUserInput extends PartialType(
|
|
511
|
-
OmitType(CreateUserInput, ["password"])
|
|
512
|
-
) {}
|
|
513
|
-
```
|