codesift-mcp 0.5.30 → 0.8.2
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 +7 -2
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +25 -3
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/git-hooks-installer.d.ts +2 -0
- package/dist/cli/git-hooks-installer.d.ts.map +1 -1
- package/dist/cli/git-hooks-installer.js +47 -7
- package/dist/cli/git-hooks-installer.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +53 -0
- 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/_shared.js +2 -2
- package/dist/parser/extractors/_shared.js.map +1 -1
- package/dist/parser/extractors/hono.d.ts.map +1 -1
- package/dist/parser/extractors/hono.js +60 -15
- 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/parser/extractors/python.js +4 -5
- package/dist/parser/extractors/python.js.map +1 -1
- package/dist/parser/extractors/typescript.d.ts.map +1 -1
- package/dist/parser/extractors/typescript.js +70 -22
- package/dist/parser/extractors/typescript.js.map +1 -1
- package/dist/register-tool-loaders.d.ts +22 -0
- package/dist/register-tool-loaders.d.ts.map +1 -1
- package/dist/register-tool-loaders.js +38 -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 +527 -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.js +1 -1
- package/dist/server-helpers.js.map +1 -1
- package/dist/storage/index-store.d.ts +13 -1
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +34 -33
- 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/tools/_helpers.d.ts +2 -0
- package/dist/tools/_helpers.d.ts.map +1 -1
- package/dist/tools/_helpers.js +16 -1
- package/dist/tools/_helpers.js.map +1 -1
- package/dist/tools/astro-audit.d.ts +40 -0
- package/dist/tools/astro-audit.d.ts.map +1 -1
- package/dist/tools/astro-audit.js +94 -5
- package/dist/tools/astro-audit.js.map +1 -1
- package/dist/tools/astro-env-validator.d.ts +38 -0
- package/dist/tools/astro-env-validator.d.ts.map +1 -0
- package/dist/tools/astro-env-validator.js +190 -0
- package/dist/tools/astro-env-validator.js.map +1 -0
- package/dist/tools/astro-helpers.js +2 -2
- package/dist/tools/astro-helpers.js.map +1 -1
- package/dist/tools/astro-image-audit.d.ts +35 -0
- package/dist/tools/astro-image-audit.d.ts.map +1 -0
- package/dist/tools/astro-image-audit.js +129 -0
- package/dist/tools/astro-image-audit.js.map +1 -0
- package/dist/tools/astro-middleware.d.ts.map +1 -1
- package/dist/tools/astro-middleware.js +36 -11
- package/dist/tools/astro-middleware.js.map +1 -1
- package/dist/tools/astro-migration.d.ts.map +1 -1
- package/dist/tools/astro-migration.js +66 -0
- package/dist/tools/astro-migration.js.map +1 -1
- package/dist/tools/astro-svg-components.d.ts +32 -0
- package/dist/tools/astro-svg-components.d.ts.map +1 -0
- package/dist/tools/astro-svg-components.js +123 -0
- package/dist/tools/astro-svg-components.js.map +1 -0
- package/dist/tools/context-tools.d.ts.map +1 -1
- package/dist/tools/context-tools.js +45 -7
- package/dist/tools/context-tools.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 +54 -6
- 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 +292 -19
- 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 +20 -7
- package/dist/tools/project-tools.js.map +1 -1
- package/dist/tools/react-tools.d.ts +39 -9
- package/dist/tools/react-tools.d.ts.map +1 -1
- package/dist/tools/react-tools.js +313 -18
- 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 +35 -5
- package/dist/tools/search-tools.js.map +1 -1
- package/dist/tools/status-tools.d.ts +1 -0
- package/dist/tools/status-tools.d.ts.map +1 -1
- package/dist/tools/status-tools.js +1 -0
- package/dist/tools/status-tools.js.map +1 -1
- package/dist/tools/symbol-tools.d.ts +11 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -1
- package/dist/tools/symbol-tools.js +107 -6
- 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 +29 -0
- package/dist/utils/heritage-edges.d.ts.map +1 -0
- package/dist/utils/heritage-edges.js +94 -0
- package/dist/utils/heritage-edges.js.map +1 -0
- 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/ts-imports.d.ts +7 -1
- package/dist/utils/ts-imports.d.ts.map +1 -1
- package/dist/utils/ts-imports.js +40 -7
- package/dist/utils/ts-imports.js.map +1 -1
- package/dist/utils/tsconfig-paths.d.ts +6 -5
- package/dist/utils/tsconfig-paths.d.ts.map +1 -1
- package/dist/utils/tsconfig-paths.js +52 -14
- 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 +16 -6
- package/rules/codesift.mdc +10 -3
- package/rules/codex.md +10 -3
- package/rules/gemini.md +10 -3
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yii3 attribute conversion candidates (M2).
|
|
3
|
+
*
|
|
4
|
+
* Yii3 is natively PHP 8 attribute-based. The mechanical mapping from
|
|
5
|
+
* Yii2 array-config idioms to Yii3 attributes is well-defined, but
|
|
6
|
+
* applying it across thousands of files is the bottleneck for any
|
|
7
|
+
* Yii2→Yii3 migration. This tool surfaces every site that's a candidate
|
|
8
|
+
* for the conversion + a proposed attribute form, capped by sample limit
|
|
9
|
+
* so the consumer can triage at their own pace.
|
|
10
|
+
*
|
|
11
|
+
* Conversions covered:
|
|
12
|
+
*
|
|
13
|
+
* behaviors-to-attributes
|
|
14
|
+
* behaviors() returning an array with TimestampBehavior /
|
|
15
|
+
* BlameableBehavior / SluggableBehavior / etc → #[Behavior(class)] on
|
|
16
|
+
* the class. We surface the entire behaviors() body in `current_form`
|
|
17
|
+
* so the auditor sees the array-shape that needs conversion.
|
|
18
|
+
*
|
|
19
|
+
* rules-to-attributes
|
|
20
|
+
* rules() returning array of [['field'], 'validator'] tuples →
|
|
21
|
+
* #[Required], #[Email], #[StringLength(min: 1)] on the property.
|
|
22
|
+
* Each tuple becomes one or more proposed attributes.
|
|
23
|
+
*
|
|
24
|
+
* urlmanager-rule-to-route
|
|
25
|
+
* 'GET api/users/<id>' => 'user/view' (in urlManager rules) →
|
|
26
|
+
* #[Route(method: 'GET', path: '/api/users/{id}')] on the controller
|
|
27
|
+
* action. We resolve the controller/action target from the rule's
|
|
28
|
+
* right side. {param} placeholders are emitted but type constraints
|
|
29
|
+
* are dropped (Yii2 supports inline regex like <id:\\d+>; Yii3 uses
|
|
30
|
+
* route attributes like #[Route('/{id<int>}')]).
|
|
31
|
+
*
|
|
32
|
+
* Output shape:
|
|
33
|
+
* - candidates[] — flat list of all conversions
|
|
34
|
+
* - by_rule[] — grouped + sample-capped, sorted by count desc
|
|
35
|
+
* - summary — total + per-rule counts
|
|
36
|
+
*
|
|
37
|
+
* Like M1, this tool never auto-applies. Each candidate ships:
|
|
38
|
+
* current_form (the source as written today)
|
|
39
|
+
* suggested_replacement (the attribute equivalent)
|
|
40
|
+
* confidence ("high" | "medium" | "low")
|
|
41
|
+
* blockers[] (string reasons the conversion may be unsafe —
|
|
42
|
+
* e.g. "rule references a Closure validator that
|
|
43
|
+
* can't be lifted to an attribute")
|
|
44
|
+
*/
|
|
45
|
+
import { readFile } from "node:fs/promises";
|
|
46
|
+
import { join } from "node:path";
|
|
47
|
+
import { getCodeIndex } from "./index-tools.js";
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Implementation
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
const VENDOR_RE = /(^|\/)(?:vendor|node_modules|runtime|tests\/_data)(\/|$)/;
|
|
52
|
+
const SAMPLE_LIMIT = 5;
|
|
53
|
+
export async function findYii3AttributeCandidates(repo, options) {
|
|
54
|
+
const index = await getCodeIndex(repo);
|
|
55
|
+
if (!index)
|
|
56
|
+
throw new Error(`Repository "${repo}" not found.`);
|
|
57
|
+
const sampleLimit = options?.max_samples_per_rule ?? SAMPLE_LIMIT;
|
|
58
|
+
const includeVendor = options?.include_vendor ?? false;
|
|
59
|
+
const filePattern = options?.file_pattern;
|
|
60
|
+
const ruleFilter = options?.rules ? new Set(options.rules) : null;
|
|
61
|
+
const phpFiles = index.files.filter((f) => {
|
|
62
|
+
if (!f.path.endsWith(".php"))
|
|
63
|
+
return false;
|
|
64
|
+
if (!includeVendor && VENDOR_RE.test(f.path))
|
|
65
|
+
return false;
|
|
66
|
+
if (filePattern && !f.path.includes(filePattern))
|
|
67
|
+
return false;
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
70
|
+
const candidates = [];
|
|
71
|
+
// Symbol-level rules use the index directly.
|
|
72
|
+
if (!ruleFilter || ruleFilter.has("behaviors-to-attributes")) {
|
|
73
|
+
findBehaviorsToAttributes(index, candidates);
|
|
74
|
+
}
|
|
75
|
+
if (!ruleFilter || ruleFilter.has("rules-to-attributes")) {
|
|
76
|
+
findRulesToAttributes(index, candidates);
|
|
77
|
+
}
|
|
78
|
+
// File-level rule (urlmanager-rule-to-route) reads config files directly.
|
|
79
|
+
if (!ruleFilter || ruleFilter.has("urlmanager-rule-to-route")) {
|
|
80
|
+
await Promise.all(phpFiles
|
|
81
|
+
.filter((f) => /config\/(?:web|main|api|backend|frontend|common)(?:[-_][\w-]+)?\.php$/.test(f.path))
|
|
82
|
+
.map(async (f) => {
|
|
83
|
+
let content;
|
|
84
|
+
try {
|
|
85
|
+
content = await readFile(join(index.root, f.path), "utf-8");
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
findUrlManagerRules(content, f.path, candidates);
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
// Group + cap.
|
|
94
|
+
const byRuleMap = new Map();
|
|
95
|
+
for (const c of candidates) {
|
|
96
|
+
if (!byRuleMap.has(c.rule_id))
|
|
97
|
+
byRuleMap.set(c.rule_id, []);
|
|
98
|
+
byRuleMap.get(c.rule_id).push(c);
|
|
99
|
+
}
|
|
100
|
+
const byRule = [...byRuleMap.entries()]
|
|
101
|
+
.map(([rule_id, list]) => ({
|
|
102
|
+
rule_id,
|
|
103
|
+
count: list.length,
|
|
104
|
+
samples: list.slice(0, sampleLimit),
|
|
105
|
+
}))
|
|
106
|
+
.sort((a, b) => b.count - a.count);
|
|
107
|
+
return {
|
|
108
|
+
repo,
|
|
109
|
+
scanned_files: phpFiles.length,
|
|
110
|
+
total_candidates: candidates.length,
|
|
111
|
+
by_rule: byRule,
|
|
112
|
+
candidates,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Rule: behaviors() → #[Behavior(...)]
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
function findBehaviorsToAttributes(index, out) {
|
|
119
|
+
const behaviorsMethods = index.symbols.filter((s) => s.kind === "method" &&
|
|
120
|
+
s.name === "behaviors" &&
|
|
121
|
+
s.file.endsWith(".php") &&
|
|
122
|
+
s.source &&
|
|
123
|
+
!VENDOR_RE.test(s.file));
|
|
124
|
+
for (const m of behaviorsMethods) {
|
|
125
|
+
const src = m.source;
|
|
126
|
+
// Pull the body's `return [ ... ];` block. We don't try to walk
|
|
127
|
+
// every key; instead we count the entries that look like behavior
|
|
128
|
+
// class references and surface the whole body for the auditor.
|
|
129
|
+
const returnMatch = /return\s*\[([\s\S]*?)\]\s*;/.exec(src);
|
|
130
|
+
if (!returnMatch)
|
|
131
|
+
continue;
|
|
132
|
+
const body = returnMatch[1];
|
|
133
|
+
// Detect behavior classes — anything ending in "Behavior".
|
|
134
|
+
const behaviorRe = /([A-Z][\w]*Behavior)(?:::class|['"])/g;
|
|
135
|
+
const found = new Set();
|
|
136
|
+
let bm;
|
|
137
|
+
while ((bm = behaviorRe.exec(body)) !== null) {
|
|
138
|
+
found.add(bm[1]);
|
|
139
|
+
}
|
|
140
|
+
if (found.size === 0)
|
|
141
|
+
continue;
|
|
142
|
+
const blockers = [];
|
|
143
|
+
if (/=>\s*function\s*\(/.test(body)) {
|
|
144
|
+
blockers.push("behavior config contains closure — review manually");
|
|
145
|
+
}
|
|
146
|
+
const list = [...found];
|
|
147
|
+
out.push({
|
|
148
|
+
rule_id: "behaviors-to-attributes",
|
|
149
|
+
file: m.file,
|
|
150
|
+
line: m.start_line,
|
|
151
|
+
current_form: `behaviors() with ${list.length} entr${list.length === 1 ? "y" : "ies"}: ${list.join(", ")}`,
|
|
152
|
+
suggested_replacement: list
|
|
153
|
+
.map((b) => `#[Behavior(${b}::class)]`)
|
|
154
|
+
.join(" "),
|
|
155
|
+
confidence: blockers.length > 0 ? "medium" : "high",
|
|
156
|
+
blockers,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
// Rule: rules() → #[Required], #[Email], etc.
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
const VALIDATOR_TO_ATTRIBUTE = {
|
|
164
|
+
required: "Required",
|
|
165
|
+
email: "Email",
|
|
166
|
+
string: "StringLength",
|
|
167
|
+
integer: "IntegerValue",
|
|
168
|
+
number: "NumericValue",
|
|
169
|
+
url: "Url",
|
|
170
|
+
boolean: "BooleanValue",
|
|
171
|
+
date: "Date",
|
|
172
|
+
in: "InRange",
|
|
173
|
+
match: "RegexMatch",
|
|
174
|
+
unique: "Unique",
|
|
175
|
+
exist: "Exist",
|
|
176
|
+
default: "DefaultValue",
|
|
177
|
+
filter: "Callback",
|
|
178
|
+
safe: "Safe",
|
|
179
|
+
};
|
|
180
|
+
function findRulesToAttributes(index, out) {
|
|
181
|
+
const rulesMethods = index.symbols.filter((s) => s.kind === "method" &&
|
|
182
|
+
s.name === "rules" &&
|
|
183
|
+
s.file.endsWith(".php") &&
|
|
184
|
+
s.source &&
|
|
185
|
+
!VENDOR_RE.test(s.file));
|
|
186
|
+
for (const m of rulesMethods) {
|
|
187
|
+
const src = m.source;
|
|
188
|
+
const returnMatch = /return\s*\[([\s\S]*?)\]\s*;/.exec(src);
|
|
189
|
+
if (!returnMatch)
|
|
190
|
+
continue;
|
|
191
|
+
const body = returnMatch[1];
|
|
192
|
+
// Each rule is a tuple [['field' | ['field1', ...]], 'validator', …].
|
|
193
|
+
// We capture the first two positional arguments per tuple.
|
|
194
|
+
const tupleRe = /\[\s*(?:\[([^\]]+)\]|['"]([\w-]+)['"])\s*,\s*['"]([\w-]+)['"]/g;
|
|
195
|
+
const seen = new Map();
|
|
196
|
+
let tm;
|
|
197
|
+
while ((tm = tupleRe.exec(body)) !== null) {
|
|
198
|
+
const fields = (tm[1] ?? tm[2] ?? "")
|
|
199
|
+
.split(",")
|
|
200
|
+
.map((x) => x.trim().replace(/^['"]|['"]$/g, ""))
|
|
201
|
+
.filter(Boolean);
|
|
202
|
+
const validator = tm[3];
|
|
203
|
+
for (const f of fields) {
|
|
204
|
+
if (!seen.has(f))
|
|
205
|
+
seen.set(f, new Set());
|
|
206
|
+
seen.get(f).add(validator);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (seen.size === 0)
|
|
210
|
+
continue;
|
|
211
|
+
const blockers = [];
|
|
212
|
+
if (/=>\s*function\s*\(/.test(body)) {
|
|
213
|
+
blockers.push("rule references a closure validator — manual conversion");
|
|
214
|
+
}
|
|
215
|
+
for (const [field, validators] of seen.entries()) {
|
|
216
|
+
const attrs = [];
|
|
217
|
+
for (const v of validators) {
|
|
218
|
+
const mapped = VALIDATOR_TO_ATTRIBUTE[v];
|
|
219
|
+
if (mapped)
|
|
220
|
+
attrs.push(`#[${mapped}]`);
|
|
221
|
+
else
|
|
222
|
+
attrs.push(`#[Validator('${v}')]`);
|
|
223
|
+
}
|
|
224
|
+
out.push({
|
|
225
|
+
rule_id: "rules-to-attributes",
|
|
226
|
+
file: m.file,
|
|
227
|
+
line: m.start_line,
|
|
228
|
+
current_form: `rules() entry for $${field}: ${[...validators].join(", ")}`,
|
|
229
|
+
suggested_replacement: `${attrs.join(" ")} public mixed \$${field};`,
|
|
230
|
+
confidence: validators.size === 1 && VALIDATOR_TO_ATTRIBUTE[[...validators][0]] ? "high" : "medium",
|
|
231
|
+
blockers: [...blockers],
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Rule: urlManager rules → #[Route(...)]
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
function findUrlManagerRules(content, file, out) {
|
|
240
|
+
// Match `'GET api/users/<id>' => 'user/view'` style entries. Yii2
|
|
241
|
+
// urlManager also accepts unverbed forms ('home' => 'site/index'); we
|
|
242
|
+
// capture both. The right side is `controller/action[/sub]`.
|
|
243
|
+
const ruleRe = /['"](?:(GET|POST|PUT|DELETE|PATCH)\s+)?([^'"]+)['"]\s*=>\s*['"]([\w\/-]+)['"]/g;
|
|
244
|
+
let m;
|
|
245
|
+
while ((m = ruleRe.exec(content)) !== null) {
|
|
246
|
+
const verb = m[1] ?? null;
|
|
247
|
+
const pattern = m[2];
|
|
248
|
+
const target = m[3];
|
|
249
|
+
const line = countLines(content, m.index);
|
|
250
|
+
// Skip non-route contexts: rules() entries, validation messages, etc.
|
|
251
|
+
// Best heuristic: target must contain a "/" (controller/action shape).
|
|
252
|
+
if (!target.includes("/"))
|
|
253
|
+
continue;
|
|
254
|
+
// Reject obvious false positives: 'class' => 'app\\X' (FQCN target).
|
|
255
|
+
if (/\\/.test(target))
|
|
256
|
+
continue;
|
|
257
|
+
// Convert <param> and <param:regex> placeholders to Yii3 {param}.
|
|
258
|
+
// Regex constraints are dropped — Yii3 has its own attribute syntax.
|
|
259
|
+
const path = "/" +
|
|
260
|
+
pattern.replace(/<(\w+)(?::[^>]+)?>/g, "{$1}").replace(/^\//, "");
|
|
261
|
+
const targetSegments = target.split("/");
|
|
262
|
+
const action = targetSegments[targetSegments.length - 1];
|
|
263
|
+
const controller = targetSegments.slice(0, -1).join("/");
|
|
264
|
+
const blockers = [];
|
|
265
|
+
if (/<\w+:/.test(pattern)) {
|
|
266
|
+
blockers.push("rule has inline regex constraint — re-encode with Yii3 typed route");
|
|
267
|
+
}
|
|
268
|
+
if (target.split("/").length > 2) {
|
|
269
|
+
blockers.push("rule targets a module — verify Yii3 module mapping");
|
|
270
|
+
}
|
|
271
|
+
const verbDecl = verb ? `method: '${verb}'` : "";
|
|
272
|
+
const replacement = `#[Route(${[verbDecl, `path: '${path}'`].filter(Boolean).join(", ")})]\npublic function action${pascalize(action)}() { … }`;
|
|
273
|
+
out.push({
|
|
274
|
+
rule_id: "urlmanager-rule-to-route",
|
|
275
|
+
file,
|
|
276
|
+
line,
|
|
277
|
+
current_form: `'${verb ? verb + " " : ""}${pattern}' => '${target}'`,
|
|
278
|
+
suggested_replacement: `// On ${controller}Controller::action${pascalize(action)}:\n${replacement}`,
|
|
279
|
+
confidence: blockers.length === 0 ? "high" : "medium",
|
|
280
|
+
blockers,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// Helpers
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
function pascalize(s) {
|
|
288
|
+
return s
|
|
289
|
+
.split(/[-_]/)
|
|
290
|
+
.map((p) => (p.length > 0 ? p[0].toUpperCase() + p.slice(1) : ""))
|
|
291
|
+
.join("");
|
|
292
|
+
}
|
|
293
|
+
function countLines(source, idx) {
|
|
294
|
+
let line = 1;
|
|
295
|
+
for (let i = 0; i < idx; i++) {
|
|
296
|
+
if (source.charCodeAt(i) === 10)
|
|
297
|
+
line++;
|
|
298
|
+
}
|
|
299
|
+
return line;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=yii3-attribute-candidates-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yii3-attribute-candidates-tools.js","sourceRoot":"","sources":["../../src/tools/yii3-attribute-candidates-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yii3 migration audit (M4) — decision-support tool.
|
|
3
|
+
*
|
|
4
|
+
* Inventories Yii2-specific API usage across a codebase and projects an
|
|
5
|
+
* effort estimate so the team can choose between staying on Yii 2.0.49+
|
|
6
|
+
* with PHP 8 vs migrating to Yii3. The tool is grep-style by design: it
|
|
7
|
+
* does not try to understand semantics, only to count call sites by
|
|
8
|
+
* category and surface the highest-leverage blockers.
|
|
9
|
+
*
|
|
10
|
+
* Every category maps a Yii2 idiom to its Yii3 equivalent and assigns a
|
|
11
|
+
* severity + per-call effort estimate. The aggregated effort_estimate
|
|
12
|
+
* gives a rough hours-low/hours-high range. Severity reflects how hard
|
|
13
|
+
* the migration is, NOT how dangerous the current code is.
|
|
14
|
+
*
|
|
15
|
+
* Out of scope:
|
|
16
|
+
* - Vendor / third-party packages (we strip vendor/ paths before scan).
|
|
17
|
+
* - Semantic disambiguation (e.g. `Yii::$app->db` is service-locator
|
|
18
|
+
* even when the property is dynamically resolved at runtime — we
|
|
19
|
+
* don't try to detect that).
|
|
20
|
+
* - Migration plans for non-Yii frameworks (Laravel/Symfony).
|
|
21
|
+
*/
|
|
22
|
+
export type Yii3MigrationCategoryName = "service-locator" | "object-factory" | "aliases" | "i18n" | "logger" | "application-props" | "module" | "request" | "response" | "session" | "user-identity" | "active-record" | "validators" | "form-model" | "widgets" | "view" | "url-manager" | "console" | "migrations" | "queue" | "rbac";
|
|
23
|
+
export type Severity = "critical" | "high" | "medium" | "low";
|
|
24
|
+
export type EffortBucket = "trivial" | "small" | "medium" | "large";
|
|
25
|
+
export interface CategoryDefinition {
|
|
26
|
+
category: Yii3MigrationCategoryName;
|
|
27
|
+
severity: Severity;
|
|
28
|
+
description: string;
|
|
29
|
+
yii3_replacement: string;
|
|
30
|
+
effort_per_call: EffortBucket;
|
|
31
|
+
/** One or more regexes; a file is counted once per match. The regex must
|
|
32
|
+
* be globally flagged so we can iterate matches in a single source pass. */
|
|
33
|
+
patterns: RegExp[];
|
|
34
|
+
}
|
|
35
|
+
export interface CategoryFinding {
|
|
36
|
+
category: Yii3MigrationCategoryName;
|
|
37
|
+
severity: Severity;
|
|
38
|
+
count: number;
|
|
39
|
+
effort_per_call: EffortBucket;
|
|
40
|
+
description: string;
|
|
41
|
+
yii3_replacement: string;
|
|
42
|
+
/** First few file:line:snippet triples — capped to keep output tight. */
|
|
43
|
+
sample_files: Array<{
|
|
44
|
+
file: string;
|
|
45
|
+
line: number;
|
|
46
|
+
snippet: string;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export interface Yii3MigrationAudit {
|
|
50
|
+
repo: string;
|
|
51
|
+
scanned_files: number;
|
|
52
|
+
total_call_sites: number;
|
|
53
|
+
by_category: CategoryFinding[];
|
|
54
|
+
by_severity: Record<Severity, number>;
|
|
55
|
+
blockers: Array<{
|
|
56
|
+
category: Yii3MigrationCategoryName;
|
|
57
|
+
reason: string;
|
|
58
|
+
related_files_count: number;
|
|
59
|
+
}>;
|
|
60
|
+
effort_estimate: {
|
|
61
|
+
hours_low: number;
|
|
62
|
+
hours_high: number;
|
|
63
|
+
note: string;
|
|
64
|
+
};
|
|
65
|
+
decision_signal: "stay-on-yii2" | "consider-yii3" | "high-effort-yii3" | "blocked";
|
|
66
|
+
yii_version_detected: string | null;
|
|
67
|
+
php_version_required: string | null;
|
|
68
|
+
}
|
|
69
|
+
export declare function yii3MigrationAudit(repo: string, options?: {
|
|
70
|
+
file_pattern?: string;
|
|
71
|
+
max_samples_per_category?: number;
|
|
72
|
+
include_vendor?: boolean;
|
|
73
|
+
}): Promise<Yii3MigrationAudit>;
|
|
74
|
+
//# sourceMappingURL=yii3-migration-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yii3-migration-tools.d.ts","sourceRoot":"","sources":["../../src/tools/yii3-migration-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,gBAAgB,GAChB,SAAS,GACT,MAAM,GACN,QAAQ,GACR,mBAAmB,GACnB,QAAQ,GACR,SAAS,GACT,UAAU,GACV,SAAS,GACT,eAAe,GACf,eAAe,GACf,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,MAAM,GACN,aAAa,GACb,SAAS,GACT,YAAY,GACZ,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,yBAAyB,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,YAAY,CAAC;IAC9B;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,yBAAyB,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,YAAY,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC;QACd,QAAQ,EAAE,yBAAyB,CAAC;QACpC,MAAM,EAAE,MAAM,CAAC;QACf,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC,CAAC;IACH,eAAe,EAAE;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,eAAe,EACX,cAAc,GACd,eAAe,GACf,kBAAkB,GAClB,SAAS,CAAC;IACd,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAqSD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GACA,OAAO,CAAC,kBAAkB,CAAC,CA2J7B"}
|