Skip to content

feat(tailordb): type-level hooks/validators with issues() API and default support#1487

Closed
toiroakr wants to merge 556 commits into
mainfrom
chore/type-level-hook
Closed

feat(tailordb): type-level hooks/validators with issues() API and default support#1487
toiroakr wants to merge 556 commits into
mainfrom
chore/type-level-hook

Conversation

@toiroakr

@toiroakr toiroakr commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Aggregate per-field hooks and validators into single type-level create/update scripts (type_hook / type_validate) instead of per-field scripts
  • Redesign type-level hooks from per-field mapping (Hooks<F>) to single function API (TypeHook<F> = { create?, update? }) where each function receives { input, oldRecord, invoker, now } and returns partial field overrides
  • Replace input/oldRecord (untyped) with typed oldValue in field-level hooks; cross-field references now use type-level hooks only
  • Hook functions use input parameter (pre-record) matching the platform _input variable; validate uses newRecord (post-hooks)
  • Add .default() builder method for fields with "now" support for datetime/date/time types, applied after hooks on create via ?? defaultValue
  • Use optionalOnCreate proto field instead of field-level hook placeholder (_value) for Create-input optionality
  • Block .default() on optional fields with TypeLevelError
  • Simplify field-level ValidateFn from { newValue, oldValue } to { value } only
  • Remove Validators<F> record-syntax overload; type-level validate only accepts TypeValidateFn<F> function form
  • Add type-level .validate((args, issues) => { ... }) with DottedPaths autocomplete for cross-field validation
  • Add issues() API for type-level validate with typed field paths
  • Kysely plugin: wrap fields with .default() in Generated<T> to match optionalOnCreate behavior
  • Add codemods v2/tailordb-validate-simplify and v2/tailordb-hook-redesign with migration guidance and examples
  • Update all examples, templates, and tests to new API

@changeset-bot

changeset-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7f2fce9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@tailor-platform/sdk Major
@tailor-platform/create-sdk Major
@tailor-platform/sdk-codemod Patch

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

pkg-pr-new Bot commented Jun 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

pnpm add https://pkg.pr.new/@tailor-platform/create-sdk@f1b7b8c
pnpm add https://pkg.pr.new/@tailor-platform/sdk@f1b7b8c

commit: f1b7b8c

@github-actions

This comment has been minimized.

toiroakr and others added 27 commits June 25, 2026 22:36
Add lookahead `(?![\w-])` to TAILOR_SDK_RE so that hyphenated
identifiers like `tailor-sdk-skills` are not partially matched and
incorrectly rewritten to `tailor-skills`. Aligns with the pattern
used in apply-to-deploy and cli-rename transforms.

Clarify the rename-bin description: only `.gitignore` entries need
manual update (the codemod skips paths preceded by a dot); references
to lock-file paths in YAML and Markdown are rewritten automatically.
Regenerate v2.md.
Skip body-identifier rename for any name that is also declared as a
function or variable in the file body, preventing incorrect rewrites of
locals that happen to share the SDK import name (e.g. a helper that
re-declares defineWaitPoints in an inner scope).

Adds a local-shadow fixture to verify the import specifier is still
renamed while the shadowed body usages are left unchanged.
Replace the over-broad needsBodyRename.delete() guard with a per-scope
byte-range map. For each local declaration that shadows an SDK import
name, record the byte range of its containing statement_block (or program
for top-level). Body identifiers are only skipped when their position
falls within one of those ranges, so top-level SDK usages are correctly
renamed even when the same name is re-declared in a nested function.

Adds a nested-shadow fixture to verify: top-level defineWaitPoints is
renamed to createWaitPoints while the re-declared local inside a helper
function and its calls are left unchanged.
Add for_statement and for_in_statement to the scope-kind check when
walking up the AST to find the containing scope of a local declaration.
Without this, a variable_declarator in a for-loop initializer
(for (let defineWaitPoints = ...)) walked all the way up to program,
causing the entire file to be treated as shadowed and preventing top-level
SDK usages from being renamed.

Adds a for-loop-shadow fixture to verify that top-level defineWaitPoints
is renamed while the loop counter and body references are left unchanged.
chore(sdk): replace tsx with amaro for TypeScript loading
…mlinks and tests

- Add v2/rename-bin transform entry to tsdown.config.ts so the script is included in the published package
- Rewrite `npx tailor-sdk@...` to `npx @tailor-platform/sdk@...` to avoid resolving the unrelated npm `tailor` package
- Add NPX_RE regex to handle npx invocations separately from the general binary rename
- Update test fixtures to reflect correct npx rewrite (basic-shell, basic-yaml, version-qualified)
- Add v2/rename-bin to transform.test.ts fixture test suite
- Rename .agents/skills/tailor-sdk and .claude/skills/tailor-sdk symlinks to tailor
- Regenerate v2 migration docs
# Conflicts:
#	packages/sdk-codemod/src/registry.ts
#	packages/sdk/docs/cli/tailordb.md
#	packages/sdk/docs/migration/v2.md
#	packages/sdk/scripts/perf/runtime-perf.sh
#	packages/sdk/src/cli/shared/skills-installer.ts
…, and bunx

Like `npx`, `pnpm dlx` / `yarn dlx` / `bunx` resolve npm package names — rewriting
`tailor-sdk@...` to `tailor@...` would download the unrelated CSS Sprites Generator.
Extend PKG_RUNNER_RE (renamed from NPX_RE) to cover all package-runner forms so
`<runner> tailor-sdk@...` becomes `<runner> @tailor-platform/sdk@...`.
Add yarn dlx and bunx cases to the version-qualified fixture.
…r-platform/sdk

Previously `tailor-sdk@latest` without a package-runner prefix was rewritten
to `tailor@latest`, which resolves the unrelated CSS Sprites Generator package.
Now any version-pinned form falls back to `@tailor-platform/sdk@version`, so
`npx -y tailor-sdk@latest` and bare `tailor-sdk@1.0.0` both produce the
correct package name. Unversioned `tailor-sdk` still becomes `tailor`.
…kage rewrite

`npx -y tailor-sdk login` was falling through to TAILOR_SDK_RE, producing
`npx -y tailor login`, which downloads the unrelated npm `tailor` package.
Extend PKG_RUNNER_RE to include optional short/long flags in the runner
capture group so the replacement preserves them and produces
`npx -y @tailor-platform/sdk login` as expected.
chore(sdk): rename CLI binary from tailor-sdk to tailor

This comment was marked as off-topic.

This comment was marked as off-topic.

…tax validators

- Simplify ValidateFn from { newValue, oldValue } to { value } only
- Remove Validators<F> record-syntax overload from type-level validate
- Block .default() on optional fields with TypeLevelError
- Migrate all examples, templates, and tests to new API

This comment was marked as off-topic.

Fields with .default() now produce Generated<T> in Kysely types,
matching the optionalOnCreate behavior sent to the platform.
Update inventory-management template to reflect type-level hook
migration (totalPrice no longer has a per-field hook).

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@toiroakr toiroakr closed this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants