@codyswann/lisa 1.0.0 → 1.0.5

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.
Files changed (280) hide show
  1. package/README.md +244 -36
  2. package/all/copy-overwrite/.claude/README.md +1 -3
  3. package/all/copy-overwrite/.claude/REFERENCE.md +519 -0
  4. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +7 -7
  5. package/all/copy-overwrite/.claude/agents/test-coverage-agent.md +17 -0
  6. package/all/copy-overwrite/.claude/commands/git/commit.md +9 -5
  7. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +1 -1
  8. package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +209 -0
  9. package/all/copy-overwrite/.claude/commands/project/add-test-coverage.md +58 -0
  10. package/all/copy-overwrite/.claude/commands/project/archive.md +1 -1
  11. package/all/copy-overwrite/.claude/commands/project/complete-task.md +53 -1
  12. package/all/copy-overwrite/.claude/commands/project/debrief.md +12 -23
  13. package/all/copy-overwrite/.claude/commands/project/execute.md +33 -77
  14. package/all/copy-overwrite/.claude/commands/project/fix-linter-error.md +87 -0
  15. package/all/copy-overwrite/.claude/commands/project/implement.md +24 -28
  16. package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +30 -55
  17. package/all/copy-overwrite/.claude/commands/project/plan.md +87 -242
  18. package/all/copy-overwrite/.claude/commands/project/reduce-max-lines-per-function.md +76 -0
  19. package/all/copy-overwrite/.claude/commands/project/reduce-max-lines.md +75 -0
  20. package/all/copy-overwrite/.claude/commands/project/research.md +86 -188
  21. package/all/copy-overwrite/.claude/commands/project/review.md +19 -38
  22. package/all/copy-overwrite/.claude/commands/project/setup.md +1 -1
  23. package/all/copy-overwrite/.claude/commands/project/verify.md +62 -25
  24. package/all/copy-overwrite/.claude/commands/pull-request/review.md +25 -7
  25. package/all/copy-overwrite/.claude/commands/tasks/load.md +63 -0
  26. package/all/copy-overwrite/.claude/commands/tasks/sync.md +84 -0
  27. package/all/copy-overwrite/.claude/hooks/README.md +75 -0
  28. package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +61 -0
  29. package/all/copy-overwrite/.claude/hooks/debug-hook.sh +47 -0
  30. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +2 -0
  31. package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +95 -0
  32. package/all/copy-overwrite/.claude/{skills/coding-philosophy/SKILL.md → rules/coding-philosophy.md} +93 -70
  33. package/all/copy-overwrite/.claude/settings.json +35 -14
  34. package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +41 -9
  35. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +2 -0
  36. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +2 -0
  37. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +2 -0
  38. package/all/copy-overwrite/.safety-net.json +25 -0
  39. package/all/copy-overwrite/CLAUDE.md +8 -30
  40. package/all/copy-overwrite/HUMAN.md +517 -17
  41. package/all/create-only/.claude/rules/PROJECT_RULES.md +9 -0
  42. package/all/create-only/scripts/setup-deploy-key.sh +190 -0
  43. package/all/deletions.json +5 -0
  44. package/cdk/copy-overwrite/.github/workflows/ci.yml +142 -0
  45. package/cdk/copy-overwrite/.github/workflows/deploy.yml +59 -0
  46. package/cdk/copy-overwrite/eslint.cdk.ts +175 -0
  47. package/cdk/copy-overwrite/eslint.config.ts +51 -0
  48. package/cdk/copy-overwrite/eslint.slow.config.ts +80 -0
  49. package/cdk/copy-overwrite/knip.json +53 -0
  50. package/cdk/copy-overwrite/tsconfig.eslint.json +11 -0
  51. package/cdk/merge/package.json +17 -1
  52. package/dist/cli/index.d.ts +3 -2
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +83 -64
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/prompts.d.ts +17 -3
  57. package/dist/cli/prompts.d.ts.map +1 -1
  58. package/dist/cli/prompts.js +52 -16
  59. package/dist/cli/prompts.js.map +1 -1
  60. package/dist/core/config.d.ts +13 -4
  61. package/dist/core/config.d.ts.map +1 -1
  62. package/dist/core/config.js +17 -9
  63. package/dist/core/config.js.map +1 -1
  64. package/dist/core/git-service.d.ts +40 -0
  65. package/dist/core/git-service.d.ts.map +1 -0
  66. package/dist/core/git-service.js +52 -0
  67. package/dist/core/git-service.js.map +1 -0
  68. package/dist/core/index.d.ts +3 -3
  69. package/dist/core/index.js +3 -3
  70. package/dist/core/lisa.d.ts +124 -7
  71. package/dist/core/lisa.d.ts.map +1 -1
  72. package/dist/core/lisa.js +423 -221
  73. package/dist/core/lisa.js.map +1 -1
  74. package/dist/core/manifest.d.ts +5 -1
  75. package/dist/core/manifest.d.ts.map +1 -1
  76. package/dist/core/manifest.js +22 -16
  77. package/dist/core/manifest.js.map +1 -1
  78. package/dist/detection/detector.interface.d.ts +1 -1
  79. package/dist/detection/detectors/cdk.d.ts +6 -1
  80. package/dist/detection/detectors/cdk.d.ts.map +1 -1
  81. package/dist/detection/detectors/cdk.js +16 -8
  82. package/dist/detection/detectors/cdk.js.map +1 -1
  83. package/dist/detection/detectors/expo.d.ts +6 -1
  84. package/dist/detection/detectors/expo.d.ts.map +1 -1
  85. package/dist/detection/detectors/expo.js +13 -8
  86. package/dist/detection/detectors/expo.js.map +1 -1
  87. package/dist/detection/detectors/nestjs.d.ts +7 -2
  88. package/dist/detection/detectors/nestjs.d.ts.map +1 -1
  89. package/dist/detection/detectors/nestjs.js +17 -9
  90. package/dist/detection/detectors/nestjs.js.map +1 -1
  91. package/dist/detection/detectors/npm-package.d.ts +6 -1
  92. package/dist/detection/detectors/npm-package.d.ts.map +1 -1
  93. package/dist/detection/detectors/npm-package.js +9 -4
  94. package/dist/detection/detectors/npm-package.js.map +1 -1
  95. package/dist/detection/detectors/typescript.d.ts +6 -1
  96. package/dist/detection/detectors/typescript.d.ts.map +1 -1
  97. package/dist/detection/detectors/typescript.js +12 -7
  98. package/dist/detection/detectors/typescript.js.map +1 -1
  99. package/dist/detection/index.d.ts +13 -3
  100. package/dist/detection/index.d.ts.map +1 -1
  101. package/dist/detection/index.js +17 -7
  102. package/dist/detection/index.js.map +1 -1
  103. package/dist/errors/index.d.ts +66 -2
  104. package/dist/errors/index.d.ts.map +1 -1
  105. package/dist/errors/index.js +89 -17
  106. package/dist/errors/index.js.map +1 -1
  107. package/dist/index.js +3 -3
  108. package/dist/index.js.map +1 -1
  109. package/dist/logging/console-logger.d.ts +21 -1
  110. package/dist/logging/console-logger.d.ts.map +1 -1
  111. package/dist/logging/console-logger.js +26 -6
  112. package/dist/logging/console-logger.js.map +1 -1
  113. package/dist/logging/index.d.ts +3 -3
  114. package/dist/logging/index.js +2 -2
  115. package/dist/logging/logger.interface.d.ts +1 -1
  116. package/dist/logging/silent-logger.d.ts +21 -1
  117. package/dist/logging/silent-logger.d.ts.map +1 -1
  118. package/dist/logging/silent-logger.js +20 -0
  119. package/dist/logging/silent-logger.js.map +1 -1
  120. package/dist/strategies/copy-contents.d.ts +47 -6
  121. package/dist/strategies/copy-contents.d.ts.map +1 -1
  122. package/dist/strategies/copy-contents.js +99 -49
  123. package/dist/strategies/copy-contents.js.map +1 -1
  124. package/dist/strategies/copy-overwrite.d.ts +10 -2
  125. package/dist/strategies/copy-overwrite.d.ts.map +1 -1
  126. package/dist/strategies/copy-overwrite.js +17 -9
  127. package/dist/strategies/copy-overwrite.js.map +1 -1
  128. package/dist/strategies/create-only.d.ts +10 -2
  129. package/dist/strategies/create-only.d.ts.map +1 -1
  130. package/dist/strategies/create-only.js +14 -6
  131. package/dist/strategies/create-only.js.map +1 -1
  132. package/dist/strategies/index.d.ts +17 -7
  133. package/dist/strategies/index.d.ts.map +1 -1
  134. package/dist/strategies/index.js +19 -9
  135. package/dist/strategies/index.js.map +1 -1
  136. package/dist/strategies/merge.d.ts +10 -2
  137. package/dist/strategies/merge.d.ts.map +1 -1
  138. package/dist/strategies/merge.js +21 -21
  139. package/dist/strategies/merge.js.map +1 -1
  140. package/dist/strategies/strategy.interface.d.ts +1 -1
  141. package/dist/strategies/strategy.interface.d.ts.map +1 -1
  142. package/dist/transaction/backup.d.ts +15 -1
  143. package/dist/transaction/backup.d.ts.map +1 -1
  144. package/dist/transaction/backup.js +47 -12
  145. package/dist/transaction/backup.js.map +1 -1
  146. package/dist/transaction/index.d.ts +3 -3
  147. package/dist/transaction/index.js +2 -2
  148. package/dist/transaction/transaction.d.ts +25 -2
  149. package/dist/transaction/transaction.d.ts.map +1 -1
  150. package/dist/transaction/transaction.js +25 -2
  151. package/dist/transaction/transaction.js.map +1 -1
  152. package/dist/utils/file-operations.d.ts +21 -0
  153. package/dist/utils/file-operations.d.ts.map +1 -1
  154. package/dist/utils/file-operations.js +48 -12
  155. package/dist/utils/file-operations.js.map +1 -1
  156. package/dist/utils/index.d.ts +3 -3
  157. package/dist/utils/index.js +3 -3
  158. package/dist/utils/json-utils.d.ts +12 -0
  159. package/dist/utils/json-utils.d.ts.map +1 -1
  160. package/dist/utils/json-utils.js +17 -5
  161. package/dist/utils/json-utils.js.map +1 -1
  162. package/dist/utils/path-utils.d.ts +11 -0
  163. package/dist/utils/path-utils.d.ts.map +1 -1
  164. package/dist/utils/path-utils.js +12 -1
  165. package/dist/utils/path-utils.js.map +1 -1
  166. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +5 -0
  167. package/eslint-plugin-code-organization/index.js +5 -0
  168. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +5 -0
  169. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +2 -0
  170. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +2 -0
  171. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +2 -0
  172. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +2 -0
  173. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +2 -0
  174. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +2 -0
  175. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +2 -41
  176. package/{typescript → expo}/copy-overwrite/.github/workflows/build.yml +3 -0
  177. package/expo/copy-overwrite/.github/workflows/ci.yml +36 -0
  178. package/{typescript → expo}/copy-overwrite/.github/workflows/deploy.yml +22 -26
  179. package/{typescript → expo}/copy-overwrite/.github/workflows/lighthouse.yml +4 -1
  180. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +5 -0
  181. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +5 -0
  182. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +5 -0
  183. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +5 -0
  184. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +5 -0
  185. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +6 -1
  186. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +5 -0
  187. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +5 -0
  188. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -68
  189. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +5 -3
  190. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +5 -0
  191. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +5 -0
  192. package/expo/copy-overwrite/eslint.config.ts +53 -0
  193. package/expo/copy-overwrite/eslint.expo.ts +330 -0
  194. package/expo/copy-overwrite/eslint.slow.config.ts +86 -0
  195. package/expo/copy-overwrite/knip.json +132 -0
  196. package/expo/copy-overwrite/lighthouserc.js +27 -0
  197. package/expo/copy-overwrite/tsconfig.eslint.json +25 -0
  198. package/expo/create-only/lighthouserc-config.json +6 -1
  199. package/expo/merge/package.json +16 -3
  200. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +1 -1
  201. package/{typescript → nestjs}/copy-overwrite/.github/k6/README.md +2 -2
  202. package/{typescript → nestjs}/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +3 -0
  203. package/{typescript → nestjs}/copy-overwrite/.github/k6/examples/data-driven-test.js +5 -0
  204. package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/load.js +6 -2
  205. package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/smoke.js +5 -0
  206. package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/soak.js +5 -0
  207. package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/spike.js +5 -0
  208. package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/stress.js +5 -0
  209. package/{typescript → nestjs}/copy-overwrite/.github/k6/scripts/api-test.js +5 -0
  210. package/{typescript → nestjs}/copy-overwrite/.github/k6/scripts/default-test.js +5 -0
  211. package/nestjs/copy-overwrite/.github/workflows/ci.yml +29 -0
  212. package/nestjs/copy-overwrite/.github/workflows/deploy.yml +291 -0
  213. package/{typescript → nestjs}/copy-overwrite/.github/workflows/load-test.yml +3 -0
  214. package/nestjs/copy-overwrite/eslint.config.ts +53 -0
  215. package/nestjs/copy-overwrite/eslint.nestjs.ts +178 -0
  216. package/nestjs/merge/package.json +11 -3
  217. package/package.json +34 -40
  218. package/typescript/copy-contents/.husky/pre-commit +1 -1
  219. package/typescript/copy-contents/.husky/pre-push +99 -118
  220. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +2 -0
  221. package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +3 -11
  222. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +2 -0
  223. package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +68 -0
  224. package/typescript/copy-overwrite/.claude/settings.json +79 -0
  225. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +44 -0
  226. package/typescript/copy-overwrite/.github/README.md +49 -1
  227. package/typescript/copy-overwrite/.github/dependabot.yml +3 -0
  228. package/typescript/copy-overwrite/.github/workflows/ci.yml +7 -29
  229. package/typescript/copy-overwrite/.github/workflows/claude.yml +3 -0
  230. package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +6 -4
  231. package/typescript/copy-overwrite/.github/workflows/create-issue-on-failure.yml +176 -0
  232. package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +3 -1
  233. package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +3 -1
  234. package/typescript/copy-overwrite/.github/workflows/lint-slow.yml +40 -0
  235. package/typescript/copy-overwrite/.github/workflows/quality.yml +151 -38
  236. package/typescript/copy-overwrite/.github/workflows/release.yml +3 -0
  237. package/typescript/copy-overwrite/.gitleaksignore +3 -0
  238. package/typescript/copy-overwrite/.lintstagedrc.json +6 -0
  239. package/typescript/copy-overwrite/.prettierignore +2 -1
  240. package/typescript/copy-overwrite/.yamllint +2 -0
  241. package/typescript/copy-overwrite/ast-grep/rule-tests/.gitkeep +3 -0
  242. package/typescript/copy-overwrite/ast-grep/rules/.gitkeep +3 -0
  243. package/typescript/copy-overwrite/ast-grep/utils/.gitkeep +3 -0
  244. package/typescript/copy-overwrite/{commitlint.config.js → commitlint.config.cjs} +5 -0
  245. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +5 -0
  246. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +5 -0
  247. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +5 -0
  248. package/typescript/copy-overwrite/eslint.base.ts +430 -0
  249. package/typescript/copy-overwrite/eslint.config.ts +52 -0
  250. package/typescript/copy-overwrite/eslint.ignore.config.json +19 -2
  251. package/typescript/copy-overwrite/eslint.slow.config.ts +69 -0
  252. package/typescript/copy-overwrite/eslint.typescript.ts +142 -0
  253. package/typescript/copy-overwrite/knip.json +64 -0
  254. package/typescript/copy-overwrite/sgconfig.yml +11 -0
  255. package/typescript/copy-overwrite/tsconfig.eslint.json +9 -0
  256. package/typescript/create-only/eslint.config.local.ts +24 -0
  257. package/typescript/{copy-overwrite/eslint.thresholds.config.json → create-only/eslint.thresholds.json} +1 -1
  258. package/typescript/github-rulesets/base.json +2 -75
  259. package/typescript/merge/.claude/settings.json +160 -0
  260. package/typescript/merge/package.json +35 -34
  261. package/all/copy-overwrite/.claude/commands/rules/format-md.md +0 -72
  262. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +0 -416
  263. package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +0 -316
  264. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +0 -73
  265. package/expo/copy-overwrite/eslint.config.mjs +0 -560
  266. package/lisa.sh +0 -35
  267. package/typescript/copy-overwrite/eslint.config.mjs +0 -390
  268. /package/{all/create-only/PROJECT_RULES.md → cdk/copy-overwrite/.github/workflows/.keep} +0 -0
  269. /package/{typescript → nestjs}/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +0 -0
  270. /package/{typescript → nestjs}/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +0 -0
  271. /package/{typescript → nestjs}/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +0 -0
  272. /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/load.json +0 -0
  273. /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/smoke.json +0 -0
  274. /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/soak.json +0 -0
  275. /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/spike.json +0 -0
  276. /package/{typescript → nestjs}/copy-overwrite/.github/k6/scenarios/stress.json +0 -0
  277. /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/normal.json +0 -0
  278. /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/relaxed.json +0 -0
  279. /package/{typescript → nestjs}/copy-overwrite/.github/k6/thresholds/strict.json +0 -0
  280. /package/{typescript → nestjs}/copy-overwrite/.github/workflows/k6-load-test-README.md +0 -0
