@groma/scanner-react 0.1.3 → 0.1.4

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 (3) hide show
  1. package/README.md +123 -8
  2. package/dist/index.js +1383 -121
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -25,12 +25,11 @@ declarations. the TypeScript scanner's 7.1 SDK is unchanged. No consumer build
25
25
  or installation script is required. Public naming and publication are separate
26
26
  release decisions.
27
27
 
28
- Install the application's declared dependencies and React types with its
29
- package manager and lockfile. The scanner reads each selected project's `tsconfig.json` through
30
- the TypeScript compiler and inventories its owned TSX source files. Missing
31
- React dependencies, invalid configuration, syntax errors, and semantic errors
32
- in those TSX files fail preparation with instructions. It does not claim to
33
- type-check unrelated server source files. It does not run application code.
28
+ The scanner reads each selected project's `tsconfig.json` and owned TSX files
29
+ using its bundled TypeScript compiler. Project dependencies and React types do
30
+ not need to be installed. Invalid configuration and source syntax fail with a
31
+ diagnostic; missing external types do not prevent local callback extraction.
32
+ The scanner does not run application code or require successful type checking.
34
33
 
35
34
  ## Evidence and tooling
36
35
 
@@ -58,6 +57,122 @@ In OKF, the result remains readable Code links and relationship rows. In C4,
58
57
  React components remain source evidence, not automatic architecture components
59
58
  or a new containment level. Core owns interpretation and curated ownership.
60
59
 
