@tailor-platform/sdk-codemod 0.4.0 → 0.4.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
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @tailor-platform/sdk-codemod
|
|
2
2
|
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1934](https://github.com/tailor-platform/sdk/pull/1934) [`2a3ec7b`](https://github.com/tailor-platform/sdk/commit/2a3ec7b108275410bf5b35d23784b07aa147c5ea) Thanks [@toiroakr](https://github.com/toiroakr)! - Drop the `chalk` dependency in favor of Node's built-in styling, and decide color support per output stream. Diagnostics on stderr now keep their colors when you redirect stdout (`tailor executor list > out.txt`), and stop writing escape codes into the file when you redirect stderr (`tailor deploy 2> log.txt`). `NO_COLOR`, `FORCE_COLOR` and non-TTY detection keep working as before.
|
|
8
|
+
|
|
9
|
+
`@tailor-platform/sdk-codemod`, `@tailor-platform/sdk-plugin-seed` and `@tailor-platform/sdk-plugin-tailordb-erd` now declare the Node and Bun versions they need (`node >=22.15.0`, `bun >=1.2.0`), matching `@tailor-platform/sdk`. Installing them on an older runtime reports the mismatch instead of failing once the CLI runs.
|
|
10
|
+
|
|
11
|
+
- [#2008](https://github.com/tailor-platform/sdk/pull/2008) [`f2135ab`](https://github.com/tailor-platform/sdk/commit/f2135ab6dd3d130d88803b9829a26024de930ed3) Thanks [@toiroakr](https://github.com/toiroakr)! - Consistently call a TailorDB schema definition a "table" instead of a "type" across the docs, matching the `db.type()` → `db.table()` rename. Also fix three leftover `db.type(...)` code samples in `docs/services/tailordb.md` that should have read `db.table(...)`.
|
|
12
|
+
|
|
13
|
+
Update the `v2/idp-publish-events-rename` codemod registry description to say "tables" instead of "types", matching the same wording fix.
|
|
14
|
+
|
|
15
|
+
## 0.4.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#1957](https://github.com/tailor-platform/sdk/pull/1957) [`a465547`](https://github.com/tailor-platform/sdk/commit/a465547df712ca8c607c1e42cf12c15fe3e830d1) Thanks [@toiroakr](https://github.com/toiroakr)! - Invoke the CLI as `npx @tailor-platform/sdk <command>` wherever an invocation is written for you. `npx` resolves a command it cannot find locally as a package name, so `npx tailor` fell through to an unrelated `tailor` package on npm whenever the SDK was not installed in the project — including in CI, where npm installs without prompting. Omitting the version specifier keeps using the project's installed SDK when there is one.
|
|
20
|
+
|
|
21
|
+
- Setup examples in the README, the quickstart, and the scaffolded project READMEs now use the package-runner form. Bun examples use `bun tailor <command>`, which resolves the local binary without fetching from the registry.
|
|
22
|
+
- Workflows generated by `tailor setup` use `npx @tailor-platform/sdk` for npm projects and `bun run tailor` for Bun projects. `tailor setup check` reports the template as outdated so existing projects regenerate; re-run `tailor setup` to pick it up.
|
|
23
|
+
- The `v2/seed-exec-to-cli-plugin` and `v2/sdk-skills-shim` codemods write the package-runner form when the invocation they produce goes through a runner that installs from the registry (`npx`, `bunx`, `pnpm`/`yarn dlx`, `npm exec`). A runner that resolves project binaries, such as `pnpm exec`, still gets the bare `tailor` binary.
|
|
24
|
+
|
|
3
25
|
## 0.4.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as path from "pathe";
|
|
2
2
|
//#region codemods/v2/sdk-skills-shim/scripts/transform.ts
|
|
3
|
-
const SHIM_PATTERN =
|
|
4
|
-
const
|
|
3
|
+
const SHIM_PATTERN = new RegExp(`((?<![\\w.-])(?:npx|bunx|(?:pnpm|yarn)[ \\t]+dlx|npm[ \\t]+exec)(?:[ \\t]+-{1,2}[\\w-]*)*[ \\t]+)?\\btailor-sdk-skills(?:@[^\\s'"\`]+)?(?:[ \\t]+install)?\\b(?!-)`, "g");
|
|
4
|
+
const CLI_BINARY = "tailor";
|
|
5
|
+
const CLI_PACKAGE = "@tailor-platform/sdk";
|
|
5
6
|
function replaceShim(value) {
|
|
6
|
-
return value.replace(SHIM_PATTERN,
|
|
7
|
+
return value.replace(SHIM_PATTERN, (_match, runner) => `${runner ?? ""}${runner == null ? CLI_BINARY : CLI_PACKAGE} skills add`);
|
|
7
8
|
}
|
|
8
9
|
function transformText(source) {
|
|
9
10
|
if (!SHIM_PATTERN.test(source)) return null;
|
|
@@ -22,8 +22,17 @@ const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
22
22
|
]);
|
|
23
23
|
const NODE_FLAG_PATTERN = new RegExp(`(${VALUE_NODE_FLAG})(?:=(${ARG_VALUE})|${SPACE}(${ARG_VALUE}))|(${BOOLEAN_NODE_FLAG})`, "g");
|
|
24
24
|
const ENV_FILE_FLAG = /^--env-file(?:-if-exists)?$/;
|
|
25
|
-
const RUNNER_PREFIX_PATTERN = new RegExp(`(?<![\\w.-])(
|
|
25
|
+
const RUNNER_PREFIX_PATTERN = new RegExp(`(?<![\\w.-])(pnpm|npm|yarn|bunx|bun|npx)(?:${SPACE}(run|exec|dlx))?${SPACE}$`);
|
|
26
26
|
const RUNNER_PREFIX_WINDOW = 64;
|
|
27
|
+
const CLI_BINARY = "tailor";
|
|
28
|
+
const CLI_PACKAGE = "@tailor-platform/sdk";
|
|
29
|
+
const PACKAGE_RUNNER = `npx ${CLI_PACKAGE}`;
|
|
30
|
+
/** Whether a runner installs names it cannot resolve from the project. */
|
|
31
|
+
function installsMissingNames(runner, subcommand) {
|
|
32
|
+
if (runner === "npx" || runner === "bunx") return true;
|
|
33
|
+
if (subcommand === "dlx") return true;
|
|
34
|
+
return runner === "npm" && subcommand === "exec";
|
|
35
|
+
}
|
|
27
36
|
/** Translate the leading `node` flags into flags the CLI command accepts. */
|
|
28
37
|
function carriedOverFlags(nodeFlags) {
|
|
29
38
|
return [...nodeFlags.matchAll(NODE_FLAG_PATTERN)].filter((match) => match[1] != null && ENV_FILE_FLAG.test(match[1])).map((match) => ` ${match[1]} ${match[2] ?? match[3]}`).join("");
|
|
@@ -32,11 +41,12 @@ function carriedOverFlags(nodeFlags) {
|
|
|
32
41
|
* Rewrite runner invocations. The runner spells validation as its first
|
|
33
42
|
* positional argument, so a consumed `validate` selects the subcommand.
|
|
34
43
|
*/
|
|
35
|
-
function rewrite(value,
|
|
44
|
+
function rewrite(value, inventedHead = CLI_BINARY) {
|
|
36
45
|
return value.replace(RUNNER_PATTERN, (_match, nodeFlags, _quote, validate, offset) => {
|
|
37
46
|
const command = validate ? "validate" : "apply";
|
|
38
47
|
const before = value.slice(Math.max(0, offset - RUNNER_PREFIX_WINDOW), offset);
|
|
39
|
-
|
|
48
|
+
const existing = RUNNER_PREFIX_PATTERN.exec(before);
|
|
49
|
+
return `${existing ? installsMissingNames(existing[1], existing[2]) ? CLI_PACKAGE : CLI_BINARY : inventedHead} seed ${command}${carriedOverFlags(nodeFlags)}`;
|
|
40
50
|
});
|
|
41
51
|
}
|
|
42
52
|
function transformText(source) {
|
|
@@ -49,7 +59,7 @@ function transformText(source) {
|
|
|
49
59
|
* node_modules rather than the PATH.
|
|
50
60
|
*/
|
|
51
61
|
function transformSourceText(source) {
|
|
52
|
-
const updated = rewrite(source,
|
|
62
|
+
const updated = rewrite(source, PACKAGE_RUNNER);
|
|
53
63
|
if (FORK_PATTERN.test(source) && updated.includes("exec.mjs")) return null;
|
|
54
64
|
return updated === source ? null : updated;
|
|
55
65
|
}
|
|
@@ -106,7 +116,7 @@ function reviewFindings(source, filePath, relativePath) {
|
|
|
106
116
|
return {
|
|
107
117
|
file: relativePath,
|
|
108
118
|
line: index + 1,
|
|
109
|
-
message: "Replace the fork()-based seed runner call with execSync(\"npx tailor seed apply\"), forwarding env/stdio, and unwind the surrounding await/Promise plumbing.",
|
|
119
|
+
message: "Replace the fork()-based seed runner call with execSync(\"npx @tailor-platform/sdk seed apply\"), forwarding env/stdio, and unwind the surrounding await/Promise plumbing.",
|
|
110
120
|
excerpt: lines[index].trim()
|
|
111
121
|
};
|
|
112
122
|
});
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { gte, lt, parse, valid } from "semver";
|
|
|
9
9
|
import * as fs from "node:fs";
|
|
10
10
|
import { realpathSync } from "node:fs";
|
|
11
11
|
import { Lang, parse as parse$1 } from "@ast-grep/napi";
|
|
12
|
-
import
|
|
12
|
+
import { stripVTControlCharacters, styleText } from "node:util";
|
|
13
13
|
import { structuredPatch } from "diff";
|
|
14
14
|
import picomatch from "picomatch";
|
|
15
15
|
import { execFileSync } from "node:child_process";
|
|
@@ -205,13 +205,16 @@ const allCodemods = [
|
|
|
205
205
|
examples: [{
|
|
206
206
|
lang: "sh",
|
|
207
207
|
before: "npx tailor-sdk-skills",
|
|
208
|
-
after: "tailor skills add"
|
|
208
|
+
after: "npx @tailor-platform/sdk skills add"
|
|
209
209
|
}],
|
|
210
210
|
prompt: [
|
|
211
211
|
"The standalone tailor-sdk-skills binary is removed in v2; call the skills add",
|
|
212
212
|
"subcommand on the main tailor CLI instead. Replace any remaining",
|
|
213
213
|
"tailor-sdk-skills invocations the codemod did not rewrite with",
|
|
214
|
-
"`tailor skills add
|
|
214
|
+
"`tailor skills add`, or `npx @tailor-platform/sdk skills add` when the",
|
|
215
|
+
"invocation runs through a package runner (npx, bunx, pnpm/yarn dlx, npm exec)",
|
|
216
|
+
"— those resolve a package name, and `npx tailor` reaches an unrelated",
|
|
217
|
+
"`tailor` package on npm."
|
|
215
218
|
].join("\n")
|
|
216
219
|
},
|
|
217
220
|
{
|
|
@@ -680,7 +683,7 @@ const allCodemods = [
|
|
|
680
683
|
{
|
|
681
684
|
id: "v2/idp-publish-events-rename",
|
|
682
685
|
name: "defineIdp publishUserEvents → publishEvents",
|
|
683
|
-
description: "Rename the `defineIdp` option `publishUserEvents` to `publishEvents`, matching the field name TailorDB
|
|
686
|
+
description: "Rename the `defineIdp` option `publishUserEvents` to `publishEvents`, matching the field name that TailorDB tables, resolvers, and workflows already use.",
|
|
684
687
|
since: "1.5.0",
|
|
685
688
|
until: "2.0.0",
|
|
686
689
|
prereleaseUntil: V2_NEXT_11,
|
|
@@ -1290,7 +1293,7 @@ const allCodemods = [
|
|
|
1290
1293
|
" typically fork the runner and await a hand-rolled Promise around",
|
|
1291
1294
|
" `child.on(\"close\", ...)`). The plugin is a CLI-dispatched binary rather",
|
|
1292
1295
|
" than a forkable JS module, so call it synchronously instead —",
|
|
1293
|
-
" `execSync(\"npx tailor seed apply\", { env, stdio: \"inherit\" })` — keeping",
|
|
1296
|
+
" `execSync(\"npx @tailor-platform/sdk seed apply\", { env, stdio: \"inherit\" })` — keeping",
|
|
1294
1297
|
" the original `env` and `stdio` forwarding, and unwind the surrounding",
|
|
1295
1298
|
" Promise wrapper (drop the now-unused `await`, and the `async` keyword when",
|
|
1296
1299
|
" nothing else in the function awaits). Note that `execSync` throws on a",
|
|
@@ -1518,6 +1521,46 @@ function getApplicableCodemods(fromVersion, toVersion) {
|
|
|
1518
1521
|
return allCodemods.filter((codemod) => gte(fromVersion, codemod.since) && lt(fromVersion, effectiveCodemodBoundary(codemod)) && reachesCodemodBoundary(toVersion, codemod));
|
|
1519
1522
|
}
|
|
1520
1523
|
//#endregion
|
|
1524
|
+
//#region ../shared/src/color.ts
|
|
1525
|
+
const style = (name) => (text) => styleText(name, text, { validateStream: false });
|
|
1526
|
+
/**
|
|
1527
|
+
* Style functions by name, so call sites read `color.bold(text)`. Styling is
|
|
1528
|
+
* always applied; `renderFor` drops it again when the destination stream has no
|
|
1529
|
+
* color support. Add a name here when a package needs one that is not listed.
|
|
1530
|
+
*/
|
|
1531
|
+
const color = {
|
|
1532
|
+
bold: style("bold"),
|
|
1533
|
+
dim: style("dim"),
|
|
1534
|
+
italic: style("italic"),
|
|
1535
|
+
gray: style("gray"),
|
|
1536
|
+
white: style("white"),
|
|
1537
|
+
red: style("red"),
|
|
1538
|
+
green: style("green"),
|
|
1539
|
+
yellow: style("yellow"),
|
|
1540
|
+
cyan: style("cyan"),
|
|
1541
|
+
magenta: style("magenta"),
|
|
1542
|
+
redBright: style("redBright"),
|
|
1543
|
+
greenBright: style("greenBright"),
|
|
1544
|
+
cyanBright: style("cyanBright")
|
|
1545
|
+
};
|
|
1546
|
+
const supportsColor = (stream) => {
|
|
1547
|
+
const forced = process.env.FORCE_COLOR;
|
|
1548
|
+
if (forced !== void 0) return forced !== "0" && forced !== "false";
|
|
1549
|
+
if (process.env.NODE_DISABLE_COLORS !== void 0) return false;
|
|
1550
|
+
if ((process.env.NO_COLOR ?? "") !== "") return false;
|
|
1551
|
+
if (process.env.TERM === "dumb") return false;
|
|
1552
|
+
return stream.isTTY === true;
|
|
1553
|
+
};
|
|
1554
|
+
/**
|
|
1555
|
+
* Prepares styled text for the stream it is written to.
|
|
1556
|
+
* @param stream - Stream the text is written to
|
|
1557
|
+
* @param text - Styled text
|
|
1558
|
+
* @returns Text with styling removed when the stream has no color support
|
|
1559
|
+
*/
|
|
1560
|
+
function renderFor(stream, text) {
|
|
1561
|
+
return supportsColor(stream) ? text : stripVTControlCharacters(text);
|
|
1562
|
+
}
|
|
1563
|
+
//#endregion
|
|
1521
1564
|
//#region src/runner.ts
|
|
1522
1565
|
/** Default file patterns for TypeScript files. */
|
|
1523
1566
|
const DEFAULT_FILE_PATTERNS = ["**/*.{ts,tsx,mts,cts}"];
|
|
@@ -1589,6 +1632,9 @@ async function* walkFiles(root, relativeDir = "") {
|
|
|
1589
1632
|
if (entry.isFile()) yield relative;
|
|
1590
1633
|
}
|
|
1591
1634
|
}
|
|
1635
|
+
function writeDiffLine(line, style) {
|
|
1636
|
+
process.stderr.write(renderFor(process.stderr, `${style ? style(line) : line}\n`));
|
|
1637
|
+
}
|
|
1592
1638
|
/**
|
|
1593
1639
|
* Print a colorized unified diff for a single file to stderr.
|
|
1594
1640
|
* @param filePath - Absolute path to the file
|
|
@@ -1598,13 +1644,14 @@ async function* walkFiles(root, relativeDir = "") {
|
|
|
1598
1644
|
function printDiff(filePath, before, after) {
|
|
1599
1645
|
const patch = structuredPatch(filePath, filePath, before, after, "", "", { context: 3 });
|
|
1600
1646
|
if (patch.hunks.length === 0) return;
|
|
1601
|
-
|
|
1602
|
-
|
|
1647
|
+
writeDiffLine("");
|
|
1648
|
+
writeDiffLine(`--- ${filePath}`, color.bold);
|
|
1649
|
+
writeDiffLine(`+++ ${filePath}`, color.bold);
|
|
1603
1650
|
for (const hunk of patch.hunks) {
|
|
1604
|
-
|
|
1605
|
-
for (const line of hunk.lines) if (line.startsWith("+"))
|
|
1606
|
-
else if (line.startsWith("-"))
|
|
1607
|
-
else
|
|
1651
|
+
writeDiffLine(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`, color.cyan);
|
|
1652
|
+
for (const line of hunk.lines) if (line.startsWith("+")) writeDiffLine(line, color.green);
|
|
1653
|
+
else if (line.startsWith("-")) writeDiffLine(line, color.red);
|
|
1654
|
+
else writeDiffLine(line);
|
|
1608
1655
|
}
|
|
1609
1656
|
}
|
|
1610
1657
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk-codemod",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Codemod runner for Tailor Platform SDK upgrades",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"type": "module",
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@ast-grep/napi": "0.45.0",
|
|
20
|
-
"chalk": "5.6.2",
|
|
21
20
|
"diff": "9.0.0",
|
|
22
21
|
"pathe": "2.0.3",
|
|
23
22
|
"picomatch": "4.0.5",
|
|
@@ -29,12 +28,17 @@
|
|
|
29
28
|
"devDependencies": {
|
|
30
29
|
"@types/node": "24.13.3",
|
|
31
30
|
"@types/picomatch": "4.0.3",
|
|
32
|
-
"@types/semver": "7.
|
|
33
|
-
"eslint-plugin-zod": "4.
|
|
31
|
+
"@types/semver": "7.8.0",
|
|
32
|
+
"eslint-plugin-zod": "4.9.0",
|
|
34
33
|
"oxlint": "1.76.0",
|
|
35
34
|
"tsdown": "0.22.14",
|
|
36
35
|
"typescript": "6.0.3",
|
|
37
|
-
"vitest": "4.1.10"
|
|
36
|
+
"vitest": "4.1.10",
|
|
37
|
+
"@tailor-platform/shared": "^0.0.0"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"bun": ">=1.2.0",
|
|
41
|
+
"node": ">=22.15.0"
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|
|
40
44
|
"build": "tsdown",
|