@facilis.dev/analyze 0.0.0-stage → 0.1.1

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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -2
  3. package/dist/analyze.d.ts +17 -0
  4. package/dist/analyze.js +99 -0
  5. package/dist/ast/node.d.ts +29 -0
  6. package/dist/ast/node.js +85 -0
  7. package/dist/ast/walk.d.ts +8 -0
  8. package/dist/ast/walk.js +40 -0
  9. package/dist/diagnostics.d.ts +5 -0
  10. package/dist/diagnostics.js +12 -0
  11. package/dist/fs.d.ts +13 -0
  12. package/dist/fs.js +51 -0
  13. package/dist/graph-edges.d.ts +3 -0
  14. package/dist/graph-edges.js +148 -0
  15. package/dist/graph-ids.d.ts +6 -0
  16. package/dist/graph-ids.js +22 -0
  17. package/dist/graph.d.ts +15 -0
  18. package/dist/graph.js +162 -0
  19. package/dist/index.d.ts +24 -0
  20. package/dist/index.js +17 -0
  21. package/dist/json.d.ts +8 -0
  22. package/dist/json.js +31 -0
  23. package/dist/module-graph.d.ts +33 -0
  24. package/dist/module-graph.js +86 -0
  25. package/dist/module-info.d.ts +27 -0
  26. package/dist/module-info.js +143 -0
  27. package/dist/node.d.ts +16 -0
  28. package/dist/node.js +41 -0
  29. package/dist/parser.d.ts +16 -0
  30. package/dist/parser.js +1 -0
  31. package/dist/passes/clients.d.ts +22 -0
  32. package/dist/passes/clients.js +167 -0
  33. package/dist/passes/config.d.ts +16 -0
  34. package/dist/passes/config.js +229 -0
  35. package/dist/passes/file-facts.d.ts +13 -0
  36. package/dist/passes/file-facts.js +130 -0
  37. package/dist/passes/i18n.d.ts +14 -0
  38. package/dist/passes/i18n.js +55 -0
  39. package/dist/passes/job-relations-diagnostics.d.ts +9 -0
  40. package/dist/passes/job-relations-diagnostics.js +38 -0
  41. package/dist/passes/job-relations.d.ts +18 -0
  42. package/dist/passes/job-relations.js +52 -0
  43. package/dist/passes/jobs.d.ts +20 -0
  44. package/dist/passes/jobs.js +133 -0
  45. package/dist/passes/jsx-text.d.ts +28 -0
  46. package/dist/passes/jsx-text.js +121 -0
  47. package/dist/passes/jsx.d.ts +24 -0
  48. package/dist/passes/jsx.js +135 -0
  49. package/dist/passes/path-expression.d.ts +26 -0
  50. package/dist/passes/path-expression.js +265 -0
  51. package/dist/passes/route-config.d.ts +24 -0
  52. package/dist/passes/route-config.js +152 -0
  53. package/dist/passes/route-description.d.ts +13 -0
  54. package/dist/passes/route-description.js +23 -0
  55. package/dist/passes/route-elevation.d.ts +18 -0
  56. package/dist/passes/route-elevation.js +136 -0
  57. package/dist/passes/route-handler.d.ts +27 -0
  58. package/dist/passes/route-handler.js +87 -0
  59. package/dist/passes/route-location.d.ts +16 -0
  60. package/dist/passes/route-location.js +58 -0
  61. package/dist/passes/route-relation-resolve.d.ts +51 -0
  62. package/dist/passes/route-relation-resolve.js +172 -0
  63. package/dist/passes/route-relations-diagnostics.d.ts +15 -0
  64. package/dist/passes/route-relations-diagnostics.js +79 -0
  65. package/dist/passes/route-relations-follow.d.ts +16 -0
  66. package/dist/passes/route-relations-follow.js +116 -0
  67. package/dist/passes/route-relations-usage.d.ts +50 -0
  68. package/dist/passes/route-relations-usage.js +44 -0
  69. package/dist/passes/route-relations-walk.d.ts +25 -0
  70. package/dist/passes/route-relations-walk.js +199 -0
  71. package/dist/passes/route-relations.d.ts +17 -0
  72. package/dist/passes/route-relations.js +43 -0
  73. package/dist/passes/route-table.d.ts +21 -0
  74. package/dist/passes/route-table.js +104 -0
  75. package/dist/passes/route-tables.d.ts +10 -0
  76. package/dist/passes/route-tables.js +42 -0
  77. package/dist/passes/routes.d.ts +18 -0
  78. package/dist/passes/routes.js +152 -0
  79. package/dist/passes/schema-column-types.d.ts +9 -0
  80. package/dist/passes/schema-column-types.js +55 -0
  81. package/dist/passes/schema-columns.d.ts +35 -0
  82. package/dist/passes/schema-columns.js +197 -0
  83. package/dist/passes/schema-dsl.d.ts +24 -0
  84. package/dist/passes/schema-dsl.js +117 -0
  85. package/dist/passes/schema-file-links-ddl.d.ts +18 -0
  86. package/dist/passes/schema-file-links-ddl.js +106 -0
  87. package/dist/passes/schema-file-links.d.ts +19 -0
  88. package/dist/passes/schema-file-links.js +144 -0
  89. package/dist/passes/schema-foreign-keys.d.ts +21 -0
  90. package/dist/passes/schema-foreign-keys.js +80 -0
  91. package/dist/passes/schema-policies.d.ts +15 -0
  92. package/dist/passes/schema-policies.js +201 -0
  93. package/dist/passes/schema-re-exports.d.ts +5 -0
  94. package/dist/passes/schema-re-exports.js +77 -0
  95. package/dist/passes/schema-relations.d.ts +8 -0
  96. package/dist/passes/schema-relations.js +182 -0
  97. package/dist/passes/schema-scope.d.ts +7 -0
  98. package/dist/passes/schema-scope.js +20 -0
  99. package/dist/passes/schema-tables.d.ts +13 -0
  100. package/dist/passes/schema-tables.js +149 -0
  101. package/dist/passes/schema.d.ts +9 -0
  102. package/dist/passes/schema.js +55 -0
  103. package/dist/passes/screen-components.d.ts +22 -0
  104. package/dist/passes/screen-components.js +143 -0
  105. package/dist/passes/screen-intrinsics.d.ts +18 -0
  106. package/dist/passes/screen-intrinsics.js +21 -0
  107. package/dist/passes/screen-preview.d.ts +29 -0
  108. package/dist/passes/screen-preview.js +174 -0
  109. package/dist/passes/screens.d.ts +12 -0
  110. package/dist/passes/screens.js +278 -0
  111. package/dist/passes/static-read.d.ts +47 -0
  112. package/dist/passes/static-read.js +151 -0
  113. package/dist/passes/views.d.ts +20 -0
  114. package/dist/passes/views.js +101 -0
  115. package/dist/passes/workflow-tables.d.ts +18 -0
  116. package/dist/passes/workflow-tables.js +71 -0
  117. package/dist/passes/workflows.d.ts +8 -0
  118. package/dist/passes/workflows.js +160 -0
  119. package/dist/path-resolver.d.ts +20 -0
  120. package/dist/path-resolver.js +134 -0
  121. package/dist/revision.d.ts +2 -0
  122. package/dist/revision.js +23 -0
  123. package/dist/source.d.ts +4 -0
  124. package/dist/source.js +13 -0
  125. package/dist/static-eval.d.ts +36 -0
  126. package/dist/static-eval.js +215 -0
  127. package/dist/types-graph.d.ts +144 -0
  128. package/dist/types-graph.js +4 -0
  129. package/dist/types-jobs.d.ts +28 -0
  130. package/dist/types-jobs.js +14 -0
  131. package/dist/types-relations.d.ts +49 -0
  132. package/dist/types-relations.js +11 -0
  133. package/dist/types-workflows.d.ts +36 -0
  134. package/dist/types-workflows.js +3 -0
  135. package/dist/types.d.ts +226 -0
  136. package/dist/types.js +1 -0
  137. package/package.json +49 -4
  138. package/src/analyze.ts +119 -0
  139. package/src/ast/node.ts +102 -0
  140. package/src/ast/walk.ts +37 -0
  141. package/src/diagnostics.ts +22 -0
  142. package/src/fs.ts +59 -0
  143. package/src/graph-edges.ts +167 -0
  144. package/src/graph-ids.ts +31 -0
  145. package/src/graph.ts +194 -0
  146. package/src/index.ts +26 -0
  147. package/src/json.ts +34 -0
  148. package/src/module-graph.ts +117 -0
  149. package/src/module-info.ts +162 -0
  150. package/src/node.ts +54 -0
  151. package/src/parser.ts +19 -0
  152. package/src/passes/clients.ts +233 -0
  153. package/src/passes/config.ts +278 -0
  154. package/src/passes/file-facts.ts +142 -0
  155. package/src/passes/i18n.ts +66 -0
  156. package/src/passes/job-relations-diagnostics.ts +60 -0
  157. package/src/passes/job-relations.ts +76 -0
  158. package/src/passes/jobs.ts +181 -0
  159. package/src/passes/jsx-text.ts +126 -0
  160. package/src/passes/jsx.ts +142 -0
  161. package/src/passes/path-expression.ts +297 -0
  162. package/src/passes/route-config.ts +188 -0
  163. package/src/passes/route-description.ts +33 -0
  164. package/src/passes/route-elevation.ts +161 -0
  165. package/src/passes/route-handler.ts +105 -0
  166. package/src/passes/route-location.ts +62 -0
  167. package/src/passes/route-relation-resolve.ts +228 -0
  168. package/src/passes/route-relations-diagnostics.ts +115 -0
  169. package/src/passes/route-relations-follow.ts +146 -0
  170. package/src/passes/route-relations-usage.ts +98 -0
  171. package/src/passes/route-relations-walk.ts +255 -0
  172. package/src/passes/route-relations.ts +62 -0
  173. package/src/passes/route-table.ts +123 -0
  174. package/src/passes/route-tables.ts +50 -0
  175. package/src/passes/routes.ts +188 -0
  176. package/src/passes/schema-column-types.ts +62 -0
  177. package/src/passes/schema-columns.ts +287 -0
  178. package/src/passes/schema-dsl.ts +136 -0
  179. package/src/passes/schema-file-links-ddl.ts +125 -0
  180. package/src/passes/schema-file-links.ts +213 -0
  181. package/src/passes/schema-foreign-keys.ts +121 -0
  182. package/src/passes/schema-policies.ts +270 -0
  183. package/src/passes/schema-re-exports.ts +95 -0
  184. package/src/passes/schema-relations.ts +239 -0
  185. package/src/passes/schema-scope.ts +29 -0
  186. package/src/passes/schema-tables.ts +216 -0
  187. package/src/passes/schema.ts +67 -0
  188. package/src/passes/screen-components.ts +162 -0
  189. package/src/passes/screen-intrinsics.ts +29 -0
  190. package/src/passes/screen-preview.ts +295 -0
  191. package/src/passes/screens.ts +291 -0
  192. package/src/passes/static-read.ts +196 -0
  193. package/src/passes/views.ts +125 -0
  194. package/src/passes/workflow-tables.ts +87 -0
  195. package/src/passes/workflows.ts +213 -0
  196. package/src/path-resolver.ts +146 -0
  197. package/src/revision.ts +25 -0
  198. package/src/source.ts +15 -0
  199. package/src/static-eval.ts +242 -0
  200. package/src/types-graph.ts +176 -0
  201. package/src/types-jobs.ts +40 -0
  202. package/src/types-relations.ts +64 -0
  203. package/src/types-workflows.ts +42 -0
  204. package/src/types.ts +299 -0
