@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
package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Gluestack UI Component Classification
|
|
2
|
+
|
|
3
|
+
This document maps all Gluestack UI components to their atomic design level.
|
|
4
|
+
|
|
5
|
+
## Atoms (Foundation)
|
|
6
|
+
|
|
7
|
+
These components are the building blocks. Use them directly from `@/components/ui/`.
|
|
8
|
+
|
|
9
|
+
### Layout Atoms
|
|
10
|
+
| Component | Import | Description |
|
|
11
|
+
|-----------|--------|-------------|
|
|
12
|
+
| Box | `@/components/ui/box` | Basic container |
|
|
13
|
+
| Center | `@/components/ui/center` | Centered container |
|
|
14
|
+
| HStack | `@/components/ui/hstack` | Horizontal stack |
|
|
15
|
+
| VStack | `@/components/ui/vstack` | Vertical stack |
|
|
16
|
+
| Grid | `@/components/ui/grid` | Grid layout |
|
|
17
|
+
| Divider | `@/components/ui/divider` | Visual separator |
|
|
18
|
+
|
|
19
|
+
### Typography Atoms
|
|
20
|
+
| Component | Import | Description |
|
|
21
|
+
|-----------|--------|-------------|
|
|
22
|
+
| Text | `@/components/ui/text` | Body text |
|
|
23
|
+
| Heading | `@/components/ui/heading` | Headings h1-h6 |
|
|
24
|
+
|
|
25
|
+
### Interactive Atoms
|
|
26
|
+
| Component | Import | Description |
|
|
27
|
+
|-----------|--------|-------------|
|
|
28
|
+
| Button | `@/components/ui/button` | Clickable button |
|
|
29
|
+
| ButtonText | `@/components/ui/button` | Button label |
|
|
30
|
+
| ButtonIcon | `@/components/ui/button` | Button icon |
|
|
31
|
+
| ButtonSpinner | `@/components/ui/button` | Button loading state |
|
|
32
|
+
| Pressable | `@/components/ui/pressable` | Touchable wrapper |
|
|
33
|
+
| Link | `@/components/ui/link` | Navigation link |
|
|
34
|
+
| LinkText | `@/components/ui/link` | Link label |
|
|
35
|
+
|
|
36
|
+
### Input Atoms
|
|
37
|
+
| Component | Import | Description |
|
|
38
|
+
|-----------|--------|-------------|
|
|
39
|
+
| Input | `@/components/ui/input` | Text input container |
|
|
40
|
+
| InputField | `@/components/ui/input` | Text input field |
|
|
41
|
+
| InputSlot | `@/components/ui/input` | Input addon slot |
|
|
42
|
+
| InputIcon | `@/components/ui/input` | Input icon |
|
|
43
|
+
| Textarea | `@/components/ui/textarea` | Multi-line input |
|
|
44
|
+
| TextareaInput | `@/components/ui/textarea` | Textarea field |
|
|
45
|
+
|
|
46
|
+
### Selection Atoms
|
|
47
|
+
| Component | Import | Description |
|
|
48
|
+
|-----------|--------|-------------|
|
|
49
|
+
| Checkbox | `@/components/ui/checkbox` | Checkbox control |
|
|
50
|
+
| CheckboxIndicator | `@/components/ui/checkbox` | Checkbox visual |
|
|
51
|
+
| CheckboxIcon | `@/components/ui/checkbox` | Checkbox checkmark |
|
|
52
|
+
| CheckboxLabel | `@/components/ui/checkbox` | Checkbox text |
|
|
53
|
+
| Radio | `@/components/ui/radio` | Radio button |
|
|
54
|
+
| RadioIndicator | `@/components/ui/radio` | Radio visual |
|
|
55
|
+
| RadioIcon | `@/components/ui/radio` | Radio dot |
|
|
56
|
+
| RadioLabel | `@/components/ui/radio` | Radio text |
|
|
57
|
+
| Switch | `@/components/ui/switch` | Toggle switch |
|
|
58
|
+
| Slider | `@/components/ui/slider` | Range slider |
|
|
59
|
+
|
|
60
|
+
### Media Atoms
|
|
61
|
+
| Component | Import | Description |
|
|
62
|
+
|-----------|--------|-------------|
|
|
63
|
+
| Image | `@/components/ui/image` | Image display |
|
|
64
|
+
| Icon | `@/components/ui/icon` | Icon display |
|
|
65
|
+
| Avatar | `@/components/ui/avatar` | User avatar |
|
|
66
|
+
| AvatarImage | `@/components/ui/avatar` | Avatar image |
|
|
67
|
+
| AvatarFallbackText | `@/components/ui/avatar` | Avatar initials |
|
|
68
|
+
|
|
69
|
+
### Feedback Atoms
|
|
70
|
+
| Component | Import | Description |
|
|
71
|
+
|-----------|--------|-------------|
|
|
72
|
+
| Spinner | `@/components/ui/spinner` | Loading indicator |
|
|
73
|
+
| Badge | `@/components/ui/badge` | Status badge |
|
|
74
|
+
| BadgeText | `@/components/ui/badge` | Badge label |
|
|
75
|
+
| BadgeIcon | `@/components/ui/badge` | Badge icon |
|
|
76
|
+
| Progress | `@/components/ui/progress` | Progress bar |
|
|
77
|
+
| ProgressFilledTrack | `@/components/ui/progress` | Progress fill |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Molecules (Simple Compositions)
|
|
82
|
+
|
|
83
|
+
These components combine atoms for a single purpose. Some Gluestack components are molecules.
|
|
84
|
+
|
|
85
|
+
### Form Molecules
|
|
86
|
+
| Component | Import | Description |
|
|
87
|
+
|-----------|--------|-------------|
|
|
88
|
+
| FormControl | `@/components/ui/form-control` | Form field wrapper |
|
|
89
|
+
| FormControlLabel | `@/components/ui/form-control` | Field label |
|
|
90
|
+
| FormControlLabelText | `@/components/ui/form-control` | Label text |
|
|
91
|
+
| FormControlHelper | `@/components/ui/form-control` | Helper text |
|
|
92
|
+
| FormControlHelperText | `@/components/ui/form-control` | Helper content |
|
|
93
|
+
| FormControlError | `@/components/ui/form-control` | Error container |
|
|
94
|
+
| FormControlErrorIcon | `@/components/ui/form-control` | Error icon |
|
|
95
|
+
| FormControlErrorText | `@/components/ui/form-control` | Error message |
|
|
96
|
+
| Select | `@/components/ui/select` | Dropdown select |
|
|
97
|
+
| SelectTrigger | `@/components/ui/select` | Select button |
|
|
98
|
+
| SelectInput | `@/components/ui/select` | Select display |
|
|
99
|
+
| SelectPortal | `@/components/ui/select` | Select dropdown |
|
|
100
|
+
| SelectItem | `@/components/ui/select` | Select option |
|
|
101
|
+
|
|
102
|
+
### Feedback Molecules
|
|
103
|
+
| Component | Import | Description |
|
|
104
|
+
|-----------|--------|-------------|
|
|
105
|
+
| Alert | `@/components/ui/alert` | Alert message |
|
|
106
|
+
| AlertIcon | `@/components/ui/alert` | Alert icon |
|
|
107
|
+
| AlertText | `@/components/ui/alert` | Alert content |
|
|
108
|
+
| Toast | `@/components/ui/toast` | Toast notification |
|
|
109
|
+
| ToastTitle | `@/components/ui/toast` | Toast heading |
|
|
110
|
+
| ToastDescription | `@/components/ui/toast` | Toast message |
|
|
111
|
+
|
|
112
|
+
### Content Molecules
|
|
113
|
+
| Component | Import | Description |
|
|
114
|
+
|-----------|--------|-------------|
|
|
115
|
+
| Card | `@/components/ui/card` | Content card |
|
|
116
|
+
| Tooltip | `@/components/ui/tooltip` | Hover tooltip |
|
|
117
|
+
| TooltipContent | `@/components/ui/tooltip` | Tooltip body |
|
|
118
|
+
| TooltipText | `@/components/ui/tooltip` | Tooltip text |
|
|
119
|
+
| Popover | `@/components/ui/popover` | Popover container |
|
|
120
|
+
| PopoverContent | `@/components/ui/popover` | Popover body |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Organisms (Complex Sections)
|
|
125
|
+
|
|
126
|
+
These components form distinct interface sections and may contain multiple molecules.
|
|
127
|
+
|
|
128
|
+
### Overlay Organisms
|
|
129
|
+
| Component | Import | Description |
|
|
130
|
+
|-----------|--------|-------------|
|
|
131
|
+
| Modal | `@/components/ui/modal` | Modal dialog |
|
|
132
|
+
| ModalBackdrop | `@/components/ui/modal` | Modal overlay |
|
|
133
|
+
| ModalContent | `@/components/ui/modal` | Modal body |
|
|
134
|
+
| ModalHeader | `@/components/ui/modal` | Modal header |
|
|
135
|
+
| ModalBody | `@/components/ui/modal` | Modal content |
|
|
136
|
+
| ModalFooter | `@/components/ui/modal` | Modal actions |
|
|
137
|
+
| ModalCloseButton | `@/components/ui/modal` | Modal close |
|
|
138
|
+
| Actionsheet | `@/components/ui/actionsheet` | Bottom sheet |
|
|
139
|
+
| ActionsheetBackdrop | `@/components/ui/actionsheet` | Sheet overlay |
|
|
140
|
+
| ActionsheetContent | `@/components/ui/actionsheet` | Sheet body |
|
|
141
|
+
| ActionsheetItem | `@/components/ui/actionsheet` | Sheet option |
|
|
142
|
+
| ActionsheetItemText | `@/components/ui/actionsheet` | Option text |
|
|
143
|
+
| Drawer | `@/components/ui/drawer` | Side drawer |
|
|
144
|
+
| DrawerBackdrop | `@/components/ui/drawer` | Drawer overlay |
|
|
145
|
+
| DrawerContent | `@/components/ui/drawer` | Drawer body |
|
|
146
|
+
|
|
147
|
+
### Navigation Organisms
|
|
148
|
+
| Component | Import | Description |
|
|
149
|
+
|-----------|--------|-------------|
|
|
150
|
+
| Menu | `@/components/ui/menu` | Dropdown menu |
|
|
151
|
+
| MenuItem | `@/components/ui/menu` | Menu option |
|
|
152
|
+
| MenuItemLabel | `@/components/ui/menu` | Option text |
|
|
153
|
+
| Accordion | `@/components/ui/accordion` | Accordion list |
|
|
154
|
+
| AccordionItem | `@/components/ui/accordion` | Accordion section |
|
|
155
|
+
| AccordionHeader | `@/components/ui/accordion` | Section header |
|
|
156
|
+
| AccordionTrigger | `@/components/ui/accordion` | Section toggle |
|
|
157
|
+
| AccordionContent | `@/components/ui/accordion` | Section content |
|
|
158
|
+
|
|
159
|
+
### Feedback Organisms
|
|
160
|
+
| Component | Import | Description |
|
|
161
|
+
|-----------|--------|-------------|
|
|
162
|
+
| AlertDialog | `@/components/ui/alert-dialog` | Confirmation dialog |
|
|
163
|
+
| AlertDialogBackdrop | `@/components/ui/alert-dialog` | Dialog overlay |
|
|
164
|
+
| AlertDialogContent | `@/components/ui/alert-dialog` | Dialog body |
|
|
165
|
+
| AlertDialogHeader | `@/components/ui/alert-dialog` | Dialog header |
|
|
166
|
+
| AlertDialogBody | `@/components/ui/alert-dialog` | Dialog content |
|
|
167
|
+
| AlertDialogFooter | `@/components/ui/alert-dialog` | Dialog actions |
|
|
168
|
+
| AlertDialogCloseButton | `@/components/ui/alert-dialog` | Dialog close |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Classification Decision Guide
|
|
173
|
+
|
|
174
|
+
When deciding which level a Gluestack component belongs to:
|
|
175
|
+
|
|
176
|
+
### Use as Atom when:
|
|
177
|
+
- It's a single, indivisible UI element
|
|
178
|
+
- It has no internal state management
|
|
179
|
+
- Examples: Button, Text, Icon, Input, Badge
|
|
180
|
+
|
|
181
|
+
### Use as Molecule when:
|
|
182
|
+
- It combines multiple atoms for one purpose
|
|
183
|
+
- It may have isolated UI state
|
|
184
|
+
- Examples: FormControl (label + input + error), Alert (icon + text)
|
|
185
|
+
|
|
186
|
+
### Use as Organism when:
|
|
187
|
+
- It forms a complete interface section
|
|
188
|
+
- It has multiple interactive parts
|
|
189
|
+
- Examples: Modal (backdrop + content + header + body + footer), Menu
|
|
190
|
+
|
|
191
|
+
### Composition Example
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Page (in app/ or features/*/screens/)
|
|
195
|
+
export default function ProductScreen() {
|
|
196
|
+
const { data } = useProductQuery();
|
|
197
|
+
return (
|
|
198
|
+
<MainLayout> {/* Template */}
|
|
199
|
+
<ProductDetail product={data.product} /> {/* Organism */}
|
|
200
|
+
</MainLayout>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Organism (in components/organisms/)
|
|
205
|
+
const ProductDetail = memo(function ProductDetail({ product }: Props) {
|
|
206
|
+
return (
|
|
207
|
+
<Card> {/* Molecule */}
|
|
208
|
+
<ProductImage src={product.image} /> {/* Atom */}
|
|
209
|
+
<VStack> {/* Atom */}
|
|
210
|
+
<Heading>{product.name}</Heading> {/* Atom */}
|
|
211
|
+
<PriceDisplay price={product.price} /> {/* Molecule */}
|
|
212
|
+
<AddToCartButton /> {/* Molecule */}
|
|
213
|
+
</VStack>
|
|
214
|
+
</Card>
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Molecule (in components/molecules/)
|
|
219
|
+
const PriceDisplay = memo(function PriceDisplay({ price, original }: Props) {
|
|
220
|
+
return (
|
|
221
|
+
<HStack space="sm"> {/* Atom */}
|
|
222
|
+
<Text className="text-primary-500"> {/* Atom */}
|
|
223
|
+
${price}
|
|
224
|
+
</Text>
|
|
225
|
+
{original && (
|
|
226
|
+
<Text className="line-through"> {/* Atom */}
|
|
227
|
+
${original}
|
|
228
|
+
</Text>
|
|
229
|
+
)}
|
|
230
|
+
</HStack>
|
|
231
|
+
);
|
|
232
|
+
});
|
|
233
|
+
```
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Atomic Design Structure Validator
|
|
4
|
+
|
|
5
|
+
Validates that components are correctly placed in the atomic design hierarchy
|
|
6
|
+
and that import dependencies flow in the correct direction.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python validate_atomic_structure.py [path]
|
|
10
|
+
|
|
11
|
+
If no path provided, validates the entire project from current directory.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
import re
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import NamedTuple
|
|
19
|
+
|
|
20
|
+
# Atomic levels in order of allowed dependencies (lower can't import higher)
|
|
21
|
+
ATOMIC_LEVELS = {
|
|
22
|
+
"atoms": 0,
|
|
23
|
+
"molecules": 1,
|
|
24
|
+
"organisms": 2,
|
|
25
|
+
"templates": 3,
|
|
26
|
+
"screens": 4, # Pages
|
|
27
|
+
"app": 4, # Expo Router pages
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# Patterns to identify atomic level from file path
|
|
31
|
+
LEVEL_PATTERNS = [
|
|
32
|
+
(r"/components/atoms/", "atoms"),
|
|
33
|
+
(r"/components/molecules/", "molecules"),
|
|
34
|
+
(r"/components/organisms/", "organisms"),
|
|
35
|
+
(r"/components/templates/", "templates"),
|
|
36
|
+
(r"/features/[^/]+/components/atoms/", "atoms"),
|
|
37
|
+
(r"/features/[^/]+/components/molecules/", "molecules"),
|
|
38
|
+
(r"/features/[^/]+/components/organisms/", "organisms"),
|
|
39
|
+
(r"/features/[^/]+/screens/", "screens"),
|
|
40
|
+
(r"/app/", "app"),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
# Import patterns to detect
|
|
44
|
+
IMPORT_PATTERNS = [
|
|
45
|
+
r'from\s+["\'](@/components/atoms/[^"\']+)["\']',
|
|
46
|
+
r'from\s+["\'](@/components/molecules/[^"\']+)["\']',
|
|
47
|
+
r'from\s+["\'](@/components/organisms/[^"\']+)["\']',
|
|
48
|
+
r'from\s+["\'](@/components/templates/[^"\']+)["\']',
|
|
49
|
+
r'from\s+["\'](@/features/[^/]+/components/atoms/[^"\']+)["\']',
|
|
50
|
+
r'from\s+["\'](@/features/[^/]+/components/molecules/[^"\']+)["\']',
|
|
51
|
+
r'from\s+["\'](@/features/[^/]+/components/organisms/[^"\']+)["\']',
|
|
52
|
+
r'from\s+["\'](@/features/[^/]+/screens/[^"\']+)["\']',
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ValidationError(NamedTuple):
|
|
57
|
+
"""Represents a validation error."""
|
|
58
|
+
file_path: str
|
|
59
|
+
line_number: int
|
|
60
|
+
error_type: str
|
|
61
|
+
message: str
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ValidationResult(NamedTuple):
|
|
65
|
+
"""Represents the overall validation result."""
|
|
66
|
+
errors: list
|
|
67
|
+
warnings: list
|
|
68
|
+
files_checked: int
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_atomic_level(file_path: str) -> str | None:
|
|
72
|
+
"""Determine the atomic level of a file based on its path."""
|
|
73
|
+
for pattern, level in LEVEL_PATTERNS:
|
|
74
|
+
if re.search(pattern, file_path):
|
|
75
|
+
return level
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def get_import_level(import_path: str) -> str | None:
|
|
80
|
+
"""Determine the atomic level of an import path."""
|
|
81
|
+
if "/atoms/" in import_path:
|
|
82
|
+
return "atoms"
|
|
83
|
+
if "/molecules/" in import_path:
|
|
84
|
+
return "molecules"
|
|
85
|
+
if "/organisms/" in import_path:
|
|
86
|
+
return "organisms"
|
|
87
|
+
if "/templates/" in import_path:
|
|
88
|
+
return "templates"
|
|
89
|
+
if "/screens/" in import_path:
|
|
90
|
+
return "screens"
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def check_import_direction(
|
|
95
|
+
file_level: str,
|
|
96
|
+
import_level: str,
|
|
97
|
+
file_path: str,
|
|
98
|
+
import_path: str,
|
|
99
|
+
line_number: int,
|
|
100
|
+
) -> ValidationError | None:
|
|
101
|
+
"""Check if an import violates the atomic design dependency rules."""
|
|
102
|
+
file_rank = ATOMIC_LEVELS.get(file_level, -1)
|
|
103
|
+
import_rank = ATOMIC_LEVELS.get(import_level, -1)
|
|
104
|
+
|
|
105
|
+
if import_rank > file_rank:
|
|
106
|
+
return ValidationError(
|
|
107
|
+
file_path=file_path,
|
|
108
|
+
line_number=line_number,
|
|
109
|
+
error_type="INVALID_IMPORT_DIRECTION",
|
|
110
|
+
message=f"{file_level} cannot import from {import_level}: {import_path}",
|
|
111
|
+
)
|
|
112
|
+
return None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def check_file_has_state(content: str) -> bool:
|
|
116
|
+
"""Check if a file uses React state hooks."""
|
|
117
|
+
state_patterns = [
|
|
118
|
+
r"\buseState\b",
|
|
119
|
+
r"\buseReducer\b",
|
|
120
|
+
r"\buseRef\b",
|
|
121
|
+
]
|
|
122
|
+
return any(re.search(pattern, content) for pattern in state_patterns)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def check_file_fetches_data(content: str) -> bool:
|
|
126
|
+
"""Check if a file fetches data."""
|
|
127
|
+
fetch_patterns = [
|
|
128
|
+
r"\buseQuery\b",
|
|
129
|
+
r"\buseMutation\b",
|
|
130
|
+
r"\buseLazyQuery\b",
|
|
131
|
+
r"\buseSubscription\b",
|
|
132
|
+
r"\bfetch\(",
|
|
133
|
+
r"\baxios\.",
|
|
134
|
+
]
|
|
135
|
+
return any(re.search(pattern, content) for pattern in fetch_patterns)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def validate_atom(file_path: str, content: str) -> list:
|
|
139
|
+
"""Validate that an atom follows atomic design rules."""
|
|
140
|
+
errors = []
|
|
141
|
+
|
|
142
|
+
# Atoms should not have state
|
|
143
|
+
if check_file_has_state(content):
|
|
144
|
+
# Check if it's just useRef (allowed in atoms for DOM refs)
|
|
145
|
+
if re.search(r"\buseState\b|\buseReducer\b", content):
|
|
146
|
+
errors.append(ValidationError(
|
|
147
|
+
file_path=file_path,
|
|
148
|
+
line_number=0,
|
|
149
|
+
error_type="ATOM_HAS_STATE",
|
|
150
|
+
message="Atoms should be stateless. Move state to a parent molecule.",
|
|
151
|
+
))
|
|
152
|
+
|
|
153
|
+
# Atoms should not fetch data
|
|
154
|
+
if check_file_fetches_data(content):
|
|
155
|
+
errors.append(ValidationError(
|
|
156
|
+
file_path=file_path,
|
|
157
|
+
line_number=0,
|
|
158
|
+
error_type="ATOM_FETCHES_DATA",
|
|
159
|
+
message="Atoms should not fetch data. Move data fetching to a page.",
|
|
160
|
+
))
|
|
161
|
+
|
|
162
|
+
return errors
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def validate_molecule(file_path: str, content: str) -> list:
|
|
166
|
+
"""Validate that a molecule follows atomic design rules."""
|
|
167
|
+
errors = []
|
|
168
|
+
|
|
169
|
+
# Molecules should not fetch data
|
|
170
|
+
if check_file_fetches_data(content):
|
|
171
|
+
errors.append(ValidationError(
|
|
172
|
+
file_path=file_path,
|
|
173
|
+
line_number=0,
|
|
174
|
+
error_type="MOLECULE_FETCHES_DATA",
|
|
175
|
+
message="Molecules should not fetch data. Accept data as props.",
|
|
176
|
+
))
|
|
177
|
+
|
|
178
|
+
return errors
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def validate_organism(file_path: str, content: str) -> list:
|
|
182
|
+
"""Validate that an organism follows atomic design rules."""
|
|
183
|
+
errors = []
|
|
184
|
+
|
|
185
|
+
# Organisms should not fetch data (data comes from pages)
|
|
186
|
+
if check_file_fetches_data(content):
|
|
187
|
+
errors.append(ValidationError(
|
|
188
|
+
file_path=file_path,
|
|
189
|
+
line_number=0,
|
|
190
|
+
error_type="ORGANISM_FETCHES_DATA",
|
|
191
|
+
message="Organisms should receive data as props. Move fetching to page.",
|
|
192
|
+
))
|
|
193
|
+
|
|
194
|
+
return errors
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def validate_template(file_path: str, content: str) -> list:
|
|
198
|
+
"""Validate that a template follows atomic design rules."""
|
|
199
|
+
errors = []
|
|
200
|
+
|
|
201
|
+
# Templates should not fetch data
|
|
202
|
+
if check_file_fetches_data(content):
|
|
203
|
+
errors.append(ValidationError(
|
|
204
|
+
file_path=file_path,
|
|
205
|
+
line_number=0,
|
|
206
|
+
error_type="TEMPLATE_FETCHES_DATA",
|
|
207
|
+
message="Templates should only handle layout. Move data fetching to page.",
|
|
208
|
+
))
|
|
209
|
+
|
|
210
|
+
return errors
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def validate_file(file_path: str) -> list:
|
|
214
|
+
"""Validate a single file for atomic design compliance."""
|
|
215
|
+
errors = []
|
|
216
|
+
|
|
217
|
+
# Skip non-TypeScript/JavaScript files
|
|
218
|
+
if not file_path.endswith((".tsx", ".ts", ".jsx", ".js")):
|
|
219
|
+
return errors
|
|
220
|
+
|
|
221
|
+
# Skip test files
|
|
222
|
+
if ".test." in file_path or ".spec." in file_path or "__tests__" in file_path:
|
|
223
|
+
return errors
|
|
224
|
+
|
|
225
|
+
# Skip ui/ directory (Gluestack library)
|
|
226
|
+
if "/components/ui/" in file_path:
|
|
227
|
+
return errors
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
231
|
+
content = f.read()
|
|
232
|
+
except (IOError, UnicodeDecodeError):
|
|
233
|
+
return errors
|
|
234
|
+
|
|
235
|
+
file_level = get_atomic_level(file_path)
|
|
236
|
+
if not file_level:
|
|
237
|
+
return errors
|
|
238
|
+
|
|
239
|
+
# Check import directions
|
|
240
|
+
for line_number, line in enumerate(content.split("\n"), 1):
|
|
241
|
+
for pattern in IMPORT_PATTERNS:
|
|
242
|
+
matches = re.findall(pattern, line)
|
|
243
|
+
for import_path in matches:
|
|
244
|
+
import_level = get_import_level(import_path)
|
|
245
|
+
if import_level:
|
|
246
|
+
error = check_import_direction(
|
|
247
|
+
file_level, import_level, file_path, import_path, line_number
|
|
248
|
+
)
|
|
249
|
+
if error:
|
|
250
|
+
errors.append(error)
|
|
251
|
+
|
|
252
|
+
# Level-specific validations
|
|
253
|
+
validators = {
|
|
254
|
+
"atoms": validate_atom,
|
|
255
|
+
"molecules": validate_molecule,
|
|
256
|
+
"organisms": validate_organism,
|
|
257
|
+
"templates": validate_template,
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
validator = validators.get(file_level)
|
|
261
|
+
if validator:
|
|
262
|
+
errors.extend(validator(file_path, content))
|
|
263
|
+
|
|
264
|
+
return errors
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def validate_directory(root_path: str) -> ValidationResult:
|
|
268
|
+
"""Validate all files in a directory tree."""
|
|
269
|
+
all_errors = []
|
|
270
|
+
all_warnings = []
|
|
271
|
+
files_checked = 0
|
|
272
|
+
|
|
273
|
+
for dirpath, _, filenames in os.walk(root_path):
|
|
274
|
+
# Skip node_modules and other non-source directories
|
|
275
|
+
if any(skip in dirpath for skip in ["node_modules", ".git", "dist", "build", ".expo"]):
|
|
276
|
+
continue
|
|
277
|
+
|
|
278
|
+
for filename in filenames:
|
|
279
|
+
file_path = os.path.join(dirpath, filename)
|
|
280
|
+
errors = validate_file(file_path)
|
|
281
|
+
all_errors.extend(errors)
|
|
282
|
+
files_checked += 1
|
|
283
|
+
|
|
284
|
+
return ValidationResult(
|
|
285
|
+
errors=all_errors,
|
|
286
|
+
warnings=all_warnings,
|
|
287
|
+
files_checked=files_checked,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def format_error(error: ValidationError) -> str:
|
|
292
|
+
"""Format a validation error for display."""
|
|
293
|
+
return f"{error.file_path}:{error.line_number}: [{error.error_type}] {error.message}"
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def main():
|
|
297
|
+
"""Main entry point."""
|
|
298
|
+
path = sys.argv[1] if len(sys.argv) > 1 else "."
|
|
299
|
+
|
|
300
|
+
if not os.path.exists(path):
|
|
301
|
+
print(f"Error: Path '{path}' does not exist")
|
|
302
|
+
sys.exit(1)
|
|
303
|
+
|
|
304
|
+
print(f"Validating atomic design structure in: {path}")
|
|
305
|
+
print("-" * 60)
|
|
306
|
+
|
|
307
|
+
if os.path.isfile(path):
|
|
308
|
+
errors = validate_file(path)
|
|
309
|
+
files_checked = 1
|
|
310
|
+
else:
|
|
311
|
+
result = validate_directory(path)
|
|
312
|
+
errors = result.errors
|
|
313
|
+
files_checked = result.files_checked
|
|
314
|
+
|
|
315
|
+
if errors:
|
|
316
|
+
print(f"\nFound {len(errors)} error(s):\n")
|
|
317
|
+
for error in errors:
|
|
318
|
+
print(f" {format_error(error)}")
|
|
319
|
+
print()
|
|
320
|
+
sys.exit(1)
|
|
321
|
+
else:
|
|
322
|
+
print(f"\n✓ All {files_checked} files pass atomic design validation")
|
|
323
|
+
sys.exit(0)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
if __name__ == "__main__":
|
|
327
|
+
main()
|