@codyswann/lisa 1.0.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/LICENSE +21 -0
- package/README.md +867 -0
- package/all/copy-overwrite/.claude/README.md +205 -0
- package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
- package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
- package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
- package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
- package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
- package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
- package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
- package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
- package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
- package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
- package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
- package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
- package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
- package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
- package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
- package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
- package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
- package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
- package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
- package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
- package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
- package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
- package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
- package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
- package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
- package/all/copy-overwrite/.claude/hooks/README.md +301 -0
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
- package/all/copy-overwrite/.claude/settings.json +41 -0
- package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
- package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
- 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 +303 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/all/copy-overwrite/CLAUDE.md +77 -0
- package/all/copy-overwrite/HUMAN.md +17 -0
- package/all/copy-overwrite/specs/.keep +0 -0
- package/all/create-only/PROJECT_RULES.md +0 -0
- package/cdk/merge/package.json +20 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +107 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +45 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +58 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/config.d.ts +73 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +36 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lisa.d.ts +81 -0
- package/dist/core/lisa.d.ts.map +1 -0
- package/dist/core/lisa.js +459 -0
- package/dist/core/lisa.js.map +1 -0
- package/dist/core/manifest.d.ts +58 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +104 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/detection/detector.interface.d.ts +15 -0
- package/dist/detection/detector.interface.d.ts.map +1 -0
- package/dist/detection/detector.interface.js +2 -0
- package/dist/detection/detector.interface.js.map +1 -0
- package/dist/detection/detectors/cdk.d.ts +10 -0
- package/dist/detection/detectors/cdk.d.ts.map +1 -0
- package/dist/detection/detectors/cdk.js +34 -0
- package/dist/detection/detectors/cdk.js.map +1 -0
- package/dist/detection/detectors/expo.d.ts +10 -0
- package/dist/detection/detectors/expo.d.ts.map +1 -0
- package/dist/detection/detectors/expo.js +30 -0
- package/dist/detection/detectors/expo.js.map +1 -0
- package/dist/detection/detectors/nestjs.d.ts +10 -0
- package/dist/detection/detectors/nestjs.d.ts.map +1 -0
- package/dist/detection/detectors/nestjs.js +34 -0
- package/dist/detection/detectors/nestjs.js.map +1 -0
- package/dist/detection/detectors/npm-package.d.ts +13 -0
- package/dist/detection/detectors/npm-package.d.ts.map +1 -0
- package/dist/detection/detectors/npm-package.js +30 -0
- package/dist/detection/detectors/npm-package.js.map +1 -0
- package/dist/detection/detectors/typescript.d.ts +10 -0
- package/dist/detection/detectors/typescript.d.ts.map +1 -0
- package/dist/detection/detectors/typescript.js +25 -0
- package/dist/detection/detectors/typescript.js.map +1 -0
- package/dist/detection/index.d.ts +24 -0
- package/dist/detection/index.d.ts.map +1 -0
- package/dist/detection/index.js +57 -0
- package/dist/detection/index.js.map +1 -0
- package/dist/errors/index.d.ts +69 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +110 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/console-logger.d.ts +12 -0
- package/dist/logging/console-logger.d.ts.map +1 -0
- package/dist/logging/console-logger.js +22 -0
- package/dist/logging/console-logger.js.map +1 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.interface.d.ts +20 -0
- package/dist/logging/logger.interface.d.ts.map +1 -0
- package/dist/logging/logger.interface.js +2 -0
- package/dist/logging/logger.interface.js.map +1 -0
- package/dist/logging/silent-logger.d.ts +12 -0
- package/dist/logging/silent-logger.d.ts.map +1 -0
- package/dist/logging/silent-logger.js +21 -0
- package/dist/logging/silent-logger.js.map +1 -0
- package/dist/strategies/copy-contents.d.ts +14 -0
- package/dist/strategies/copy-contents.d.ts.map +1 -0
- package/dist/strategies/copy-contents.js +69 -0
- package/dist/strategies/copy-contents.js.map +1 -0
- package/dist/strategies/copy-overwrite.d.ts +14 -0
- package/dist/strategies/copy-overwrite.d.ts.map +1 -0
- package/dist/strategies/copy-overwrite.js +47 -0
- package/dist/strategies/copy-overwrite.js.map +1 -0
- package/dist/strategies/create-only.d.ts +13 -0
- package/dist/strategies/create-only.d.ts.map +1 -0
- package/dist/strategies/create-only.js +30 -0
- package/dist/strategies/create-only.js.map +1 -0
- package/dist/strategies/index.d.ts +31 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +52 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/merge.d.ts +13 -0
- package/dist/strategies/merge.d.ts.map +1 -0
- package/dist/strategies/merge.js +60 -0
- package/dist/strategies/merge.js.map +1 -0
- package/dist/strategies/strategy.interface.d.ts +31 -0
- package/dist/strategies/strategy.interface.d.ts.map +1 -0
- package/dist/strategies/strategy.interface.js +2 -0
- package/dist/strategies/strategy.interface.js.map +1 -0
- package/dist/transaction/backup.d.ts +38 -0
- package/dist/transaction/backup.d.ts.map +1 -0
- package/dist/transaction/backup.js +97 -0
- package/dist/transaction/backup.js.map +1 -0
- package/dist/transaction/index.d.ts +4 -0
- package/dist/transaction/index.d.ts.map +1 -0
- package/dist/transaction/index.js +3 -0
- package/dist/transaction/index.js.map +1 -0
- package/dist/transaction/transaction.d.ts +34 -0
- package/dist/transaction/transaction.d.ts.map +1 -0
- package/dist/transaction/transaction.js +68 -0
- package/dist/transaction/transaction.js.map +1 -0
- package/dist/utils/file-operations.d.ts +29 -0
- package/dist/utils/file-operations.d.ts.map +1 -0
- package/dist/utils/file-operations.js +84 -0
- package/dist/utils/file-operations.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json-utils.d.ts +22 -0
- package/dist/utils/json-utils.d.ts.map +1 -0
- package/dist/utils/json-utils.js +57 -0
- package/dist/utils/json-utils.js.map +1 -0
- package/dist/utils/path-utils.d.ts +21 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +35 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/eslint-plugin-code-organization/README.md +149 -0
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/eslint-plugin-code-organization/index.js +23 -0
- package/eslint-plugin-code-organization/package.json +10 -0
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
- package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
- package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
- package/expo/copy-overwrite/.easignore.extra +2 -0
- package/expo/copy-overwrite/.mcp.json +33 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
- package/expo/copy-overwrite/eslint.config.mjs +560 -0
- package/expo/copy-overwrite/lighthouserc.js +194 -0
- package/expo/create-only/lighthouserc-config.json +28 -0
- package/expo/merge/package.json +132 -0
- package/lisa.sh +35 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- package/nestjs/merge/package.json +75 -0
- package/package.json +124 -0
- package/typescript/copy-contents/.husky/commit-msg +91 -0
- package/typescript/copy-contents/.husky/pre-commit +96 -0
- package/typescript/copy-contents/.husky/pre-push +211 -0
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
- package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
- package/typescript/copy-overwrite/.github/README.md +455 -0
- package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
- package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
- package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
- package/typescript/copy-overwrite/.github/k6/README.md +386 -0
- package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
- package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
- package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
- package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
- package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
- package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
- package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
- package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
- package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
- package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
- package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
- package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
- package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
- package/typescript/copy-overwrite/.gitleaksignore +28 -0
- package/typescript/copy-overwrite/.nvmrc +1 -0
- package/typescript/copy-overwrite/.prettierignore +23 -0
- package/typescript/copy-overwrite/.prettierrc.json +22 -0
- package/typescript/copy-overwrite/.versionrc +42 -0
- package/typescript/copy-overwrite/.yamllint +20 -0
- package/typescript/copy-overwrite/commitlint.config.js +11 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/typescript/copy-overwrite/eslint.config.mjs +390 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
- package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
- package/typescript/github-rulesets/base.json +106 -0
- package/typescript/merge/.claude/settings.json +28 -0
- package/typescript/merge/package.json +71 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lighthouse CI Configuration
|
|
3
|
+
*
|
|
4
|
+
* This configuration file defines performance budgets and assertion rules for
|
|
5
|
+
* Lighthouse CI to monitor and enforce web performance standards in CI/CD pipelines.
|
|
6
|
+
*
|
|
7
|
+
* ## Configuration Approach
|
|
8
|
+
*
|
|
9
|
+
* Uses assertions (not budget.json) for:
|
|
10
|
+
* - More comprehensive checks available
|
|
11
|
+
* - Better CI integration and error reporting
|
|
12
|
+
* - Ability to combine preset with custom assertions
|
|
13
|
+
* - Note: Cannot use both budget.json and assertions together
|
|
14
|
+
*
|
|
15
|
+
* ## Project-Specific Configuration
|
|
16
|
+
*
|
|
17
|
+
* Thresholds are loaded from `lighthouserc-config.json`. To customize for your
|
|
18
|
+
* project, edit that file. This JS file can be copied between projects unchanged.
|
|
19
|
+
*
|
|
20
|
+
* ## Threshold Strategy
|
|
21
|
+
*
|
|
22
|
+
* Thresholds are set to be realistic for Expo web apps while preventing
|
|
23
|
+
* significant regressions. CI environments have higher variance than local.
|
|
24
|
+
*
|
|
25
|
+
* Known issues that remain as "warn" (non-blocking):
|
|
26
|
+
* - errors-in-console: Missing favicon.ico causes 404
|
|
27
|
+
* - image-aspect-ratio: Some images have incorrect sizing
|
|
28
|
+
* - meta-description: Not a priority for mobile-first app
|
|
29
|
+
* - max-potential-fid: High variance in CI environments
|
|
30
|
+
* - largest-contentful-paint: Expo apps struggle to meet Core Web Vital threshold
|
|
31
|
+
*
|
|
32
|
+
* @see {@link https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/configuration.md|Lighthouse CI Configuration}
|
|
33
|
+
* @see {@link https://web.dev/vitals/|Core Web Vitals}
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
const fs = require("fs");
|
|
37
|
+
const path = require("path");
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Default configuration values.
|
|
41
|
+
* These are used when lighthouserc-config.json doesn't specify a value.
|
|
42
|
+
*/
|
|
43
|
+
const defaults = {
|
|
44
|
+
collect: {
|
|
45
|
+
staticDistDir: "./dist",
|
|
46
|
+
numberOfRuns: 5,
|
|
47
|
+
},
|
|
48
|
+
assertions: {
|
|
49
|
+
buttonName: { minScore: 0.9 },
|
|
50
|
+
validSourceMaps: { minScore: 0.9 },
|
|
51
|
+
errorsInConsole: { minScore: 1 },
|
|
52
|
+
performance: { minScore: 0.55 },
|
|
53
|
+
firstContentfulPaint: { maxNumericValue: 1500 },
|
|
54
|
+
largestContentfulPaint: { maxNumericValue: 4000 },
|
|
55
|
+
interactive: { maxNumericValue: 6000 },
|
|
56
|
+
cumulativeLayoutShift: { maxNumericValue: 0.1 },
|
|
57
|
+
totalByteWeight: { maxNumericValue: 850000 },
|
|
58
|
+
scriptSize: { maxNumericValue: 750000 },
|
|
59
|
+
fontDisplay: { minScore: 0.9 },
|
|
60
|
+
imageAspectRatio: { minScore: 1 },
|
|
61
|
+
metaDescription: { minScore: 1 },
|
|
62
|
+
unusedJavascript: { maxLength: 2 },
|
|
63
|
+
bootupTime: { minScore: 0.9 },
|
|
64
|
+
mainthreadWorkBreakdown: { minScore: 0.9 },
|
|
65
|
+
maxPotentialFid: { minScore: 1 },
|
|
66
|
+
legacyJavascript: { maxLength: 2 },
|
|
67
|
+
legacyJavascriptInsight: { minScore: 0.4 },
|
|
68
|
+
speedIndex: { minScore: 0.9 },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Load and merge project-specific configuration from lighthouserc-config.json.
|
|
74
|
+
*
|
|
75
|
+
* @returns {object} Merged configuration with defaults
|
|
76
|
+
*/
|
|
77
|
+
function loadConfig() {
|
|
78
|
+
const configPath = path.join(__dirname, "lighthouserc-config.json");
|
|
79
|
+
|
|
80
|
+
if (!fs.existsSync(configPath)) {
|
|
81
|
+
return defaults;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const projectConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
collect: { ...defaults.collect, ...projectConfig.collect },
|
|
88
|
+
assertions: {
|
|
89
|
+
...defaults.assertions,
|
|
90
|
+
...Object.fromEntries(
|
|
91
|
+
Object.entries(projectConfig.assertions || {}).map(([key, value]) => [
|
|
92
|
+
key,
|
|
93
|
+
{ ...defaults.assertions[key], ...value },
|
|
94
|
+
])
|
|
95
|
+
),
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const config = loadConfig();
|
|
101
|
+
const { collect, assertions: a } = config;
|
|
102
|
+
|
|
103
|
+
module.exports = {
|
|
104
|
+
ci: {
|
|
105
|
+
collect: {
|
|
106
|
+
staticDistDir: collect.staticDistDir,
|
|
107
|
+
numberOfRuns: collect.numberOfRuns,
|
|
108
|
+
chromePath: process.env.CHROME_PATH || undefined,
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
assert: {
|
|
112
|
+
preset: "lighthouse:recommended",
|
|
113
|
+
|
|
114
|
+
assertions: {
|
|
115
|
+
// Accessibility
|
|
116
|
+
"button-name": ["error", { minScore: a.buttonName.minScore }],
|
|
117
|
+
"valid-source-maps": [
|
|
118
|
+
"error",
|
|
119
|
+
{ minScore: a.validSourceMaps.minScore },
|
|
120
|
+
],
|
|
121
|
+
"errors-in-console": ["warn", { minScore: a.errorsInConsole.minScore }],
|
|
122
|
+
|
|
123
|
+
// Performance Score
|
|
124
|
+
"categories:performance": [
|
|
125
|
+
"error",
|
|
126
|
+
{ minScore: a.performance.minScore, aggregationMethod: "median" },
|
|
127
|
+
],
|
|
128
|
+
|
|
129
|
+
// Core Web Vitals - Timing Metrics
|
|
130
|
+
"first-contentful-paint": [
|
|
131
|
+
"error",
|
|
132
|
+
{ maxNumericValue: a.firstContentfulPaint.maxNumericValue },
|
|
133
|
+
],
|
|
134
|
+
"largest-contentful-paint": [
|
|
135
|
+
"warn",
|
|
136
|
+
{ maxNumericValue: a.largestContentfulPaint.maxNumericValue },
|
|
137
|
+
],
|
|
138
|
+
interactive: [
|
|
139
|
+
"error",
|
|
140
|
+
{ maxNumericValue: a.interactive.maxNumericValue },
|
|
141
|
+
],
|
|
142
|
+
"cumulative-layout-shift": [
|
|
143
|
+
"error",
|
|
144
|
+
{ maxNumericValue: a.cumulativeLayoutShift.maxNumericValue },
|
|
145
|
+
],
|
|
146
|
+
|
|
147
|
+
// Resource Budgets
|
|
148
|
+
"total-byte-weight": [
|
|
149
|
+
"error",
|
|
150
|
+
{ maxNumericValue: a.totalByteWeight.maxNumericValue },
|
|
151
|
+
],
|
|
152
|
+
"resource-summary:script:size": [
|
|
153
|
+
"error",
|
|
154
|
+
{ maxNumericValue: a.scriptSize.maxNumericValue },
|
|
155
|
+
],
|
|
156
|
+
|
|
157
|
+
// Best Practices
|
|
158
|
+
"font-display": ["error", { minScore: a.fontDisplay.minScore }],
|
|
159
|
+
"image-aspect-ratio": [
|
|
160
|
+
"warn",
|
|
161
|
+
{ minScore: a.imageAspectRatio.minScore },
|
|
162
|
+
],
|
|
163
|
+
|
|
164
|
+
// SEO
|
|
165
|
+
"meta-description": ["warn", { minScore: a.metaDescription.minScore }],
|
|
166
|
+
|
|
167
|
+
// Performance Insights
|
|
168
|
+
"unused-javascript": [
|
|
169
|
+
"error",
|
|
170
|
+
{ maxLength: a.unusedJavascript.maxLength },
|
|
171
|
+
],
|
|
172
|
+
"bootup-time": ["error", { minScore: a.bootupTime.minScore }],
|
|
173
|
+
"mainthread-work-breakdown": [
|
|
174
|
+
"error",
|
|
175
|
+
{ minScore: a.mainthreadWorkBreakdown.minScore },
|
|
176
|
+
],
|
|
177
|
+
"max-potential-fid": ["warn", { minScore: a.maxPotentialFid.minScore }],
|
|
178
|
+
"legacy-javascript": [
|
|
179
|
+
"error",
|
|
180
|
+
{ maxLength: a.legacyJavascript.maxLength },
|
|
181
|
+
],
|
|
182
|
+
"legacy-javascript-insight": [
|
|
183
|
+
"warn",
|
|
184
|
+
{ minScore: a.legacyJavascriptInsight.minScore },
|
|
185
|
+
],
|
|
186
|
+
"speed-index": ["error", { minScore: a.speedIndex.minScore }],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
upload: {
|
|
191
|
+
target: "temporary-public-storage",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"collect": {
|
|
3
|
+
"staticDistDir": "./dist",
|
|
4
|
+
"numberOfRuns": 5
|
|
5
|
+
},
|
|
6
|
+
"assertions": {
|
|
7
|
+
"buttonName": { "minScore": 0.9 },
|
|
8
|
+
"validSourceMaps": { "minScore": 0.9 },
|
|
9
|
+
"errorsInConsole": { "minScore": 1 },
|
|
10
|
+
"performance": { "minScore": 0.55 },
|
|
11
|
+
"firstContentfulPaint": { "maxNumericValue": 1500 },
|
|
12
|
+
"largestContentfulPaint": { "maxNumericValue": 4000 },
|
|
13
|
+
"interactive": { "maxNumericValue": 6000 },
|
|
14
|
+
"cumulativeLayoutShift": { "maxNumericValue": 0.1 },
|
|
15
|
+
"totalByteWeight": { "maxNumericValue": 850000 },
|
|
16
|
+
"scriptSize": { "maxNumericValue": 750000 },
|
|
17
|
+
"fontDisplay": { "minScore": 0.9 },
|
|
18
|
+
"imageAspectRatio": { "minScore": 1 },
|
|
19
|
+
"metaDescription": { "minScore": 1 },
|
|
20
|
+
"unusedJavascript": { "maxLength": 2 },
|
|
21
|
+
"bootupTime": { "minScore": 0.9 },
|
|
22
|
+
"mainthreadWorkBreakdown": { "minScore": 0.9 },
|
|
23
|
+
"maxPotentialFid": { "minScore": 1 },
|
|
24
|
+
"legacyJavascript": { "maxLength": 2 },
|
|
25
|
+
"legacyJavascriptInsight": { "minScore": 0.4 },
|
|
26
|
+
"speedIndex": { "minScore": 0.9 }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scripts": {
|
|
3
|
+
"start:local": "cp .env.localhost .env.local && EXPO_ATLAS=true expo start",
|
|
4
|
+
"start:dev": "EXPO_ATLAS=true cp .env.development .env.local && EXPO_ATLAS=true expo start",
|
|
5
|
+
"start:staging": "cp .env.staging .env.local && EXPO_ATLAS=true expo start",
|
|
6
|
+
"start:production": "cp .env.production .env.local && EXPO_ATLAS=true expo start",
|
|
7
|
+
"fetch:graphql:schema:dev": "./scripts/fetch-graphql-schema.sh development",
|
|
8
|
+
"fetch:graphql:schema:staging": "./scripts/fetch-graphql-schema.sh staging",
|
|
9
|
+
"fetch:graphql:schema:production": "./scripts/fetch-graphql-schema.sh production",
|
|
10
|
+
"export:web": "expo export --platform web --source-maps",
|
|
11
|
+
"lighthouse:check": "lhci autorun --collect.settings.chromeFlags='--no-sandbox --disable-gpu --headless'",
|
|
12
|
+
"playwright:build": "expo export --platform web",
|
|
13
|
+
"playwright:test": "bun run playwright:build && playwright test",
|
|
14
|
+
"playwright:test:ui": "bun run playwright:build && playwright test --ui",
|
|
15
|
+
"maestro:test": "maestro test .maestro/flows",
|
|
16
|
+
"maestro:test:smoke": "maestro test .maestro/flows --include-tags=smoke",
|
|
17
|
+
"maestro:studio": "maestro studio",
|
|
18
|
+
"pre-build:eas": "cat .gitignore > .easignore && cat .easignore.extra >> .easignore",
|
|
19
|
+
"android": "expo run:android",
|
|
20
|
+
"ios": "expo run:ios"
|
|
21
|
+
},
|
|
22
|
+
"main": "expo-router/entry",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@apollo/client": "^3.10.8",
|
|
25
|
+
"@expo/metro-runtime": "~6.1.2",
|
|
26
|
+
"@gluestack-ui/core": "^3.0.10",
|
|
27
|
+
"@gluestack-ui/utils": "^3.0.7",
|
|
28
|
+
"@gorhom/bottom-sheet": "^5.2.6",
|
|
29
|
+
"@hookform/resolvers": "^3.9.0",
|
|
30
|
+
"@legendapp/motion": "^2.4.0",
|
|
31
|
+
"@react-native-async-storage/async-storage": "2.2.0",
|
|
32
|
+
"@react-native-masked-view/masked-view": "^0.3.2",
|
|
33
|
+
"@react-navigation/drawer": "^7.5.0",
|
|
34
|
+
"@react-navigation/elements": "^1.3.31",
|
|
35
|
+
"@sentry/react-native": "7.2.0",
|
|
36
|
+
"@shopify/flash-list": "2.0.2",
|
|
37
|
+
"@shopify/react-native-skia": "2.2.12",
|
|
38
|
+
"apollo-link-sentry": "^4.0.0",
|
|
39
|
+
"base-64": "^1.0.0",
|
|
40
|
+
"date-fns": "^3.6.0",
|
|
41
|
+
"date-fns-tz": "^3.1.3",
|
|
42
|
+
"events": "^3.3.0",
|
|
43
|
+
"expo": "~54.0.31",
|
|
44
|
+
"expo-application": "~7.0.8",
|
|
45
|
+
"expo-battery": "~10.0.8",
|
|
46
|
+
"expo-build-properties": "~1.0.10",
|
|
47
|
+
"expo-clipboard": "~8.0.8",
|
|
48
|
+
"expo-constants": "~18.0.13",
|
|
49
|
+
"expo-crypto": "^15.0.8",
|
|
50
|
+
"expo-dev-client": "~6.0.20",
|
|
51
|
+
"expo-device": "~8.0.10",
|
|
52
|
+
"expo-font": "~14.0.10",
|
|
53
|
+
"expo-linear-gradient": "~15.0.8",
|
|
54
|
+
"expo-linking": "~8.0.11",
|
|
55
|
+
"expo-localization": "^17.0.8",
|
|
56
|
+
"expo-network": "~8.0.8",
|
|
57
|
+
"expo-notifications": "~0.32.16",
|
|
58
|
+
"expo-router": "~6.0.21",
|
|
59
|
+
"expo-secure-store": "~15.0.8",
|
|
60
|
+
"expo-splash-screen": "~31.0.13",
|
|
61
|
+
"expo-status-bar": "~3.0.9",
|
|
62
|
+
"expo-system-ui": "~6.0.9",
|
|
63
|
+
"expo-updates": "~29.0.16",
|
|
64
|
+
"graphql": "^16.12.0",
|
|
65
|
+
"i18n-js": "^4.5.1",
|
|
66
|
+
"lucide-react-native": "^0.562.0",
|
|
67
|
+
"nativewind": "^4.2.1",
|
|
68
|
+
"patch-package": "^8.0.0",
|
|
69
|
+
"react": "19.1.0",
|
|
70
|
+
"react-dom": "19.1.0",
|
|
71
|
+
"react-hook-form": "^7.70.0",
|
|
72
|
+
"react-native": "0.81.4",
|
|
73
|
+
"react-native-gesture-handler": "~2.30.0",
|
|
74
|
+
"react-native-keyboard-controller": "1.20.4",
|
|
75
|
+
"react-native-reanimated": "~4.2.1",
|
|
76
|
+
"react-native-safe-area-context": "^5.6.2",
|
|
77
|
+
"react-native-screens": "~4.19.0",
|
|
78
|
+
"react-native-store-version": "^1.4.1",
|
|
79
|
+
"react-native-svg": "^15.15.1",
|
|
80
|
+
"react-native-web": "^0.21.2",
|
|
81
|
+
"react-native-worklets": "0.7.1",
|
|
82
|
+
"tailwindcss": "^3.4.7",
|
|
83
|
+
"tar": "^7.5.3",
|
|
84
|
+
"text-encoding-polyfill": "^0.6.7",
|
|
85
|
+
"use-debounce": "^10.1.0",
|
|
86
|
+
"usehooks-ts": "^3.1.1",
|
|
87
|
+
"zod": "^4.3.5"
|
|
88
|
+
},
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"@babel/core": "^7.20.0",
|
|
91
|
+
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
|
92
|
+
"@graphql-codegen/cli": "^6.1.0",
|
|
93
|
+
"@graphql-codegen/typescript": "^4.1.6",
|
|
94
|
+
"@graphql-codegen/typescript-operations": "^4.4.2",
|
|
95
|
+
"@graphql-codegen/typescript-react-apollo": "^4.3.4",
|
|
96
|
+
"@lhci/cli": "^0.15.1",
|
|
97
|
+
"@playwright/test": "^1.57.0",
|
|
98
|
+
"@react-native-community/cli": "^20.0.2",
|
|
99
|
+
"@react-native-community/cli-platform-android": "^20.0.2",
|
|
100
|
+
"@react-native-community/cli-platform-ios": "^20.0.2",
|
|
101
|
+
"@testing-library/react-native": "^13.0.0",
|
|
102
|
+
"@types/base-64": "^1.0.2",
|
|
103
|
+
"@types/react": "~19.1.10",
|
|
104
|
+
"@types/react-dom": "^19.1.7",
|
|
105
|
+
"babel-plugin-istanbul": "^6.1.1",
|
|
106
|
+
"babel-plugin-module-resolver": "^5.0.2",
|
|
107
|
+
"baseline-browser-mapping": "^2.9.2",
|
|
108
|
+
"eslint-config-expo": "^10.0.0",
|
|
109
|
+
"eslint-plugin-component-structure": "file:./eslint-plugin-component-structure",
|
|
110
|
+
"eslint-plugin-jsx-a11y": "^6.10.0",
|
|
111
|
+
"eslint-plugin-react": "^7.37.0",
|
|
112
|
+
"eslint-plugin-react-compiler": "^19.1.0-rc.2",
|
|
113
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
114
|
+
"eslint-plugin-react-perf": "^3.3.0",
|
|
115
|
+
"eslint-plugin-tailwindcss": "^3.18.0",
|
|
116
|
+
"eslint-plugin-ui-standards": "file:./eslint-plugin-ui-standards",
|
|
117
|
+
"expo-atlas": "^0.4.0",
|
|
118
|
+
"globals": "^16.0.0",
|
|
119
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
120
|
+
"jest-expo": "^54.0.12",
|
|
121
|
+
"react-test-renderer": "19.1.0"
|
|
122
|
+
},
|
|
123
|
+
"resolutions": {
|
|
124
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
125
|
+
"tar": "^7.5.3"
|
|
126
|
+
},
|
|
127
|
+
"overrides": {
|
|
128
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
129
|
+
"zod-validation-error": "^4.0.0",
|
|
130
|
+
"tar": "^7.5.3"
|
|
131
|
+
}
|
|
132
|
+
}
|
package/lisa.sh
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Lisa - Claude Code governance framework
|
|
4
|
+
#
|
|
5
|
+
# This script wraps the TypeScript implementation. If Node.js is not available,
|
|
6
|
+
# it falls back to the legacy bash implementation.
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
LISA_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
12
|
+
|
|
13
|
+
# Check if Node.js is available and the dist directory exists
|
|
14
|
+
if command -v node &> /dev/null && [[ -d "$LISA_DIR/dist" ]]; then
|
|
15
|
+
# Run the TypeScript version
|
|
16
|
+
exec node "$LISA_DIR/dist/index.js" "$@"
|
|
17
|
+
elif command -v npx &> /dev/null && [[ -f "$LISA_DIR/package.json" ]]; then
|
|
18
|
+
# Try building and running via npm
|
|
19
|
+
echo "[INFO] Building TypeScript version..."
|
|
20
|
+
cd "$LISA_DIR"
|
|
21
|
+
npm run build --silent 2>/dev/null || true
|
|
22
|
+
if [[ -d "$LISA_DIR/dist" ]]; then
|
|
23
|
+
exec node "$LISA_DIR/dist/index.js" "$@"
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# If we get here, TypeScript version is not available
|
|
28
|
+
echo "[ERROR] TypeScript version not available."
|
|
29
|
+
echo ""
|
|
30
|
+
echo "To use Lisa, please ensure Node.js is installed and run:"
|
|
31
|
+
echo " cd $LISA_DIR && npm install && npm run build"
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Then run Lisa again:"
|
|
34
|
+
echo " $0 $*"
|
|
35
|
+
exit 1
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nestjs-graphql
|
|
3
|
+
description: Comprehensive guide for NestJS GraphQL development using Apollo and code-first approach. This skill should be used when writing GraphQL resolvers, mutations, queries, types, subscriptions, or implementing advanced features like field middleware, complexity limits, and custom scalars. Also covers project-specific patterns including zero-trust auth decorators and DataLoader integration.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NestJS GraphQL Development Guide
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
This skill provides comprehensive guidance for building GraphQL APIs with NestJS using Apollo Server and the code-first approach. It covers official NestJS GraphQL patterns plus project-specific implementations for authentication, authorization, and data loading.
|
|
11
|
+
|
|
12
|
+
## When to Use This Skill
|
|
13
|
+
|
|
14
|
+
- Writing new GraphQL resolvers, queries, or mutations
|
|
15
|
+
- Creating GraphQL object types, input types, or enums
|
|
16
|
+
- Implementing field resolvers or computed fields
|
|
17
|
+
- Adding subscriptions for real-time updates
|
|
18
|
+
- Configuring query complexity limits
|
|
19
|
+
- Creating custom scalars or field middleware
|
|
20
|
+
- Implementing authentication/authorization on GraphQL operations
|
|
21
|
+
- Setting up DataLoader for N+1 prevention
|
|
22
|
+
|
|
23
|
+
## Quick Reference
|
|
24
|
+
|
|
25
|
+
### Core Decorators
|
|
26
|
+
|
|
27
|
+
| Decorator | Purpose | Import |
|
|
28
|
+
|-----------|---------|--------|
|
|
29
|
+
| `@Resolver()` | Define resolver class | `@nestjs/graphql` |
|
|
30
|
+
| `@Query()` | Define query operation | `@nestjs/graphql` |
|
|
31
|
+
| `@Mutation()` | Define mutation operation | `@nestjs/graphql` |
|
|
32
|
+
| `@Args()` | Extract arguments | `@nestjs/graphql` |
|
|
33
|
+
| `@Context()` | Access GraphQL context | `@nestjs/graphql` |
|
|
34
|
+
| `@Parent()` | Access parent in field resolver | `@nestjs/graphql` |
|
|
35
|
+
| `@ResolveField()` | Define field resolver | `@nestjs/graphql` |
|
|
36
|
+
| `@ObjectType()` | Define GraphQL object type | `@nestjs/graphql` |
|
|
37
|
+
| `@InputType()` | Define GraphQL input type | `@nestjs/graphql` |
|
|
38
|
+
| `@Field()` | Define field on type | `@nestjs/graphql` |
|
|
39
|
+
| `@Extensions()` | Attach metadata to fields | `@nestjs/graphql` |
|
|
40
|
+
|
|
41
|
+
### Type Decorators
|
|
42
|
+
|
|
43
|
+
| Decorator | GraphQL Type | TypeScript Type |
|
|
44
|
+
|-----------|-------------|-----------------|
|
|
45
|
+
| `@Field(() => String)` | "String!" | `string` |
|
|
46
|
+
| `@Field(() => Int)` | "Int!" | `number` |
|
|
47
|
+
| `@Field(() => Float)` | "Float!" | `number` |
|
|
48
|
+
| `@Field(() => Boolean)` | "Boolean!" | `boolean` |
|
|
49
|
+
| `@Field(() => ID)` | "ID!" | `string` |
|
|
50
|
+
| `@Field(() => [String])` | "[String!]!" | `string[]` |
|
|
51
|
+
| `@Field({ nullable: true })` | `String` | `string \| null` |
|
|
52
|
+
|
|
53
|
+
## Code-First Patterns
|
|
54
|
+
|
|
55
|
+
### Basic Resolver Structure
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { Args, Context, Mutation, Query, Resolver } from "@nestjs/graphql";
|
|
59
|
+
import { Public, Authed } from "../auth";
|
|
60
|
+
|
|
61
|
+
@Resolver(() => Entity)
|
|
62
|
+
export class EntityResolver {
|
|
63
|
+
constructor(private readonly entityService: EntityService) {}
|
|
64
|
+
|
|
65
|
+
@Query(() => Entity, { description: "Retrieve entity by ID" })
|
|
66
|
+
@Authed()
|
|
67
|
+
async entity(@Args("id", { type: () => ID }) id: string): Promise<Entity> {
|
|
68
|
+
return this.entityService.findById(id);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Mutation(() => Entity, { description: "Create new entity" })
|
|
72
|
+
@Authed()
|
|
73
|
+
async createEntity(
|
|
74
|
+
@Args("input") input: CreateEntityInput,
|
|
75
|
+
@Context() { req }: GraphQLContext
|
|
76
|
+
): Promise<Entity> {
|
|
77
|
+
return this.entityService.create(input, req.user.id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Object Type Definition
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { Field, ID, ObjectType } from "@nestjs/graphql";
|
|
86
|
+
|
|
87
|
+
@ObjectType({ description: "Represents a user in the system" })
|
|
88
|
+
export class User {
|
|
89
|
+
@Field(() => ID, { description: "Unique identifier" })
|
|
90
|
+
id: string;
|
|
91
|
+
|
|
92
|
+
@Field(() => String, { description: "User's email address" })
|
|
93
|
+
email: string;
|
|
94
|
+
|
|
95
|
+
@Field(() => String, { nullable: true, description: "Display name" })
|
|
96
|
+
displayName?: string;
|
|
97
|
+
|
|
98
|
+
@Field(() => Date, { description: "Account creation timestamp" })
|
|
99
|
+
createdAt: Date;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Input Type Definition
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { Field, InputType } from "@nestjs/graphql";
|
|
107
|
+
|
|
108
|
+
@InputType({ description: "Input for creating a new user" })
|
|
109
|
+
export class CreateUserInput {
|
|
110
|
+
@Field(() => String, { description: "User's email address" })
|
|
111
|
+
email: string;
|
|
112
|
+
|
|
113
|
+
@Field(() => String, { description: "User's password" })
|
|
114
|
+
password: string;
|
|
115
|
+
|
|
116
|
+
@Field(() => String, { nullable: true, description: "Optional display name" })
|
|
117
|
+
displayName?: string;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## References
|
|
122
|
+
|
|
123
|
+
This skill includes detailed reference files for specific topics:
|
|
124
|
+
|
|
125
|
+
### references/quick-start.md
|
|
126
|
+
Setup and configuration for NestJS GraphQL with Apollo driver, module configuration, and code-first vs schema-first approaches.
|
|
127
|
+
|
|
128
|
+
### references/resolvers-mutations.md
|
|
129
|
+
Comprehensive guide to writing resolvers, queries, mutations, field resolvers, and using decorators like @Args, @Context, @Parent.
|
|
130
|
+
|
|
131
|
+
### references/types-scalars.md
|
|
132
|
+
Creating object types, input types, enums, interfaces, unions, and custom scalars. Includes mapped types (PartialType, PickType, etc.).
|
|
133
|
+
|
|
134
|
+
### references/advanced-features.md
|
|
135
|
+
Field middleware, query complexity, plugins, subscriptions, and extensions.
|
|
136
|
+
|
|
137
|
+
### references/project-patterns.md
|
|
138
|
+
Project-specific patterns including zero-trust auth decorators (@Public, @Authed, @Owner, @Groups), DataLoader integration, and GraphQL documentation standards.
|
|
139
|
+
|
|
140
|
+
## Common Tasks
|
|
141
|
+
|
|
142
|
+
### Adding a New Query
|
|
143
|
+
|
|
144
|
+
1. Add method to resolver with `@Query()` decorator
|
|
145
|
+
2. Add auth decorator (`@Public()`, `@Authed()`, or `@Groups()`)
|
|
146
|
+
3. Define return type in decorator: `@Query(() => ReturnType)`
|
|
147
|
+
4. Add description: `@Query(() => ReturnType, { description: "..." })`
|
|
148
|
+
5. Use `@Args()` for parameters with descriptions
|
|
149
|
+
|
|
150
|
+
### Adding a New Mutation
|
|
151
|
+
|
|
152
|
+
1. Add method to resolver with `@Mutation()` decorator
|
|
153
|
+
2. Add auth decorator (mutations typically use `@Authed()`)
|
|
154
|
+
3. Create InputType for complex inputs
|
|
155
|
+
4. Access user context via `@Context() { req }: GraphQLContext`
|
|
156
|
+
|
|
157
|
+
### Adding Field Resolver
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
@ResolveField(() => [Comment], { description: "Entity's comments" })
|
|
161
|
+
async comments(
|
|
162
|
+
@Parent() entity: Entity,
|
|
163
|
+
@Context() { loaders }: GraphQLContext
|
|
164
|
+
): Promise<Comment[]> {
|
|
165
|
+
return loaders.commentsLoader.load(entity.id);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Adding DataLoader for New Entity
|
|
170
|
+
|
|
171
|
+
1. Add batch method to service: `getByIds(ids: string[]): Promise<Entity[]>`
|
|
172
|
+
2. Add loader type to `IDataLoaders` interface
|
|
173
|
+
3. Create loader in `DataLoaderService.getLoaders()`
|
|
174
|
+
4. Use in resolver: `loaders.entityLoader.load(id)`
|
|
175
|
+
|
|
176
|
+
See `references/project-patterns.md` for detailed DataLoader patterns.
|