@kernlang/codemod 3.3.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/LICENSE +678 -0
- package/dist/adapter-registry.d.ts +12 -0
- package/dist/adapter-registry.js +21 -0
- package/dist/adapter-registry.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/zustand-store.d.ts +14 -0
- package/dist/adapters/zustand-store.js +261 -0
- package/dist/adapters/zustand-store.js.map +1 -0
- package/dist/apply-files.d.ts +19 -0
- package/dist/apply-files.js +60 -0
- package/dist/apply-files.js.map +1 -0
- package/dist/apply.d.ts +37 -0
- package/dist/apply.js +275 -0
- package/dist/apply.js.map +1 -0
- package/dist/audit.d.ts +10 -0
- package/dist/audit.js +26 -0
- package/dist/audit.js.map +1 -0
- package/dist/diagnostics.d.ts +36 -0
- package/dist/diagnostics.js +117 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/format.d.ts +13 -0
- package/dist/format.js +30 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.js +47 -0
- package/dist/project.js.map +1 -0
- package/dist/template-loader.d.ts +15 -0
- package/dist/template-loader.js +55 -0
- package/dist/template-loader.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry — keyed by TemplateMatch.templateName.
|
|
3
|
+
*
|
|
4
|
+
* Adapters are registered up-front (see adapters/index.ts). A future public
|
|
5
|
+
* API could expose `register()` for external adapters; for MVP the set is
|
|
6
|
+
* fixed and shipped with the package.
|
|
7
|
+
*/
|
|
8
|
+
import type { TemplateAdapter } from './types.js';
|
|
9
|
+
export declare function registerAdapter(adapter: TemplateAdapter): void;
|
|
10
|
+
export declare function getAdapter(templateName: string): TemplateAdapter | undefined;
|
|
11
|
+
export declare function listAdapters(): TemplateAdapter[];
|
|
12
|
+
export declare function hasAdapter(templateName: string): boolean;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter registry — keyed by TemplateMatch.templateName.
|
|
3
|
+
*
|
|
4
|
+
* Adapters are registered up-front (see adapters/index.ts). A future public
|
|
5
|
+
* API could expose `register()` for external adapters; for MVP the set is
|
|
6
|
+
* fixed and shipped with the package.
|
|
7
|
+
*/
|
|
8
|
+
const registry = new Map();
|
|
9
|
+
export function registerAdapter(adapter) {
|
|
10
|
+
registry.set(adapter.templateName, adapter);
|
|
11
|
+
}
|
|
12
|
+
export function getAdapter(templateName) {
|
|
13
|
+
return registry.get(templateName);
|
|
14
|
+
}
|
|
15
|
+
export function listAdapters() {
|
|
16
|
+
return Array.from(registry.values());
|
|
17
|
+
}
|
|
18
|
+
export function hasAdapter(templateName) {
|
|
19
|
+
return registry.has(templateName);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=adapter-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../src/adapter-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEpD,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,OAAO,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAAoB;IAC7C,OAAO,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,eAAe,CAAC,mBAAmB,CAAC,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zustand store adapter.
|
|
3
|
+
*
|
|
4
|
+
* Resolves and rewrites:
|
|
5
|
+
* export const useXStore = create<State>((set, get) => ({ ... }));
|
|
6
|
+
* export const useXStore = create<State>()((set, get) => ({ ... }));
|
|
7
|
+
*
|
|
8
|
+
* Fails closed on: aliased `create` imports, non-object returns, spread
|
|
9
|
+
* elements, computed property keys, type-annotated actions where the declared
|
|
10
|
+
* type diverges from the implementation, multiple zustand stores in one file,
|
|
11
|
+
* and non-`create` calls.
|
|
12
|
+
*/
|
|
13
|
+
import type { TemplateAdapter } from '../types.js';
|
|
14
|
+
export declare const zustandStoreAdapter: TemplateAdapter;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zustand store adapter.
|
|
3
|
+
*
|
|
4
|
+
* Resolves and rewrites:
|
|
5
|
+
* export const useXStore = create<State>((set, get) => ({ ... }));
|
|
6
|
+
* export const useXStore = create<State>()((set, get) => ({ ... }));
|
|
7
|
+
*
|
|
8
|
+
* Fails closed on: aliased `create` imports, non-object returns, spread
|
|
9
|
+
* elements, computed property keys, type-annotated actions where the declared
|
|
10
|
+
* type diverges from the implementation, multiple zustand stores in one file,
|
|
11
|
+
* and non-`create` calls.
|
|
12
|
+
*/
|
|
13
|
+
import { SyntaxKind, } from 'ts-morph';
|
|
14
|
+
const ZUSTAND_MODULE = 'zustand';
|
|
15
|
+
const CREATE_NAME = 'create';
|
|
16
|
+
function hasUnaliasedCreateImport(sourceFile) {
|
|
17
|
+
for (const imp of sourceFile.getImportDeclarations()) {
|
|
18
|
+
if (imp.getModuleSpecifierValue() !== ZUSTAND_MODULE)
|
|
19
|
+
continue;
|
|
20
|
+
for (const named of imp.getNamedImports()) {
|
|
21
|
+
if (named.getName() !== CREATE_NAME)
|
|
22
|
+
continue;
|
|
23
|
+
// Fail closed on aliased import: `import { create as foo } from 'zustand'`
|
|
24
|
+
const alias = named.getAliasNode();
|
|
25
|
+
if (alias && alias.getText() !== CREATE_NAME)
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns the CallExpression that looks like `create<T>(...)` or `create<T>()(...)`.
|
|
34
|
+
* For the curried form, returns the OUTER call (the one whose callee is `create`)
|
|
35
|
+
* because that's where `stateType` lives, and we still need to descend into the
|
|
36
|
+
* inner call to find the object literal.
|
|
37
|
+
*/
|
|
38
|
+
function findCreateCall(node) {
|
|
39
|
+
if (!node)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (node.isKind(SyntaxKind.CallExpression)) {
|
|
42
|
+
const call = node.asKindOrThrow(SyntaxKind.CallExpression);
|
|
43
|
+
const expr = call.getExpression();
|
|
44
|
+
// Direct: create<T>(...)
|
|
45
|
+
if (expr.isKind(SyntaxKind.Identifier) && expr.getText() === CREATE_NAME) {
|
|
46
|
+
return call;
|
|
47
|
+
}
|
|
48
|
+
// Curried: create<T>()(...) — outer call's callee is itself a CallExpression
|
|
49
|
+
// whose callee is the `create` identifier.
|
|
50
|
+
if (expr.isKind(SyntaxKind.CallExpression)) {
|
|
51
|
+
const inner = expr.asKindOrThrow(SyntaxKind.CallExpression);
|
|
52
|
+
const innerExpr = inner.getExpression();
|
|
53
|
+
if (innerExpr.isKind(SyntaxKind.Identifier) && innerExpr.getText() === CREATE_NAME) {
|
|
54
|
+
return inner; // Return the inner `create<T>()` — outer call is the factory invocation
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Follow a create<T>(...) call to the ObjectLiteralExpression returned by its
|
|
62
|
+
* state initializer. Handles:
|
|
63
|
+
* create<T>((set, get) => ({ ... })) — direct arrow returning obj literal
|
|
64
|
+
* create<T>()((set, get) => ({ ... })) — curried factory
|
|
65
|
+
* create<T>()((set) => { return { ... }; }) — arrow with block body
|
|
66
|
+
*/
|
|
67
|
+
function findStateObjectLiteral(createCall) {
|
|
68
|
+
// Determine the actual state-initializer call.
|
|
69
|
+
// For curried form, the parent of createCall is a CallExpression whose arguments
|
|
70
|
+
// hold the arrow fn. For direct form, createCall itself has the arguments.
|
|
71
|
+
const parent = createCall.getParent();
|
|
72
|
+
let argsCall;
|
|
73
|
+
if (parent?.isKind(SyntaxKind.CallExpression)) {
|
|
74
|
+
const parentCall = parent.asKindOrThrow(SyntaxKind.CallExpression);
|
|
75
|
+
if (parentCall.getExpression() === createCall) {
|
|
76
|
+
// Curried: parent call holds the arrow fn
|
|
77
|
+
argsCall = parentCall;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
argsCall = createCall;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
argsCall = createCall;
|
|
85
|
+
}
|
|
86
|
+
const args = argsCall.getArguments();
|
|
87
|
+
if (args.length === 0)
|
|
88
|
+
return undefined;
|
|
89
|
+
const first = args[0];
|
|
90
|
+
let body;
|
|
91
|
+
if (first.isKind(SyntaxKind.ArrowFunction)) {
|
|
92
|
+
body = first.getBody();
|
|
93
|
+
}
|
|
94
|
+
else if (first.isKind(SyntaxKind.FunctionExpression)) {
|
|
95
|
+
body = first.getBody();
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
if (!body)
|
|
101
|
+
return undefined;
|
|
102
|
+
// Body can be a direct ObjectLiteralExpression (arrow returning object literal
|
|
103
|
+
// via parenthesized expression: `=> ({...})`) or a block statement that
|
|
104
|
+
// returns an object literal.
|
|
105
|
+
if (body.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
106
|
+
return body.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
107
|
+
}
|
|
108
|
+
if (body.isKind(SyntaxKind.ParenthesizedExpression)) {
|
|
109
|
+
const inner = body.asKindOrThrow(SyntaxKind.ParenthesizedExpression).getExpression();
|
|
110
|
+
if (inner.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
111
|
+
return inner.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (body.isKind(SyntaxKind.Block)) {
|
|
115
|
+
const block = body.asKindOrThrow(SyntaxKind.Block);
|
|
116
|
+
const stmts = block.getStatements();
|
|
117
|
+
if (stmts.length !== 1)
|
|
118
|
+
return undefined;
|
|
119
|
+
const only = stmts[0];
|
|
120
|
+
if (!only.isKind(SyntaxKind.ReturnStatement))
|
|
121
|
+
return undefined;
|
|
122
|
+
const retExpr = only.asKindOrThrow(SyntaxKind.ReturnStatement).getExpression();
|
|
123
|
+
if (retExpr?.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
124
|
+
return retExpr.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
125
|
+
}
|
|
126
|
+
if (retExpr?.isKind(SyntaxKind.ParenthesizedExpression)) {
|
|
127
|
+
const inner = retExpr.asKindOrThrow(SyntaxKind.ParenthesizedExpression).getExpression();
|
|
128
|
+
if (inner.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
129
|
+
return inner.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
function findOwningVariableStatement(call) {
|
|
136
|
+
let cur = call;
|
|
137
|
+
while (cur) {
|
|
138
|
+
if (cur.isKind(SyntaxKind.VariableStatement)) {
|
|
139
|
+
return cur.asKindOrThrow(SyntaxKind.VariableStatement);
|
|
140
|
+
}
|
|
141
|
+
cur = cur.getParent();
|
|
142
|
+
}
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
function countCreateCalls(sourceFile) {
|
|
146
|
+
let count = 0;
|
|
147
|
+
for (const call of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
148
|
+
const createCall = findCreateCall(call);
|
|
149
|
+
if (createCall === call)
|
|
150
|
+
count++;
|
|
151
|
+
}
|
|
152
|
+
return count;
|
|
153
|
+
}
|
|
154
|
+
export const zustandStoreAdapter = {
|
|
155
|
+
templateName: 'zustand-store',
|
|
156
|
+
resolveRegion(sourceFile, _match) {
|
|
157
|
+
if (!hasUnaliasedCreateImport(sourceFile)) {
|
|
158
|
+
return { ok: false, reason: 'zustand `create` is missing or aliased' };
|
|
159
|
+
}
|
|
160
|
+
// Reject files with multiple zustand stores to avoid ambiguity on which to rewrite.
|
|
161
|
+
if (countCreateCalls(sourceFile) > 1) {
|
|
162
|
+
return { ok: false, reason: 'multiple zustand stores in file' };
|
|
163
|
+
}
|
|
164
|
+
// Find the one create call and walk up to its VariableStatement.
|
|
165
|
+
let createCall;
|
|
166
|
+
for (const call of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
167
|
+
const found = findCreateCall(call);
|
|
168
|
+
if (found === call) {
|
|
169
|
+
createCall = call;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (!createCall) {
|
|
174
|
+
return { ok: false, reason: 'no create<T>(...) call found' };
|
|
175
|
+
}
|
|
176
|
+
const varStmt = findOwningVariableStatement(createCall);
|
|
177
|
+
if (!varStmt) {
|
|
178
|
+
return { ok: false, reason: 'create call is not inside a variable declaration' };
|
|
179
|
+
}
|
|
180
|
+
// Sanity check: exactly one declaration, and its initializer transitively contains our call.
|
|
181
|
+
const decls = varStmt.getDeclarations();
|
|
182
|
+
if (decls.length !== 1) {
|
|
183
|
+
return { ok: false, reason: 'multi-declarator variable statement' };
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
ok: true,
|
|
187
|
+
region: {
|
|
188
|
+
start: varStmt.getStart(),
|
|
189
|
+
end: varStmt.getEnd(),
|
|
190
|
+
label: `VariableStatement@L${varStmt.getStartLineNumber()}`,
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
extractChildren(sourceFile, _region, _match) {
|
|
195
|
+
// Re-resolve the create call — the region only gives us offsets, not the node.
|
|
196
|
+
let createCall;
|
|
197
|
+
for (const call of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
198
|
+
const found = findCreateCall(call);
|
|
199
|
+
if (found === call) {
|
|
200
|
+
createCall = call;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (!createCall) {
|
|
205
|
+
return { ok: false, reason: 'create call disappeared during extract' };
|
|
206
|
+
}
|
|
207
|
+
const objLit = findStateObjectLiteral(createCall);
|
|
208
|
+
if (!objLit) {
|
|
209
|
+
return { ok: false, reason: 'state initializer is not an object literal' };
|
|
210
|
+
}
|
|
211
|
+
const properties = objLit.getProperties();
|
|
212
|
+
if (properties.length === 0) {
|
|
213
|
+
return { ok: true, children: [] };
|
|
214
|
+
}
|
|
215
|
+
const childLines = [];
|
|
216
|
+
for (const prop of properties) {
|
|
217
|
+
// Fail closed on anything that isn't a plain PropertyAssignment or ShorthandPropertyAssignment.
|
|
218
|
+
if (prop.isKind(SyntaxKind.SpreadAssignment)) {
|
|
219
|
+
return { ok: false, reason: 'spread in state initializer' };
|
|
220
|
+
}
|
|
221
|
+
if (prop.isKind(SyntaxKind.GetAccessor) || prop.isKind(SyntaxKind.SetAccessor)) {
|
|
222
|
+
return { ok: false, reason: 'accessor in state initializer' };
|
|
223
|
+
}
|
|
224
|
+
if (prop.isKind(SyntaxKind.MethodDeclaration)) {
|
|
225
|
+
// Method shorthand — emit as-is.
|
|
226
|
+
childLines.push(prop.getText());
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (prop.isKind(SyntaxKind.ShorthandPropertyAssignment)) {
|
|
230
|
+
childLines.push(prop.getText());
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (prop.isKind(SyntaxKind.PropertyAssignment)) {
|
|
234
|
+
const assignment = prop.asKindOrThrow(SyntaxKind.PropertyAssignment);
|
|
235
|
+
const nameNode = assignment.getNameNode();
|
|
236
|
+
// Reject computed keys like [Symbol.iterator] or [dynamicKey].
|
|
237
|
+
if (nameNode.isKind(SyntaxKind.ComputedPropertyName)) {
|
|
238
|
+
return { ok: false, reason: 'computed property key in state initializer' };
|
|
239
|
+
}
|
|
240
|
+
childLines.push(prop.getText());
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
ok: false,
|
|
245
|
+
reason: `unsupported property kind: ${prop.getKindName()}`,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// Append commas between lines to preserve object-literal syntax when re-emitted
|
|
249
|
+
// inside the template's `({ {{CHILDREN}} })`.
|
|
250
|
+
const withCommas = childLines.map((line, i) => {
|
|
251
|
+
const needsComma = i < childLines.length - 1 || !line.trimEnd().endsWith(',');
|
|
252
|
+
if (!needsComma)
|
|
253
|
+
return line;
|
|
254
|
+
if (line.trimEnd().endsWith(','))
|
|
255
|
+
return line;
|
|
256
|
+
return `${line},`;
|
|
257
|
+
});
|
|
258
|
+
return { ok: true, children: withCommas };
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=zustand-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zustand-store.js","sourceRoot":"","sources":["../../src/adapters/zustand-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch driver — apply codemod across one or more files.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Load the shared ts-morph Project once.
|
|
6
|
+
* - For each file: ensure it's in the Project, detect templates, and run
|
|
7
|
+
* applyMatch for every candidate above the confidence threshold.
|
|
8
|
+
* - Emit one audit entry per decision.
|
|
9
|
+
*
|
|
10
|
+
* The driver does not own --interactive prompting; the CLI layer wraps around
|
|
11
|
+
* this and streams decisions to the user.
|
|
12
|
+
*/
|
|
13
|
+
import type { ApplyOptions, ApplyResult } from './types.js';
|
|
14
|
+
import './adapters/index.js';
|
|
15
|
+
export interface ApplyFilesResult {
|
|
16
|
+
results: ApplyResult[];
|
|
17
|
+
auditPath: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function applyFiles(filePaths: string[], options?: ApplyOptions): ApplyFilesResult;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch driver — apply codemod across one or more files.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Load the shared ts-morph Project once.
|
|
6
|
+
* - For each file: ensure it's in the Project, detect templates, and run
|
|
7
|
+
* applyMatch for every candidate above the confidence threshold.
|
|
8
|
+
* - Emit one audit entry per decision.
|
|
9
|
+
*
|
|
10
|
+
* The driver does not own --interactive prompting; the CLI layer wraps around
|
|
11
|
+
* this and streams decisions to the user.
|
|
12
|
+
*/
|
|
13
|
+
import { detectTemplates } from '@kernlang/review';
|
|
14
|
+
import { resolve } from 'path';
|
|
15
|
+
import { applyMatch } from './apply.js';
|
|
16
|
+
import { defaultAuditPath, writeAuditEntry } from './audit.js';
|
|
17
|
+
import { snapshotAffectedSet } from './diagnostics.js';
|
|
18
|
+
import { loadHostProject } from './project.js';
|
|
19
|
+
// Register built-in adapters via side-effect import.
|
|
20
|
+
import './adapters/index.js';
|
|
21
|
+
export function applyFiles(filePaths, options = {}) {
|
|
22
|
+
const cwd = options.cwd ?? process.cwd();
|
|
23
|
+
const auditPath = options.auditPath ?? defaultAuditPath(cwd);
|
|
24
|
+
const project = loadHostProject({ cwd });
|
|
25
|
+
const results = [];
|
|
26
|
+
for (const input of filePaths) {
|
|
27
|
+
const absPath = resolve(cwd, input);
|
|
28
|
+
let sourceFile = project.getSourceFile(absPath);
|
|
29
|
+
if (!sourceFile) {
|
|
30
|
+
try {
|
|
31
|
+
sourceFile = project.addSourceFileAtPath(absPath);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const result = {
|
|
35
|
+
filePath: absPath,
|
|
36
|
+
templateName: '<unknown>',
|
|
37
|
+
confidencePct: 0,
|
|
38
|
+
decision: 'skipped',
|
|
39
|
+
reason: `could not add to Project: ${err.message}`,
|
|
40
|
+
timestamp: new Date().toISOString(),
|
|
41
|
+
};
|
|
42
|
+
writeAuditEntry(auditPath, result);
|
|
43
|
+
results.push(result);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const matches = detectTemplates(sourceFile);
|
|
48
|
+
if (matches.length === 0)
|
|
49
|
+
continue;
|
|
50
|
+
// Snapshot affected-set once per file so every candidate shares the baseline.
|
|
51
|
+
const preDiagnostics = snapshotAffectedSet(project, sourceFile);
|
|
52
|
+
for (const match of matches) {
|
|
53
|
+
const result = applyMatch({ project, filePath: absPath, match, preDiagnostics }, options);
|
|
54
|
+
writeAuditEntry(auditPath, result);
|
|
55
|
+
results.push(result);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { results, auditPath };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=apply-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-files.js","sourceRoot":"","sources":["../src/apply-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,qDAAqD;AACrD,OAAO,qBAAqB,CAAC;AAO7B,MAAM,UAAU,UAAU,CAAC,SAAmB,EAAE,UAAwB,EAAE;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,MAAM,GAAgB;oBAC1B,QAAQ,EAAE,OAAO;oBACjB,YAAY,EAAE,WAAW;oBACzB,aAAa,EAAE,CAAC;oBAChB,QAAQ,EAAE,SAAS;oBACnB,MAAM,EAAE,6BAA8B,GAAa,CAAC,OAAO,EAAE;oBAC7D,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC,CAAC;gBACF,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACrB,SAAS;YACX,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,8EAA8E;QAC9E,MAAM,cAAc,GAAG,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAEhE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;YAC1F,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAChC,CAAC"}
|
package/dist/apply.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply orchestrator — turn a TemplateMatch into a transformed source file.
|
|
3
|
+
*
|
|
4
|
+
* Pipeline:
|
|
5
|
+
* 1. Adapter resolves the exact rewrite region (re-derived from AST; detector
|
|
6
|
+
* reports endLine=EOF which we ignore).
|
|
7
|
+
* 2. Adapter extracts the user interior as CHILDREN lines.
|
|
8
|
+
* 3. Parse match.suggestedKern into an IR node and register the named
|
|
9
|
+
* template if it isn't already.
|
|
10
|
+
* 4. Attach a `handler` child carrying the extracted CHILDREN.
|
|
11
|
+
* 5. expandTemplateNode → generateCoreNode-style line array.
|
|
12
|
+
* 6. Strip template-prepended imports (source file already imports them).
|
|
13
|
+
* 7. Splice new text into source at [region.start, region.end] (no comment
|
|
14
|
+
* duplication — `before` already contains any leading trivia).
|
|
15
|
+
* 8. Mutate the original SourceFile IN-PLACE with replaceWithText so that
|
|
16
|
+
* downstream consumers see the transformed module when diagnostics run,
|
|
17
|
+
* then revert if any gate fails.
|
|
18
|
+
* 9. Reparse check (syntax), re-detect gate (template still recognized),
|
|
19
|
+
* affected-set diagnostics gate, whole-program gate (--write only).
|
|
20
|
+
* 10. Write audit entry and return ApplyResult.
|
|
21
|
+
*
|
|
22
|
+
* The shared ts-morph Project is the caller's responsibility (see project.ts)
|
|
23
|
+
* so affected-set diagnostics amortize across --interactive sessions.
|
|
24
|
+
*/
|
|
25
|
+
import { type TemplateMatch } from '@kernlang/review';
|
|
26
|
+
import type { Project } from 'ts-morph';
|
|
27
|
+
import type { ApplyOptions, ApplyResult } from './types.js';
|
|
28
|
+
export interface ApplyFileInput {
|
|
29
|
+
project: Project;
|
|
30
|
+
/** Absolute path to the file being transformed (must already be in Project). */
|
|
31
|
+
filePath: string;
|
|
32
|
+
/** One TemplateMatch candidate from detectTemplates(). */
|
|
33
|
+
match: TemplateMatch;
|
|
34
|
+
/** Pre-computed file-level diagnostics snapshot (perf: avoids re-walking). */
|
|
35
|
+
preDiagnostics?: ReadonlyArray<string>;
|
|
36
|
+
}
|
|
37
|
+
export declare function applyMatch(input: ApplyFileInput, options?: ApplyOptions): ApplyResult;
|