@tailor-platform/sdk-codemod 0.3.0-next.0 → 0.3.0-next.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/CHANGELOG.md +86 -0
- package/dist/codemods/v2/apply-to-deploy/scripts/transform.js +22 -4
- package/dist/codemods/v2/auth-invoker-unwrap/scripts/transform.js +99 -11
- package/dist/codemods/v2/cli-rename/scripts/transform.js +373 -14
- package/dist/codemods/v2/execute-script-arg/scripts/transform.js +60 -0
- package/dist/codemods/v2/principal-unify/scripts/transform.js +1131 -43
- package/dist/codemods/v2/tailordb-namespace/scripts/transform.js +5 -4
- package/dist/index.js +521 -37
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,96 @@
|
|
|
1
1
|
# @tailor-platform/sdk-codemod
|
|
2
2
|
|
|
3
|
+
## 0.3.0-next.2
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#1473](https://github.com/tailor-platform/sdk/pull/1473) [`7ddf3c7`](https://github.com/tailor-platform/sdk/commit/7ddf3c716adf85a66a75d554da7730b5406f84b1) Thanks [@dqn](https://github.com/dqn)! - Add the `v2/principal-unify` codemod so `tailor-sdk upgrade` can migrate SDK principal APIs to `TailorPrincipal`.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
- [#1515](https://github.com/tailor-platform/sdk/pull/1515) [`dcf66a1`](https://github.com/tailor-platform/sdk/commit/dcf66a1e648f5287eaea9ea330eb4ad726a4d363) Thanks [@dqn](https://github.com/dqn)! - Rewrite `tailor-sdk apply` to `tailor-sdk deploy` in source files that contain embedded CLI command strings.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
- [#1482](https://github.com/tailor-platform/sdk/pull/1482) [`8b5870e`](https://github.com/tailor-platform/sdk/commit/8b5870e85db1efec7647acb98226f8161e3d1583) Thanks [@toiroakr](https://github.com/toiroakr)! - Add LLM-assisted review support to the codemod runner. A codemod can declare `suspiciousPatterns` plus a `prompt`; after running, files whose post-transform content still matches a suspicious pattern are reported as `llmReviews` (in the JSON output and on stderr) together with the codemod's migration prompt. This surfaces the cases a deterministic transform cannot safely complete (e.g. a value reached through a variable) so they can be finished with an LLM. The `auth.invoker(...)` codemod adopts this for its non-literal-argument cases.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
- [#1495](https://github.com/tailor-platform/sdk/pull/1495) [`6234022`](https://github.com/tailor-platform/sdk/commit/6234022d7dc03813b8dade831b86f63a5f7a20e6) Thanks [@toiroakr](https://github.com/toiroakr)! - Generate the v2 migration guide (`packages/sdk/docs/migration/v2.md`) from the codemod registry, which is the single source of truth. Each entry renders its name, automation level (Automatic / Partially automatic / Manual), description, optional before/after `examples`, and — for changes the codemods cannot fully migrate on their own — the LLM/manual migration prompt. Run `pnpm codemod:docs:update` to regenerate and `pnpm codemod:docs:check` (wired into `pnpm check`) to verify it is in sync.
|
|
24
|
+
|
|
25
|
+
`scriptPath` is now optional, so the registry can also describe codemod-less ("manual") migrations that ship only guidance (`examples` / `prompt` / `suspiciousPatterns`) with no automatic transform. A manual entry with a `prompt` but no scoping pattern is surfaced as a project-wide `llmReviews` entry at runtime.
|
|
26
|
+
|
|
27
|
+
Add a `sdk-codemod list` command that prints every registered rule (id, name, kind, version range).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
- [#1517](https://github.com/tailor-platform/sdk/pull/1517) [`a649764`](https://github.com/tailor-platform/sdk/commit/a6497649be2786b3f6e410c8aa98c4247a599258) Thanks [@dqn](https://github.com/dqn)! - Reduce false-positive v2 codemod warnings and LLM-review prompts from source comments, string literals, and identifier substring matches.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
- [#1476](https://github.com/tailor-platform/sdk/pull/1476) [`fa83075`](https://github.com/tailor-platform/sdk/commit/fa83075f5e0e91085c0ef0cb44b7058a28a79ec3) Thanks [@toiroakr](https://github.com/toiroakr)! - `executeScript` now takes its `arg` as a JSON-serializable value instead of a pre-serialized JSON string. Pass the value directly (e.g. `arg: { a: 1 }`) instead of `arg: JSON.stringify({ a: 1 })`.
|
|
35
|
+
|
|
36
|
+
Add the `v2/execute-script-arg` codemod, which unwraps `JSON.stringify(...)` passed as the `executeScript` `arg` option. Indirect forms (a stringified value held in a variable, etc.) cannot be rewritten automatically and are surfaced as an LLM-assisted review task with a migration prompt.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
- [#1518](https://github.com/tailor-platform/sdk/pull/1518) [`ab10b1f`](https://github.com/tailor-platform/sdk/commit/ab10b1fea309ec5496e09bdca394d46d58603f5f) Thanks [@dqn](https://github.com/dqn)! - Reduce noisy `executeScript` LLM-review prompts by flagging files only when unresolved `arg` stringification remains likely.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
- [#1509](https://github.com/tailor-platform/sdk/pull/1509) [`7cadaa7`](https://github.com/tailor-platform/sdk/commit/7cadaa7c4987b81130ca80ba80bc5d5b26276394) Thanks [@dqn](https://github.com/dqn)! - Rename resolver, executor, workflow trigger, and typed workflow start machine-user options from `authInvoker` to `invoker`.
|
|
44
|
+
|
|
45
|
+
Update create-sdk templates and the v2 auth invoker codemod to generate the new `invoker` option.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
- [#1519](https://github.com/tailor-platform/sdk/pull/1519) [`4e3fa47`](https://github.com/tailor-platform/sdk/commit/4e3fa47d24e6bb1145eac13c355e976f2d594851) Thanks [@dqn](https://github.com/dqn)! - Limit the `openDownloadStream` migration review prompt to files that reference deprecated download stream APIs.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
- [#1521](https://github.com/tailor-platform/sdk/pull/1521) [`2d0689e`](https://github.com/tailor-platform/sdk/commit/2d0689e8ac0079473294fab367799a5431c130f4) Thanks [@dqn](https://github.com/dqn)! - Flag files that need project-specific review after the v2 principal migration, including resolver helper adapters and nullable `caller` follow-ups.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
- [#1525](https://github.com/tailor-platform/sdk/pull/1525) [`425a19d`](https://github.com/tailor-platform/sdk/commit/425a19dd58da6e373b739d3b3e838c2ff3d1736a) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency semver to v7.8.5
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
- [#1520](https://github.com/tailor-platform/sdk/pull/1520) [`ed3d338`](https://github.com/tailor-platform/sdk/commit/ed3d338ce71d68904ef1fb83afbbd06a7e5f6973) Thanks [@dqn](https://github.com/dqn)! - Flag files that still reference ambient Tailor runtime globals so the v2 migration can opt them into `@tailor-platform/sdk/runtime/globals`.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
- [#1439](https://github.com/tailor-platform/sdk/pull/1439) [`c5b10d2`](https://github.com/tailor-platform/sdk/commit/c5b10d2841ded08927285bce538c05220cde5e4c) Thanks [@dqn](https://github.com/dqn)! - Unify function principal context around `TailorPrincipal`.
|
|
65
|
+
|
|
66
|
+
Resolver contexts now use `caller` and `invoker` as `TailorPrincipal | null`, workflow and executor invokers also use `TailorPrincipal | null`, and event executor `actor` uses `TailorPrincipal | null` with `id`/`type` fields. The legacy `TailorUser`, `TailorInvoker`, `TailorActor`, `TailorActorType`, and `unauthenticatedTailorUser` exports are removed.
|
|
67
|
+
|
|
68
|
+
## 0.3.0-next.1
|
|
69
|
+
### Patch Changes
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
- [#1460](https://github.com/tailor-platform/sdk/pull/1460) [`f49c6d1`](https://github.com/tailor-platform/sdk/commit/f49c6d1b5a856969cb4e04ae7d3a87ed34aa020f) Thanks [@dqn](https://github.com/dqn)! - Remove the v1 runtime globals compatibility layer. Importing from `@tailor-platform/sdk` no longer activates the ambient `tailor.*` / `tailordb.*` declarations; opt into globals with `@tailor-platform/sdk/runtime/globals` or use the typed wrappers from `@tailor-platform/sdk/runtime`.
|
|
74
|
+
|
|
75
|
+
The capital-cased `Tailordb.*` namespace is removed. If your project still references `Tailordb.QueryResult`, `Tailordb.CommandType`, `Tailordb.Client`, or `typeof Tailordb.Client`, migrate before upgrading: run `pnpm dlx @tailor-platform/sdk-codemod v2/tailordb-namespace` to rewrite them to lowercase `tailordb.*`, then add `import "@tailor-platform/sdk/runtime/globals"` so the rewritten references resolve.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
- [#1457](https://github.com/tailor-platform/sdk/pull/1457) [`84325f8`](https://github.com/tailor-platform/sdk/commit/84325f8602a5631b7c323c997b1425235509920e) Thanks [@dqn](https://github.com/dqn)! - Remove deprecated CLI aliases for the v2 command surface. Use `tailor-sdk deploy` instead of `tailor-sdk apply`, `tailor-sdk crashreport` instead of `tailor-sdk crash-report`, and the hyphenated `--machine-user` option instead of the hidden `--machineuser` alias.
|
|
79
|
+
|
|
80
|
+
Fix the v2 CLI rename codemod to migrate the hidden `--machineuser` option to `--machine-user`.
|
|
81
|
+
|
|
3
82
|
## 0.3.0-next.0
|
|
4
83
|
### Minor Changes
|
|
5
84
|
|
|
6
85
|
|
|
7
86
|
|
|
87
|
+
- [#1435](https://github.com/tailor-platform/sdk/pull/1435) [`49c0cc9`](https://github.com/tailor-platform/sdk/commit/49c0cc99171d7e317a50a18804a21067d89f9493) Thanks [@dqn](https://github.com/dqn)! - Add the `v2/plugin-cli-import` codemod so `tailor-sdk upgrade` rewrites deprecated plugin imports from `@tailor-platform/sdk/cli` (`kyselyTypePlugin`, `enumConstantsPlugin`, `fileUtilsPlugin`, `seedPlugin`) to their dedicated `@tailor-platform/sdk/plugin/*` subpaths, splitting any non-plugin specifiers onto a separate import.
|
|
88
|
+
|
|
89
|
+
## 0.3.0
|
|
90
|
+
### Minor Changes
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
8
94
|
- [#1435](https://github.com/tailor-platform/sdk/pull/1435) [`49c0cc9`](https://github.com/tailor-platform/sdk/commit/49c0cc99171d7e317a50a18804a21067d89f9493) Thanks [@dqn](https://github.com/dqn)! - Add the `v2/plugin-cli-import` codemod so `tailor-sdk upgrade` rewrites deprecated plugin imports from `@tailor-platform/sdk/cli` (`kyselyTypePlugin`, `enumConstantsPlugin`, `fileUtilsPlugin`, `seedPlugin`) to their dedicated `@tailor-platform/sdk/plugin/*` subpaths, splitting any non-plugin specifiers onto a separate import.
|
|
9
95
|
|
|
10
96
|
## 0.2.7
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import * as path from "pathe";
|
|
2
2
|
//#region codemods/v2/apply-to-deploy/scripts/transform.ts
|
|
3
|
-
const
|
|
3
|
+
const ARG_VALUE = `(?:[^\\s'"\`;&|]+|'[^']*'|"(?:(?:\\\\.)|[^"\\\\])*")`;
|
|
4
|
+
const GLOBAL_ARG_PATTERN = `(?:(?:\\s+(?:--verbose|--json|-j))|(?:\\s+(?:--env-file|--env-file-if-exists|-e)(?:=${ARG_VALUE}|\\s+${ARG_VALUE})))*`;
|
|
5
|
+
const APPLY_PATTERN = new RegExp(`(?<![\\w-])tailor-sdk(?:@[^\\s'"\`]+)?(?![\\w-])(${GLOBAL_ARG_PATTERN}\\s+)apply(?![-\\w])`, "g");
|
|
6
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
7
|
+
".ts",
|
|
8
|
+
".tsx",
|
|
9
|
+
".mts",
|
|
10
|
+
".cts",
|
|
11
|
+
".js",
|
|
12
|
+
".jsx",
|
|
13
|
+
".mjs",
|
|
14
|
+
".cjs"
|
|
15
|
+
]);
|
|
4
16
|
function replaceApply(value) {
|
|
5
|
-
return value.replace(APPLY_PATTERN, (
|
|
17
|
+
return value.replace(APPLY_PATTERN, (match) => `${match.slice(0, -5)}deploy`);
|
|
6
18
|
}
|
|
7
19
|
function transformText(source) {
|
|
8
20
|
if (!APPLY_PATTERN.test(source)) return null;
|
|
@@ -10,6 +22,10 @@ function transformText(source) {
|
|
|
10
22
|
const updated = replaceApply(source);
|
|
11
23
|
return updated === source ? null : updated;
|
|
12
24
|
}
|
|
25
|
+
function transformSourceText(source) {
|
|
26
|
+
const updated = source.split(/(\r\n|\n|\r)/).map((part, index) => index % 2 === 0 ? replaceApply(part) : part).join("");
|
|
27
|
+
return updated === source ? null : updated;
|
|
28
|
+
}
|
|
13
29
|
function transformPackageJson(source) {
|
|
14
30
|
let parsed;
|
|
15
31
|
try {
|
|
@@ -35,14 +51,16 @@ function transformPackageJson(source) {
|
|
|
35
51
|
/**
|
|
36
52
|
* Replace `tailor-sdk apply` invocations with `tailor-sdk deploy`.
|
|
37
53
|
*
|
|
38
|
-
* `deploy` is
|
|
54
|
+
* `deploy` is the canonical v2 command name.
|
|
39
55
|
* @param source - File contents
|
|
40
56
|
* @param filePath - Absolute path to the file (used to dispatch package.json vs text)
|
|
41
57
|
* @returns Transformed source or null when nothing matched.
|
|
42
58
|
*/
|
|
43
59
|
function transform(source, filePath) {
|
|
44
60
|
if (!source.includes("tailor-sdk")) return null;
|
|
45
|
-
|
|
61
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
62
|
+
if (ext === ".json") return transformPackageJson(source);
|
|
63
|
+
if (SOURCE_EXTENSIONS.has(ext)) return transformSourceText(source);
|
|
46
64
|
return transformText(source);
|
|
47
65
|
}
|
|
48
66
|
//#endregion
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Lang, parse } from "@ast-grep/napi";
|
|
2
2
|
//#region codemods/v2/auth-invoker-unwrap/scripts/transform.ts
|
|
3
|
-
const
|
|
3
|
+
const QUICK_FILTER_NEEDLES = ["auth.invoker", "authInvoker"];
|
|
4
4
|
function quickFilter(source) {
|
|
5
|
-
return source.includes(
|
|
5
|
+
return QUICK_FILTER_NEEDLES.some((needle) => source.includes(needle));
|
|
6
6
|
}
|
|
7
7
|
function isInsideImportStatement(node) {
|
|
8
8
|
let current = node.parent();
|
|
@@ -121,14 +121,101 @@ function findAuthImports(root) {
|
|
|
121
121
|
return false;
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
|
+
function sameRange(a, b) {
|
|
125
|
+
const ar = a.range();
|
|
126
|
+
const br = b.range();
|
|
127
|
+
return ar.start.index === br.start.index && ar.end.index === br.end.index;
|
|
128
|
+
}
|
|
129
|
+
function keyText(node) {
|
|
130
|
+
if (!node) return null;
|
|
131
|
+
return node.text().replace(/^['"]|['"]$/g, "");
|
|
132
|
+
}
|
|
133
|
+
function expressionArguments(args) {
|
|
134
|
+
return args.children().filter((child) => ![
|
|
135
|
+
"(",
|
|
136
|
+
")",
|
|
137
|
+
","
|
|
138
|
+
].includes(child.kind()));
|
|
139
|
+
}
|
|
140
|
+
function argumentCallForObject(objectNode) {
|
|
141
|
+
const args = objectNode.parent();
|
|
142
|
+
const call = args?.parent();
|
|
143
|
+
if (args?.kind() !== "arguments" || call?.kind() !== "call_expression") return null;
|
|
144
|
+
const index = expressionArguments(args).findIndex((arg) => sameRange(arg, objectNode));
|
|
145
|
+
return index === -1 ? null : {
|
|
146
|
+
call,
|
|
147
|
+
index
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function calleeText(call) {
|
|
151
|
+
return call.field("function")?.text() ?? "";
|
|
152
|
+
}
|
|
153
|
+
function isCreateCallOptionObject(objectNode, functionName) {
|
|
154
|
+
const callInfo = argumentCallForObject(objectNode);
|
|
155
|
+
return callInfo?.index === 0 && callInfo.call.field("function")?.kind() === "identifier" && calleeText(callInfo.call) === functionName;
|
|
156
|
+
}
|
|
157
|
+
function isExecutorOperationObject(objectNode) {
|
|
158
|
+
const operationPair = objectNode.parent();
|
|
159
|
+
if (operationPair?.kind() !== "pair" || keyText(operationPair.field("key")) !== "operation") return false;
|
|
160
|
+
const configObject = operationPair.parent();
|
|
161
|
+
return configObject?.kind() === "object" && isCreateCallOptionObject(configObject, "createExecutor");
|
|
162
|
+
}
|
|
163
|
+
function isSupportedInvokerOptionObject(objectNode) {
|
|
164
|
+
return isCreateCallOptionObject(objectNode, "createResolver") || isCreateCallOptionObject(objectNode, "startWorkflow") || isExecutorOperationObject(objectNode);
|
|
165
|
+
}
|
|
166
|
+
function optionObjectForPairKey(node) {
|
|
167
|
+
const parent = node.parent();
|
|
168
|
+
if (!parent || parent.kind() !== "pair") return null;
|
|
169
|
+
const key = parent.field("key");
|
|
170
|
+
if (!key || !sameRange(key, node)) return null;
|
|
171
|
+
const objectNode = parent.parent();
|
|
172
|
+
return objectNode?.kind() === "object" ? objectNode : null;
|
|
173
|
+
}
|
|
174
|
+
function isSupportedInvokerOptionKey(node) {
|
|
175
|
+
const objectNode = optionObjectForPairKey(node) ?? node.parent();
|
|
176
|
+
return objectNode?.kind() === "object" && isSupportedInvokerOptionObject(objectNode);
|
|
177
|
+
}
|
|
178
|
+
function isSupportedInvokerValueCall(node) {
|
|
179
|
+
const pair = node.parent();
|
|
180
|
+
if (pair?.kind() !== "pair") return false;
|
|
181
|
+
const value = pair.field("value");
|
|
182
|
+
if (!value || !sameRange(value, node)) return false;
|
|
183
|
+
const key = keyText(pair.field("key"));
|
|
184
|
+
if (key !== "authInvoker" && key !== "invoker") return false;
|
|
185
|
+
const objectNode = pair.parent();
|
|
186
|
+
return objectNode?.kind() === "object" && isSupportedInvokerOptionObject(objectNode);
|
|
187
|
+
}
|
|
188
|
+
function findAuthInvokerShorthands(root) {
|
|
189
|
+
return root.findAll({ rule: {
|
|
190
|
+
kind: "shorthand_property_identifier",
|
|
191
|
+
regex: "^authInvoker$"
|
|
192
|
+
} }).filter(isSupportedInvokerOptionKey);
|
|
193
|
+
}
|
|
194
|
+
function findAuthInvokerPropertyKeys(root) {
|
|
195
|
+
return root.findAll({ rule: {
|
|
196
|
+
kind: "property_identifier",
|
|
197
|
+
regex: "^authInvoker$"
|
|
198
|
+
} }).filter(isSupportedInvokerOptionKey);
|
|
199
|
+
}
|
|
200
|
+
function findQuotedAuthInvokerPropertyKeys(root) {
|
|
201
|
+
return root.findAll({ rule: {
|
|
202
|
+
kind: "string",
|
|
203
|
+
regex: "^['\"]authInvoker['\"]$"
|
|
204
|
+
} }).filter(isSupportedInvokerOptionKey);
|
|
205
|
+
}
|
|
206
|
+
function renameQuotedKey(node) {
|
|
207
|
+
const quote = node.text().startsWith("'") ? "'" : "\"";
|
|
208
|
+
return `${quote}invoker${quote}`;
|
|
209
|
+
}
|
|
124
210
|
/**
|
|
125
|
-
* Replace `auth.invoker("name")` calls with the bare `"name"` string literal
|
|
211
|
+
* Replace `auth.invoker("name")` calls with the bare `"name"` string literal
|
|
212
|
+
* and rename `authInvoker:` option keys to `invoker:`.
|
|
126
213
|
* If no other `auth` references remain after the rewrite, drop the `auth`
|
|
127
214
|
* specifier (or the entire import line when `auth` was its sole specifier).
|
|
128
215
|
*
|
|
129
|
-
* `auth.invoker()` was
|
|
130
|
-
* directly
|
|
131
|
-
* pull config-layer
|
|
216
|
+
* `auth.invoker()` was removed in favor of passing the machine user name
|
|
217
|
+
* directly to `invoker`; carrying the `auth` import only for `.invoker()`
|
|
218
|
+
* would otherwise pull config-layer modules into runtime bundles.
|
|
132
219
|
* @param source - File contents
|
|
133
220
|
* @param filePath - Absolute path to the file (kept for the runner signature)
|
|
134
221
|
* @returns Transformed source or null when nothing matched.
|
|
@@ -136,15 +223,16 @@ function findAuthImports(root) {
|
|
|
136
223
|
function transform(source, _filePath) {
|
|
137
224
|
if (!quickFilter(source)) return null;
|
|
138
225
|
const root = parse(source.includes("</") || source.includes("/>") ? Lang.Tsx : Lang.TypeScript, source).root();
|
|
139
|
-
const calls = findInvokerCalls(root);
|
|
140
|
-
if (calls.length === 0) return null;
|
|
226
|
+
const calls = findInvokerCalls(root).filter((c) => isSupportedInvokerValueCall(c.callNode));
|
|
141
227
|
const edits = calls.map((c) => c.callNode.replace(c.argText));
|
|
142
|
-
|
|
228
|
+
edits.push(...findAuthInvokerPropertyKeys(root).map((node) => node.replace("invoker")));
|
|
229
|
+
edits.push(...findQuotedAuthInvokerPropertyKeys(root).map((node) => node.replace(renameQuotedKey(node))));
|
|
230
|
+
edits.push(...findAuthInvokerShorthands(root).map((node) => node.replace("invoker: authInvoker")));
|
|
231
|
+
if (calls.length > 0 && countRemainingAuthRefs(root, calls.map((c) => c.range)) === 0) for (const importStmt of findAuthImports(root)) {
|
|
143
232
|
const edit = buildAuthImportRemovalEdit(source, importStmt);
|
|
144
233
|
if (edit) edits.push(edit);
|
|
145
234
|
}
|
|
146
|
-
|
|
147
|
-
let result = root.commitEdits(edits);
|
|
235
|
+
let result = edits.length === 0 ? source : root.commitEdits(edits);
|
|
148
236
|
result = result.replace(/^[\t ]*\n+/, "").replace(/\n{3,}/g, "\n\n");
|
|
149
237
|
return result === source ? null : result;
|
|
150
238
|
}
|