refactor(sdk)!: move TailorDB erdSite config into the ERD plugin's own configuration#1811
refactor(sdk)!: move TailorDB erdSite config into the ERD plugin's own configuration#1811toiroakr wants to merge 9 commits into
Conversation
…sites })
Remove the plugin-only erdSite field from the core TailorDB service schema.
The ERD deploy target is now configured on the ERD plugin itself via
tailordbErdPlugin({ sites }) from @tailor-platform/sdk-plugin-tailordb-erd/plugin,
registered through definePlugins(). The ERD commands validate each namespace
against config.db and each site name against staticWebsites at config load.
loadTailorDBNamespaces() now returns the config module's registered plugins and
passes them to namespace selector callbacks so external CLI plugins can read
their own definePlugins() configuration.
Adds the v2/erd-site-to-plugin codemod (prereleaseUntil: V2_NEXT_PENDING) that
rewrites db.<namespace>.erdSite entries into a definePlugins() entry.
🦋 Changeset detectedLatest commit: 3321c78 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
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 |
commit: |
example/tailor.config.ts now imports @tailor-platform/sdk-plugin-tailordb-erd/plugin, which resolves to the package's dist output. Jobs that load the example config (generate, deploy, migration, runtime performance) previously only built @tailor-platform/sdk and failed with ERR_MODULE_NOT_FOUND.
This comment has been minimized.
This comment has been minimized.
Wrap the erd-site-to-plugin codemod name in backticks so the <namespace> placeholder is not swallowed as an HTML tag in the rendered migration doc heading, and mention definePlugins() in the explicit-namespace error message so it matches the all-namespaces variant.
This comment has been minimized.
This comment has been minimized.
Move the CLI bin entry to dist/cli.js and make dist/index.js the plugin module, so the config plugin is imported as @tailor-platform/sdk-plugin-tailordb-erd instead of a /plugin subpath. The package root was previously not importable (bin-only, no exports), so the root export is new surface rather than a change.
This comment has been minimized.
This comment has been minimized.
| import type { Edit, SgNode } from "@ast-grep/napi"; | ||
|
|
||
| const PLUGIN_IMPORT = | ||
| 'import { tailordbErdPlugin } from "@tailor-platform/sdk-plugin-tailordb-erd";'; |
There was a problem hiding this comment.
How is the required package dependency surfaced for v1 projects, given that a clean transform adds this import, leaves no residual prompt, and makes config loading fail with ERR_MODULE_NOT_FOUND when the plugin is absent?
There was a problem hiding this comment.
Addressed in 5782d6f: migrated configs are now flagged for LLM review (suspiciousPatterns includes tailordbErdPlugin), and the codemod description/prompt state upfront that the package must be installed as a dev dependency — otherwise config loading fails with ERR_MODULE_NOT_FOUND.
| const valueNode = erdPair?.field("value"); | ||
| if (!erdPair || !valueNode) continue; | ||
|
|
||
| siteEntries.push(`${nsKey.text()}: ${valueNode.text()}`); |
There was a problem hiding this comment.
When defineConfig() is called inside a factory, this moves an erdSite expression that references a parameter or local into the module-level plugins export, leaving that binding out of scope and making the migrated config unloadable.
There was a problem hiding this comment.
Fixed in 5782d6f: defineConfig() calls inside functions are now skipped entirely, so an erdSite value referencing a parameter or local is never hoisted. Factory configs go to LLM review with guidance to keep referenced bindings in scope (factory-config fixture added).
| const closeIndent = multiline[2] ?? ""; | ||
| const head = callText.slice(0, callText.length - multiline[0].length); | ||
| const hasArgs = !/\(\s*$/.test(head); | ||
| return `${head}${hasArgs ? "," : ""}\n${closeIndent} ${arg},\n${closeIndent})`; |
There was a problem hiding this comment.
If the last multiline definePlugins() argument has no trailing comma and is followed by a // comment, the inserted comma lands inside that comment, so the codemod emits invalid TypeScript.
There was a problem hiding this comment.
Fixed in 5782d6f: argument insertion now derives offsets from the argument-list AST nodes (last argument / existing comma token) instead of string surgery, so a trailing line comment can no longer swallow the separating comma (comment-arg fixture added).
| let result = tree.commitEdits(edits); | ||
|
|
||
| const importLines = [PLUGIN_IMPORT]; | ||
| if (!pluginsCall && !/import\s*\{[^}]*\bdefinePlugins\b/.test(result)) { |
There was a problem hiding this comment.
With definePlugins as makePlugins, this check treats the original name as locally bound and then emits a new definePlugins(...) call that has no binding.
There was a problem hiding this comment.
Fixed in 5782d6f: the local binding of definePlugins is now resolved from the sdk import specifier (honoring aliases), so the aliased call is extended instead of emitting an unbound definePlugins reference (aliased-define-plugins fixture added).
| legacyPatterns: ["erdSite:"], | ||
| // Property-key shapes only, so an unrelated `erdSite` variable (e.g. a | ||
| // defineStaticWebSite binding) is not re-flagged after a clean transform. | ||
| suspiciousPatterns: ["erdSite:", /\berdSite\s*[,}]/], |
There was a problem hiding this comment.
Quoted keys such as "erdSite" in a dynamic db object are masked before these residual patterns run, so the codemod leaves the removed field in place while reporting no warning or LLM review.
There was a problem hiding this comment.
Fixed in 5782d6f: added sourceStringLegacyPatterns / sourceStringSuspiciousPatterns for erdSite, so quoted keys that survive masking only as string fragments are still reported both as a residual warning and for LLM review.
…e cases - Skip defineConfig() calls inside functions: hoisting an erdSite value that references a parameter or local into a module-level definePlugins() export would leave the binding out of scope. Factory configs go to LLM review. - Append arguments via AST offsets so a trailing line comment after the last definePlugins() argument cannot swallow the separating comma. - Resolve the local binding of definePlugins from the sdk import so an aliased import (definePlugins as makePlugins) extends the aliased call instead of emitting an unbound definePlugins reference. - Detect quoted "erdSite" keys via sourceString legacy/suspicious patterns; masking previously hid them from residual matching entirely. - Flag migrated configs (tailordbErdPlugin) for LLM review and state in the description/prompt that the plugin package must be installed as a dev dependency, since a clean transform otherwise surfaced the new dependency only as ERR_MODULE_NOT_FOUND at config load.
This comment has been minimized.
This comment has been minimized.
… property removePairEdit previously removed only the separating comma, leaving a comment that documented the removed property orphaned on its own line.
This comment has been minimized.
This comment has been minimized.
…rgument appendArgEdit inserted the new definePlugins argument before a comment on the last argument's line, moving the comment onto the inserted line. The separating comma still goes right after the last argument; the new argument now goes after the same-line comment.
This comment has been minimized.
This comment has been minimized.
With requireErdSite, an invalid tailordbErdPlugin({ sites }) entry for an
unrelated namespace no longer blocks deploying an explicitly targeted valid
one; such issues degrade to warnings. resolveErdSites now returns structured
{ namespace, message } issues so callers can scope what is fatal. Also
reword the LoadedTailorDBNamespaces.plugins docstring: loadConfig collects
plugins from any matching array export, not only definePlugins().
This comment has been minimized.
This comment has been minimized.
…e changeset example removePairEdit now consumes a same-line // comment when removing an erdSite property that has no trailing comma (the leading-comma path), so the comment no longer dangles on the previous property. The changeset example now imports definePlugins so the snippet compiles as written.
Summary
erdSitefield from the core TailorDB service config schema. Core (tailor deploy/generate) never read it; the external ERD CLI plugin was its sole consumer, so the setting moves to the standard plugin configuration surface.tailordbErdPlugin({ sites })to@tailor-platform/sdk-plugin-tailordb-erd(imported from the package root; the CLI bin moved to its own entry) as adefinePlugins()-compatible configuration carrier. Thetailor tailordb erdcommands resolve deploy targets from it.siteskey must be an owned namespace inconfig.db, and each value must match a static website defined instaticWebsites. Mismatches are fatal forerd deployand warnings forerd export/serve, so typos surface early instead of at deploy time. The old.describe()text that mislabeled the value as a "URL" is gone with the field.loadTailorDBNamespaces()to also return the config module's registeredpluginsand pass them to namespace selector callbacks, so external CLI plugins can read their owndefinePlugins()configuration.v2/erd-site-to-plugincodemod (registered withprereleaseUntil: V2_NEXT_PENDING) that removesdb.<namespace>.erdSiteentries and appendstailordbErdPlugin({ sites: { <namespace>: <value> } })to an existingdefinePlugins()call (or creates thepluginsexport), including the imports. Non-literal configs are flagged for LLM-assisted review.install-depsCI action, since loading the example config now requires its dist output.example/tailor.config.ts, the plugin README, and the generated migration docs; add changesets (sdk: major, sdk-plugin-tailordb-erd: minor, sdk-codemod: patch).Breaking Changes
db.<namespace>.erdSiteis no longer accepted intailor.config.ts(strict schema parse error). Configure the ERD deploy target on the plugin instead:The
v2/erd-site-to-plugincodemod migrates existing configs automatically.