codesift-mcp 0.7.0 → 0.8.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.
- package/README.md +3 -3
- package/dist/cli/git-hooks-installer.d.ts.map +1 -1
- package/dist/cli/git-hooks-installer.js +18 -5
- package/dist/cli/git-hooks-installer.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +106 -2
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/setup.d.ts +5 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +31 -5
- package/dist/cli/setup.js.map +1 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -1
- package/dist/config.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +6 -1
- package/dist/instructions.js.map +1 -1
- package/dist/parser/extractors/hono.d.ts.map +1 -1
- package/dist/parser/extractors/hono.js +21 -13
- package/dist/parser/extractors/hono.js.map +1 -1
- package/dist/parser/extractors/php.d.ts +12 -0
- package/dist/parser/extractors/php.d.ts.map +1 -1
- package/dist/parser/extractors/php.js +440 -26
- package/dist/parser/extractors/php.js.map +1 -1
- package/dist/register-tool-loaders.d.ts +16 -0
- package/dist/register-tool-loaders.d.ts.map +1 -1
- package/dist/register-tool-loaders.js +26 -0
- package/dist/register-tool-loaders.js.map +1 -1
- package/dist/register-tools.d.ts +3 -1
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +354 -7
- package/dist/register-tools.js.map +1 -1
- package/dist/retrieval/codebase-retrieval.d.ts.map +1 -1
- package/dist/retrieval/codebase-retrieval.js +22 -0
- package/dist/retrieval/codebase-retrieval.js.map +1 -1
- package/dist/retrieval/retrieval-schemas.d.ts +4 -0
- package/dist/retrieval/retrieval-schemas.d.ts.map +1 -1
- package/dist/retrieval/semantic-handlers.js +1 -1
- package/dist/retrieval/semantic-handlers.js.map +1 -1
- package/dist/search/semantic.d.ts +21 -5
- package/dist/search/semantic.d.ts.map +1 -1
- package/dist/search/semantic.js +129 -4
- package/dist/search/semantic.js.map +1 -1
- package/dist/search/tool-ranker.js +1 -1
- package/dist/search/tool-ranker.js.map +1 -1
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +96 -1
- package/dist/server-helpers.js.map +1 -1
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +7 -5
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/registry.d.ts +28 -4
- package/dist/storage/registry.d.ts.map +1 -1
- package/dist/storage/registry.js +126 -5
- package/dist/storage/registry.js.map +1 -1
- package/dist/storage/usage-stats.d.ts +2 -0
- package/dist/storage/usage-stats.d.ts.map +1 -1
- package/dist/storage/usage-stats.js +6 -0
- package/dist/storage/usage-stats.js.map +1 -1
- package/dist/storage/usage-tracker.js +1 -1
- package/dist/storage/usage-tracker.js.map +1 -1
- package/dist/tools/_helpers.d.ts.map +1 -1
- package/dist/tools/_helpers.js +14 -0
- package/dist/tools/_helpers.js.map +1 -1
- package/dist/tools/conversation-tools.js +1 -1
- package/dist/tools/conversation-tools.js.map +1 -1
- package/dist/tools/index-tools.d.ts +12 -0
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +52 -5
- package/dist/tools/index-tools.js.map +1 -1
- package/dist/tools/insights-tools.d.ts +137 -0
- package/dist/tools/insights-tools.d.ts.map +1 -0
- package/dist/tools/insights-tools.js +438 -0
- package/dist/tools/insights-tools.js.map +1 -0
- package/dist/tools/pattern-tools.d.ts +7 -0
- package/dist/tools/pattern-tools.d.ts.map +1 -1
- package/dist/tools/pattern-tools.js +287 -15
- package/dist/tools/pattern-tools.js.map +1 -1
- package/dist/tools/php-tools.d.ts +78 -4
- package/dist/tools/php-tools.d.ts.map +1 -1
- package/dist/tools/php-tools.js +824 -42
- package/dist/tools/php-tools.js.map +1 -1
- package/dist/tools/php8-compat-tools.d.ts +62 -0
- package/dist/tools/php8-compat-tools.d.ts.map +1 -0
- package/dist/tools/php8-compat-tools.js +287 -0
- package/dist/tools/php8-compat-tools.js.map +1 -0
- package/dist/tools/php8-migration-candidates-tools.d.ts +68 -0
- package/dist/tools/php8-migration-candidates-tools.d.ts.map +1 -0
- package/dist/tools/php8-migration-candidates-tools.js +476 -0
- package/dist/tools/php8-migration-candidates-tools.js.map +1 -0
- package/dist/tools/phpstan-baseline-tools.d.ts +62 -0
- package/dist/tools/phpstan-baseline-tools.d.ts.map +1 -0
- package/dist/tools/phpstan-baseline-tools.js +263 -0
- package/dist/tools/phpstan-baseline-tools.js.map +1 -0
- package/dist/tools/project-tools.d.ts +4 -2
- package/dist/tools/project-tools.d.ts.map +1 -1
- package/dist/tools/project-tools.js +19 -6
- package/dist/tools/project-tools.js.map +1 -1
- package/dist/tools/react-tools.d.ts +24 -0
- package/dist/tools/react-tools.d.ts.map +1 -1
- package/dist/tools/react-tools.js +292 -3
- package/dist/tools/react-tools.js.map +1 -1
- package/dist/tools/search-tools.d.ts.map +1 -1
- package/dist/tools/search-tools.js +92 -10
- package/dist/tools/search-tools.js.map +1 -1
- package/dist/tools/symbol-tools.d.ts.map +1 -1
- package/dist/tools/symbol-tools.js +4 -1
- package/dist/tools/symbol-tools.js.map +1 -1
- package/dist/tools/yii-console-tools.d.ts +69 -0
- package/dist/tools/yii-console-tools.d.ts.map +1 -0
- package/dist/tools/yii-console-tools.js +256 -0
- package/dist/tools/yii-console-tools.js.map +1 -0
- package/dist/tools/yii-migrations-tools.d.ts +79 -0
- package/dist/tools/yii-migrations-tools.d.ts.map +1 -0
- package/dist/tools/yii-migrations-tools.js +543 -0
- package/dist/tools/yii-migrations-tools.js.map +1 -0
- package/dist/tools/yii-modules-tools.d.ts +63 -0
- package/dist/tools/yii-modules-tools.d.ts.map +1 -0
- package/dist/tools/yii-modules-tools.js +201 -0
- package/dist/tools/yii-modules-tools.js.map +1 -0
- package/dist/tools/yii-rbac-tools.d.ts +89 -0
- package/dist/tools/yii-rbac-tools.d.ts.map +1 -0
- package/dist/tools/yii-rbac-tools.js +238 -0
- package/dist/tools/yii-rbac-tools.js.map +1 -0
- package/dist/tools/yii3-attribute-candidates-tools.d.ts +72 -0
- package/dist/tools/yii3-attribute-candidates-tools.d.ts.map +1 -0
- package/dist/tools/yii3-attribute-candidates-tools.js +301 -0
- package/dist/tools/yii3-attribute-candidates-tools.js.map +1 -0
- package/dist/tools/yii3-migration-tools.d.ts +74 -0
- package/dist/tools/yii3-migration-tools.d.ts.map +1 -0
- package/dist/tools/yii3-migration-tools.js +440 -0
- package/dist/tools/yii3-migration-tools.js.map +1 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/constant-file-pattern.d.ts +3 -1
- package/dist/utils/constant-file-pattern.d.ts.map +1 -1
- package/dist/utils/constant-file-pattern.js +6 -4
- package/dist/utils/constant-file-pattern.js.map +1 -1
- package/dist/utils/heritage-edges.d.ts +16 -0
- package/dist/utils/heritage-edges.d.ts.map +1 -1
- package/dist/utils/heritage-edges.js +31 -10
- package/dist/utils/heritage-edges.js.map +1 -1
- package/dist/utils/source-stripper.d.ts +23 -0
- package/dist/utils/source-stripper.d.ts.map +1 -0
- package/dist/utils/source-stripper.js +239 -0
- package/dist/utils/source-stripper.js.map +1 -0
- package/dist/utils/tsconfig-paths.d.ts +2 -2
- package/dist/utils/tsconfig-paths.d.ts.map +1 -1
- package/dist/utils/tsconfig-paths.js +10 -4
- package/dist/utils/tsconfig-paths.js.map +1 -1
- package/dist/utils/wall-clock.d.ts +9 -0
- package/dist/utils/wall-clock.d.ts.map +1 -0
- package/dist/utils/wall-clock.js +19 -0
- package/dist/utils/wall-clock.js.map +1 -0
- package/package.json +1 -1
- package/rules/codesift.md +10 -3
- package/rules/codesift.mdc +10 -3
- package/rules/codex.md +10 -3
- package/rules/gemini.md +10 -3
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yii2 console command inventory (N4).
|
|
3
|
+
*
|
|
4
|
+
* Console controllers in Yii2 (extends yii\\console\\Controller) are
|
|
5
|
+
* typically cron jobs, queue workers, or one-off ops scripts. They're
|
|
6
|
+
* a high-leverage surface to audit because they:
|
|
7
|
+
* - run with elevated privileges (no HTTP auth gate)
|
|
8
|
+
* - frequently lack the test coverage the web side has
|
|
9
|
+
* - are the most common place to find unbounded ->all() reads
|
|
10
|
+
*
|
|
11
|
+
* The tool inventories every console controller and its action methods.
|
|
12
|
+
* For each action it surfaces:
|
|
13
|
+
* - declared CLI argument list (extracted from the method signature)
|
|
14
|
+
* - whether the action accepts variadic ...$args
|
|
15
|
+
* - the docblock (often the only documentation for a command)
|
|
16
|
+
* - flags (warnings / hints) about specific risks:
|
|
17
|
+
* - exits-without-return-status: action returns void / nothing,
|
|
18
|
+
* so cron schedulers can't tell success from failure
|
|
19
|
+
* - has-unbounded-all: ->all() found in body without ->limit /
|
|
20
|
+
* ->batch / ->each (cron killer)
|
|
21
|
+
* - has-no-error-handling: no try/catch around the body
|
|
22
|
+
*
|
|
23
|
+
* Output is structured per-controller so consumers can:
|
|
24
|
+
* - cross-reference with crontab / SystemCron entries
|
|
25
|
+
* - flag commands that need test coverage
|
|
26
|
+
* - prioritize commands that look risky
|
|
27
|
+
*/
|
|
28
|
+
import { getCodeIndex } from "./index-tools.js";
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Implementation
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
const CONSOLE_BASE_NAMES = new Set(["Controller"]);
|
|
33
|
+
/**
|
|
34
|
+
* Detect whether a class extends yii\\console\\Controller (or any descendant).
|
|
35
|
+
* Combines a path heuristic — files under `console/`, `commands/`, or
|
|
36
|
+
* `*Console*Controller.php` — with the structural extends check, so we
|
|
37
|
+
* don't pick up web controllers that happen to extend the same base
|
|
38
|
+
* `Controller` class but live under controllers/.
|
|
39
|
+
*/
|
|
40
|
+
function isConsoleControllerClass(cls, index) {
|
|
41
|
+
// Path heuristic: Yii2 advanced/standard convention puts console code
|
|
42
|
+
// under console/controllers/ or commands/. tgm-panel uses commands/.
|
|
43
|
+
// We accept either.
|
|
44
|
+
const inConsoleDir = /(?:^|\/)(?:console\/controllers|commands)\//.test(cls.file);
|
|
45
|
+
if (!inConsoleDir)
|
|
46
|
+
return false;
|
|
47
|
+
// Structural extends check. For the path-matched files we want to
|
|
48
|
+
// confirm the class actually extends a Yii2 Controller (the common
|
|
49
|
+
// base) — picking up vendor classes that happen to live under
|
|
50
|
+
// commands/ is a false positive risk that walking the chain prevents.
|
|
51
|
+
return walkExtendsForConsole(cls, index, new Set(), 0);
|
|
52
|
+
}
|
|
53
|
+
function walkExtendsForConsole(cls, index, visited, depth) {
|
|
54
|
+
if (depth > 5)
|
|
55
|
+
return false;
|
|
56
|
+
if (visited.has(cls.name))
|
|
57
|
+
return false;
|
|
58
|
+
visited.add(cls.name);
|
|
59
|
+
const exts = cls.extends ?? [];
|
|
60
|
+
for (const baseFqcn of exts) {
|
|
61
|
+
const last = baseFqcn.split(/[\\\\]+/).pop() ?? baseFqcn;
|
|
62
|
+
if (CONSOLE_BASE_NAMES.has(last))
|
|
63
|
+
return true;
|
|
64
|
+
// Also accept the explicit "ConsoleController" suffix used by some
|
|
65
|
+
// teams (matches the common convention where console controllers
|
|
66
|
+
// share a project-specific base class).
|
|
67
|
+
if (last === "ConsoleController")
|
|
68
|
+
return true;
|
|
69
|
+
const baseSym = index.symbols.find((s) => s.kind === "class" && s.name === last);
|
|
70
|
+
if (baseSym &&
|
|
71
|
+
walkExtendsForConsole(baseSym, index, visited, depth + 1)) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Fallback for stale indexes without extends metadata.
|
|
76
|
+
if (!cls.extends && cls.source) {
|
|
77
|
+
return /extends\s+(?:\\?yii\\console\\Controller|Controller)\b/.test(cls.source);
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
export async function analyzeYiiConsoleCommands(repo, options) {
|
|
82
|
+
const index = await getCodeIndex(repo);
|
|
83
|
+
if (!index)
|
|
84
|
+
throw new Error(`Repository "${repo}" not found.`);
|
|
85
|
+
const consoleClasses = index.symbols.filter((s) => {
|
|
86
|
+
if (s.kind !== "class")
|
|
87
|
+
return false;
|
|
88
|
+
if (!s.file.endsWith(".php"))
|
|
89
|
+
return false;
|
|
90
|
+
if (!s.name.endsWith("Controller"))
|
|
91
|
+
return false;
|
|
92
|
+
if (!isConsoleControllerClass(s, index))
|
|
93
|
+
return false;
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
const controllers = [];
|
|
97
|
+
for (const cls of consoleClasses) {
|
|
98
|
+
const cliId = pascalToKebab(cls.name.replace(/Controller$/, ""));
|
|
99
|
+
if (options?.controller_id && cliId !== options.controller_id)
|
|
100
|
+
continue;
|
|
101
|
+
const actionMethods = index.symbols.filter((s) => s.parent === cls.id &&
|
|
102
|
+
s.kind === "method" &&
|
|
103
|
+
s.name.startsWith("action") &&
|
|
104
|
+
s.name.length > "action".length);
|
|
105
|
+
const actions = actionMethods.map((m) => {
|
|
106
|
+
const actionId = pascalToKebab(m.name.slice("action".length));
|
|
107
|
+
const args = parseActionArguments(m.signature ?? "");
|
|
108
|
+
const variadic = /\.{3}\$\w+/.test(m.signature ?? "");
|
|
109
|
+
const flags = scanActionFlags(m.source ?? "", m.name);
|
|
110
|
+
return {
|
|
111
|
+
name: m.name,
|
|
112
|
+
cli_id: actionId,
|
|
113
|
+
arguments: args,
|
|
114
|
+
variadic,
|
|
115
|
+
docstring: m.docstring ?? null,
|
|
116
|
+
start_line: m.start_line,
|
|
117
|
+
flags,
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
actions.sort((a, b) => a.name.localeCompare(b.name));
|
|
121
|
+
controllers.push({
|
|
122
|
+
class: cls.name,
|
|
123
|
+
cli_id: cliId,
|
|
124
|
+
file: cls.file,
|
|
125
|
+
actions,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
controllers.sort((a, b) => a.cli_id.localeCompare(b.cli_id));
|
|
129
|
+
// Cross-controller summary: actions with ≥2 flags, sorted by flag count.
|
|
130
|
+
const highRisk = [];
|
|
131
|
+
for (const c of controllers) {
|
|
132
|
+
for (const a of c.actions) {
|
|
133
|
+
if (a.flags.length >= 2) {
|
|
134
|
+
highRisk.push({
|
|
135
|
+
controller: c.class,
|
|
136
|
+
action: a.name,
|
|
137
|
+
cli_id: `${c.cli_id}/${a.cli_id}`,
|
|
138
|
+
flags: a.flags,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
highRisk.sort((a, b) => b.flags.length - a.flags.length);
|
|
144
|
+
const totalActions = controllers.reduce((n, c) => n + c.actions.length, 0);
|
|
145
|
+
return {
|
|
146
|
+
repo,
|
|
147
|
+
total_controllers: controllers.length,
|
|
148
|
+
total_actions: totalActions,
|
|
149
|
+
controllers,
|
|
150
|
+
high_risk_actions: highRisk,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Helpers
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
function pascalToKebab(s) {
|
|
157
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Parse a method signature string like "(string $repo, int $limit = 10, ...$rest)"
|
|
161
|
+
* into a structured argument list. Type and default are best-effort — we
|
|
162
|
+
* preserve the source-side spelling, callers can normalize.
|
|
163
|
+
*/
|
|
164
|
+
function parseActionArguments(signature) {
|
|
165
|
+
if (!signature)
|
|
166
|
+
return [];
|
|
167
|
+
// Strip leading "(" and trailing "): ReturnType" → keep just the param list
|
|
168
|
+
const inner = signature.replace(/^\(|\).*$/g, "");
|
|
169
|
+
if (!inner.trim())
|
|
170
|
+
return [];
|
|
171
|
+
const args = [];
|
|
172
|
+
// Split on commas at top level only — parameters can have default values
|
|
173
|
+
// containing commas (e.g. `array $cfg = [1, 2]`). For a CLI tool this is
|
|
174
|
+
// rare so a comma-split + simple bracket-balance fixup is enough.
|
|
175
|
+
const parts = splitParams(inner);
|
|
176
|
+
for (const part of parts) {
|
|
177
|
+
const trimmed = part.trim();
|
|
178
|
+
if (!trimmed)
|
|
179
|
+
continue;
|
|
180
|
+
// Skip variadic — handled separately by the caller via .test()
|
|
181
|
+
if (/^\.{3}\$/.test(trimmed))
|
|
182
|
+
continue;
|
|
183
|
+
// Extract: optional type + $name + optional `= default`
|
|
184
|
+
const m = /^(?:([?\w\\|&]+)\s+)?\$(\w+)(?:\s*=\s*(.+))?$/.exec(trimmed);
|
|
185
|
+
if (!m)
|
|
186
|
+
continue;
|
|
187
|
+
const type = m[1] ?? null;
|
|
188
|
+
const name = m[2];
|
|
189
|
+
const defaultValue = m[3]?.trim() ?? null;
|
|
190
|
+
args.push({
|
|
191
|
+
name,
|
|
192
|
+
type,
|
|
193
|
+
default: defaultValue,
|
|
194
|
+
required: defaultValue === null,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return args;
|
|
198
|
+
}
|
|
199
|
+
function splitParams(s) {
|
|
200
|
+
const out = [];
|
|
201
|
+
let depth = 0;
|
|
202
|
+
let buf = "";
|
|
203
|
+
for (const c of s) {
|
|
204
|
+
if (c === "(" || c === "[" || c === "{")
|
|
205
|
+
depth++;
|
|
206
|
+
else if (c === ")" || c === "]" || c === "}")
|
|
207
|
+
depth--;
|
|
208
|
+
if (c === "," && depth === 0) {
|
|
209
|
+
out.push(buf);
|
|
210
|
+
buf = "";
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
buf += c;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (buf.trim())
|
|
217
|
+
out.push(buf);
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
function scanActionFlags(body, methodName) {
|
|
221
|
+
const flags = [];
|
|
222
|
+
if (!body)
|
|
223
|
+
return flags;
|
|
224
|
+
// exits-without-return-status: actions that have no `return` statement OR
|
|
225
|
+
// return only void/null. Yii2's ExitCode constants are the recommended
|
|
226
|
+
// way to surface success/failure to the cron scheduler.
|
|
227
|
+
const hasExitReturn = /\breturn\s+(?:ExitCode::|self::|static::)/.test(body);
|
|
228
|
+
const hasIntReturn = /\breturn\s+(?:0|1|-?\d+)\s*;/.test(body);
|
|
229
|
+
const hasAnyReturn = /\breturn\b/.test(body);
|
|
230
|
+
if (!hasExitReturn && !hasIntReturn && !hasAnyReturn) {
|
|
231
|
+
flags.push("exits-without-return-status");
|
|
232
|
+
}
|
|
233
|
+
// has-unbounded-all: ->all() with no ->limit / ->batch / ->each in
|
|
234
|
+
// the same body. Same heuristic as the perf pattern.
|
|
235
|
+
if (/->all\s*\(\s*\)/.test(body) &&
|
|
236
|
+
!/->(?:limit|batch|each)\b/.test(body)) {
|
|
237
|
+
flags.push("has-unbounded-all");
|
|
238
|
+
}
|
|
239
|
+
// has-no-error-handling: no try/catch around the body. Cron jobs that
|
|
240
|
+
// throw uncaught exceptions can leave their state half-written; at
|
|
241
|
+
// minimum a top-level catch + ExitCode::OK / UNSPECIFIED_ERROR is
|
|
242
|
+
// worth surfacing.
|
|
243
|
+
if (!/\btry\s*\{/.test(body)) {
|
|
244
|
+
flags.push("has-no-error-handling");
|
|
245
|
+
}
|
|
246
|
+
// uses-output-via-echo: directly printing via echo / print. The Yii2
|
|
247
|
+
// idiom is `$this->stdout(...)` / `$this->stderr(...)` which respects
|
|
248
|
+
// output piping and color settings. Skipped on actionHelp / actionInit
|
|
249
|
+
// where echo is a fine choice.
|
|
250
|
+
if (!/^action(?:Help|Init|Index)$/.test(methodName) &&
|
|
251
|
+
/\b(?:echo|print)\s+(?!Yii::)/.test(body)) {
|
|
252
|
+
flags.push("uses-output-via-echo");
|
|
253
|
+
}
|
|
254
|
+
return flags;
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=yii-console-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yii-console-tools.js","sourceRoot":"","sources":["../../src/tools/yii-console-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yii2 migrations audit (N2).
|
|
3
|
+
*
|
|
4
|
+
* Yii2 ships its own PHP-DSL migration system — `extends Migration` with
|
|
5
|
+
* `$this->createTable()`, `$this->addColumn()`, `$this->dropTable()`, etc.
|
|
6
|
+
* The generic SQL toolchain (migration_lint, analyze_schema, sql_audit) is
|
|
7
|
+
* auto-loaded for composer.json projects but parses only `.sql` files, so
|
|
8
|
+
* the 379 migrations in tgm-panel are invisible to it.
|
|
9
|
+
*
|
|
10
|
+
* This tool fills that gap. For each migration class we:
|
|
11
|
+
* 1. Map the DSL calls to a structured operation list
|
|
12
|
+
* (create_table, drop_table, add_column, ...).
|
|
13
|
+
* 2. Run audit checks per migration:
|
|
14
|
+
* - missing_safe_down (irreversible)
|
|
15
|
+
* - drop_without_safety (drop in safeUp without index/backup hint)
|
|
16
|
+
* - alter_without_online_ddl (alter on large tables without
|
|
17
|
+
* ALGORITHM=INPLACE, LOCK=NONE for MySQL 8)
|
|
18
|
+
* - fk_without_index (addForeignKey on a column without
|
|
19
|
+
* a corresponding createIndex earlier)
|
|
20
|
+
* 3. Surface a per-table operation index (which migrations touch table X).
|
|
21
|
+
*
|
|
22
|
+
* The DSL parser is deliberately regex-based, not tree-sitter. Migration
|
|
23
|
+
* methods follow a small, stable grammar (a few verbs from yii\\db\\Migration
|
|
24
|
+
* with predictable argument shapes) and the AST coverage we'd buy with a
|
|
25
|
+
* full walker isn't worth the cost. The audit is a discovery tool, not a
|
|
26
|
+
* gate — false positives are acceptable, false negatives are the failure
|
|
27
|
+
* mode we minimize.
|
|
28
|
+
*/
|
|
29
|
+
export type YiiMigrationOpKind = "create_table" | "drop_table" | "rename_table" | "add_column" | "drop_column" | "alter_column" | "rename_column" | "create_index" | "drop_index" | "add_primary_key" | "drop_primary_key" | "add_foreign_key" | "drop_foreign_key" | "execute_raw_sql" | "insert" | "update" | "delete" | "batch_insert";
|
|
30
|
+
export interface YiiMigrationOp {
|
|
31
|
+
kind: YiiMigrationOpKind;
|
|
32
|
+
/** Primary table the op touches, when statically determinable. */
|
|
33
|
+
table: string | null;
|
|
34
|
+
/** Column name when applicable (add_column, alter_column, rename_column). */
|
|
35
|
+
column?: string;
|
|
36
|
+
/** Index name when applicable (create_index, drop_index). */
|
|
37
|
+
index_name?: string;
|
|
38
|
+
/** Foreign key constraint name when applicable. */
|
|
39
|
+
fk_name?: string;
|
|
40
|
+
/** 1-based line within the migration class source where the op occurred. */
|
|
41
|
+
line: number;
|
|
42
|
+
/** Raw method name from the DSL call. */
|
|
43
|
+
raw: string;
|
|
44
|
+
}
|
|
45
|
+
export interface YiiMigrationAuditFinding {
|
|
46
|
+
rule_id: "missing-safe-down" | "drop-without-safety" | "alter-without-online-ddl" | "fk-without-index" | "raw-sql-without-comment";
|
|
47
|
+
severity: "high" | "medium" | "low";
|
|
48
|
+
description: string;
|
|
49
|
+
fix: string;
|
|
50
|
+
}
|
|
51
|
+
export interface YiiMigrationFile {
|
|
52
|
+
file: string;
|
|
53
|
+
class_name: string;
|
|
54
|
+
/** Up-flow operations (`up()` or `safeUp()`). */
|
|
55
|
+
up_ops: YiiMigrationOp[];
|
|
56
|
+
/** Down-flow operations (`down()` or `safeDown()`). */
|
|
57
|
+
down_ops: YiiMigrationOp[];
|
|
58
|
+
/** True iff the migration uses safeUp/safeDown (transactional in Yii2). */
|
|
59
|
+
is_safe_transactional: boolean;
|
|
60
|
+
/** Tables touched by this migration (union of up + down). */
|
|
61
|
+
tables: string[];
|
|
62
|
+
findings: YiiMigrationAuditFinding[];
|
|
63
|
+
}
|
|
64
|
+
export interface YiiMigrationsAudit {
|
|
65
|
+
repo: string;
|
|
66
|
+
scanned_files: number;
|
|
67
|
+
total_migrations: number;
|
|
68
|
+
/** All migration files keyed by canonical relative path. */
|
|
69
|
+
migrations: YiiMigrationFile[];
|
|
70
|
+
/** Per-table back-index: list of migrations touching that table. */
|
|
71
|
+
by_table: Record<string, string[]>;
|
|
72
|
+
/** Aggregate finding counts by rule. */
|
|
73
|
+
findings_summary: Record<string, number>;
|
|
74
|
+
}
|
|
75
|
+
export declare function analyzeYiiMigrations(repo: string, options?: {
|
|
76
|
+
file_pattern?: string;
|
|
77
|
+
rules?: YiiMigrationAuditFinding["rule_id"][];
|
|
78
|
+
}): Promise<YiiMigrationsAudit>;
|
|
79
|
+
//# sourceMappingURL=yii-migrations-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yii-migrations-tools.d.ts","sourceRoot":"","sources":["../../src/tools/yii-migrations-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAUH,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,aAAa,GACb,cAAc,GACd,eAAe,GACf,cAAc,GACd,YAAY,GACZ,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,cAAc,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,kEAAkE;IAClE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EACH,mBAAmB,GACnB,qBAAqB,GACrB,0BAA0B,GAC1B,kBAAkB,GAClB,yBAAyB,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,uDAAuD;IACvD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,2EAA2E;IAC3E,qBAAqB,EAAE,OAAO,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AA+ND,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,wBAAwB,CAAC,SAAS,CAAC,EAAE,CAAA;CAAE,GACjF,OAAO,CAAC,kBAAkB,CAAC,CAmG7B"}
|