@@ -0,0 +1,64 @@
1
+ // Route relation-usage and view facts (D-157), split from types.ts so the base fact model
2
+ // stays under the 300-line source limit. A fact that cannot be determined is explicit:
3
+ // an empty usage is "nothing observed", never "nothing to check".
4
+
5
+ import type { ElevationKind, SourceRef, UnknownFact } from "./types.ts";
6
+
7
+ /** A view declared with defineView under db/views/ (D-097/D-098). Not a graph node (D-157). */
8
+ export interface ViewFact {
9
+ readonly name: string;
10
+ /** TypeScript binding holding the view, when declared as a const. */
11
+ readonly binding: string | null;
12
+ /** Base tables named by the declaration (metadata only, D-097); [] when absent. */
13
+ readonly tables: readonly string[];
14
+ /** The view's own permission; null keeps the invoker behaviour (D-098). */
15
+ readonly permission: string | null;
16
+ /** null when a declared permission could not be read, so the mode is unknown. */
17
+ readonly access: "invoker" | "definer" | null;
18
+ readonly source: SourceRef;
19
+ readonly unknown: readonly UnknownFact[];
20
+ }
21
+
22
+ /** One relation (table or view) a route reaches through a db client. */
23
+ export interface RouteRelationUse {
24
+ readonly name: string;
25
+ /** The use site, so a finding can jump to the expression. */
26
+ readonly source: SourceRef;
27
+ }
28
+
29
+ /** What one audited elevation callback reaches through its elevated db client (D-157). */
30
+ export interface RouteElevationUsage {
31
+ readonly kind: ElevationKind;
32
+ /** The ctx.sudo / ctx.system call site. */
33
+ readonly source: SourceRef;
34
+ /** The elevation's own `tables` option; [] when unknown. */
35
+ readonly tables: readonly string[];
36
+ readonly used: readonly RouteRelationUse[];
37
+ readonly unresolved: readonly SourceRef[];
38
+ /** The elevation's `tables` option is missing or not statically readable. */
39
+ readonly tablesUnknown: boolean;
40
+ /** The elevated client reached a callee outside the project graph. */
41
+ readonly opaque: boolean;
42
+ }
43
+
44
+ /** Static db usage of one route handler, following project-local helper calls (D-157). */
45
+ export interface RouteRelationsFact {
46
+ /** Relations reached through ctx.db outside elevations, deduplicated by name. */
47
+ readonly used: readonly RouteRelationUse[];
48
+ /** Dynamic/unresolvable relation expressions, and uses the pass could not inspect. */
49
+ readonly unresolved: readonly SourceRef[];
50
+ /** `db.execute(...)` call sites; legal only with rawSql: true. */
51
+ readonly rawSql: readonly SourceRef[];
52
+ /** A project-external callee received the route's db client, so usage is incomplete. */
53
+ readonly opaque: boolean;
54
+ readonly elevations: readonly RouteElevationUsage[];
55
+ }
56
+
57
+ /** Usage of a route the pass cannot scan (invalid wrapper): explicitly empty, not unknown. */
58
+ export const EMPTY_ROUTE_RELATIONS: RouteRelationsFact = {
59
+ used: [],
60
+ unresolved: [],
61
+ rawSql: [],
62
+ opaque: false,
63
+ elevations: [],
64
+ };
@@ -0,0 +1,42 @@
1
+ // Workflow fact shapes, split from types.ts so the base fact model stays under the 300-line
2
+ // source limit (D-135 W3). They are re-exported from types.ts, so existing imports keep working.
3
+
4
+ import type { SourceRef, UnknownFact } from "./types.ts";
5
+
6
+ /** One step of a `defineWorkflow` chain, as the static subset reads it. */
7
+ export interface WorkflowStepFact {
8
+ readonly index: number;
9
+ readonly kind: "job" | "approval";
10
+ /** Job name for a job step, approval title key for an approval step. */
11
+ readonly name: string | null;
12
+ /** Approval assignment permission, when the definition declares one. */
13
+ readonly permission: string | null;
14
+ /** Forward step index declared by `onReject.step`, when present. */
15
+ readonly onRejectStep: number | null;
16
+ readonly source: SourceRef;
17
+ }
18
+
19
+ /** One `server/workflows/**` definition. */
20
+ export interface WorkflowFact {
21
+ readonly name: string;
22
+ readonly sourceFile: string;
23
+ readonly source: SourceRef;
24
+ readonly steps: readonly WorkflowStepFact[];
25
+ readonly unknown: readonly UnknownFact[];
26
+ }
27
+
28
+ /**
29
+ * Table surface of a workflow, derived from the jobs its steps reference (never declared):
30
+ * the sorted union of the referenced jobs' own `dbTables` (tables and views alike).
31
+ */
32
+ export interface WorkflowTablesFact {
33
+ readonly name: string;
34
+ readonly sourceFile: string;
35
+ readonly source: SourceRef;
36
+ /** Sorted unique union of the referenced jobs' declared dbTables. */
37
+ readonly tables: readonly string[];
38
+ /** Job-step names with no definition under `server/jobs/**`; [] when all resolve. */
39
+ readonly unknownJobs: readonly string[];
40
+ /** True when a referenced job's dbTables is unreadable, so the union is incomplete. */
41
+ readonly unknown: boolean;
42
+ }
package/src/types.ts ADDED
@@ -0,0 +1,299 @@
1
+ import type { JobFact, JobRelationsFact } from "./types-jobs.ts";
2
+ import type { RouteRelationsFact, ViewFact } from "./types-relations.ts";
3
+ import type { ProjectGraph } from "./types-graph.ts";
4
+ import type { WorkflowFact, WorkflowTablesFact } from "./types-workflows.ts";
5
+
6
+ /**
7
+ * Fact model of the AST analyzer (docs/findings/ast-dsl-contract.md).
8
+ *
9
+ * Facts are parser-independent and always carry their source. A fact that cannot be
10
+ * determined is represented explicitly (null or an unknown entry), never as an empty value:
11
+ * in particular "dbTables unknown" (null) is not "no DB tables" ([]).
12
+ */
13
+
14
+ export interface SourceRef {
15
+ readonly file: string;
16
+ readonly line: number;
17
+ }
18
+
19
+ export interface UnknownFact {
20
+ readonly code: string;
21
+ readonly reason: string;
22
+ readonly source: SourceRef;
23
+ }
24
+
25
+ export type Severity = "error" | "warning" | "info";
26
+
27
+ export interface Diagnostic {
28
+ readonly code: string;
29
+ readonly severity: Severity;
30
+ readonly message: string;
31
+ readonly source: SourceRef | null;
32
+ }
33
+
34
+ export interface LocaleCatalogs {
35
+ readonly [locale: string]: Readonly<Record<string, string>>;
36
+ }
37
+
38
+ // ── config ──────────────────────────────────────────────────────────────────────────
39
+
40
+ export interface ConfigFacts {
41
+ readonly parsed: boolean;
42
+ readonly source: SourceRef | null;
43
+ readonly permissions: readonly string[];
44
+ readonly roles: Readonly<Record<string, readonly string[]>>;
45
+ readonly defaultRole: string | null;
46
+ readonly defaultLocale: string | null;
47
+ readonly locales: readonly string[];
48
+ readonly migrationsDir: string;
49
+ readonly tenantColumns: readonly string[];
50
+ readonly ownerColumns: readonly string[];
51
+ readonly unknown: readonly UnknownFact[];
52
+ }
53
+
54
+ // ── schema ──────────────────────────────────────────────────────────────────────────
55
+
56
+ export type ColumnDefaultKind = "literal" | "now" | "random" | "unknown";
57
+
58
+ export interface ColumnDefaultFact {
59
+ readonly kind: ColumnDefaultKind;
60
+ readonly value: string | null;
61
+ }
62
+
63
+ export interface ForeignKeyFact {
64
+ readonly columns: readonly string[];
65
+ readonly targetTable: string;
66
+ readonly targetColumns: readonly string[];
67
+ readonly onDelete: string | null;
68
+ readonly onUpdate: string | null;
69
+ readonly source: SourceRef;
70
+ }
71
+
72
+ export interface ColumnFact {
73
+ /** Drizzle property key in the table object (the dbColumns domain). */
74
+ readonly property: string;
75
+ /** SQL column name (first literal argument of the builder, or the property key). */
76
+ readonly name: string;
77
+ readonly builder: string;
78
+ /** Display type derived from the builder and its arguments. */
79
+ readonly type: string;
80
+ readonly notNull: boolean;
81
+ readonly primaryKey: boolean;
82
+ readonly unique: boolean;
83
+ readonly default: ColumnDefaultFact | null;
84
+ readonly source: SourceRef;
85
+ readonly unknown: readonly UnknownFact[];
86
+ }
87
+
88
+ export type PolicyCommand = "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "ALL";
89
+
90
+ export interface PolicyFact {
91
+ readonly name: string;
92
+ readonly command: PolicyCommand;
93
+ readonly restrictive: boolean;
94
+ readonly source: SourceRef;
95
+ readonly unknown: readonly UnknownFact[];
96
+ }
97
+
98
+ export interface ScopeFact {
99
+ readonly column: string;
100
+ readonly kind: "tenant" | "owner";
101
+ }
102
+
103
+ export interface TableFact {
104
+ readonly name: string;
105
+ /** TypeScript binding holding the table, when declared as a const. */
106
+ readonly binding: string | null;
107
+ readonly columns: readonly ColumnFact[];
108
+ readonly primaryKey: readonly string[];
109
+ readonly foreignKeys: readonly ForeignKeyFact[];
110
+ readonly policies: readonly PolicyFact[];
111
+ readonly rlsEnabled: boolean;
112
+ readonly scope: ScopeFact | null;
113
+ readonly source: SourceRef;
114
+ readonly unknown: readonly UnknownFact[];
115
+ }
116
+
117
+ export interface RelationFact {
118
+ readonly from: string;
119
+ readonly to: string;
120
+ readonly cardinality: "one" | "many";
121
+ readonly fields: readonly string[];
122
+ readonly references: readonly string[];
123
+ readonly source: SourceRef;
124
+ readonly unknown: readonly UnknownFact[];
125
+ }
126
+
127
+ // ── routes ─────────────────────────────────────────────────────────────────────────
128
+
129
+ export type HttpMethod =
130
+ "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "TRACE" | "CONNECT" | "ALL";
131
+
132
+ export type WrapperState = "valid" | "invalid" | "unknown";
133
+
134
+ export interface RouteInputFact {
135
+ readonly body: boolean;
136
+ /** A multipart/form-data schema (D-053); mutually exclusive with `body`. */
137
+ readonly form: boolean;
138
+ readonly query: boolean;
139
+ readonly params: boolean;
140
+ }
141
+
142
+ export type ElevationKind = "sudo" | "system";
143
+
144
+ /** One audited elevation call in a route handler (D-099): `ctx.sudo` / `ctx.system`. */
145
+ export interface ElevationFact {
146
+ readonly kind: ElevationKind;
147
+ /** Tables passed to the elevation; [] when the array cannot be read statically. */
148
+ readonly tables: readonly string[];
149
+ /** The audit operation label, when statically readable. */
150
+ readonly operation: string | null;
151
+ readonly source: SourceRef;
152
+ readonly unknown: readonly UnknownFact[];
153
+ }
154
+
155
+ export interface RouteFact {
156
+ readonly method: HttpMethod;
157
+ readonly path: string;
158
+ readonly sourceFile: string;
159
+ readonly source: SourceRef;
160
+ readonly wrapper: WrapperState;
161
+ /** null = unknown; [] = explicitly public. */
162
+ readonly permission: readonly string[] | null;
163
+ /**
164
+ * True when the wrapper declares the route callable from another origin; false when absent;
165
+ * null when the declaration cannot be read statically (a cross-origin route is never assumed).
166
+ */
167
+ readonly crossSite: boolean | null;
168
+ /** null = unknown; [] = explicitly no DB. */
169
+ readonly dbTables: readonly string[] | null;
170
+ /** null = unknown; [] = explicitly no columns. */
171
+ readonly dbColumns: readonly string[] | null;
172
+ /** rawSql: true allows `db.execute` (D-157); false when absent; null when unreadable. */
173
+ readonly rawSql: boolean | null;
174
+ /** Static db usage of the handler, project-local helper calls followed (D-157). */
175
+ readonly relations: RouteRelationsFact;
176
+ readonly description: string | null;
177
+ readonly input: RouteInputFact;
178
+ /** True when the handler body reads the request body (SPEC §9.3 rule 8). */
179
+ readonly handlerBodyRead: boolean;
180
+ /** True when the handler body reads the multipart form (SPEC §9.3 rule 8, D-053). */
181
+ readonly handlerFormRead: boolean;
182
+ /** Audited elevation calls in the handler, in source order. */
183
+ readonly elevations: readonly ElevationFact[];
184
+ readonly unknown: readonly UnknownFact[];
185
+ }
186
+
187
+ // ── per-file module facts ──────────────────────────────────────────────────────────
188
+
189
+ export type ImportKind =
190
+ "named" | "default" | "namespace" | "side-effect" | "export-from" | "dynamic" | "require";
191
+
192
+ /** One module reference of a source file: static import, re-export, dynamic import or require. */
193
+ export interface ImportFact {
194
+ readonly specifier: string;
195
+ readonly kind: ImportKind;
196
+ /** Local binding the reference introduces; null for side-effect/re-export/dynamic forms. */
197
+ readonly local: string | null;
198
+ /** Imported name for named imports ("default" for a default import); null otherwise. */
199
+ readonly imported: string | null;
200
+ readonly source: SourceRef;
201
+ }
202
+
203
+ /** One literal `t("key")` call; interpolated keys are skipped because they are not static. */
204
+ export interface TranslationCallFact {
205
+ readonly key: string;
206
+ readonly source: SourceRef;
207
+ }
208
+
209
+ /** One call to a bare identifier (`drizzle(...)`, `t(...)`): enough for the security rules. */
210
+ export interface CallFact {
211
+ readonly name: string;
212
+ readonly source: SourceRef;
213
+ }
214
+
215
+ export interface FileFacts {
216
+ /** Project-relative path of the parsed source file. */
217
+ readonly path: string;
218
+ readonly imports: readonly ImportFact[];
219
+ readonly translationCalls: readonly TranslationCallFact[];
220
+ readonly calls: readonly CallFact[];
221
+ }
222
+
223
+ // ── pages / client consumers ───────────────────────────────────────────────────────
224
+
225
+ export type PageKind = "page" | "component" | "lib" | "other";
226
+
227
+ export type PathKind = "literal" | "concat" | "template" | "builder" | "dynamic" | "unknown";
228
+
229
+ export interface RouteCallFact {
230
+ readonly expression: string;
231
+ readonly kind: PathKind;
232
+ readonly staticPrefix: string | null;
233
+ readonly matchedRouteIds: readonly string[];
234
+ readonly source: SourceRef;
235
+ readonly unknown: readonly UnknownFact[];
236
+ }
237
+
238
+ export interface PageFact {
239
+ readonly path: string;
240
+ readonly kind: PageKind;
241
+ readonly calls: readonly RouteCallFact[];
242
+ readonly source: SourceRef;
243
+ readonly unknown: readonly UnknownFact[];
244
+ }
245
+
246
+ // ── graph ──────────────────────────────────────────────────────────────────────────
247
+ // The graph-facing shapes live in types-graph.ts (the 300-line split); they are re-exported
248
+ // here so every existing `from "./types.ts"` import keeps working.
249
+
250
+ export type {
251
+ GraphEdge,
252
+ GraphEdgeKind,
253
+ GraphNode,
254
+ GraphNodeData,
255
+ GraphNodeKind,
256
+ PageLink,
257
+ PageNodeData,
258
+ PagePreview,
259
+ PagePreviewNode,
260
+ ProjectGraph,
261
+ RouteNodeData,
262
+ ScreenFacts,
263
+ TableNodeData,
264
+ ViewNodeData,
265
+ WorkflowNodeData,
266
+ WorkflowStepNodeData,
267
+ } from "./types-graph.ts";
268
+ export type {
269
+ RouteElevationUsage,
270
+ RouteRelationUse,
271
+ RouteRelationsFact,
272
+ ViewFact,
273
+ } from "./types-relations.ts";
274
+ export type { WorkflowFact, WorkflowStepFact, WorkflowTablesFact } from "./types-workflows.ts";
275
+
276
+ // ── analysis ───────────────────────────────────────────────────────────────────────
277
+
278
+ export interface Analysis {
279
+ readonly revision: string;
280
+ readonly files: readonly string[];
281
+ readonly config: ConfigFacts;
282
+ readonly routes: readonly RouteFact[];
283
+ readonly tables: readonly TableFact[];
284
+ readonly relations: readonly RelationFact[];
285
+ /** Declarative views (D-157): facts, and graph nodes since D-160. */
286
+ readonly views: readonly ViewFact[];
287
+ readonly pages: readonly PageFact[];
288
+ readonly workflows: readonly WorkflowFact[];
289
+ /** Job definitions, with D-157 applied to the db client their `run` body sees. */
290
+ readonly jobs: readonly JobFact[];
291
+ readonly jobRelations: Readonly<Record<string, JobRelationsFact>>;
292
+ /** Each workflow's table surface, derived from the jobs its steps reference. */
293
+ readonly workflowTables: readonly WorkflowTablesFact[];
294
+ /** Module facts for every parsed source file, in path order. */
295
+ readonly fileFacts: readonly FileFacts[];
296
+ readonly locales: LocaleCatalogs;
297
+ readonly diagnostics: readonly Diagnostic[];
298
+ readonly graph: ProjectGraph;
299
+ }