Conversation
… and TailorPrincipal unification
Add three codemods that the upgrade runner applies when migrating from
1.x to 2.x:
- `v2/test-run-arg-input` strips the deprecated `{ "input": ... }`
wrapper from `tailor-sdk function test-run --arg` JSON in
package.json scripts, shell scripts, and Markdown code blocks.
- `v2/sdk-skills-shim` rewrites `tailor-sdk-skills` invocations to
`tailor-sdk skills install` across package.json, shell, YAML, and
Markdown files.
- `v2/principal-unify` renames TailorUser, TailorActor, and
TailorInvoker to the unified TailorPrincipal, drops
`unauthenticatedTailorUser` (replacing value references with
`null`), and renames `user` to `caller` inside `createResolver`
body parameters and member accesses.
Generalize the fixture harness so each codemod can declare multiple
`tests/<case>/` directories with arbitrary file extensions, and treat
cases with no `expected.*` as no-change expectations. Wire the new
transforms into the registry and tsdown entries, and ignore the
fixture trees from oxlint and oxfmt to keep representative user code
samples intact.
🦋 Changeset detectedLatest commit: 8833ca4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
⚡ pkg.pr.new@tailor-platform/sdk@tailor-platform/create-sdk
|
This comment has been minimized.
This comment has been minimized.
… cleanup in v2/principal-unify Resolve the two caveats noted on the codemod: - When `unauthenticatedTailorUser` import removal empties an SDK import statement, post-process the result to drop leading blank lines and collapse runs of three or more newlines down to one empty line. - For `createResolver` bodies that locally redeclare `user`, collect the byte ranges of the enclosing scopes and skip renaming `user` references within them. Param-level destructure and references outside the shadow zone are still rewritten to `caller`. Add a `shadow` fixture covering an inner-block redeclaration and trim the leading blank lines from the `unauthenticated` expected fixture.
This comment has been minimized.
This comment has been minimized.
- Skip the null rewrite when unauthenticatedTailorUser is the object of a
member expression so the codemod no longer emits null.id; the import is
still dropped so the resulting type error points authors at the broken
access.
- Match @tailor-platform/sdk/test imports as well so the documented test
helper unauthenticatedTailorUser is removed there too.
- Restrict resolver-body destructuring rewrites to the top-level object
pattern. Nested patterns like ({ input: { user } }) are left alone, and
aliased pairs like ({ user: currentUser }) now rewrite the property key
to caller while preserving the local binding.
- Dedupe TailorPrincipal across multiple SDK import statements so a file
that splits TailorUser and TailorActor across imports collapses to one
TailorPrincipal binding.
- Skip ctx.user rewrites that sit inside nested functions which re-bind
the resolver context name (items.map((ctx) => ctx.user.id)).
Add fixtures for each case and update the unauthenticated expected
output, which previously asserted the broken null.id behavior.
This comment has been minimized.
This comment has been minimized.
…cture, chained shell commands
principal-unify:
- Track local names introduced by aliased imports (e.g. unauthenticatedTailorUser
as testUser) and rewrite their references to null too.
- Include shorthand_property_identifier (object literal shorthand) in body
rewrites so ({ user }) => ({ user }) becomes ({ caller }) => ({ caller })
instead of leaving the return value referencing an undefined binding.
- Rewrite destructures that read from the resolver context, so
const { user } = ctx becomes const { caller: user } = ctx, preserving the
local binding name.
test-run-arg-input:
- Tokenize lines on unquoted shell command boundaries (;, &&, ||, |, &) and
only run the {input: ...} unwrap on segments that actually contain
tailor-sdk function test-run, so chained commands like
`tailor-sdk function test-run ... --arg '{"input":...}' && other-cli --arg '{"input":...}'`
no longer corrupt the unrelated argument.
Add fixtures for each new case (aliased-unauthenticated, object-shorthand-return,
ctx-destructure, chained-commands).
…s, handle version pins and continuations
principal-unify:
- Object literal shorthand (`{ user }` in a return value) is now expanded to
`{ user: caller }` instead of being collapsed to `{ caller }`, so the
resolver's emitted output schema stays the same after the binding rename.
- Type renames are restricted to TailorUser/TailorActor/TailorInvoker that are
imported from `@tailor-platform/sdk` (or `/test`) without an alias. Local
types like `import { TailorUser } from "./domain"` are left alone, and
aliased SDK imports keep working through the alias.
- The unauthenticated-import rewrite is now driven by names actually imported
from the SDK and skips identifier references that fall inside scopes which
rebind the same name (variable declarations or function parameters), so
shadowing arrow params do not get replaced with `null` and produce
`(null) => null`.
sdk-skills-shim:
- The shim regex now consumes the optional `@version` suffix used by
`npx tailor-sdk-skills@latest` / `pnpm dlx tailor-sdk-skills@1.2.3` and an
optional ` install` subcommand, so the rewrite no longer leaves `@latest`
attached to `tailor-sdk skills install`.
test-run-arg-input:
- Backslash-newline line continuations are folded into a single logical line
via a sentinel before transformation, so a multi-line invocation where
`tailor-sdk function test-run` and `--arg '{"input":...}'` sit on separate
physical lines still has the wrapper unwrapped.
Add fixtures (local-tailor-types, unauthenticated-shadowed, version-qualified,
multiline-shell) and update object-shorthand-return to assert the new output
shape.
…nd defaulted user destructures
principal-unify:
- Detect when the resolver pattern or body already binds `caller` (as another
destructure entry, a let/const declaration, or a function parameter) and
skip the rewrite for that resolver. The previous code would emit duplicate
bindings or silently re-target an unrelated value.
- Resolve the local name(s) of `createResolver` from the SDK import block, so
aliased forms like `import { createResolver as makeResolver } ...` are now
migrated, and unrelated local helpers named `createResolver` (when the SDK
import does not actually bring it in) are left alone. Calls inside scopes
that shadow the binding are also skipped.
- Handle the `{ user = fallback }` defaulted destructure
(`object_assignment_pattern`) by renaming the inner shorthand identifier and
preserving the default expression.
Add fixtures (caller-collision, aliased-create-resolver, defaulted-destructure)
covering each branch.
This comment has been minimized.
This comment has been minimized.
…ler key conflict, arg continuations
principal-unify:
- Body-identifier rewrites in the destructured-resolver path now go through
collectAllShadowRanges, so a nested arrow that re-binds `user` as its own
parameter (e.g. `items.map((user) => user.id)`) keeps its inner reference
pointing at the inner binding instead of being incorrectly renamed.
- collectCtxShadowRanges also treats `var ctx = ...` / `let ctx = ...` style
re-bindings of the resolver context name as shadows, so subsequent
destructures of the rebound variable are not mistaken for the resolver
context.
- hasCallerBindingConflict additionally checks the property `key` of pair
patterns, so `({ user, caller: x })` is detected as conflicting with the
shorthand rename instead of producing a duplicate-key destructure.
test-run-arg-input:
- The shell-line argument regex accepts the JOIN_MARKER as part of the
separator group, so a backslash-newline continuation between `--arg` and
the quoted JSON still matches and the wrapper is unwrapped.
- The marker itself is now plain ASCII (`SDK_CODEMOD_JOIN`) so the regex can
reference it as a literal alternative without escaping or stray bytes.
Add fixtures (param-shadow-user, ctx-rebound, caller-key-conflict,
multiline-arg-continuation) covering each branch.
This comment has been minimized.
This comment has been minimized.
… and pattern-aware
principal-unify:
- collectAllShadowRanges previously used `inside: { kind: "variable_declarator" }`,
which also matched value-side identifier references such as `user` in
`const userId = user.id`. Walking up to the enclosing scope from such a
match marked the entire body as shadowed, so every body rename was
silently suppressed and the codemod produced `({ caller }) => { const x =
user.id; ... }` instead. The scan now iterates `variable_declarator` nodes
directly and only consults `field("name")`.
- Added a shared `patternBindsName` helper that recurses through
`object_pattern`, `array_pattern`, `object_assignment_pattern`, `pair_pattern`,
`assignment_pattern`, and `rest_pattern` so destructured parameters like
`({ user }) => ...` and `(({ user, items }) => items.map(({ user }) => user))`
are recognised as re-bindings of `user`. functionRebindsName uses the same
helper for both single-arrow params and `formal_parameters` children.
test-run-arg-input:
- Updated the JOIN_MARKER comment to describe the actual ASCII strategy
instead of the inaccurate "Unicode private-use area" claim left over from
an earlier iteration.
Add fixtures (body-with-derived-const, nested-destructure-shadow) covering
the previously-broken behaviour.
test-run-arg-input: - Build SHELL_ARG_PATTERN via new RegExp with the JOIN_MARKER constant interpolated, instead of duplicating the literal token inside the regex source. The marker is now defined in one place. principal-unify: - Extract iterateImportSpecs generator that yields each specifier's imported name, alias node, and effective local name. The three import walks (rebuildImportStatement, sdkRenameSourceNames collection, createResolverLocalNames collection) consume it so the spec parsing logic lives in one place.
…re scope-walk helper principal-unify: - quickFilter now derives its needle list from Object.keys(TYPE_RENAME_MAP) plus the unauthenticated/createResolver tokens, so adding another renamed type only needs the map entry. - collectAllShadowRanges and collectCtxShadowRanges shared the same declarator-to-enclosing-scope walk; extracted enclosingScopeRange and consume it from both call sites.
…liased type imports
test-run-arg-input:
- equals-form fixture exercises the SHELL_ARG_PATTERN \s*=\s* separator
branch (tailor-sdk function test-run --arg='{"input":...}'), which the
prior fixtures only hit through the whitespace separator.
- double-quoted-shell fixture exercises shell-context double-quoted JSON
with backslash-escaped quotes, which was previously only exercised via
package.json scripts.
principal-unify:
- aliased-type-import fixture exercises the aliased TailorUser/TailorActor/
TailorInvoker import path, asserting the alias is preserved
(`TailorPrincipal as MyUser`) and the body's MyUser type references stay
untouched.
Also exclude `packages/sdk-codemod/codemods/**/tests/**` from the lefthook
format hook to match the existing `.oxfmtrc.json` and
`packages/sdk-codemod/.oxlintrc.json` ignore patterns. Without this entry,
committing only fixture files makes oxfmt receive an empty staged-files
list and exit with "Expected at least one target file."
Code Metrics Report (packages/sdk)
Details | | main (e88296c) | #1104 (44c2b83) | +/- |
|--------------------|----------------|-----------------|------|
| Coverage | 60.6% | 60.6% | 0.0% |
| Files | 356 | 356 | 0 |
| Lines | 12104 | 12104 | 0 |
| Covered | 7339 | 7339 | 0 |
| Code to Test Ratio | 1:0.4 | 1:0.4 | 0.0 |
| Code | 79598 | 79598 | 0 |
| Test | 32624 | 32624 | 0 |SDK Configure Bundle Size
Runtime Performance
Type Performance (instantiations)
Reported by octocov |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First batch of v2 upgrade codemods. Refs tailor-inc/platform-planning#583. More codemods will be appended to this branch as specs land.
Codemod Checklist
v2/define-generators-to-plugins—defineGenerators→definePlugins(already shipped)v2/test-run-arg-input— strip{ "input": ... }wrapper fromfunction test-run --argJSONv2/sdk-skills-shim—tailor-sdk-skills→tailor-sdk skills installv2/principal-unify— unifyTailorUser/TailorActor/TailorInvokerintoTailorPrincipal, dropunauthenticatedTailorUser, rename resolveruser→callerdb.type/t.objectretirement (waiting on newcreateTableAPI spec)apply→deployrename (waiting on naming decision)--separated option rename (waiting on rename map)attributes/attributeListmap / uuid list normalization (waiting on platform spec)Out of codemod scope:
updatedAtdefault change (Version Packages #607). Internal behavior change, no user code transform needed.Examples
v2/test-run-arg-inputv2/sdk-skills-shimv2/principal-unifyprincipal-unifyis scope-aware: when a resolver body locally redeclaresuser, references inside the redeclaring scope are left intact and only the param-bound references are renamed tocaller. When theunauthenticatedTailorUserimport is the only remaining specifier, the empty import is removed along with its trailing newline and any leading blank lines that result.Main Changes
packages/sdk-codemod/codemods/v2/, each withcodemod.yaml,scripts/transform.ts, and atests/fixture tree.transform.test.tsto auto-discovertests/<case>/directories with arbitrary file extensions, treating cases withoutexpected.*as no-change expectations.src/registry.tsandtsdown.config.ts.