@@ -1,316 +0,0 @@
1
- # Immutable Patterns Reference
2
-
3
- This document provides comprehensive examples of immutable patterns used in this codebase.
4
-
5
- ## Building Lookup Objects with Reduce
6
-
7
- ### Basic Pattern
8
-
9
- ```typescript
10
- const colorMap =
11
- edges?.reduce(
12
- (acc, edge) => (edge.color ? { ...acc, [edge.tagId]: edge.color } : acc),
13
- {} as Record<string, string>
14
- ) ?? {};
15
- ```
16
-
17
- ### With Null Safety
18
-
19
- ```typescript
20
- const boardColorMap =
21
- data?.edges?.reduce(
22
- (acc, edge) => (edge.color ? { ...acc, [edge.tagId]: edge.color } : acc),
23
- {} as Record<string, string>
24
- ) ?? {};
25
- ```
26
-
27
- ### Accumulating Multiple Properties
28
-
29
- ```typescript
30
- const teamGprAccumulator = validPlayers.reduce(
31
- (acc, player) => {
32
- const teamId = player.team?.id;
33
- if (!teamId) return acc;
34
-
35
- const existing = acc[teamId];
36
- return {
37
- ...acc,
38
- [teamId]: {
39
- teamId,
40
- teamName: player.team.name,
41
- gprSum: (existing?.gprSum ?? 0) + player.gpr,
42
- playerCount: (existing?.playerCount ?? 0) + 1,
43
- },
44
- };
45
- },
46
- {} as Record<
47
- string,
48
- { teamId: string; teamName: string; gprSum: number; playerCount: number }
49
- >
50
- );
51
- ```
52
-
53
- ### With Parallel Array Lookups (using index)
54
-
55
- ```typescript
56
- const formattedMetricsMap = useMemo(
57
- () =>
58
- metrics.reduce(
59
- (acc, metric, index) => ({
60
- ...acc,
61
- [metric.displayName]: formattedMetrics[index],
62
- }),
63
- {} as Record<string, ICompositeMetric>
64
- ),
65
- [metrics, formattedMetrics]
66
- );
67
- ```
68
-
69
- ## Record vs Map
70
-
71
- Always prefer `Record<string, T>` over `Map<string, T>` for simple lookups.
72
-
73
- ### Record Pattern (Preferred)
74
-
75
- ```typescript
76
- type UserNameMap = Record<string, string>;
77
- const userNames: UserNameMap = { id1: "John Doe", id2: "Jane Smith" };
78
-
79
- // Access
80
- const name = userNames[userId];
81
- const hasPlayer = playerId in playersOnKanban;
82
- ```
83
-
84
- ### Why Not Map
85
-
86
- ```typescript
87
- // Avoid this pattern
88
- const lookup = new Map<string, User>();
89
- users.forEach(u => lookup.set(u.id, u));
90
- const user = lookup.get(userId);
91
-
92
- // Use this instead
93
- const lookup = users.reduce(
94
- (acc, u) => ({ ...acc, [u.id]: u }),
95
- {} as Record<string, User>
96
- );
97
- const user = lookup[userId];
98
- ```
99
-
100
- ## Array Transformations
101
-
102
- ### Spread Before Sort
103
-
104
- Never sort in place. Always spread first.
105
-
106
- ```typescript
107
- // Correct
108
- const sorted = [...Object.values(seasonData)].sort((a, b) =>
109
- a.season > b.season ? 1 : -1
110
- );
111
-
112
- // Incorrect - mutates original
113
- const sorted = seasonData.sort((a, b) => a.season - b.season);
114
- ```
115
-
116
- ### Filter with Boolean
117
-
118
- ```typescript
119
- const validPlayers = leaguePlayers.filter(
120
- Boolean
121
- ) as readonly PlayerWithScores[];
122
- ```
123
-
124
- ### Map for Transformation
125
-
126
- ```typescript
127
- const teamGprData: readonly TeamGprData[] = Object.values(
128
- teamGprAccumulator
129
- ).map(team => ({
130
- teamId: team.teamId,
131
- teamName: team.teamName,
132
- averageGpr: team.playerCount > 0 ? team.gprSum / team.playerCount : 0,
133
- }));
134
- ```
135
-
136
- ### Updating Array Item at Index
137
-
138
- ```typescript
139
- // Correct - creates new array
140
- const updated = current.map((item, idx) => (idx === target ? newItem : item));
141
-
142
- // Incorrect - mutation
143
- current[target] = newItem;
144
- ```
145
-
146
- ### Adding to Array
147
-
148
- ```typescript
149
- // Correct
150
- const withNew = [...existing, newItem];
151
-
152
- // Incorrect
153
- existing.push(newItem);
154
- ```
155
-
156
- ### Removing from Array
157
-
158
- ```typescript
159
- // Correct
160
- const without = items.filter(item => item.id !== idToRemove);
161
-
162
- // Incorrect
163
- const idx = items.findIndex(item => item.id === idToRemove);
164
- items.splice(idx, 1);
165
- ```
166
-
167
- ## Object Updates
168
-
169
- ### Spread for Updates
170
-
171
- ```typescript
172
- // Correct
173
- const updated = { ...user, name: "New Name" };
174
-
175
- // Incorrect
176
- user.name = "New Name";
177
- ```
178
-
179
- ### Nested Object Updates
180
-
181
- ```typescript
182
- const updated = {
183
- ...state,
184
- user: {
185
- ...state.user,
186
- profile: {
187
- ...state.user.profile,
188
- avatar: newAvatar,
189
- },
190
- },
191
- };
192
- ```
193
-
194
- ### Conditional Property Addition
195
-
196
- ```typescript
197
- const result = {
198
- ...baseObj,
199
- ...(condition && { optionalProp: value }),
200
- };
201
- ```
202
-
203
- ## Conditional Values Without Let
204
-
205
- ### Ternary for Simple Conditions
206
-
207
- ```typescript
208
- // Correct
209
- const status = isComplete ? "done" : "pending";
210
-
211
- // Incorrect
212
- let status = "pending";
213
- if (isComplete) {
214
- status = "done";
215
- }
216
- ```
217
-
218
- ### Ternary Chain for Multiple Conditions
219
-
220
- ```typescript
221
- const priority = score > 90 ? "high" : score > 70 ? "medium" : "low";
222
- ```
223
-
224
- ### Nullish Coalescing
225
-
226
- ```typescript
227
- const displayName = user.name ?? "Unknown User";
228
- const count = existing?.count ?? 0;
229
- ```
230
-
231
- ### Optional Chaining with Nullish Coalescing
232
-
233
- ```typescript
234
- const firstName =
235
- user.cognitoUser?.Attributes?.find(attr => attr.Name === "given_name")
236
- ?.Value ?? "";
237
- ```
238
-
239
- ## Apollo Reactive Variables
240
-
241
- ### Immutable Updates
242
-
243
- ```typescript
244
- // Direct update for simple values
245
- isLoadingVar(true);
246
- errorVar("Error message");
247
-
248
- // Spread for array updates
249
- messagesVar([...messagesVar(), newMessage]);
250
-
251
- // Spread for complex updates
252
- const current = messagesVar();
253
- messagesVar([...current, newMessage]);
254
- ```
255
-
256
- ### Operation Hooks for Complex Updates
257
-
258
- ```typescript
259
- export const useMessageOperations = () => {
260
- const addMessage = useCallback((message: IMessage) => {
261
- const current = messagesVar();
262
- messagesVar([...current, message]);
263
- }, []);
264
-
265
- const clearMessages = useCallback(() => {
266
- messagesVar([]);
267
- }, []);
268
-
269
- return { addMessage, clearMessages };
270
- };
271
- ```
272
-
273
- ## Readonly Types
274
-
275
- ### Function Parameters
276
-
277
- ```typescript
278
- export const calculateTeamGprRank = (
279
- leaguePlayers: readonly (PlayerWithScores | null | undefined)[],
280
- myTeamId: string | null | undefined
281
- ): number | null => {
282
- // ...
283
- };
284
- ```
285
-
286
- ### Apollo Cache Modifiers
287
-
288
- ```typescript
289
- modify({
290
- fields: {
291
- myField(existingData: readonly { __ref: string }[] = [], { readField }) {
292
- return existingData.filter(ref => readField("id", ref) !== idToRemove);
293
- },
294
- },
295
- });
296
- ```
297
-
298
- ## Testing Immutability
299
-
300
- ### Verify New Object Creation
301
-
302
- ```typescript
303
- test("should create new object on each reduce iteration", () => {
304
- expect(result1).not.toBe(result2); // Different references
305
- expect(result1).toEqual(result2); // Same values
306
- });
307
- ```
308
-
309
- ### Verify Record vs Map
310
-
311
- ```typescript
312
- test("should return plain object, not Map", () => {
313
- expect(result).toBeInstanceOf(Object);
314
- expect(result).not.toBeInstanceOf(Map);
315
- });
316
- ```
@@ -1,73 +0,0 @@
1
- module.exports = {
2
- meta: {
3
- type: "problem",
4
- docs: {
5
- description: "Disallow inline style prop usage",
6
- category: "Best Practices",
7
- recommended: true,
8
- },
9
- fixable: null,
10
- schema: [
11
- {
12
- type: "object",
13
- properties: {
14
- allowedPaths: {
15
- type: "array",
16
- items: { type: "string" },
17
- },
18
- allowedComponents: {
19
- type: "array",
20
- items: { type: "string" },
21
- },
22
- },
23
- additionalProperties: false,
24
- },
25
- ],
26
- messages: {
27
- noInlineStyles:
28
- "Inline styles are not allowed. Use Gluestack components with semantic props or create a reusable component.",
29
- noInlineStylesComponent:
30
- "Inline styles are not allowed on {{componentName}}. Use semantic props or create a reusable component.",
31
- },
32
- },
33
-
34
- create(context) {
35
- const options = context.options[0] || {};
36
- const allowedPaths = options.allowedPaths || [
37
- "/components/ui/",
38
- "/components/custom/ui/",
39
- "\\components\\ui\\", // Windows
40
- "\\components\\custom\\ui\\", // Windows
41
- ];
42
- const allowedComponents = options.allowedComponents || [];
43
-
44
- return {
45
- JSXAttribute(node) {
46
- if (node.name.name !== "style") return;
47
-
48
- const filename = context.getFilename();
49
- const isPathAllowed = allowedPaths.some(path =>
50
- filename.includes(path)
51
- );
52
-
53
- if (isPathAllowed) return;
54
-
55
- // Check if it's an allowed component
56
- const parentElement = node.parent;
57
- const componentName = parentElement.name.name;
58
-
59
- if (allowedComponents.includes(componentName)) return;
60
-
61
- context.report({
62
- node,
63
- messageId: componentName
64
- ? "noInlineStylesComponent"
65
- : "noInlineStyles",
66
- data: {
67
- componentName,
68
- },
69
- });
70
- },
71
- };
72
- },
73
- };