leadcode 0.2.1 → 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/dist/analyzers/detection.d.ts.map +1 -1
- package/dist/analyzers/detection.js +55 -5
- package/dist/analyzers/detection.js.map +1 -1
- package/dist/context7/client.d.ts +17 -0
- package/dist/context7/client.d.ts.map +1 -0
- package/dist/context7/client.js +82 -0
- package/dist/context7/client.js.map +1 -0
- package/dist/context7/index.d.ts +5 -0
- package/dist/context7/index.d.ts.map +1 -0
- package/dist/context7/index.js +3 -0
- package/dist/context7/index.js.map +1 -0
- package/dist/context7/queries.d.ts +11 -0
- package/dist/context7/queries.d.ts.map +1 -0
- package/dist/context7/queries.js +229 -0
- package/dist/context7/queries.js.map +1 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +3 -242
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +21 -260
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/types.d.ts +2 -232
- package/dist/i18n/types.d.ts.map +1 -1
- package/dist/index.js +13 -19
- package/dist/index.js.map +1 -1
- package/dist/templates/claude-md.d.ts +3 -2
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +97 -65
- package/dist/templates/claude-md.js.map +1 -1
- package/dist/tools/fetch-docs.d.ts +13 -0
- package/dist/tools/fetch-docs.d.ts.map +1 -0
- package/dist/tools/fetch-docs.js +141 -0
- package/dist/tools/fetch-docs.js.map +1 -0
- package/dist/tools/generate-claude-md.d.ts.map +1 -1
- package/dist/tools/generate-claude-md.js +12 -12
- package/dist/tools/generate-claude-md.js.map +1 -1
- package/dist/tools/update-claude-md.d.ts.map +1 -1
- package/dist/tools/update-claude-md.js +63 -11
- package/dist/tools/update-claude-md.js.map +1 -1
- package/dist/tools/validate-claude-md.d.ts.map +1 -1
- package/dist/tools/validate-claude-md.js +10 -48
- package/dist/tools/validate-claude-md.js.map +1 -1
- package/dist/types.d.ts +2 -43
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/rules/auth.d.ts +0 -3
- package/dist/rules/auth.d.ts.map +0 -1
- package/dist/rules/auth.js +0 -48
- package/dist/rules/auth.js.map +0 -1
- package/dist/rules/cross-stack.d.ts +0 -3
- package/dist/rules/cross-stack.d.ts.map +0 -1
- package/dist/rules/cross-stack.js +0 -320
- package/dist/rules/cross-stack.js.map +0 -1
- package/dist/rules/drizzle.d.ts +0 -3
- package/dist/rules/drizzle.d.ts.map +0 -1
- package/dist/rules/drizzle.js +0 -43
- package/dist/rules/drizzle.js.map +0 -1
- package/dist/rules/index.d.ts +0 -7
- package/dist/rules/index.d.ts.map +0 -1
- package/dist/rules/index.js +0 -104
- package/dist/rules/index.js.map +0 -1
- package/dist/rules/nextjs.d.ts +0 -4
- package/dist/rules/nextjs.d.ts.map +0 -1
- package/dist/rules/nextjs.js +0 -86
- package/dist/rules/nextjs.js.map +0 -1
- package/dist/rules/node.d.ts +0 -3
- package/dist/rules/node.d.ts.map +0 -1
- package/dist/rules/node.js +0 -61
- package/dist/rules/node.js.map +0 -1
- package/dist/rules/prisma.d.ts +0 -3
- package/dist/rules/prisma.d.ts.map +0 -1
- package/dist/rules/prisma.js +0 -44
- package/dist/rules/prisma.js.map +0 -1
- package/dist/rules/react.d.ts +0 -3
- package/dist/rules/react.d.ts.map +0 -1
- package/dist/rules/react.js +0 -58
- package/dist/rules/react.js.map +0 -1
- package/dist/rules/state.d.ts +0 -3
- package/dist/rules/state.d.ts.map +0 -1
- package/dist/rules/state.js +0 -54
- package/dist/rules/state.js.map +0 -1
- package/dist/rules/tailwind.d.ts +0 -3
- package/dist/rules/tailwind.d.ts.map +0 -1
- package/dist/rules/tailwind.js +0 -41
- package/dist/rules/tailwind.js.map +0 -1
- package/dist/rules/trpc.d.ts +0 -3
- package/dist/rules/trpc.d.ts.map +0 -1
- package/dist/rules/trpc.js +0 -35
- package/dist/rules/trpc.js.map +0 -1
- package/dist/rules/typescript.d.ts +0 -3
- package/dist/rules/typescript.d.ts.map +0 -1
- package/dist/rules/typescript.js +0 -54
- package/dist/rules/typescript.js.map +0 -1
- package/dist/rules/validation.d.ts +0 -3
- package/dist/rules/validation.d.ts.map +0 -1
- package/dist/rules/validation.js +0 -38
- package/dist/rules/validation.js.map +0 -1
- package/dist/tools/detect-gaps.d.ts +0 -3
- package/dist/tools/detect-gaps.d.ts.map +0 -1
- package/dist/tools/detect-gaps.js +0 -34
- package/dist/tools/detect-gaps.js.map +0 -1
- package/dist/tools/suggest.d.ts +0 -3
- package/dist/tools/suggest.d.ts.map +0 -1
- package/dist/tools/suggest.js +0 -99
- package/dist/tools/suggest.js.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -43,6 +43,8 @@ export interface DetectedStack {
|
|
|
43
43
|
css: string | null;
|
|
44
44
|
testing: string | null;
|
|
45
45
|
stateManagement: string | null;
|
|
46
|
+
dataFetching: string | null;
|
|
47
|
+
formLibrary: string | null;
|
|
46
48
|
apiStyle: string | null;
|
|
47
49
|
bundler: string | null;
|
|
48
50
|
linter: string | null;
|
|
@@ -70,47 +72,4 @@ export interface RepoAnalysis {
|
|
|
70
72
|
structure: StructureInfo;
|
|
71
73
|
detected: DetectedStack;
|
|
72
74
|
}
|
|
73
|
-
export interface Gap {
|
|
74
|
-
category: string;
|
|
75
|
-
severity: "high" | "medium" | "low";
|
|
76
|
-
message: string;
|
|
77
|
-
details?: string;
|
|
78
|
-
}
|
|
79
|
-
export interface SuggestionOption {
|
|
80
|
-
level: "simple" | "clean" | "scalable";
|
|
81
|
-
description: string;
|
|
82
|
-
pros: string[];
|
|
83
|
-
cons: string[];
|
|
84
|
-
claudeImpact: string;
|
|
85
|
-
}
|
|
86
|
-
export interface Suggestion {
|
|
87
|
-
topic: string;
|
|
88
|
-
options: SuggestionOption[];
|
|
89
|
-
}
|
|
90
|
-
export interface GapCheck {
|
|
91
|
-
category: string;
|
|
92
|
-
severity: "high" | "medium" | "low";
|
|
93
|
-
check: (analysis: RepoAnalysis) => boolean;
|
|
94
|
-
message: string;
|
|
95
|
-
details?: string;
|
|
96
|
-
}
|
|
97
|
-
export interface Convention {
|
|
98
|
-
id: string;
|
|
99
|
-
description: string;
|
|
100
|
-
rule: string;
|
|
101
|
-
}
|
|
102
|
-
export interface CrossRef {
|
|
103
|
-
techs: string[];
|
|
104
|
-
conventions: Convention[];
|
|
105
|
-
interdictions: string[];
|
|
106
|
-
}
|
|
107
|
-
export interface Rule {
|
|
108
|
-
id: string;
|
|
109
|
-
name: string;
|
|
110
|
-
applies: (analysis: RepoAnalysis) => boolean;
|
|
111
|
-
gaps: GapCheck[];
|
|
112
|
-
conventions: Convention[];
|
|
113
|
-
interdictions: string[];
|
|
114
|
-
crossRefs: CrossRef[];
|
|
115
|
-
}
|
|
116
75
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IAErB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IAErB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IAErB,eAAe,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAEzC,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IAErB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IAErB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IAErB,eAAe,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAEzC,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB"}
|
package/package.json
CHANGED
package/dist/rules/auth.d.ts
DELETED
package/dist/rules/auth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/rules/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,eAAO,MAAM,SAAS,EAAE,IAiDvB,CAAC"}
|
package/dist/rules/auth.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
export const authRules = {
|
|
2
|
-
id: "auth",
|
|
3
|
-
name: "Authentication",
|
|
4
|
-
applies: (a) => a.detected.auth !== null,
|
|
5
|
-
gaps: [
|
|
6
|
-
{
|
|
7
|
-
category: "auth-middleware",
|
|
8
|
-
severity: "high",
|
|
9
|
-
check: (a) => a.framework?.name === "next" &&
|
|
10
|
-
a.framework.variant === "app-router" &&
|
|
11
|
-
!a.structure.hasMiddleware,
|
|
12
|
-
message: "No middleware.ts detected for route protection",
|
|
13
|
-
details: "Next.js App Router should use middleware.ts for authentication checks on protected routes.",
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
category: "auth-session",
|
|
17
|
-
severity: "medium",
|
|
18
|
-
check: (a) => !a.structure.hasLibDir && !a.structure.hasUtilsDir,
|
|
19
|
-
message: "No centralized auth utility detected (e.g., lib/auth.ts)",
|
|
20
|
-
details: "Every protected Server Component and API route must validate the session server-side. Never rely on client-side auth state alone.",
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
conventions: [
|
|
24
|
-
{
|
|
25
|
-
id: "auth-server-check",
|
|
26
|
-
description: "Server-side auth checks",
|
|
27
|
-
rule: "Always validate authentication on the server (middleware, Server Components, API routes). Client-side checks are for UX only, not security.",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
id: "auth-centralized",
|
|
31
|
-
description: "Centralized auth utilities",
|
|
32
|
-
rule: "Create a single auth utility (e.g., lib/auth.ts) that exports getCurrentUser(), requireAuth(), etc. All auth checks go through this module.",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: "auth-protect-api",
|
|
36
|
-
description: "Protect API routes",
|
|
37
|
-
rule: "Every API route that requires auth must call requireAuth() at the top. No exceptions.",
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
interdictions: [
|
|
41
|
-
"NEVER store auth tokens in localStorage — use httpOnly cookies.",
|
|
42
|
-
"NEVER trust client-sent user IDs — always derive user identity from the session.",
|
|
43
|
-
"NEVER expose user passwords, hashes, or internal IDs in API responses.",
|
|
44
|
-
"NEVER skip auth checks on API routes because 'the UI prevents access'.",
|
|
45
|
-
],
|
|
46
|
-
crossRefs: [],
|
|
47
|
-
};
|
|
48
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/rules/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/rules/auth.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI;IACxC,IAAI,EAAE;QACJ;YACE,QAAQ,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACX,CAAC,CAAC,SAAS,EAAE,IAAI,KAAK,MAAM;gBAC5B,CAAC,CAAC,SAAS,CAAC,OAAO,KAAK,YAAY;gBACpC,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa;YAC5B,OAAO,EAAE,gDAAgD;YACzD,OAAO,EACL,4FAA4F;SAC/F;QACD;YACE,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW;YAChE,OAAO,EAAE,0DAA0D;YACnE,OAAO,EACL,mIAAmI;SACtI;KACF;IACD,WAAW,EAAE;QACX;YACE,EAAE,EAAE,mBAAmB;YACvB,WAAW,EAAE,yBAAyB;YACtC,IAAI,EAAE,6IAA6I;SACpJ;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,WAAW,EAAE,4BAA4B;YACzC,IAAI,EAAE,6IAA6I;SACpJ;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,WAAW,EAAE,oBAAoB;YACjC,IAAI,EAAE,uFAAuF;SAC9F;KACF;IACD,aAAa,EAAE;QACb,iEAAiE;QACjE,kFAAkF;QAClF,wEAAwE;QACxE,wEAAwE;KACzE;IACD,SAAS,EAAE,EAAE;CACd,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cross-stack.d.ts","sourceRoot":"","sources":["../../src/rules/cross-stack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,eAAO,MAAM,eAAe,EAAE,IA8T7B,CAAC"}
|
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
export const crossStackRules = {
|
|
2
|
-
id: "cross-stack",
|
|
3
|
-
name: "Cross-Stack Rules",
|
|
4
|
-
applies: () => true, // Always active, individual crossRefs have their own conditions
|
|
5
|
-
gaps: [],
|
|
6
|
-
conventions: [],
|
|
7
|
-
interdictions: [],
|
|
8
|
-
crossRefs: [
|
|
9
|
-
// Next.js + Prisma
|
|
10
|
-
{
|
|
11
|
-
techs: ["next", "prisma"],
|
|
12
|
-
conventions: [
|
|
13
|
-
{
|
|
14
|
-
id: "next-prisma-server-only",
|
|
15
|
-
description: "Prisma only in server context",
|
|
16
|
-
rule: "Import Prisma client ONLY in Server Components, Server Actions, Route Handlers, and middleware. Never in files with 'use client'.",
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
id: "next-prisma-singleton",
|
|
20
|
-
description: "Prisma singleton for Next.js",
|
|
21
|
-
rule: "Use globalThis pattern for Prisma in development to prevent hot-reload connection leaks: `globalThis.prisma ??= new PrismaClient()`.",
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: "next-prisma-data-layer",
|
|
25
|
-
description: "Data access layer",
|
|
26
|
-
rule: "Create a data access layer (lib/data/ or lib/queries/) that wraps Prisma calls. Server Components call data functions, not Prisma directly.",
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
interdictions: [
|
|
30
|
-
"NEVER import @prisma/client in any file that has 'use client' directive.",
|
|
31
|
-
"NEVER pass full Prisma models to Client Components — select only the fields needed and create plain objects.",
|
|
32
|
-
"NEVER run Prisma queries inside React render functions without proper caching (use React cache() or unstable_cache).",
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
// Next.js + NextAuth
|
|
36
|
-
{
|
|
37
|
-
techs: ["next", "next-auth"],
|
|
38
|
-
conventions: [
|
|
39
|
-
{
|
|
40
|
-
id: "next-auth-middleware",
|
|
41
|
-
description: "Auth via middleware",
|
|
42
|
-
rule: "Use middleware.ts with NextAuth's auth() wrapper to protect routes. Define public routes explicitly, protect everything else by default.",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: "next-auth-session-server",
|
|
46
|
-
description: "Session in Server Components",
|
|
47
|
-
rule: "Use auth() from next-auth in Server Components to get the session. Use useSession() only in Client Components that need reactive session state.",
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
interdictions: [
|
|
51
|
-
"NEVER check auth client-side only — always validate server-side.",
|
|
52
|
-
"NEVER expose NextAuth secret or provider credentials in client code.",
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
|
-
// Next.js + Zod
|
|
56
|
-
{
|
|
57
|
-
techs: ["next", "zod"],
|
|
58
|
-
conventions: [
|
|
59
|
-
{
|
|
60
|
-
id: "next-zod-server-actions",
|
|
61
|
-
description: "Zod in Server Actions",
|
|
62
|
-
rule: "Validate all Server Action inputs with Zod schemas. Parse at the top of every action before any business logic.",
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: "next-zod-route-handlers",
|
|
66
|
-
description: "Zod in Route Handlers",
|
|
67
|
-
rule: "Validate request body/params with Zod in every Route Handler. Return 400 with formatted errors on validation failure.",
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
interdictions: [],
|
|
71
|
-
},
|
|
72
|
-
// Prisma + Zod
|
|
73
|
-
{
|
|
74
|
-
techs: ["prisma", "zod"],
|
|
75
|
-
conventions: [
|
|
76
|
-
{
|
|
77
|
-
id: "prisma-zod-sync",
|
|
78
|
-
description: "Keep Prisma and Zod in sync",
|
|
79
|
-
rule: "Zod schemas must mirror Prisma models for input validation. Consider using zod-prisma-types or manually maintaining parity.",
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
interdictions: [
|
|
83
|
-
"NEVER let Zod schemas drift from Prisma models — this causes runtime type mismatches.",
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
// tRPC + Zod
|
|
87
|
-
{
|
|
88
|
-
techs: ["trpc", "zod"],
|
|
89
|
-
conventions: [
|
|
90
|
-
{
|
|
91
|
-
id: "trpc-zod-input",
|
|
92
|
-
description: "Zod as tRPC input validator",
|
|
93
|
-
rule: "Use Zod schemas as tRPC .input() validators. Share schemas between client and server for end-to-end type safety.",
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
interdictions: [],
|
|
97
|
-
},
|
|
98
|
-
// React Query + Next.js
|
|
99
|
-
{
|
|
100
|
-
techs: ["next", "react-query"],
|
|
101
|
-
conventions: [
|
|
102
|
-
{
|
|
103
|
-
id: "next-rq-server-prefetch",
|
|
104
|
-
description: "Prefetch in Server Components",
|
|
105
|
-
rule: "Use React Query's HydrationBoundary to prefetch data in Server Components and hydrate on the client.",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id: "next-rq-client-only",
|
|
109
|
-
description: "React Query for client interactions",
|
|
110
|
-
rule: "Use React Query for user-triggered data fetching (pagination, search, mutations). Use Server Components for initial page data.",
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
interdictions: [
|
|
114
|
-
"NEVER use React Query to fetch initial page data that could be fetched in a Server Component.",
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
// Tailwind + React
|
|
118
|
-
{
|
|
119
|
-
techs: ["tailwind", "react"],
|
|
120
|
-
conventions: [
|
|
121
|
-
{
|
|
122
|
-
id: "tailwind-no-style-prop",
|
|
123
|
-
description: "Tailwind over inline styles",
|
|
124
|
-
rule: "Use Tailwind classes instead of style prop. Use cn() or clsx() for conditional classes.",
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
id: "tailwind-component-variants",
|
|
128
|
-
description: "Variant management",
|
|
129
|
-
rule: "For components with many style variants, use cva (class-variance-authority) or a similar pattern.",
|
|
130
|
-
},
|
|
131
|
-
],
|
|
132
|
-
interdictions: [
|
|
133
|
-
"NEVER mix Tailwind with inline styles unless for truly dynamic values (e.g., calculated positions).",
|
|
134
|
-
],
|
|
135
|
-
},
|
|
136
|
-
// Next.js + Drizzle
|
|
137
|
-
{
|
|
138
|
-
techs: ["next", "drizzle"],
|
|
139
|
-
conventions: [
|
|
140
|
-
{
|
|
141
|
-
id: "next-drizzle-server-only",
|
|
142
|
-
description: "Drizzle server-only",
|
|
143
|
-
rule: "Import the Drizzle client ONLY in Server Components, Server Actions, and Route Handlers. Never in 'use client' files.",
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
id: "next-drizzle-connection",
|
|
147
|
-
description: "Connection pooling",
|
|
148
|
-
rule: "Use a connection pool (e.g., @neondatabase/serverless with pool mode, or pg Pool) for serverless environments. Singleton pattern for the db client.",
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
interdictions: [
|
|
152
|
-
"NEVER import drizzle-orm in client-side code.",
|
|
153
|
-
"NEVER run migrations in production at runtime — run them in CI/CD.",
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
// Next.js + Clerk
|
|
157
|
-
{
|
|
158
|
-
techs: ["next", "clerk"],
|
|
159
|
-
conventions: [
|
|
160
|
-
{
|
|
161
|
-
id: "next-clerk-middleware",
|
|
162
|
-
description: "Clerk middleware",
|
|
163
|
-
rule: "Use clerkMiddleware() in middleware.ts. Define public routes with createRouteMatcher(). All other routes are protected by default.",
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
id: "next-clerk-server",
|
|
167
|
-
description: "Server-side auth with Clerk",
|
|
168
|
-
rule: "Use currentUser() or auth() from @clerk/nextjs/server in Server Components and Route Handlers. Use useUser() only in Client Components.",
|
|
169
|
-
},
|
|
170
|
-
],
|
|
171
|
-
interdictions: [
|
|
172
|
-
"NEVER check auth client-side only with Clerk — always validate on the server.",
|
|
173
|
-
"NEVER expose Clerk secret key in client code.",
|
|
174
|
-
],
|
|
175
|
-
},
|
|
176
|
-
// Next.js + Supabase Auth
|
|
177
|
-
{
|
|
178
|
-
techs: ["next", "supabase-auth"],
|
|
179
|
-
conventions: [
|
|
180
|
-
{
|
|
181
|
-
id: "next-supabase-server-client",
|
|
182
|
-
description: "Supabase server client",
|
|
183
|
-
rule: "Create separate Supabase clients for server (createServerClient with cookies) and browser (createBrowserClient). Never share instances.",
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
id: "next-supabase-middleware",
|
|
187
|
-
description: "Supabase auth middleware",
|
|
188
|
-
rule: "Use middleware.ts to refresh the Supabase session on every request. This prevents stale auth tokens.",
|
|
189
|
-
},
|
|
190
|
-
],
|
|
191
|
-
interdictions: [
|
|
192
|
-
"NEVER use the browser Supabase client in Server Components.",
|
|
193
|
-
"NEVER skip the middleware session refresh — it causes auth token expiration issues.",
|
|
194
|
-
],
|
|
195
|
-
},
|
|
196
|
-
// Next.js + Stripe
|
|
197
|
-
{
|
|
198
|
-
techs: ["next", "stripe"],
|
|
199
|
-
conventions: [
|
|
200
|
-
{
|
|
201
|
-
id: "next-stripe-server-only",
|
|
202
|
-
description: "Stripe SDK server-only",
|
|
203
|
-
rule: "Import the Stripe Node SDK only in Server Actions and Route Handlers. Use @stripe/stripe-js for client-side (Stripe Elements, checkout redirect).",
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
id: "next-stripe-webhooks",
|
|
207
|
-
description: "Stripe webhooks",
|
|
208
|
-
rule: "Handle Stripe webhooks in a Route Handler (app/api/webhooks/stripe/route.ts). Always verify the webhook signature. Use raw body parsing.",
|
|
209
|
-
},
|
|
210
|
-
],
|
|
211
|
-
interdictions: [
|
|
212
|
-
"NEVER expose your Stripe secret key in client code.",
|
|
213
|
-
"NEVER trust client-sent prices or product IDs — always verify on the server.",
|
|
214
|
-
"NEVER skip webhook signature verification.",
|
|
215
|
-
],
|
|
216
|
-
},
|
|
217
|
-
// Next.js + next-intl
|
|
218
|
-
{
|
|
219
|
-
techs: ["next", "next-intl"],
|
|
220
|
-
conventions: [
|
|
221
|
-
{
|
|
222
|
-
id: "next-intl-middleware",
|
|
223
|
-
description: "i18n middleware",
|
|
224
|
-
rule: "Configure next-intl middleware in middleware.ts for locale detection and routing. Define supported locales and default locale.",
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
id: "next-intl-messages",
|
|
228
|
-
description: "Message organization",
|
|
229
|
-
rule: "Keep translations in messages/{locale}.json. Organize by namespace matching your app structure. Use useTranslations('namespace') in components.",
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
id: "next-intl-server",
|
|
233
|
-
description: "Server Components i18n",
|
|
234
|
-
rule: "Use getTranslations() in Server Components, useTranslations() in Client Components. Never hardcode user-facing strings.",
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
interdictions: [
|
|
238
|
-
"NEVER hardcode user-facing strings — always use translation functions.",
|
|
239
|
-
"NEVER forget to add new strings to ALL locale files.",
|
|
240
|
-
],
|
|
241
|
-
},
|
|
242
|
-
// Prisma + NextAuth
|
|
243
|
-
{
|
|
244
|
-
techs: ["prisma", "next-auth"],
|
|
245
|
-
conventions: [
|
|
246
|
-
{
|
|
247
|
-
id: "prisma-nextauth-adapter",
|
|
248
|
-
description: "Prisma adapter for NextAuth",
|
|
249
|
-
rule: "Use @auth/prisma-adapter. Ensure your Prisma schema includes the required models (User, Account, Session, VerificationToken).",
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
id: "prisma-nextauth-session",
|
|
253
|
-
description: "Session strategy",
|
|
254
|
-
rule: "Use JWT strategy for serverless deployments (no DB lookup per request). Use database strategy only if you need server-side session revocation.",
|
|
255
|
-
},
|
|
256
|
-
],
|
|
257
|
-
interdictions: [
|
|
258
|
-
"NEVER modify the NextAuth-required Prisma models (User, Account, Session) without checking adapter compatibility.",
|
|
259
|
-
],
|
|
260
|
-
},
|
|
261
|
-
// Express/Fastify + Prisma
|
|
262
|
-
{
|
|
263
|
-
techs: ["express", "prisma"],
|
|
264
|
-
conventions: [
|
|
265
|
-
{
|
|
266
|
-
id: "express-prisma-singleton",
|
|
267
|
-
description: "Prisma singleton in Express",
|
|
268
|
-
rule: "Create a single PrismaClient instance in a dedicated module (e.g., lib/prisma.ts). Import it in route handlers. Disconnect in graceful shutdown.",
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
id: "express-prisma-n-plus-1",
|
|
272
|
-
description: "Prevent N+1 queries",
|
|
273
|
-
rule: "Always use include/select to fetch related data in one query. Never loop over results and query for each item.",
|
|
274
|
-
},
|
|
275
|
-
],
|
|
276
|
-
interdictions: [
|
|
277
|
-
"NEVER create a new PrismaClient per request — this exhausts database connections.",
|
|
278
|
-
],
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
techs: ["fastify", "prisma"],
|
|
282
|
-
conventions: [
|
|
283
|
-
{
|
|
284
|
-
id: "fastify-prisma-plugin",
|
|
285
|
-
description: "Prisma as Fastify plugin",
|
|
286
|
-
rule: "Register Prisma as a Fastify plugin with proper lifecycle hooks. Disconnect on server close.",
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
interdictions: [
|
|
290
|
-
"NEVER create a new PrismaClient per request.",
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
// Tailwind + shadcn
|
|
294
|
-
{
|
|
295
|
-
techs: ["tailwind", "shadcn"],
|
|
296
|
-
conventions: [
|
|
297
|
-
{
|
|
298
|
-
id: "shadcn-cn-utility",
|
|
299
|
-
description: "cn() utility",
|
|
300
|
-
rule: "Use the cn() utility (lib/utils.ts) for all className merging. It combines clsx and tailwind-merge.",
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
id: "shadcn-customization",
|
|
304
|
-
description: "Component customization",
|
|
305
|
-
rule: "Customize shadcn components by editing the files in components/ui/. Extend with variants using cva. Never modify the core patterns.",
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
id: "shadcn-composition",
|
|
309
|
-
description: "Compose, don't modify",
|
|
310
|
-
rule: "Build custom components by composing shadcn primitives. If you need a different variant, add it to the cva definition.",
|
|
311
|
-
},
|
|
312
|
-
],
|
|
313
|
-
interdictions: [
|
|
314
|
-
"NEVER override shadcn component styles with inline styles or external CSS — use Tailwind classes and cva variants.",
|
|
315
|
-
"NEVER copy-paste shadcn component code instead of using the CLI to add components.",
|
|
316
|
-
],
|
|
317
|
-
},
|
|
318
|
-
],
|
|
319
|
-
};
|
|
320
|
-
//# sourceMappingURL=cross-stack.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cross-stack.js","sourceRoot":"","sources":["../../src/rules/cross-stack.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/drizzle.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle.d.ts","sourceRoot":"","sources":["../../src/rules/drizzle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,eAAO,MAAM,YAAY,EAAE,IA0C1B,CAAC"}
|
package/dist/rules/drizzle.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export const drizzleRules = {
|
|
2
|
-
id: "drizzle",
|
|
3
|
-
name: "Drizzle ORM",
|
|
4
|
-
applies: (a) => a.detected.orm === "drizzle",
|
|
5
|
-
gaps: [
|
|
6
|
-
{
|
|
7
|
-
category: "drizzle-schema-org",
|
|
8
|
-
severity: "medium",
|
|
9
|
-
check: (a) => !a.structure.hasSchemasDir && !a.structure.hasLibDir,
|
|
10
|
-
message: "No clear schema organization detected for Drizzle",
|
|
11
|
-
details: "Drizzle schemas should live in a dedicated directory (e.g., db/schema/ or lib/db/). Without this, Claude will place schema files inconsistently.",
|
|
12
|
-
},
|
|
13
|
-
],
|
|
14
|
-
conventions: [
|
|
15
|
-
{
|
|
16
|
-
id: "drizzle-schema-files",
|
|
17
|
-
description: "Schema file organization",
|
|
18
|
-
rule: "Keep Drizzle schema definitions in db/schema/ with one file per domain entity. Export all from db/schema/index.ts.",
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
id: "drizzle-prepared",
|
|
22
|
-
description: "Prepared statements for hot paths",
|
|
23
|
-
rule: "Use db.query.*.findFirst/findMany with prepared statements (`.prepare()`) for frequently-called queries.",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
id: "drizzle-migrations",
|
|
27
|
-
description: "Migration workflow",
|
|
28
|
-
rule: "Generate migrations with `drizzle-kit generate`. Apply with `drizzle-kit migrate`. Never modify generated migration files.",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: "drizzle-relations",
|
|
32
|
-
description: "Define relations explicitly",
|
|
33
|
-
rule: "Define relations using the `relations()` helper alongside table definitions. This enables the relational query API.",
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
interdictions: [
|
|
37
|
-
"NEVER modify generated migration files — always generate a new migration instead.",
|
|
38
|
-
"NEVER use raw SQL when the Drizzle query builder can express the query.",
|
|
39
|
-
"NEVER import the database client in client-side code.",
|
|
40
|
-
],
|
|
41
|
-
crossRefs: [],
|
|
42
|
-
};
|
|
43
|
-
//# sourceMappingURL=drizzle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle.js","sourceRoot":"","sources":["../../src/rules/drizzle.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,SAAS;IAC5C,IAAI,EAAE;QACJ;YACE,QAAQ,EAAE,oBAAoB;YAC9B,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS;YAClE,OAAO,EAAE,mDAAmD;YAC5D,OAAO,EACL,kJAAkJ;SACrJ;KACF;IACD,WAAW,EAAE;QACX;YACE,EAAE,EAAE,sBAAsB;YAC1B,WAAW,EAAE,0BAA0B;YACvC,IAAI,EAAE,oHAAoH;SAC3H;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,WAAW,EAAE,mCAAmC;YAChD,IAAI,EAAE,0GAA0G;SACjH;QACD;YACE,EAAE,EAAE,oBAAoB;YACxB,WAAW,EAAE,oBAAoB;YACjC,IAAI,EAAE,4HAA4H;SACnI;QACD;YACE,EAAE,EAAE,mBAAmB;YACvB,WAAW,EAAE,6BAA6B;YAC1C,IAAI,EAAE,qHAAqH;SAC5H;KACF;IACD,aAAa,EAAE;QACb,mFAAmF;QACnF,yEAAyE;QACzE,uDAAuD;KACxD;IACD,SAAS,EAAE,EAAE;CACd,CAAC"}
|
package/dist/rules/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Rule, RepoAnalysis, Gap, Convention, CrossRef } from "../types.js";
|
|
2
|
-
export declare function getApplicableRules(analysis: RepoAnalysis): Rule[];
|
|
3
|
-
export declare function detectGaps(analysis: RepoAnalysis): Gap[];
|
|
4
|
-
export declare function getConventions(analysis: RepoAnalysis): Convention[];
|
|
5
|
-
export declare function getInterdictions(analysis: RepoAnalysis): string[];
|
|
6
|
-
export declare function getActiveCrossRefs(analysis: RepoAnalysis): CrossRef[];
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AA8BjF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,CAEjE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,GAAG,EAAE,CAkBxD;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,UAAU,EAAE,CAenE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,EAAE,CAejE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,QAAQ,EAAE,CA4BrE"}
|
package/dist/rules/index.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { nextjsRules, nextjsPagesRules } from "./nextjs.js";
|
|
2
|
-
import { reactRules } from "./react.js";
|
|
3
|
-
import { nodeRules } from "./node.js";
|
|
4
|
-
import { prismaRules } from "./prisma.js";
|
|
5
|
-
import { drizzleRules } from "./drizzle.js";
|
|
6
|
-
import { authRules } from "./auth.js";
|
|
7
|
-
import { validationRules } from "./validation.js";
|
|
8
|
-
import { typescriptRules } from "./typescript.js";
|
|
9
|
-
import { tailwindRules } from "./tailwind.js";
|
|
10
|
-
import { stateManagementRules } from "./state.js";
|
|
11
|
-
import { trpcRules } from "./trpc.js";
|
|
12
|
-
import { crossStackRules } from "./cross-stack.js";
|
|
13
|
-
const allRules = [
|
|
14
|
-
nextjsRules,
|
|
15
|
-
nextjsPagesRules,
|
|
16
|
-
reactRules,
|
|
17
|
-
nodeRules,
|
|
18
|
-
prismaRules,
|
|
19
|
-
drizzleRules,
|
|
20
|
-
authRules,
|
|
21
|
-
validationRules,
|
|
22
|
-
typescriptRules,
|
|
23
|
-
tailwindRules,
|
|
24
|
-
stateManagementRules,
|
|
25
|
-
trpcRules,
|
|
26
|
-
crossStackRules,
|
|
27
|
-
];
|
|
28
|
-
export function getApplicableRules(analysis) {
|
|
29
|
-
return allRules.filter((r) => r.applies(analysis));
|
|
30
|
-
}
|
|
31
|
-
export function detectGaps(analysis) {
|
|
32
|
-
const rules = getApplicableRules(analysis);
|
|
33
|
-
const gaps = [];
|
|
34
|
-
for (const rule of rules) {
|
|
35
|
-
for (const gapCheck of rule.gaps) {
|
|
36
|
-
if (gapCheck.check(analysis)) {
|
|
37
|
-
gaps.push({
|
|
38
|
-
category: gapCheck.category,
|
|
39
|
-
severity: gapCheck.severity,
|
|
40
|
-
message: gapCheck.message,
|
|
41
|
-
details: gapCheck.details,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return gaps;
|
|
47
|
-
}
|
|
48
|
-
export function getConventions(analysis) {
|
|
49
|
-
const rules = getApplicableRules(analysis);
|
|
50
|
-
const seen = new Set();
|
|
51
|
-
const conventions = [];
|
|
52
|
-
for (const rule of rules) {
|
|
53
|
-
for (const conv of rule.conventions) {
|
|
54
|
-
if (!seen.has(conv.id)) {
|
|
55
|
-
seen.add(conv.id);
|
|
56
|
-
conventions.push(conv);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return conventions;
|
|
61
|
-
}
|
|
62
|
-
export function getInterdictions(analysis) {
|
|
63
|
-
const rules = getApplicableRules(analysis);
|
|
64
|
-
const seen = new Set();
|
|
65
|
-
const interdictions = [];
|
|
66
|
-
for (const rule of rules) {
|
|
67
|
-
for (const inter of rule.interdictions) {
|
|
68
|
-
if (!seen.has(inter)) {
|
|
69
|
-
seen.add(inter);
|
|
70
|
-
interdictions.push(inter);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return interdictions;
|
|
75
|
-
}
|
|
76
|
-
export function getActiveCrossRefs(analysis) {
|
|
77
|
-
const rules = getApplicableRules(analysis);
|
|
78
|
-
const active = [];
|
|
79
|
-
// Build a set of detected tech identifiers
|
|
80
|
-
const techs = new Set();
|
|
81
|
-
if (analysis.framework) {
|
|
82
|
-
techs.add(analysis.framework.name);
|
|
83
|
-
// Add "react" for React-based frameworks so cross-refs like ["tailwind", "react"] activate
|
|
84
|
-
const reactFrameworks = new Set(["next", "vite-react", "remix"]);
|
|
85
|
-
if (reactFrameworks.has(analysis.framework.name))
|
|
86
|
-
techs.add("react");
|
|
87
|
-
}
|
|
88
|
-
const detected = analysis.detected;
|
|
89
|
-
// Add all non-null detected techs
|
|
90
|
-
for (const value of Object.values(detected)) {
|
|
91
|
-
if (typeof value === "string")
|
|
92
|
-
techs.add(value);
|
|
93
|
-
}
|
|
94
|
-
for (const rule of rules) {
|
|
95
|
-
for (const crossRef of rule.crossRefs) {
|
|
96
|
-
// A crossRef is active if ALL its required techs are present
|
|
97
|
-
if (crossRef.techs.every((t) => techs.has(t))) {
|
|
98
|
-
active.push(crossRef);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return active;
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=index.js.map
|