Repository navigation
Expand file tree
/
Copy pathrules.yml
More file actions
157 lines (146 loc) · 6.62 KB
/
Copy pathrules.yml
File metadata and controls
157 lines (146 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# src/entrypoints/rules.yml — the SHIPPED entrypoint ruleset (#72; python `rules.yml` parity).
#
# Decorator `match:` is against the import-table-resolved name (`@nestjs/common.Get`): the module
# specifier kept verbatim, aliases mapped back to the exported name. There is no checker tier.
# Base-class `match:` is against the resolved-or-written base spelling the same way.
version: 1
frameworks:
nestjs:
detect: ["@nestjs/common", "@nestjs/core"]
decorators:
- id: nestjs.controller
match: "@nestjs/common.Controller"
route: {from: positional, index: 0}
- id: nestjs.verb
match: "@nestjs/common.{Get,Post,Put,Patch,Delete,Head,Options,All}"
route: {from: positional, index: 0}
methods: {from: match_suffix}
angular:
detect: ["@angular/core"]
decorators:
- id: angular.component
match: "@angular/core.Component"
- id: angular.ngmodule
match: "@angular/core.NgModule"
nextjs:
detect: [next]
files:
- id: nextjs.app-route
match: "app/**/route.{ts,tsx,js,mjs}"
exports: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS]
methods: {from: export_name}
- id: nextjs.pages-api
match: "pages/api/**/*.{ts,tsx,js,mjs}"
exports: [default]
# The `src/` layout Next.js supports officially (#206). Separate rows, not a loosened glob:
# `globToRegExp` anchors a pattern containing `/` at the repo root by design, and a file must
# match a convention path exactly, not anywhere in the tree.
- id: nextjs.app-route-src
match: "src/app/**/route.{ts,tsx,js,mjs}"
exports: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS]
methods: {from: export_name}
- id: nextjs.pages-api-src
match: "src/pages/api/**/*.{ts,tsx,js,mjs}"
exports: [default]
sveltekit:
detect: ["@sveltejs/kit"]
files:
- id: sveltekit.server
match: "**/+server.{ts,js}"
exports: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS]
methods: {from: export_name}
# Remix, and React Router v7 which absorbed it (#206) — a route module exports named callables,
# so the file tier resolves them with no resolution work. One rule per export rather than one rule
# listing all three: the `rule` id is then what tells a consumer whether it is looking at a data
# loader, a mutation, or the rendered component. `http_methods` stays empty — mapping `loader` to
# GET and `action` to the mutating verbs needs a per-export method source the grammar lacks, and
# inventing one here would be a spelling no sibling analyzer has agreed to.
remix:
detect: ["@remix-run/node", "@remix-run/react", "@remix-run/server-runtime", "@remix-run/cloudflare", react-router]
files:
- id: remix.loader
match: "app/routes/**/*.{ts,tsx,js,jsx}"
exports: [loader]
- id: remix.action
match: "app/routes/**/*.{ts,tsx,js,jsx}"
exports: [action]
- id: remix.route-component
match: "app/routes/**/*.{ts,tsx,js,jsx}"
exports: [default]
# Astro API routes (#206): verb-named exports beside the `.astro` pages. `.astro` files themselves
# are not parsed, so this covers the `.ts`/`.js` endpoints only. `ALL` is listed because it is a
# real Astro handler; `methods: {from: export_name}` filters it to [] since it is not an HTTP verb.
astro:
detect: [astro]
files:
- id: astro.api-route
match: "src/pages/**/*.{ts,js}"
exports: [GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, ALL]
methods: {from: export_name}
# ---- non-web (#167). Framework-tier CALL rules: gated on the dependency AND matched on the
# import-table-resolved callee, so `app.on(...)` in an Express app or on any EventEmitter can
# never register as Electron. `route` carries the event / channel name for `on`/`handle` rules —
# the nearest field; python's `route` is HTTP-only.
electron:
detect: [electron]
calls:
- id: electron.app-on
match: "electron.app.{on,once}"
route: {from: positional, index: 0}
handler: {from: positional, index: -1}
- id: electron.ipc
match: "electron.ipcMain.{on,once,handle,handleOnce}"
route: {from: positional, index: 0}
handler: {from: positional, index: -1}
commander:
detect: [commander]
calls:
# `program.command("x").option(...).action(run)` — the chain between `program` and `.action`
# is one to three dotless segments (a call with parentheses has no dot).
- id: commander.action
match: "commander.program.{*,*.*,*.*.*}.action"
handler: {from: positional, index: -1}
worker_threads:
detect: ["node:worker_threads", worker_threads]
calls:
- id: worker_threads.parent-port
match: "{node:worker_threads,worker_threads}.parentPort.{on,once}"
route: {from: positional, index: 0}
handler: {from: positional, index: -1}
# Framework-independent tier. Matched on the WRITTEN spelling, never a resolved name, so a shape
# that reads as an HTTP entrypoint is flagged even when no `frameworks:` block knows the library
# (or it is not installed). Confidence `heuristic` is forced by the loader. Runs LAST; a node a
# framework rule already claimed gets no heuristic record.
heuristics:
decorators:
- id: heuristic.http-route
match: "{route,*.route,*.*.route}"
route: {from: positional, index: 0}
methods: {from: keyword, name: methods}
- id: heuristic.http-verb
match: "{*,*.*}.{get,post,put,patch,delete,head,options,websocket}"
route: {from: positional, index: 0}
methods: {from: match_suffix}
calls:
# `app.get('/p', handler)` — the record attaches to the HANDLER (the callable the request
# reaches), `via` is the module-scope call. `use` is deliberate: middleware is reachable from
# outside just as a route is; filter on http_methods for routes only.
- id: heuristic.http-verb-call
match: "{*,*.*}.{get,post,put,patch,delete,all,use}"
route: {from: positional, index: 0}
methods: {from: match_suffix}
handler: {from: positional, index: -1}
# `process` is a Node global — nothing to gate on, and the spelling is distinctive enough to be
# a heuristic. Signal and lifecycle handlers are invoked from outside the program.
- id: heuristic.process-on
match: "process.{on,once}"
route: {from: positional, index: 0}
handler: {from: positional, index: -1}
# Manifest-declared entrypoints: what runs when the package is executed. Confidence `declared`.
manifest:
- id: manifest.bin
source: package.json
field: bin
- id: manifest.main
source: package.json
field: main