@tailor-platform/sdk-codemod 0.3.0-next.3 → 0.3.0-next.5
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 +54 -0
- package/dist/codemods/{ast-grep-helpers-Bfn39biW.js → ast-grep-helpers-CXtWn3RB.js} +1 -1
- package/dist/codemods/v2/auth-connection-token-helper/scripts/transform.js +1 -1
- package/dist/codemods/v2/db-type-to-table/scripts/transform.js +383 -0
- package/dist/codemods/v2/forward-relation-name/scripts/transform.js +115 -0
- package/dist/codemods/v2/runtime-globals-opt-in/scripts/transform.js +1 -1
- package/dist/codemods/v2/runtime-subpath-namespace/scripts/transform.js +792 -0
- package/dist/index.js +218 -0
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -116,6 +116,8 @@ const RENAME_BIN_QUOTED_LEGACY_COMMAND_PATTERN = new RegExp([
|
|
|
116
116
|
].join(""));
|
|
117
117
|
const V2_NEXT_1 = "2.0.0-next.1";
|
|
118
118
|
const V2_NEXT_2 = "2.0.0-next.2";
|
|
119
|
+
const V2_NEXT_3 = "2.0.0-next.3";
|
|
120
|
+
const V2_NEXT_4 = "2.0.0-next.4";
|
|
119
121
|
/** All registered codemods, in registration order. */
|
|
120
122
|
const allCodemods = [
|
|
121
123
|
{
|
|
@@ -494,6 +496,54 @@ const allCodemods = [
|
|
|
494
496
|
"wrapper or global tailor.authconnection."
|
|
495
497
|
].join("\n")
|
|
496
498
|
},
|
|
499
|
+
{
|
|
500
|
+
id: "v2/runtime-subpath-namespace",
|
|
501
|
+
name: "Runtime subpath imports use namespace objects",
|
|
502
|
+
description: "Rewrite `@tailor-platform/sdk/runtime/*` namespace-star and flat value imports to self-named namespace imports, and aggregate `file.deleteFile` calls to `file.delete`. `TailorContextAPI` and `TailorWorkflowAPI` now describe SDK wrappers; direct platform globals use `PlatformContextAPI` and `PlatformWorkflowAPI`.",
|
|
503
|
+
since: "1.0.0",
|
|
504
|
+
until: "2.0.0",
|
|
505
|
+
prereleaseUntil: V2_NEXT_3,
|
|
506
|
+
scriptPath: "v2/runtime-subpath-namespace/scripts/transform.js",
|
|
507
|
+
filePatterns: ["**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}"],
|
|
508
|
+
legacyPatterns: [
|
|
509
|
+
"@tailor-platform/sdk/runtime/iconv",
|
|
510
|
+
"@tailor-platform/sdk/runtime/secretmanager",
|
|
511
|
+
"@tailor-platform/sdk/runtime/authconnection",
|
|
512
|
+
"@tailor-platform/sdk/runtime/idp",
|
|
513
|
+
"@tailor-platform/sdk/runtime/workflow",
|
|
514
|
+
"@tailor-platform/sdk/runtime/context",
|
|
515
|
+
"@tailor-platform/sdk/runtime/file",
|
|
516
|
+
"@tailor-platform/sdk/runtime/aigateway"
|
|
517
|
+
],
|
|
518
|
+
examples: [
|
|
519
|
+
{
|
|
520
|
+
before: "import * as iconv from \"@tailor-platform/sdk/runtime/iconv\";\niconv.convert(value, \"UTF-8\", \"Shift_JIS\");",
|
|
521
|
+
after: "import { iconv } from \"@tailor-platform/sdk/runtime/iconv\";\niconv.convert(value, \"UTF-8\", \"Shift_JIS\");"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
before: "import { get } from \"@tailor-platform/sdk/runtime/aigateway\";\nconst gateway = await get(\"main\");",
|
|
525
|
+
after: "import { aigateway } from \"@tailor-platform/sdk/runtime/aigateway\";\nconst gateway = await aigateway.get(\"main\");"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
before: "import { file } from \"@tailor-platform/sdk/runtime\";\nawait file.deleteFile(\"ns\", \"Doc\", \"blob\", \"record-id\");",
|
|
529
|
+
after: "import { file } from \"@tailor-platform/sdk/runtime\";\nawait file.delete(\"ns\", \"Doc\", \"blob\", \"record-id\");"
|
|
530
|
+
}
|
|
531
|
+
],
|
|
532
|
+
prompt: [
|
|
533
|
+
"In Tailor SDK v2, runtime subpath modules export only a self-named namespace",
|
|
534
|
+
"object (for example, `iconv` from `@tailor-platform/sdk/runtime/iconv`).",
|
|
535
|
+
"Default and flat value imports such as",
|
|
536
|
+
"`import { get } from \"@tailor-platform/sdk/runtime/aigateway\"` are removed.",
|
|
537
|
+
"The codemod rewrites straightforward namespace-star imports and flat named value",
|
|
538
|
+
"imports. It also rewrites direct `file.deleteFile` calls on the aggregate runtime",
|
|
539
|
+
"namespace to `file.delete`. Destructured aggregate `deleteFile` references require",
|
|
540
|
+
"manual migration. Review any remaining runtime imports manually, especially when",
|
|
541
|
+
"a local binding or nested scope shadows an imported value, or when",
|
|
542
|
+
"type-position namespace member references need explicit top-level type imports.",
|
|
543
|
+
"For direct platform globals, replace `TailorContextAPI` and `TailorWorkflowAPI`",
|
|
544
|
+
"type references with `PlatformContextAPI` and `PlatformWorkflowAPI` respectively."
|
|
545
|
+
].join("\n")
|
|
546
|
+
},
|
|
497
547
|
{
|
|
498
548
|
id: "v2/tailordb-namespace",
|
|
499
549
|
name: "Tailordb → tailordb (lowercase ambient namespace)",
|
|
@@ -518,6 +568,78 @@ const allCodemods = [
|
|
|
518
568
|
"declarations automatically on SDK import."
|
|
519
569
|
].join("\n")
|
|
520
570
|
},
|
|
571
|
+
{
|
|
572
|
+
id: "v2/db-type-to-table",
|
|
573
|
+
name: "db.type() → db.table()",
|
|
574
|
+
description: "Rename TailorDB schema builder calls from `db.type()` to `db.table()`. TailorDB schema definitions now use table terminology in SDK projects.",
|
|
575
|
+
since: "1.0.0",
|
|
576
|
+
until: "2.0.0",
|
|
577
|
+
prereleaseUntil: V2_NEXT_3,
|
|
578
|
+
scriptPath: "v2/db-type-to-table/scripts/transform.js",
|
|
579
|
+
filePatterns: ["**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}"],
|
|
580
|
+
legacyPatterns: ["db.type"],
|
|
581
|
+
examples: [{
|
|
582
|
+
before: "import { db } from \"@tailor-platform/sdk\";\n\nexport const user = db.type(\"User\", {\n name: db.string(),\n});",
|
|
583
|
+
after: "import { db } from \"@tailor-platform/sdk\";\n\nexport const user = db.table(\"User\", {\n name: db.string(),\n});"
|
|
584
|
+
}],
|
|
585
|
+
prompt: [
|
|
586
|
+
"In Tailor SDK v2, TailorDB schema definitions use db.table(...) instead of",
|
|
587
|
+
"db.type(...). The codemod rewrites member accesses on db imported from",
|
|
588
|
+
"@tailor-platform/sdk, including aliases such as `import { db as schema }`.",
|
|
589
|
+
"It flags destructured builder aliases such as `const { type } = db` and",
|
|
590
|
+
"local builder aliases such as `const schema = db`, `schema = db`, or",
|
|
591
|
+
"`function make(schema = db) { ... }` for manual review because the local",
|
|
592
|
+
"alias may require call-site renaming.",
|
|
593
|
+
"Review any remaining db.type references and rename SDK TailorDB schema builder",
|
|
594
|
+
"calls to db.table. Leave unrelated local objects with a .type() method unchanged."
|
|
595
|
+
].join("\n")
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
id: "v2/forward-relation-name",
|
|
599
|
+
name: "TailorDB forward relation names derive from field names",
|
|
600
|
+
description: "Review TailorDB relations that omit `toward.as`. Their forward GraphQL field names now derive from the relation field name with a trailing `ID`, `Id`, or `id` removed, instead of from the target table name.",
|
|
601
|
+
since: "1.0.0",
|
|
602
|
+
until: "2.0.0",
|
|
603
|
+
prereleaseUntil: V2_NEXT_4,
|
|
604
|
+
scriptPath: "v2/forward-relation-name/scripts/transform.js",
|
|
605
|
+
filePatterns: ["**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}"],
|
|
606
|
+
suspiciousPatterns: [
|
|
607
|
+
/\.relation\b(?!\s*\()/,
|
|
608
|
+
/\{[^}\n]*\brelation\b[^}\n]*\}\s*=/,
|
|
609
|
+
/\[\s*["']relation["']\s*\]/
|
|
610
|
+
],
|
|
611
|
+
examples: [{
|
|
612
|
+
caption: "Preserve the v1 GraphQL field name by making it explicit:",
|
|
613
|
+
before: [
|
|
614
|
+
"ownerId: db.uuid().relation({",
|
|
615
|
+
" type: \"n-1\",",
|
|
616
|
+
" toward: { type: user },",
|
|
617
|
+
"}),"
|
|
618
|
+
].join("\n"),
|
|
619
|
+
after: [
|
|
620
|
+
"ownerId: db.uuid().relation({",
|
|
621
|
+
" type: \"n-1\",",
|
|
622
|
+
" toward: { type: user, as: \"user\" },",
|
|
623
|
+
"}),"
|
|
624
|
+
].join("\n")
|
|
625
|
+
}],
|
|
626
|
+
prompt: [
|
|
627
|
+
"Tailor SDK v2 derives a default forward GraphQL relation name from the source",
|
|
628
|
+
"field name by removing a trailing ID, Id, or id. V1 derived it from the target",
|
|
629
|
+
"table name. Review each reported non-self relation that omits toward.as.",
|
|
630
|
+
"",
|
|
631
|
+
"If consumers must keep using the v1 GraphQL field name, inspect the v1 schema and",
|
|
632
|
+
"copy that exact field name into toward.as. Otherwise, update GraphQL operations",
|
|
633
|
+
"and consumer code to use the new field-based name. No change is needed when the old",
|
|
634
|
+
"and new names are identical. Relations with a guaranteed non-empty toward.as,",
|
|
635
|
+
"self-relations, and keyOnly relations are unchanged. For an empty or dynamic",
|
|
636
|
+
"toward.as, determine whether its runtime value can be falsy; if so, treat the",
|
|
637
|
+
"relation as using the default name.",
|
|
638
|
+
"",
|
|
639
|
+
"A relation field without a trailing ID, Id, or id would default to its own scalar",
|
|
640
|
+
"field name and therefore conflict. Give that relation an explicit toward.as."
|
|
641
|
+
].join("\n")
|
|
642
|
+
},
|
|
521
643
|
{
|
|
522
644
|
id: "v2/execute-script-arg",
|
|
523
645
|
name: "executeScript arg JSON.stringify → value",
|
|
@@ -770,6 +892,102 @@ const allCodemods = [
|
|
|
770
892
|
after: ".tailor/"
|
|
771
893
|
}]
|
|
772
894
|
},
|
|
895
|
+
{
|
|
896
|
+
id: "v2/tailordb-validate-simplify",
|
|
897
|
+
name: "ValidateFn simplification and type-level validate",
|
|
898
|
+
description: "Field-level `ValidateFn` is simplified from `(args: { value, data, invoker }) => boolean` to `(args: { value }) => string | void` — the function now returns the error message directly instead of a separate `[fn, message]` tuple. The `ValidateConfig` tuple form and `Validators<F>` record syntax on `db.type().validate()` are removed. Type-level validation uses `db.type().validate((args, issues) => void)` with `{ newRecord, oldRecord, invoker }` args and an `issues(field, message)` callback for cross-field rules.",
|
|
899
|
+
since: "1.0.0",
|
|
900
|
+
until: "2.0.0",
|
|
901
|
+
prereleaseUntil: V2_NEXT_4,
|
|
902
|
+
suspiciousPatterns: [
|
|
903
|
+
"ValidateConfig",
|
|
904
|
+
"Validators<",
|
|
905
|
+
"ValidatorsBase",
|
|
906
|
+
".validate("
|
|
907
|
+
],
|
|
908
|
+
examples: [{
|
|
909
|
+
caption: "Field-level validate: return an error message string instead of a boolean (tuple form removed):",
|
|
910
|
+
before: ".validate(\n [({ value }) => value.length > 5, \"Name must be longer than 5 characters\"],\n)",
|
|
911
|
+
after: ".validate(({ value }) =>\n value.length <= 5 ? \"Name must be longer than 5 characters\" : undefined,\n)"
|
|
912
|
+
}, {
|
|
913
|
+
caption: "Type-level validate: per-field record syntax replaced by a single function with `issues()` callback:",
|
|
914
|
+
before: ".validate({\n name: [({ value }) => value.length > 5, \"Name must be longer than 5\"],\n})",
|
|
915
|
+
after: ".validate(({ newRecord }, issues) => {\n if (newRecord.name && newRecord.name.length <= 5) {\n issues(\"name\", \"Name must be longer than 5\");\n }\n})"
|
|
916
|
+
}],
|
|
917
|
+
prompt: [
|
|
918
|
+
"The v2 SDK simplifies field validation and introduces type-level validation.",
|
|
919
|
+
"",
|
|
920
|
+
"Field-level `.validate()` changes:",
|
|
921
|
+
"- Signature: `(args: { value, data, invoker }) => boolean` → `(args: { value }) => string | void`",
|
|
922
|
+
"- The function now returns the error message string directly (or undefined/void to pass)",
|
|
923
|
+
" instead of returning a boolean with the message in a separate tuple.",
|
|
924
|
+
"- The `[fn, errorMessage]` tuple form (`ValidateConfig`) is removed.",
|
|
925
|
+
"- `data` and `invoker` are no longer available in field-level validators.",
|
|
926
|
+
" Use type-level `.validate()` for cross-field or invoker-dependent rules.",
|
|
927
|
+
"",
|
|
928
|
+
"Type-level `.validate()` on `db.type()` changes:",
|
|
929
|
+
"- Old: `.validate({ fieldName: fn | [fn, msg] | fn[] })` (per-field record, `Validators<F>` type)",
|
|
930
|
+
"- New: `.validate((args, issues) => void)` (single function, `TypeValidateFn<F>` type)",
|
|
931
|
+
"- Args: `{ newRecord, oldRecord, invoker }` — `newRecord` is the record after hooks run",
|
|
932
|
+
"- Call `issues(field, message)` to report validation errors; `field` supports dotted paths",
|
|
933
|
+
"- Move per-field validators that need `data`/`invoker` to the type-level function",
|
|
934
|
+
"",
|
|
935
|
+
"For each remaining `ValidateConfig`, `Validators<`, or old-signature `.validate()` usage:",
|
|
936
|
+
"1. Rewrite field-level validators to return the error string directly",
|
|
937
|
+
"2. Move cross-field / invoker-dependent validators to the type-level function",
|
|
938
|
+
"3. Remove unused `ValidateConfig` / `Validators` type imports"
|
|
939
|
+
].join("\n")
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
id: "v2/tailordb-hook-redesign",
|
|
943
|
+
name: "TailorDB hook redesign: field-level args and type-level hooks",
|
|
944
|
+
description: "Field-level `HookFn` args change from `{ value, data, invoker }` to create `{ input, invoker, now }` / update `{ input, oldValue, invoker, now }` — `value` is renamed to `input`, matching the `input` arg on type-level hooks (same pre-hook data, narrowed to one field); `data` (the full record) is removed; `oldValue` (previous field value) is added for update hooks only; `now` (operation timestamp) is shared across all hooks. Type-level hooks on `db.type().hooks()` change from per-field mapping `{ fieldName: { create, update } }` (`Hooks<F>`) to a single `{ create, update }` object (`TypeHook<F>`) — create hooks take `{ input, invoker, now }`, update hooks take `{ input, oldRecord, invoker, now }` (oldRecord is always non-null). Both return partial field overrides.",
|
|
945
|
+
since: "1.0.0",
|
|
946
|
+
until: "2.0.0",
|
|
947
|
+
prereleaseUntil: V2_NEXT_4,
|
|
948
|
+
suspiciousPatterns: [
|
|
949
|
+
"Hooks<",
|
|
950
|
+
"HookFn<",
|
|
951
|
+
"Hook<",
|
|
952
|
+
".hooks("
|
|
953
|
+
],
|
|
954
|
+
examples: [{
|
|
955
|
+
caption: "Field-level hooks: `value` renamed to `input`, `data` replaced by `oldValue` and `now`; use `now` instead of `new Date()`:",
|
|
956
|
+
before: "db.datetime().hooks({\n create: ({ value }) => value ?? new Date(),\n update: () => new Date(),\n})",
|
|
957
|
+
after: "db.datetime().hooks({\n create: ({ input, now }) => input ?? now,\n update: ({ now }) => now,\n})"
|
|
958
|
+
}, {
|
|
959
|
+
caption: "Type-level hooks: per-field mapping replaced by single create/update functions:",
|
|
960
|
+
before: ".hooks({\n fullAddress: {\n create: ({ data }) => `${data.postalCode} ${data.address}`,\n update: ({ data }) => `${data.postalCode} ${data.address}`,\n },\n})",
|
|
961
|
+
after: ".hooks({\n create: ({ input }) => ({\n fullAddress: `${input.postalCode} ${input.address}`,\n }),\n update: ({ input }) => ({\n fullAddress: `${input.postalCode} ${input.address}`,\n }),\n})"
|
|
962
|
+
}],
|
|
963
|
+
prompt: [
|
|
964
|
+
"The v2 SDK redesigns TailorDB hooks at both field and type levels.",
|
|
965
|
+
"",
|
|
966
|
+
"Field-level `.hooks()` on individual fields:",
|
|
967
|
+
"- Create args: `{ value, data, invoker }` → `{ input, invoker, now }` (no `oldValue`)",
|
|
968
|
+
"- Update args: `{ value, data, invoker }` → `{ input, oldValue, invoker, now }`",
|
|
969
|
+
"- `value` is renamed to `input`, matching the type-level hook's `input` arg — both are",
|
|
970
|
+
" the same pre-hook data, at different granularity",
|
|
971
|
+
"- `data` (full record) is removed; update hooks get `oldValue` (previous field value) instead",
|
|
972
|
+
"- `now` provides the operation timestamp — use `now` instead of `new Date()`",
|
|
973
|
+
"- If a field-level hook needs the full record (other fields), move it to a type-level hook",
|
|
974
|
+
"",
|
|
975
|
+
"Type-level `.hooks()` on `db.type()`:",
|
|
976
|
+
"- Old: `.hooks({ fieldName: { create: fn, update: fn } })` (per-field mapping, `Hooks<F>` type)",
|
|
977
|
+
"- New: `.hooks({ create: fn, update: fn })` (single object, `TypeHook<F>` type)",
|
|
978
|
+
"- Each function: `({ input, oldRecord, invoker, now }) => ({ fieldName: value, ... })`",
|
|
979
|
+
"- `input` is the pre-hook input (may have nullish values for optional/defaulted fields)",
|
|
980
|
+
"- Create hooks do not receive `oldRecord`; update hooks receive `oldRecord` (always non-null)",
|
|
981
|
+
"- Return an object with only the fields to override; unmentioned fields are unchanged",
|
|
982
|
+
"",
|
|
983
|
+
"Migration steps for each `.hooks()` call on a `db.type()`:",
|
|
984
|
+
"1. If the old per-field hooks only use `value`/`invoker` and don't reference `data`,",
|
|
985
|
+
" convert them to field-level hooks with the new args (`value` → `input`, plus `oldValue`, `now`)",
|
|
986
|
+
"2. If the old hooks reference `data` (cross-field access), convert to a type-level hook",
|
|
987
|
+
" using `input`/`oldRecord`",
|
|
988
|
+
"3. Remove unused `Hooks<F>` / `HookFn<>` type imports"
|
|
989
|
+
].join("\n")
|
|
990
|
+
},
|
|
773
991
|
{
|
|
774
992
|
id: "v2/node-minimum-22-15-0",
|
|
775
993
|
name: "Node.js minimum version raised to 22.15.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailor-platform/sdk-codemod",
|
|
3
|
-
"version": "0.3.0-next.
|
|
3
|
+
"version": "0.3.0-next.5",
|
|
4
4
|
"description": "Codemod runner for Tailor Platform SDK upgrades",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,25 +16,25 @@
|
|
|
16
16
|
],
|
|
17
17
|
"type": "module",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@ast-grep/napi": "0.44.
|
|
19
|
+
"@ast-grep/napi": "0.44.1",
|
|
20
20
|
"chalk": "5.6.2",
|
|
21
21
|
"diff": "9.0.0",
|
|
22
22
|
"pathe": "2.0.3",
|
|
23
23
|
"picomatch": "4.0.5",
|
|
24
24
|
"pkg-types": "2.3.1",
|
|
25
|
-
"politty": "0.11.
|
|
25
|
+
"politty": "0.11.2",
|
|
26
26
|
"semver": "7.8.5",
|
|
27
27
|
"zod": "4.4.3"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "24.13.
|
|
30
|
+
"@types/node": "24.13.3",
|
|
31
31
|
"@types/picomatch": "4.0.3",
|
|
32
32
|
"@types/semver": "7.7.1",
|
|
33
33
|
"eslint-plugin-zod": "4.7.0",
|
|
34
|
-
"oxlint": "1.
|
|
35
|
-
"tsdown": "0.22.
|
|
34
|
+
"oxlint": "1.73.0",
|
|
35
|
+
"tsdown": "0.22.4",
|
|
36
36
|
"typescript": "6.0.3",
|
|
37
|
-
"vitest": "4.1.
|
|
37
|
+
"vitest": "4.1.10"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "tsdown",
|