@tailor-platform/sdk-codemod 0.3.0-next.2 → 0.3.0-next.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/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # @tailor-platform/sdk-codemod
2
2
 
3
+ ## 0.3.0-next.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1693](https://github.com/tailor-platform/sdk/pull/1693) [`4751214`](https://github.com/tailor-platform/sdk/commit/4751214c0923e094a844f9ce322279a47e871075) Thanks [@dqn](https://github.com/dqn)! - Rename the TailorDB schema builder from `db.type()` to `db.table()`.
8
+
9
+ Update TailorDB definitions:
10
+
11
+ ```diff
12
+ import { db } from "@tailor-platform/sdk";
13
+
14
+ -export const user = db.type("User", {
15
+ +export const user = db.table("User", {
16
+ name: db.string(),
17
+ });
18
+ ```
19
+
20
+ - [#1704](https://github.com/tailor-platform/sdk/pull/1704) [`9c81d9c`](https://github.com/tailor-platform/sdk/commit/9c81d9c18b1d29b3e9307ea17fe54c8ce55f4dda) Thanks [@dqn](https://github.com/dqn)! - Remove flat value and default exports from `@tailor-platform/sdk/runtime/*` subpath modules. Import each subpath through its self-named namespace export instead, for example `import { iconv } from "@tailor-platform/sdk/runtime/iconv"`.
21
+
22
+ The aggregate `@tailor-platform/sdk/runtime` entry remains named-only, and its deprecated `file.deleteFile` alias is removed in favor of `file.delete`. The v2 codemod rewrites straightforward namespace-star subpath imports, flat named value imports, and aggregate `file.deleteFile` calls to the new namespace-object style.
23
+
24
+ `TailorContextAPI` and `TailorWorkflowAPI` now describe the SDK wrapper objects. Code that types the platform-provided `globalThis.tailor.context` or `globalThis.tailor.workflow` objects directly must use `PlatformContextAPI` or `PlatformWorkflowAPI` instead.
25
+
26
+ ## 0.3.0-next.3
27
+
28
+ ### Patch Changes
29
+
30
+ - [#1559](https://github.com/tailor-platform/sdk/pull/1559) [`ff8ef1c`](https://github.com/tailor-platform/sdk/commit/ff8ef1c1323daf81812c182e146fd53da20e676e) Thanks [@dqn](https://github.com/dqn)! - Rename auth attribute module augmentation from `AttributeMap` to `Attributes`.
31
+
32
+ - [#1584](https://github.com/tailor-platform/sdk/pull/1584) [`7faff07`](https://github.com/tailor-platform/sdk/commit/7faff07982909b63b87185dc1186e2919a06d4bb) Thanks [@dqn](https://github.com/dqn)! - Report the codemod runner identity in the JSON summary, including the source checkout commit and local build command when run from a branch build, so prerelease migration validation can distinguish exact npm packages from branch-head behavior.
33
+
34
+ - [#1599](https://github.com/tailor-platform/sdk/pull/1599) [`b88f6a2`](https://github.com/tailor-platform/sdk/commit/b88f6a2e1c6d8e25a797bec6ca90428f5be3b1b9) Thanks [@dqn](https://github.com/dqn)! - Apply the v2 `rename-bin` codemod to SDK CLI command strings in TypeScript and JavaScript source files.
35
+
36
+ - [#1578](https://github.com/tailor-platform/sdk/pull/1578) [`579cb47`](https://github.com/tailor-platform/sdk/commit/579cb4705cb295c1fcf9bff948d205fb245ff4e5) Thanks [@dqn](https://github.com/dqn)! - Run v2 codemods when the target version is a v2 prerelease.
37
+
38
+ - [#1686](https://github.com/tailor-platform/sdk/pull/1686) [`aecaf8c`](https://github.com/tailor-platform/sdk/commit/aecaf8c1bb7813a32e998ea7d034684541cb1c85) Thanks [@dqn](https://github.com/dqn)! - Replace `tailor skills install` with project-local `tailor skills add`, `list`, `remove`, and `sync` commands for bundled Tailor SDK agent skills.
39
+
40
+ - [#1585](https://github.com/tailor-platform/sdk/pull/1585) [`1c1ca49`](https://github.com/tailor-platform/sdk/commit/1c1ca499b4fd55a616b1531ec7ab280ceed531d3) Thanks [@dqn](https://github.com/dqn)! - Report precise file-local findings for `principal-unify` review follow-ups, including nullable caller call sites and `context.user` helper adapters.
41
+
42
+ - [#1601](https://github.com/tailor-platform/sdk/pull/1601) [`144f3e3`](https://github.com/tailor-platform/sdk/commit/144f3e30f2b0c5dac1a3288ff65c9dc5ca82c13b) Thanks [@dqn](https://github.com/dqn)! - Fix `v2/principal-unify` review findings for nested SDK field parser invoker values and destructured context helper messages.
43
+
44
+ - [#1622](https://github.com/tailor-platform/sdk/pull/1622) [`0fe8bad`](https://github.com/tailor-platform/sdk/commit/0fe8bad9afbb7702bc067ac9635b77c0438497a6) Thanks [@dqn](https://github.com/dqn)! - Remove the deprecated `auth.getConnectionToken()` helper from values returned by `defineAuth()`. Use `authconnection.getConnectionToken(...)` from `@tailor-platform/sdk/runtime` in resolvers, executors, and workflows instead. The v2 codemod rewrites direct `auth.getConnectionToken(...)` calls when the `auth` binding is imported from `tailor.config`.
45
+
46
+ - [#1557](https://github.com/tailor-platform/sdk/pull/1557) [`7ff575f`](https://github.com/tailor-platform/sdk/commit/7ff575fdfa15c00b5fc6282b28c0cb50bfdf927b) Thanks [@toiroakr](https://github.com/toiroakr)! - Rename the CLI binary from `tailor-sdk` to `tailor`.
47
+
48
+ The output directory default changes from `.tailor-sdk` to `.tailor`, and the GitHub Actions lock file path changes from `.github/tailor-sdk.lock` to `.github/tailor.lock`.
49
+
50
+ Run the `v2/rename-bin` codemod to migrate `tailor-sdk` invocations in package.json scripts, shell scripts, CI workflows, and documentation:
51
+
52
+ ```sh
53
+ npx @tailor-platform/sdk-codemod --from 1.x --to 2.0.0
54
+ ```
55
+
56
+ - [#1563](https://github.com/tailor-platform/sdk/pull/1563) [`501e8bf`](https://github.com/tailor-platform/sdk/commit/501e8bfdd2bca7201a1c9b036bf72087476da416) Thanks [@dqn](https://github.com/dqn)! - Standardize SDK-owned environment variables on the `TAILOR_*` namespace.
57
+
58
+ Replace the removed SDK-specific environment variables with their new names: `TAILOR_CONFIG_PATH`, `TAILOR_DTS_PATH`, `TAILOR_CI_ALLOW_ID_INJECTION`, `TAILOR_DEPLOY_BUILD_ONLY`, `TAILOR_BUILD_OUTPUT_DIR`, `TAILOR_SKILLS_SOURCE`, `TAILOR_TEMPLATE_SDK_VERSION`, `TAILOR_PLATFORM_URL`, `TAILOR_PLATFORM_OAUTH2_CLIENT_ID`, `TAILOR_INLINE_SOURCEMAP`, `TAILOR_QUERY_NEWLINE_ON_ENTER`, and `TAILOR_APP_LOG_LEVEL`. The deprecated `TAILOR_TOKEN` fallback is removed; use `TAILOR_PLATFORM_TOKEN`. The v2 codemod rewrites unambiguous removed SDK environment variable names and flags generic names such as `LOG_LEVEL` and `PLATFORM_URL` for manual review.
59
+
60
+ - [#1684](https://github.com/tailor-platform/sdk/pull/1684) [`de3ef5e`](https://github.com/tailor-platform/sdk/commit/de3ef5e7421a998624154df5e90da62e17664524) Thanks [@dqn](https://github.com/dqn)! - Restore Tailor field outputs for UUID, date, datetime, time, and decimal fields to plain string-compatible types and remove the strict scalar string migration guidance.
61
+
62
+ - [#1582](https://github.com/tailor-platform/sdk/pull/1582) [`b8b48a3`](https://github.com/tailor-platform/sdk/commit/b8b48a379a73314c26fbf53c74c2181e77f0565b) Thanks [@dqn](https://github.com/dqn)! - Flag JavaScript files and embedded code strings that still reference ambient Tailor runtime globals during v2 migration review.
63
+
64
+ - [#1583](https://github.com/tailor-platform/sdk/pull/1583) [`006a588`](https://github.com/tailor-platform/sdk/commit/006a5884583f23fc6852714c41e58a7ab6d65a5a) Thanks [@dqn](https://github.com/dqn)! - Automatically migrate simple direct `tailor.idp.Client` runtime global usage to the typed `idp.Client` wrapper during v2 upgrades.
65
+
66
+ - [#1639](https://github.com/tailor-platform/sdk/pull/1639) [`6616674`](https://github.com/tailor-platform/sdk/commit/6616674eb41a53619138603405a4498e3f09d70b) Thanks [@dqn](https://github.com/dqn)! - Keep v2 codemods from reusing type-only runtime helper imports when adding runtime value imports.
67
+
68
+ - [#1581](https://github.com/tailor-platform/sdk/pull/1581) [`79780bc`](https://github.com/tailor-platform/sdk/commit/79780bce19864a238602f4dd7a82fcc84e9f8501) Thanks [@dqn](https://github.com/dqn)! - Add the `v2/tailor-output-ignore-dir` codemod so SDK upgrades rewrite exact `.tailor-sdk/` ignore-file entries to `.tailor/` while leaving other `.tailor-sdk` paths unchanged.
69
+
70
+ - [#1556](https://github.com/tailor-platform/sdk/pull/1556) [`645949e`](https://github.com/tailor-platform/sdk/commit/645949ed64bda8b82fc44c0db54928698b12a2eb) Thanks [@toiroakr](https://github.com/toiroakr)! - Rename `defineWaitPoint` and `defineWaitPoints` to `createWaitPoint` and `createWaitPoints`.
71
+
72
+ These functions create runtime instances with `.wait()` and `.resolve()` methods that call the platform API at runtime, so the `create*` prefix is more accurate. Update any usages:
73
+
74
+ ```diff
75
+ -import { defineWaitPoint, defineWaitPoints } from "@tailor-platform/sdk";
76
+ +import { createWaitPoint, createWaitPoints } from "@tailor-platform/sdk";
77
+
78
+ -export const approval = defineWaitPoint<Payload, Result>("approval");
79
+ +export const approval = createWaitPoint<Payload, Result>("approval");
80
+
81
+ -export const waitPoints = defineWaitPoints((define) => ({ ... }));
82
+ +export const waitPoints = createWaitPoints((define) => ({ ... }));
83
+ ```
84
+
3
85
  ## 0.3.0-next.2
4
86
  ### Minor Changes
5
87
 
@@ -21,9 +103,9 @@
21
103
 
22
104
 
23
105
  - [#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
-
106
+
25
107
  `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
-
108
+
27
109
  Add a `sdk-codemod list` command that prints every registered rule (id, name, kind, version range).
28
110
 
29
111
 
@@ -32,7 +114,7 @@
32
114
 
33
115
 
34
116
  - [#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
-
117
+
36
118
  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
119
 
38
120
 
@@ -41,7 +123,7 @@
41
123
 
42
124
 
43
125
  - [#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
-
126
+
45
127
  Update create-sdk templates and the v2 auth invoker codemod to generate the new `invoker` option.
46
128
 
47
129
 
@@ -62,7 +144,7 @@
62
144
 
63
145
 
64
146
  - [#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
-
147
+
66
148
  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
149
 
68
150
  ## 0.3.0-next.1
@@ -71,12 +153,12 @@
71
153
 
72
154
 
73
155
  - [#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
-
156
+
75
157
  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
158
 
77
159
 
78
160
  - [#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
-
161
+
80
162
  Fix the v2 CLI rename codemod to migrate the hidden `--machineuser` option to `--machine-user`.
81
163
 
82
164
  ## 0.3.0-next.0
@@ -91,6 +173,54 @@
91
173
 
92
174
 
93
175
 
176
+ - [#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.
177
+
178
+ ## 0.3.5
179
+
180
+ ### Patch Changes
181
+
182
+ - [#1659](https://github.com/tailor-platform/sdk/pull/1659) [`6ba468f`](https://github.com/tailor-platform/sdk/commit/6ba468f4654a723ab4db01d3f3474ae96c25cc71) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency picomatch to v4.0.5
183
+
184
+ ## 0.3.4
185
+
186
+ ### Patch Changes
187
+
188
+ - [#1626](https://github.com/tailor-platform/sdk/pull/1626) [`06cc5f2`](https://github.com/tailor-platform/sdk/commit/06cc5f2960c5a09e9783d6b0923ed8c1b3d606a8) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency politty to v0.11.0
189
+
190
+ ## 0.3.3
191
+ ### Patch Changes
192
+
193
+
194
+
195
+ - [#1598](https://github.com/tailor-platform/sdk/pull/1598) [`a5a4c58`](https://github.com/tailor-platform/sdk/commit/a5a4c58cabc24af3088d85c7a0d975d5be459def) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency politty to v0.10.1
196
+
197
+ ## 0.3.2
198
+ ### Patch Changes
199
+
200
+
201
+
202
+ - [#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
203
+
204
+
205
+
206
+ - [#1533](https://github.com/tailor-platform/sdk/pull/1533) [`e3bc2ce`](https://github.com/tailor-platform/sdk/commit/e3bc2ce65ab30ee53e5de0eb48ca6c24049fcd1b) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency politty to v0.9.2
207
+
208
+
209
+
210
+ - [#1554](https://github.com/tailor-platform/sdk/pull/1554) [`a2ca1f9`](https://github.com/tailor-platform/sdk/commit/a2ca1f989a69153138ddef66931f1e8a94c8c3e9) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency @ast-grep/napi to v0.44.0
211
+
212
+ ## 0.3.1
213
+ ### Patch Changes
214
+
215
+
216
+
217
+ - [#1428](https://github.com/tailor-platform/sdk/pull/1428) [`753ac38`](https://github.com/tailor-platform/sdk/commit/753ac3876319d007322c23a7052a2399d194fb72) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency semver to v7.8.4
218
+
219
+ ## 0.3.0
220
+ ### Minor Changes
221
+
222
+
223
+
94
224
  - [#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.
95
225
 
96
226
  ## 0.2.7
@@ -0,0 +1,171 @@
1
+ //#region src/ast-grep-helpers.ts
2
+ const DECLARATION_KINDS = [
3
+ "function_declaration",
4
+ "function_expression",
5
+ "class_declaration",
6
+ "class",
7
+ "enum_declaration",
8
+ "interface_declaration",
9
+ "type_alias_declaration",
10
+ "internal_module",
11
+ "import_alias"
12
+ ];
13
+ function isBindingLeafKind(kind) {
14
+ return kind === "identifier" || kind === "type_identifier" || kind === "shorthand_property_identifier_pattern";
15
+ }
16
+ function isBindingPatternKind(kind) {
17
+ return isBindingLeafKind(kind) || kind === "object_pattern" || kind === "array_pattern" || kind === "rest_pattern";
18
+ }
19
+ function stringValue(node) {
20
+ return node?.text().replace(/^['"]|['"]$/g, "") ?? null;
21
+ }
22
+ function importSource(importStmt) {
23
+ return stringValue(importStmt.find({ rule: { kind: "string" } }) ?? null);
24
+ }
25
+ function isTypeOnlyImport(importStmt) {
26
+ return importStmt.children().some((child) => child.kind() === "type");
27
+ }
28
+ function namedImportsNode(importStmt) {
29
+ return importStmt.find({ rule: { kind: "named_imports" } }) ?? null;
30
+ }
31
+ function importSpecNames(spec) {
32
+ const ids = spec.children().filter((child) => child.kind() === "identifier");
33
+ if (ids.length === 0) return null;
34
+ return {
35
+ importedName: ids[0].text(),
36
+ localName: ids[1]?.text() ?? ids[0].text(),
37
+ typeOnly: spec.children().some((child) => child.kind() === "type")
38
+ };
39
+ }
40
+ function findImportStatements(root) {
41
+ return root.findAll({ rule: { kind: "import_statement" } }).filter((stmt) => stmt.parent()?.kind() === "program").toSorted((a, b) => a.range().start.index - b.range().start.index);
42
+ }
43
+ function importBindings(importStmt) {
44
+ const source = importSource(importStmt);
45
+ if (!source) return [];
46
+ const requireClause = importStmt.children().find((child) => child.kind() === "import_require_clause");
47
+ if (requireClause) {
48
+ const local = requireClause.children().find((child) => child.kind() === "identifier");
49
+ return local ? [{
50
+ localName: local.text(),
51
+ source,
52
+ typeOnly: false
53
+ }] : [];
54
+ }
55
+ const typeOnly = isTypeOnlyImport(importStmt);
56
+ const clause = importStmt.children().find((child) => child.kind() === "import_clause");
57
+ if (!clause) return [];
58
+ const bindings = [];
59
+ for (const child of clause.children()) {
60
+ if (child.kind() === "identifier") {
61
+ bindings.push({
62
+ localName: child.text(),
63
+ source,
64
+ typeOnly
65
+ });
66
+ continue;
67
+ }
68
+ if (child.kind() === "namespace_import") {
69
+ const local = child.children().find((grandchild) => grandchild.kind() === "identifier");
70
+ if (local) bindings.push({
71
+ localName: local.text(),
72
+ source,
73
+ typeOnly
74
+ });
75
+ continue;
76
+ }
77
+ if (child.kind() !== "named_imports") continue;
78
+ for (const spec of child.findAll({ rule: { kind: "import_specifier" } })) {
79
+ const names = importSpecNames(spec);
80
+ if (!names) continue;
81
+ bindings.push({
82
+ ...names,
83
+ source,
84
+ typeOnly: typeOnly || names.typeOnly
85
+ });
86
+ }
87
+ }
88
+ return bindings;
89
+ }
90
+ function buildAddNamedImportEdit(options) {
91
+ const { importName, imports, insertionIndex, moduleName, root, source } = options;
92
+ const existingImport = imports.find((importStmt) => importSource(importStmt) === moduleName && !isTypeOnlyImport(importStmt) && namedImportsNode(importStmt)) ?? null;
93
+ const namedImports = existingImport ? namedImportsNode(existingImport) : null;
94
+ if (namedImports) {
95
+ const specTexts = namedImports.findAll({ rule: { kind: "import_specifier" } }).map((spec) => {
96
+ const names = importSpecNames(spec);
97
+ return names?.importedName === importName && names.localName === importName ? importName : spec.text();
98
+ });
99
+ const nextSpecTexts = specTexts.includes(importName) ? specTexts : [...specTexts, importName];
100
+ return namedImports.replace(`{ ${nextSpecTexts.join(", ")} }`);
101
+ }
102
+ const pos = insertionIndex(root, imports, source);
103
+ return {
104
+ startPos: pos,
105
+ endPos: pos,
106
+ insertedText: pos === 0 || source[pos - 1] === "\n" ? `import { ${importName} } from "${moduleName}";\n\n` : `\nimport { ${importName} } from "${moduleName}";`
107
+ };
108
+ }
109
+ function collectBindingNames(node, names) {
110
+ if (isBindingLeafKind(node.kind())) {
111
+ names.add(node.text());
112
+ return;
113
+ }
114
+ for (const child of node.children()) {
115
+ if (child.kind() === "property_identifier") continue;
116
+ if (child.kind() === "=") break;
117
+ collectBindingNames(child, names);
118
+ }
119
+ }
120
+ function firstDeclaratorChild(node) {
121
+ return node.children().find((child) => child.kind() !== "=") ?? null;
122
+ }
123
+ function collectDirectBindingChildren(node, names) {
124
+ for (const child of node.children()) {
125
+ if (child.kind() === "=") break;
126
+ if (isBindingPatternKind(child.kind())) collectBindingNames(child, names);
127
+ }
128
+ }
129
+ function collectParameters(root, names) {
130
+ for (const param of root.findAll({ rule: { any: [{ kind: "required_parameter" }, { kind: "optional_parameter" }] } })) collectDirectBindingChildren(param, names);
131
+ }
132
+ function collectDeclarationNames(root, names) {
133
+ for (const decl of root.findAll({ rule: { any: DECLARATION_KINDS.map((kind) => ({ kind })) } })) {
134
+ const name = decl.children().find((child) => child.kind() === "identifier" || child.kind() === "type_identifier");
135
+ if (name) names.add(name.text());
136
+ }
137
+ }
138
+ function collectArrowParameters(root, names) {
139
+ for (const arrow of root.findAll({ rule: { kind: "arrow_function" } })) {
140
+ const children = arrow.children();
141
+ const arrowIndex = children.findIndex((child) => child.kind() === "=>");
142
+ if (arrowIndex === -1) continue;
143
+ for (const child of children.slice(0, arrowIndex)) {
144
+ if (child.kind() === "=") break;
145
+ if (isBindingPatternKind(child.kind())) collectBindingNames(child, names);
146
+ }
147
+ }
148
+ }
149
+ function collectForInBindings(root, names) {
150
+ for (const loop of root.findAll({ rule: { kind: "for_in_statement" } })) {
151
+ const children = loop.children();
152
+ const keywordIndex = children.findIndex((child) => child.kind() === "in" || child.kind() === "of");
153
+ if (keywordIndex === -1) continue;
154
+ for (const child of children.slice(0, keywordIndex)) collectBindingNames(child, names);
155
+ }
156
+ }
157
+ function localDeclarationNames(root) {
158
+ const names = /* @__PURE__ */ new Set();
159
+ for (const decl of root.findAll({ rule: { kind: "variable_declarator" } })) {
160
+ const binding = firstDeclaratorChild(decl);
161
+ if (binding) collectBindingNames(binding, names);
162
+ }
163
+ collectParameters(root, names);
164
+ collectDeclarationNames(root, names);
165
+ for (const catchClause of root.findAll({ rule: { kind: "catch_clause" } })) collectDirectBindingChildren(catchClause, names);
166
+ collectArrowParameters(root, names);
167
+ collectForInBindings(root, names);
168
+ return names;
169
+ }
170
+ //#endregion
171
+ export { importSource as a, localDeclarationNames as c, importBindings as i, collectBindingNames as n, importSpecNames as o, findImportStatements as r, isTypeOnlyImport as s, buildAddNamedImportEdit as t };
@@ -3,7 +3,7 @@ import * as path from "pathe";
3
3
  const ARG_VALUE = `(?:[^\\s'"\`;&|]+|'[^']*'|"(?:(?:\\\\.)|[^"\\\\])*")`;
4
4
  const GLOBAL_ARG_PATTERN = `(?:(?:\\s+(?:--verbose|--json|-j))|(?:\\s+(?:--env-file|--env-file-if-exists|-e)(?:=${ARG_VALUE}|\\s+${ARG_VALUE})))*`;
5
5
  const APPLY_PATTERN = new RegExp(`(?<![\\w-])tailor-sdk(?:@[^\\s'"\`]+)?(?![\\w-])(${GLOBAL_ARG_PATTERN}\\s+)apply(?![-\\w])`, "g");
6
- const SOURCE_EXTENSIONS = new Set([
6
+ const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
7
7
  ".ts",
8
8
  ".tsx",
9
9
  ".mts",
@@ -0,0 +1,213 @@
1
+ import { Lang, parse } from "@ast-grep/napi";
2
+ //#region codemods/v2/auth-attributes-rename/scripts/transform.ts
3
+ const SDK_MODULE = "@tailor-platform/sdk";
4
+ const TYPE_RENAME_MAP = {
5
+ AttributeMap: "Attributes",
6
+ UserAttributeMap: "UserAttributes",
7
+ InferredAttributeMap: "InferredAttributes"
8
+ };
9
+ function quickFilter(source) {
10
+ return source.includes(SDK_MODULE) && Object.keys(TYPE_RENAME_MAP).some((name) => source.includes(name));
11
+ }
12
+ function isSdkModuleLiteral(node) {
13
+ return node.kind() === "string" && /^["']@tailor-platform\/sdk["']$/.test(node.text());
14
+ }
15
+ function hasSdkModuleLiteral(node) {
16
+ return node.findAll({ rule: { kind: "string" } }).some(isSdkModuleLiteral);
17
+ }
18
+ function moduleSpecifierLiteral(node) {
19
+ const directLiteral = node.children().find((child) => child.kind() === "string");
20
+ if (directLiteral) return directLiteral;
21
+ return node.children().find((child) => child.kind() === "module")?.children().find((child) => child.kind() === "string");
22
+ }
23
+ function hasSdkModuleSpecifier(node) {
24
+ const literal = moduleSpecifierLiteral(node);
25
+ return literal ? isSdkModuleLiteral(literal) : false;
26
+ }
27
+ function identifierChildren(node) {
28
+ return node.children().filter((child) => child.kind() === "identifier");
29
+ }
30
+ function typeIdentifierChildren(node) {
31
+ return node.children().filter((child) => child.kind() === "type_identifier");
32
+ }
33
+ function sameRange(a, b) {
34
+ const ar = a.range();
35
+ const br = b.range();
36
+ return ar.start.index === br.start.index && ar.end.index === br.end.index;
37
+ }
38
+ function addReplacement(edits, editedRanges, node, replacement) {
39
+ if (node.text() === replacement) return;
40
+ const r = node.range();
41
+ const key = `${r.start.index}:${r.end.index}`;
42
+ if (editedRanges.has(key)) return;
43
+ editedRanges.add(key);
44
+ edits.push(node.replace(replacement));
45
+ }
46
+ function renamedType(name) {
47
+ return TYPE_RENAME_MAP[name];
48
+ }
49
+ function isDeclarationName(node) {
50
+ const parent = node.parent();
51
+ if (!parent || ![
52
+ "class_declaration",
53
+ "enum_declaration",
54
+ "interface_declaration",
55
+ "type_alias_declaration",
56
+ "type_parameter"
57
+ ].includes(parent.kind())) return false;
58
+ const name = parent?.field("name");
59
+ return !!name && sameRange(name, node);
60
+ }
61
+ function isNestedTypeName(node) {
62
+ return node.parent()?.kind() === "nested_type_identifier";
63
+ }
64
+ function declarationName(node) {
65
+ if ([
66
+ "class_declaration",
67
+ "enum_declaration",
68
+ "interface_declaration",
69
+ "type_alias_declaration"
70
+ ].includes(node.kind())) return node.field("name") ?? void 0;
71
+ if (node.kind() !== "export_statement") return void 0;
72
+ return node.children().find((child) => [
73
+ "class_declaration",
74
+ "enum_declaration",
75
+ "interface_declaration",
76
+ "type_alias_declaration"
77
+ ].includes(child.kind()))?.field("name") ?? void 0;
78
+ }
79
+ function scopeDeclaresType(scope, name, reference) {
80
+ return scope.children().some((child) => {
81
+ const declaredName = declarationName(child);
82
+ return !!declaredName && declaredName.text() === name && !sameRange(declaredName, reference);
83
+ });
84
+ }
85
+ function hasTypeParameterShadow(node, name) {
86
+ return node.findAll({ rule: { kind: "type_parameter" } }).some((parameter) => typeIdentifierChildren(parameter)[0]?.text() === name);
87
+ }
88
+ function isShadowedTypeReference(node, name) {
89
+ let current = node.parent();
90
+ while (current) {
91
+ if (current.kind() === "statement_block" && scopeDeclaresType(current, name, node)) return true;
92
+ if ([
93
+ "class_declaration",
94
+ "function_declaration",
95
+ "interface_declaration",
96
+ "method_definition",
97
+ "type_alias_declaration"
98
+ ].includes(current.kind()) && hasTypeParameterShadow(current, name)) return true;
99
+ current = current.parent();
100
+ }
101
+ return false;
102
+ }
103
+ function collectSdkImports(root, edits, editedRanges) {
104
+ const localTypeRenames = /* @__PURE__ */ new Map();
105
+ const namespaceNames = /* @__PURE__ */ new Set();
106
+ const importStmts = root.findAll({ rule: { kind: "import_statement" } });
107
+ for (const importStmt of importStmts) {
108
+ if (!hasSdkModuleSpecifier(importStmt)) continue;
109
+ const namespaceImports = importStmt.findAll({ rule: { kind: "namespace_import" } });
110
+ for (const namespaceImport of namespaceImports) {
111
+ const localName = identifierChildren(namespaceImport).at(-1)?.text();
112
+ if (localName) namespaceNames.add(localName);
113
+ }
114
+ const specs = importStmt.findAll({ rule: { kind: "import_specifier" } });
115
+ for (const spec of specs) {
116
+ const identifiers = identifierChildren(spec);
117
+ const imported = identifiers[0];
118
+ if (!imported) continue;
119
+ const replacement = renamedType(imported.text());
120
+ if (!replacement) continue;
121
+ addReplacement(edits, editedRanges, imported, replacement);
122
+ if (identifiers.length === 1) localTypeRenames.set(imported.text(), replacement);
123
+ }
124
+ }
125
+ return {
126
+ localTypeRenames,
127
+ namespaceNames
128
+ };
129
+ }
130
+ function rewriteSdkExports(root, edits, editedRanges) {
131
+ const exportStmts = root.findAll({ rule: { kind: "export_statement" } });
132
+ for (const exportStmt of exportStmts) {
133
+ if (!hasSdkModuleSpecifier(exportStmt)) continue;
134
+ const specs = exportStmt.findAll({ rule: { kind: "export_specifier" } });
135
+ for (const spec of specs) {
136
+ const exported = identifierChildren(spec)[0];
137
+ if (!exported) continue;
138
+ const replacement = renamedType(exported.text());
139
+ if (replacement) addReplacement(edits, editedRanges, exported, replacement);
140
+ }
141
+ }
142
+ }
143
+ function rewriteModuleAugmentations(root, edits, editedRanges) {
144
+ const declarations = root.findAll({ rule: { kind: "ambient_declaration" } });
145
+ for (const declaration of declarations) {
146
+ if (!hasSdkModuleSpecifier(declaration)) continue;
147
+ const interfaces = declaration.findAll({ rule: { kind: "interface_declaration" } });
148
+ for (const iface of interfaces) {
149
+ const name = typeIdentifierChildren(iface)[0];
150
+ if (name?.text() === "AttributeMap") addReplacement(edits, editedRanges, name, "Attributes");
151
+ }
152
+ }
153
+ }
154
+ function rewriteLocalTypeReferences(root, edits, editedRanges, localTypeRenames) {
155
+ if (localTypeRenames.size === 0) return;
156
+ const typeIdentifiers = root.findAll({ rule: { kind: "type_identifier" } });
157
+ for (const typeIdentifier of typeIdentifiers) {
158
+ if (isDeclarationName(typeIdentifier) || isNestedTypeName(typeIdentifier)) continue;
159
+ const replacement = localTypeRenames.get(typeIdentifier.text());
160
+ if (replacement && isShadowedTypeReference(typeIdentifier, typeIdentifier.text())) continue;
161
+ if (replacement) addReplacement(edits, editedRanges, typeIdentifier, replacement);
162
+ }
163
+ }
164
+ function rewriteNamespaceTypeReferences(root, edits, editedRanges, namespaceNames) {
165
+ if (namespaceNames.size === 0) return;
166
+ const nestedTypes = root.findAll({ rule: { kind: "nested_type_identifier" } });
167
+ for (const nestedType of nestedTypes) {
168
+ const namespaceName = identifierChildren(nestedType)[0]?.text();
169
+ if (!namespaceName || !namespaceNames.has(namespaceName)) continue;
170
+ const typeName = typeIdentifierChildren(nestedType).at(-1);
171
+ if (!typeName) continue;
172
+ const replacement = renamedType(typeName.text());
173
+ if (replacement) addReplacement(edits, editedRanges, typeName, replacement);
174
+ }
175
+ }
176
+ function isSdkImportCall(node) {
177
+ return node.kind() === "call_expression" && hasSdkModuleLiteral(node);
178
+ }
179
+ function rewriteImportTypeReferences(root, edits, editedRanges) {
180
+ const members = root.findAll({ rule: { kind: "member_expression" } });
181
+ for (const member of members) {
182
+ const object = member.field("object");
183
+ if (!object || !isSdkImportCall(object)) continue;
184
+ const property = member.field("property");
185
+ if (!property || property.kind() !== "property_identifier") continue;
186
+ const replacement = renamedType(property.text());
187
+ if (replacement) addReplacement(edits, editedRanges, property, replacement);
188
+ }
189
+ }
190
+ /**
191
+ * Rename the v1 auth attribute type API to its v2 names only when a reference
192
+ * can be tied to `@tailor-platform/sdk`.
193
+ * @param source - File contents
194
+ * @param _filePath - Absolute path to the file (kept for the runner signature)
195
+ * @returns Transformed source or null when nothing matched.
196
+ */
197
+ function transform(source, _filePath) {
198
+ if (!quickFilter(source)) return null;
199
+ const filePath = _filePath?.toLowerCase();
200
+ const root = parse(filePath?.endsWith(".tsx") || filePath?.endsWith(".jsx") ? Lang.Tsx : filePath ? Lang.TypeScript : source.includes("</") || source.includes("/>") ? Lang.Tsx : Lang.TypeScript, source).root();
201
+ const edits = [];
202
+ const editedRanges = /* @__PURE__ */ new Set();
203
+ const { localTypeRenames, namespaceNames } = collectSdkImports(root, edits, editedRanges);
204
+ rewriteSdkExports(root, edits, editedRanges);
205
+ rewriteModuleAugmentations(root, edits, editedRanges);
206
+ rewriteLocalTypeReferences(root, edits, editedRanges, localTypeRenames);
207
+ rewriteNamespaceTypeReferences(root, edits, editedRanges, namespaceNames);
208
+ rewriteImportTypeReferences(root, edits, editedRanges);
209
+ if (edits.length === 0) return null;
210
+ return root.commitEdits(edits);
211
+ }
212
+ //#endregion
213
+ export { transform as default };