60
+ ## Source outline
61
+
62
+ The scanner outlines the TSX files in a component's Code with the TypeScript
63
+ rules of the [source outline contract](../creating-a-plugin.md#source-outline):
64
+ top-level functions and types (classes, interfaces, enums), including namespace
65
+ contents, and each type's constructors and methods. A function component is a
66
+ top-level function or a function literal bound directly to a top-level name;
67
+ wrapped values such as `memo(...)` and `forwardRef(...)` are not listed, so a
68
+ file whose only component is a `memo(...)` value has no declarations and is left
69
+ out of the outline, while its Code file still appears. A class component is a
70
+ type with its methods. Every declaration has its line and
71
+ visibility, and `entry` marks the names the Code links give. The package's own
72
+ TypeScript parses each file alone, without `tsconfig.json`, dependencies or
73
+ compilation.
74
+
75
+ Core outlines each file once. For a source that the TypeScript scanner also
76
+ owns, the scanner with the lowest id among the file's Code links outlines it,
77
+ here React, with the symbols of all those links.
78
+
79
+ ## HTTP endpoints and requests
80
+
81
+ The scanner reports [HTTP facts](../evidence.md#http-endpoints-and-requests) for
82
+ the clients it recognizes in the TSX files it reads, and for the endpoints a
83
+ Next.js project declares by file location. In a project that declares `next`, it
84
+ also reads `app/**/route.ts` and `.tsx` and `pages/api/**`, which another scanner
85
+ may read as well. Next.js reads each of `app` and `pages` from the project root,
86
+ or from `src` only when the root has none, so a `src/app` beside a root `app`
87
+ serves nothing.
88
+
89
+ | Construct | Reported |
90
+ | --- | --- |
91
+ | `fetch(url, init)`, including a `node-fetch` default import | Request; a literal `method` gives the method, no options means `GET`, and options the scanner cannot read leave it out |
92
+ | `axios.get`, `.post`, `.put`, `.patch`, `.delete`, `.head`, `.options` | Request with that method |
93
+ | `axios(config)`, `axios.request(config)` | Request from the config's `url`; its `method`, else the client's, else `GET` |
94
+ | `axios.create(config)` instances | Request whose path follows the config's `baseURL`, and whose method defaults to the config's |
95
+ | `app/**/route.ts` | Endpoint per exported `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD` or `OPTIONS` handler, at the route's directory path |
96
+ | `pages/api/**` | Endpoint for the default export, which answers every method, so `*` |
97
+
98
+ `fetch` counts when it is the runtime's, which the project neither declares nor
99
+ imports, or the default export of `node-fetch`, so a `fetch` the project exports
100
+ from its own module is that function. An `axios` client counts only when its
101
+ name is the `axios` default import, or a variable the project never assigns
102
+ again holding `require('axios')` or `axios.create(...)` called on it, so
103
+ `isAxiosError`, a named `post` import and a `get` on any other object are never
104
+ requests. Options are read as values are, as decision 5 describes, so a changed,
105
+ duplicated or computed option is never taken for the literal it once held. An
106
+ option object the scanner cannot read leaves the method out instead of claiming
107
+ `GET`, and for axios leaves the base unknown too. A `fetch` input that is not a
108
+ URL, such as a `Request`, carries a method of its own, so the fact states none.
109
+ A request's own `baseURL`, in its config or in the configuration argument of a
110
+ shorthand, which a `post`, `put` or `patch` takes third, replaces the client's.
111
+ A base joins a relative path with one slash, and an absolute URL replaces it.
112
+
113
+ A client's `defaults` count too: exactly one assignment to `defaults.baseURL` or
114
+ `defaults.method` anywhere in the project sets it, and more than one, or any other
115
+ change to `defaults` itself or to those two properties, hides both. An instance
116
+ without a base of its own copies the default client's when it is created, which
117
+ the scan cannot order, so a base assigned to `axios.defaults` leaves the
118
+ instance's unknown. These are accepted risks: the one assignment is taken to run
119
+ before every request, although a test file or a function that runs only
120
+ sometimes may make it, and interceptors, code a client is handed to, a re-exported
121
+ default client, an alias such as `const alias = api`, and a destructured
122
+ `defaults` are not read.
123
+
124
+ The [producer decisions](../evidence.md#producer-checklist) for this ecosystem:
125
+
126
+ 1. **Prefixes.** An endpoint's path is its route file's directory path, as
127
+ decision 6 describes; no other prefix applies. On the client side, only an
128
+ `axios.create({ baseURL })` base precedes a path.
129
+ 2. **Endpoints.** Only the route files above, and only in a project that
130
+ declares `next`. A page, a layout, `middleware.ts`, and a component answer no
131
+ request of their own, and `pages/api.tsx` is a page, not a route. A route file
132
+ whose path holds a parallel route `@modal` or an intercepted route `(.)talks`
133
+ reports nothing, because the served path is not the file path there. A Pages
134
+ Router route whose default export is not a function in that file also reports
135
+ nothing.
136
+ 3. **Dynamic or unknown.** `` `/talks/${id}` `` fills one whole segment, so it is
137
+ dynamic. `` `/talks/${id}-latest` ``, a path built from a parameter, and an
138
+ unresolvable value are unknown. The query and fragment are dropped, computed
139
+ or not.
140
+ 4. **Local helpers.** Not supported: the URL is read at the client call, so a
141
+ helper that forwards a path parameter reports unknown text, and its callers
142
+ report nothing. Author those rows.
143
+ 5. **Bases.** A root-relative literal path has no base. A variable with a
144
+ literal initializer that the project never assigns again is literal text. So
145
+ is a property of an object literal such a variable holds: the last property
146
+ with its name, while the literal has no spread, computed key or accessor, and
147
+ no code in the project assigns or deletes that property or an object above
148
+ it, hands one of them to other code, or calls a method through them, and no
149
+ module object holding it, such as a namespace import, a re-exported namespace
150
+ or a dynamic import's result, is used other than to read one export by name.
151
+ A value the scanner cannot see, such as an ambient declaration,
152
+ `process.env.API_URL`, `import.meta.env` or a constant imported from a
153
+ package, sets `configured`. A field read through `this` holds the value of
154
+ its one plain assignment, whether its declaration, its constructor or any
155
+ code that writes it, so `resourceUrl = API_URL + '/api/speakers'` reads as
156
+ that configured base and path; a field the sources never assign, such as one
157
+ a framework injects, is the client's own base setting and sets `configured`,
158
+ and a field assigned more than once, by a subclass too, or with a value the
159
+ scanner cannot read, is unknown. Text that continues a configured value's
160
+ last segment instead of starting with `/` is unknown. A literal host, also
161
+ when literal pieces only state it together, a parameter, a value a call
162
+ returns, and any other computed value report a leading unknown segment.
163
+ 6. **File-location routes.** A route file's directory path is its served path,
164
+ with `[id]` a parameter, `[...rest]` a catch-all and `[[...rest]]` an optional
165
+ catch-all. A route group such as `(admin)` organizes files without serving a
166
+ segment, so `app/api/(admin)/audit/route.ts` serves `/api/audit`. A Pages
167
+ Router `index` file serves its directory, while a directory named `index` is an
168
+ ordinary segment. An App Router endpoint names the exported handler for its
169
+ method; a Pages Router endpoint names the function its default export
170
+ designates. Every request names the function that runs the call.
171
+ 7. **Constrained segments.** None: `[id]`, `[...rest]` and `[[...rest]]` accept
172
+ any text.
173
+ 8. **Registration order.** None: Next.js prefers the most specific route,
174
+ whatever order its files are in.
175
+
61
176
  ## Limits
62
177
 
63
178
  This revision qualifies the Backlog.md CleanupModal success callback. It does
@@ -68,7 +183,7 @@ direct bindings produce `unsupported-react-binding` diagnostics and no certain
68
183
  claim. Components that cannot resolve to a supported source function do not
69
184
  establish a callback interaction.
70
185
 
71
- TSX and TypeScript edits use the existing watch lifecycle. Healthy scanners update the architecture while failed scanners keep their saved evidence. See [validation](validation.md) for
186
+ TSX and TypeScript edits use the existing watch lifecycle. Healthy scanners update the architecture while failed scanners keep their saved evidence. See [fresh-checkout validation](../fresh-checkout-validation.md) for
72
187
  the executed artifact checks and remaining release gates.
73
188
 
74
189
  ## Nested projects
@@ -79,7 +194,7 @@ dev dependencies, peer dependencies and optional dependencies identify candidate
79
194
  A candidate also needs a tracked or unignored `tsconfig.json` and TSX source
80
195
  files belonging to that package, outside nested packages. Declaration files and
81
196
  inactive fixtures with a `.fixture` suffix do not qualify. Packages with only
82
- framework tooling dependencies are skipped. No matching project produces no evidence. Each compiler uses that project's configuration and installed dependencies;
197
+ framework tooling dependencies are skipped. No matching project produces no evidence. Each compiler uses that project's configuration and local source;
83
198
  imported source in sibling repository libraries keeps its original source path.
84
199
  Readiness checks all selected projects. An invalid selected project fails this scanner's observation; other scanners
85
200
  can still update the architecture.