@tailor-platform/create-sdk 2.0.0-next.1 → 2.0.0-next.10

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.
Files changed (100) hide show
  1. package/CHANGELOG.md +175 -0
  2. package/package.json +10 -9
  3. package/templates/executor/.oxlintrc.json +9 -1
  4. package/templates/executor/__dot__gitignore +1 -1
  5. package/templates/executor/package.json +11 -9
  6. package/templates/executor/src/db/auditLog.ts +1 -1
  7. package/templates/executor/src/db/notification.ts +1 -1
  8. package/templates/executor/src/db/user.ts +1 -1
  9. package/templates/executor/src/generated/db.ts +3 -3
  10. package/templates/executor/tailor.d.ts +4 -2
  11. package/templates/generators/.oxlintrc.json +9 -1
  12. package/templates/generators/README.md +1 -1
  13. package/templates/generators/__dot__gitignore +1 -1
  14. package/templates/generators/package.json +14 -9
  15. package/templates/generators/src/db/category.ts +1 -1
  16. package/templates/generators/src/db/order.ts +1 -1
  17. package/templates/generators/src/db/product.ts +1 -1
  18. package/templates/generators/src/db/user.ts +1 -1
  19. package/templates/generators/src/generated/db.ts +3 -3
  20. package/templates/generators/src/generated/files.ts +5 -5
  21. package/templates/generators/src/resolver/getProduct.test.ts +31 -27
  22. package/templates/generators/src/seed/data/Order.schema.ts +2 -2
  23. package/templates/generators/src/seed/data/Product.schema.ts +2 -2
  24. package/templates/generators/src/seed/data/User.schema.ts +2 -2
  25. package/templates/generators/tailor.d.ts +4 -2
  26. package/templates/hello-world/.oxlintrc.json +9 -1
  27. package/templates/hello-world/README.md +6 -6
  28. package/templates/hello-world/__dot__gitignore +1 -1
  29. package/templates/hello-world/package.json +10 -8
  30. package/templates/hello-world/src/db/user.ts +1 -1
  31. package/templates/hello-world/src/generated/kysely-tailordb.ts +1 -1
  32. package/templates/hello-world/tailor.d.ts +4 -2
  33. package/templates/inventory-management/.oxlintrc.json +9 -1
  34. package/templates/inventory-management/README.md +8 -8
  35. package/templates/inventory-management/__dot__gitignore +1 -1
  36. package/templates/inventory-management/package.json +10 -8
  37. package/templates/inventory-management/src/db/category.ts +1 -1
  38. package/templates/inventory-management/src/db/contact.ts +1 -1
  39. package/templates/inventory-management/src/db/inventory.ts +2 -2
  40. package/templates/inventory-management/src/db/notification.ts +1 -1
  41. package/templates/inventory-management/src/db/order.ts +1 -1
  42. package/templates/inventory-management/src/db/orderItem.ts +12 -8
  43. package/templates/inventory-management/src/db/product.ts +1 -1
  44. package/templates/inventory-management/src/db/user.ts +1 -1
  45. package/templates/inventory-management/src/executor/checkInventory.ts +0 -1
  46. package/templates/inventory-management/src/generated/kysely-tailordb.ts +9 -9
  47. package/templates/inventory-management/src/resolver/registerOrder.ts +4 -2
  48. package/templates/inventory-management/tailor.d.ts +4 -2
  49. package/templates/multi-application/.oxlintrc.json +9 -1
  50. package/templates/multi-application/README.md +2 -2
  51. package/templates/multi-application/__dot__gitignore +1 -1
  52. package/templates/multi-application/apps/admin/db/adminNote.ts +2 -2
  53. package/templates/multi-application/apps/admin/tailor.config.ts +1 -1
  54. package/templates/multi-application/apps/user/db/user.ts +1 -1
  55. package/templates/multi-application/apps/user/tailor.config.ts +1 -1
  56. package/templates/multi-application/package.json +10 -8
  57. package/templates/resolver/.oxlintrc.json +9 -1
  58. package/templates/resolver/README.md +2 -2
  59. package/templates/resolver/__dot__gitignore +1 -1
  60. package/templates/resolver/package.json +11 -9
  61. package/templates/resolver/src/db/user.ts +1 -1
  62. package/templates/resolver/src/generated/db.ts +1 -1
  63. package/templates/resolver/src/resolver/add.test.ts +4 -3
  64. package/templates/resolver/src/resolver/incrementUserAge.test.ts +6 -5
  65. package/templates/resolver/src/resolver/showEnv.test.ts +2 -2
  66. package/templates/resolver/src/resolver/showUserInfo.test.ts +12 -9
  67. package/templates/resolver/src/resolver/showUserInfo.ts +3 -3
  68. package/templates/resolver/src/resolver/upsertUsers.test.ts +2 -2
  69. package/templates/resolver/tailor.d.ts +4 -2
  70. package/templates/static-web-site/.oxlintrc.json +9 -1
  71. package/templates/static-web-site/__dot__gitignore +1 -1
  72. package/templates/static-web-site/package.json +10 -8
  73. package/templates/static-web-site/src/db/user.ts +1 -1
  74. package/templates/static-web-site/tailor.d.ts +4 -2
  75. package/templates/tailordb/.oxlintrc.json +9 -1
  76. package/templates/tailordb/README.md +1 -1
  77. package/templates/tailordb/__dot__gitignore +1 -1
  78. package/templates/tailordb/package.json +11 -9
  79. package/templates/tailordb/src/db/category.ts +1 -1
  80. package/templates/tailordb/src/db/comment.ts +4 -2
  81. package/templates/tailordb/src/db/task.ts +19 -27
  82. package/templates/tailordb/src/db/user.ts +1 -1
  83. package/templates/tailordb/src/generated/db.ts +3 -3
  84. package/templates/tailordb/tailor.d.ts +4 -2
  85. package/templates/workflow/.oxlintrc.json +9 -1
  86. package/templates/workflow/README.md +2 -2
  87. package/templates/workflow/__dot__gitignore +1 -1
  88. package/templates/workflow/e2e/globalSetup.ts +1 -1
  89. package/templates/workflow/e2e/workflow.test.ts +1 -1
  90. package/templates/workflow/package.json +12 -10
  91. package/templates/workflow/src/db/order.ts +1 -1
  92. package/templates/workflow/src/db/user.ts +1 -1
  93. package/templates/workflow/src/generated/db.ts +2 -2
  94. package/templates/workflow/src/resolver/resolveApproval.test.ts +18 -13
  95. package/templates/workflow/src/workflow/approval.test.ts +16 -11
  96. package/templates/workflow/src/workflow/approval.ts +2 -2
  97. package/templates/workflow/src/workflow/order-fulfillment.test.ts +30 -18
  98. package/templates/workflow/src/workflow/order-fulfillment.ts +3 -3
  99. package/templates/workflow/tailor.d.ts +4 -2
  100. package/templates/generators/src/seed/exec.mjs +0 -485
@@ -1,2 +1,2 @@
1
1
  node_modules/
2
- .tailor-sdk/
2
+ .tailor/
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "resolver",
3
+ "version": "0.0.0",
3
4
  "private": true,
4
5
  "type": "module",
5
6
  "scripts": {
6
- "generate": "tailor-sdk generate",
7
- "deploy": "tailor-sdk deploy",
7
+ "generate": "tailor generate",
8
+ "deploy": "tailor deploy",
8
9
  "test": "vitest --project unit",
9
10
  "test:unit": "vitest --project unit",
10
11
  "format": "oxfmt --write .",
@@ -14,12 +15,13 @@
14
15
  "typecheck": "tsc --noEmit"
15
16
  },
16
17
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
18
- "@types/node": "24.13.2",
19
- "oxfmt": "0.54.0",
20
- "oxlint": "1.69.0",
21
- "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
23
- "vitest": "4.1.8"
18
+ "@tailor-platform/eslint-plugin-sdk": "0.2.0-next.0",
19
+ "@tailor-platform/sdk": "2.0.0-next.10",
20
+ "@types/node": "24.13.3",
21
+ "oxfmt": "0.59.0",
22
+ "oxlint": "1.74.0",
23
+ "oxlint-tsgolint": "0.25.0",
24
+ "typescript": "6.0.3",
25
+ "vitest": "4.1.10"
24
26
  }
25
27
  }
@@ -1,7 +1,7 @@
1
1
  import { db } from "@tailor-platform/sdk";
2
2
 
3
3
  export const user = db
4
- .type("User", {
4
+ .table("User", {
5
5
  name: db.string(),
6
6
  email: db.string().unique(),
7
7
  age: db.int(),
@@ -19,7 +19,7 @@ export interface Namespace {
19
19
  email: string;
20
20
  age: number;
21
21
  createdAt: Generated<Timestamp>;
22
- updatedAt: Timestamp | null;
22
+ updatedAt: Generated<Timestamp>;
23
23
  }
24
24
  }
25
25
  }
@@ -1,4 +1,3 @@
1
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
2
1
  import { describe, expect, test } from "vitest";
3
2
  import resolver from "./add";
4
3
 
@@ -6,7 +5,8 @@ describe("add resolver", () => {
6
5
  test("adds two positive numbers", async () => {
7
6
  const result = await resolver.body({
8
7
  input: { left: 1, right: 2 },
9
- user: unauthenticatedTailorUser,
8
+ caller: null,
9
+ invoker: null,
10
10
  env: { appName: "Resolver Template", version: 1 },
11
11
  });
12
12
  expect(result).toBe(3);
@@ -15,7 +15,8 @@ describe("add resolver", () => {
15
15
  test("handles negative numbers", async () => {
16
16
  const result = await resolver.body({
17
17
  input: { left: -5, right: 3 },
18
- user: unauthenticatedTailorUser,
18
+ caller: null,
19
+ invoker: null,
19
20
  env: { appName: "Resolver Template", version: 1 },
20
21
  });
21
22
  expect(result).toBe(-2);
@@ -1,4 +1,3 @@
1
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
2
1
  import { mockTailordb } from "@tailor-platform/sdk/vitest";
3
2
  import { describe, expect, test } from "vitest";
4
3
  import resolver from "./incrementUserAge";
@@ -6,7 +5,7 @@ import resolver from "./incrementUserAge";
6
5
  describe("incrementUserAge resolver", () => {
7
6
  test("increments user age", async () => {
8
7
  using db = mockTailordb();
9
- db.enqueueResults(
8
+ db.enqueueRows(
10
9
  [], // BEGIN
11
10
  [{ age: 30 }], // SELECT
12
11
  [], // UPDATE
@@ -15,7 +14,8 @@ describe("incrementUserAge resolver", () => {
15
14
 
16
15
  const result = await resolver.body({
17
16
  input: { email: "test@example.com" },
18
- user: unauthenticatedTailorUser,
17
+ caller: null,
18
+ invoker: null,
19
19
  env: { appName: "Resolver Template", version: 1 },
20
20
  });
21
21
  expect(result).toEqual({ oldAge: 30, newAge: 31 });
@@ -24,7 +24,7 @@ describe("incrementUserAge resolver", () => {
24
24
 
25
25
  test("throws when user not found", async () => {
26
26
  using db = mockTailordb();
27
- db.enqueueResults(
27
+ db.enqueueRows(
28
28
  [], // BEGIN
29
29
  [], // SELECT (empty)
30
30
  [], // ROLLBACK
@@ -32,7 +32,8 @@ describe("incrementUserAge resolver", () => {
32
32
 
33
33
  const result = resolver.body({
34
34
  input: { email: "test@example.com" },
35
- user: unauthenticatedTailorUser,
35
+ caller: null,
36
+ invoker: null,
36
37
  env: { appName: "Resolver Template", version: 1 },
37
38
  });
38
39
  await expect(result).rejects.toThrowError(/no result/i);
@@ -1,4 +1,3 @@
1
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
2
1
  import { describe, expect, test } from "vitest";
3
2
  import resolver from "./showEnv";
4
3
 
@@ -6,7 +5,8 @@ describe("showEnv resolver", () => {
6
5
  test("returns environment variables", async () => {
7
6
  const result = await resolver.body({
8
7
  input: undefined as never,
9
- user: unauthenticatedTailorUser,
8
+ caller: null,
9
+ invoker: null,
10
10
  env: { appName: "Resolver Template", version: 1 },
11
11
  });
12
12
  expect(result).toEqual({ appName: "Resolver Template", version: 1 });
@@ -1,4 +1,4 @@
1
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
1
+ import type { TailorPrincipal } from "@tailor-platform/sdk";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import resolver from "./showUserInfo";
4
4
 
@@ -6,26 +6,29 @@ describe("showUserInfo resolver", () => {
6
6
  test("returns default user info", async () => {
7
7
  const result = await resolver.body({
8
8
  input: undefined as never,
9
- user: unauthenticatedTailorUser,
9
+ caller: null,
10
+ invoker: null,
10
11
  env: { appName: "Resolver Template", version: 1 },
11
12
  });
12
13
  expect(result).toEqual({
13
- userId: unauthenticatedTailorUser.id,
14
- userType: unauthenticatedTailorUser.type,
15
- workspaceId: unauthenticatedTailorUser.workspaceId,
14
+ userId: "anonymous",
15
+ userType: "anonymous",
16
+ workspaceId: "",
16
17
  });
17
18
  });
18
19
 
19
20
  test("returns custom user info", async () => {
20
- const customUser = {
21
- ...unauthenticatedTailorUser,
21
+ const customCaller = {
22
22
  id: "user-123",
23
23
  type: "machine_user" as const,
24
24
  workspaceId: "ws-456",
25
- };
25
+ attributes: { role: "admin" },
26
+ attributeList: [],
27
+ } satisfies TailorPrincipal;
26
28
  const result = await resolver.body({
27
29
  input: undefined as never,
28
- user: customUser,
30
+ caller: customCaller,
31
+ invoker: customCaller,
29
32
  env: { appName: "Resolver Template", version: 1 },
30
33
  });
31
34
  expect(result).toEqual({
@@ -6,9 +6,9 @@ const resolver = createResolver({
6
6
  operation: "query",
7
7
  body: (context) => {
8
8
  return {
9
- userId: context.user.id,
10
- userType: context.user.type,
11
- workspaceId: context.user.workspaceId,
9
+ userId: context.caller?.id ?? "anonymous",
10
+ userType: context.caller?.type ?? "anonymous",
11
+ workspaceId: context.caller?.workspaceId ?? "",
12
12
  };
13
13
  },
14
14
  output: t.object({
@@ -1,4 +1,3 @@
1
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
2
1
  import { createKyselyMock } from "@tailor-platform/sdk/vitest";
3
2
  import { describe, expect, test, vi } from "vitest";
4
3
  import { getDB, type Namespace } from "../generated/db";
@@ -30,7 +29,8 @@ describe("upsertUsers resolver", () => {
30
29
  { name: "Existing", email: "exists@example.com", age: 41 },
31
30
  ],
32
31
  },
33
- user: unauthenticatedTailorUser,
32
+ caller: null,
33
+ invoker: null,
34
34
  env: { appName: "Resolver Template", version: 1 },
35
35
  });
36
36
 
@@ -1,9 +1,9 @@
1
1
  // This file is auto-generated by @tailor-platform/sdk
2
2
  // Do not edit this file manually
3
- // Regenerated automatically when running 'tailor-sdk deploy' or 'tailor-sdk generate'
3
+ // Regenerated automatically when running 'tailor deploy' or 'tailor generate'
4
4
 
5
5
  declare module "@tailor-platform/sdk" {
6
- interface AttributeMap {
6
+ interface Attributes {
7
7
  role: string;
8
8
  }
9
9
  interface AttributeList {
@@ -17,6 +17,8 @@ declare module "@tailor-platform/sdk" {
17
17
  admin: true;
18
18
  }
19
19
  interface IdpNameRegistry {}
20
+ interface ConnectionNameRegistry {}
21
+ interface AIGatewayNameRegistry {}
20
22
  }
21
23
 
22
24
  export {};
@@ -1,14 +1,22 @@
1
1
  {
2
2
  "$schema": "./node_modules/oxlint/configuration_schema.json",
3
3
  "plugins": ["typescript"],
4
+ "jsPlugins": [
5
+ {
6
+ "name": "tailor-sdk",
7
+ "specifier": "@tailor-platform/eslint-plugin-sdk"
8
+ }
9
+ ],
4
10
  "categories": {
5
11
  "correctness": "error"
6
12
  },
7
13
  "env": {
8
14
  "builtin": true
9
15
  },
10
- "ignorePatterns": [".tailor-sdk/", "src/generated/", "tailor.d.ts"],
16
+ "ignorePatterns": [".tailor/", "src/generated/", "tailor.d.ts"],
11
17
  "rules": {
18
+ "tailor-sdk/no-api-prefix-in-path-pattern": "warn",
19
+ "tailor-sdk/no-unconditional-permit": "warn",
12
20
  "no-case-declarations": "error",
13
21
  "no-empty": "error",
14
22
  "no-fallthrough": "error",
@@ -1,2 +1,2 @@
1
1
  node_modules/
2
- .tailor-sdk/
2
+ .tailor/
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "static-web-site",
3
+ "version": "0.0.0",
3
4
  "private": true,
4
5
  "type": "module",
5
6
  "scripts": {
6
- "deploy": "tailor-sdk deploy",
7
- "generate": "tailor-sdk generate",
7
+ "deploy": "tailor deploy",
8
+ "generate": "tailor generate",
8
9
  "format": "oxfmt --write .",
9
10
  "format:check": "oxfmt --check .",
10
11
  "lint": "oxlint --type-aware .",
@@ -12,11 +13,12 @@
12
13
  "typecheck": "tsc --noEmit"
13
14
  },
14
15
  "devDependencies": {
15
- "@tailor-platform/sdk": "2.0.0-next.1",
16
- "@types/node": "24.13.2",
17
- "oxfmt": "0.54.0",
18
- "oxlint": "1.69.0",
19
- "oxlint-tsgolint": "0.23.0",
20
- "typescript": "5.9.3"
16
+ "@tailor-platform/eslint-plugin-sdk": "0.2.0-next.0",
17
+ "@tailor-platform/sdk": "2.0.0-next.10",
18
+ "@types/node": "24.13.3",
19
+ "oxfmt": "0.59.0",
20
+ "oxlint": "1.74.0",
21
+ "oxlint-tsgolint": "0.25.0",
22
+ "typescript": "6.0.3"
21
23
  }
22
24
  }
@@ -1,7 +1,7 @@
1
1
  import { db } from "@tailor-platform/sdk";
2
2
 
3
3
  export const user = db
4
- .type("User", {
4
+ .table("User", {
5
5
  name: db.string(),
6
6
  email: db.string().unique(),
7
7
  role: db.enum(["ADMIN", "MEMBER"]),
@@ -1,9 +1,9 @@
1
1
  // This file is auto-generated by @tailor-platform/sdk
2
2
  // Do not edit this file manually
3
- // Regenerated automatically when running 'tailor-sdk deploy' or 'tailor-sdk generate'
3
+ // Regenerated automatically when running 'tailor deploy' or 'tailor generate'
4
4
 
5
5
  declare module "@tailor-platform/sdk" {
6
- interface AttributeMap {
6
+ interface Attributes {
7
7
  role: "ADMIN" | "MEMBER";
8
8
  }
9
9
  interface AttributeList {
@@ -16,6 +16,8 @@ declare module "@tailor-platform/sdk" {
16
16
  interface IdpNameRegistry {
17
17
  "my-idp": true;
18
18
  }
19
+ interface ConnectionNameRegistry {}
20
+ interface AIGatewayNameRegistry {}
19
21
  }
20
22
 
21
23
  export {};
@@ -1,14 +1,22 @@
1
1
  {
2
2
  "$schema": "./node_modules/oxlint/configuration_schema.json",
3
3
  "plugins": ["typescript"],
4
+ "jsPlugins": [
5
+ {
6
+ "name": "tailor-sdk",
7
+ "specifier": "@tailor-platform/eslint-plugin-sdk"
8
+ }
9
+ ],
4
10
  "categories": {
5
11
  "correctness": "error"
6
12
  },
7
13
  "env": {
8
14
  "builtin": true
9
15
  },
10
- "ignorePatterns": [".tailor-sdk/", "src/generated/", "tailor.d.ts"],
16
+ "ignorePatterns": [".tailor/", "src/generated/", "tailor.d.ts"],
11
17
  "rules": {
18
+ "tailor-sdk/no-api-prefix-in-path-pattern": "warn",
19
+ "tailor-sdk/no-unconditional-permit": "warn",
12
20
  "no-case-declarations": "error",
13
21
  "no-empty": "error",
14
22
  "no-fallthrough": "error",
@@ -1,6 +1,6 @@
1
1
  # TailorDB Template
2
2
 
3
- Comprehensive TailorDB type definitions demonstrating all features of `db.type()`.
3
+ Comprehensive TailorDB type definitions demonstrating all features of `db.table()`.
4
4
 
5
5
  ## Features
6
6
 
@@ -1,2 +1,2 @@
1
1
  node_modules/
2
- .tailor-sdk/
2
+ .tailor/
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "tailordb",
3
+ "version": "0.0.0",
3
4
  "private": true,
4
5
  "type": "module",
5
6
  "scripts": {
6
- "generate": "tailor-sdk generate",
7
- "deploy": "tailor-sdk deploy",
7
+ "generate": "tailor generate",
8
+ "deploy": "tailor deploy",
8
9
  "test": "vitest --project unit",
9
10
  "test:unit": "vitest --project unit",
10
11
  "format": "oxfmt --write .",
@@ -14,12 +15,13 @@
14
15
  "typecheck": "tsc --noEmit"
15
16
  },
16
17
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
18
- "@types/node": "24.13.2",
19
- "oxfmt": "0.54.0",
20
- "oxlint": "1.69.0",
21
- "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
23
- "vitest": "4.1.8"
18
+ "@tailor-platform/eslint-plugin-sdk": "0.2.0-next.0",
19
+ "@tailor-platform/sdk": "2.0.0-next.10",
20
+ "@types/node": "24.13.3",
21
+ "oxfmt": "0.59.0",
22
+ "oxlint": "1.74.0",
23
+ "oxlint-tsgolint": "0.25.0",
24
+ "typescript": "6.0.3",
25
+ "vitest": "4.1.10"
24
26
  }
25
27
  }
@@ -2,7 +2,7 @@ import { db } from "@tailor-platform/sdk";
2
2
  import { allPermission, allGqlPermission } from "./permission";
3
3
 
4
4
  export const category = db
5
- .type("Category", "Task category with hierarchical structure", {
5
+ .table("Category", "Task category with hierarchical structure", {
6
6
  name: db.string(),
7
7
  description: db.string({ optional: true }),
8
8
  parentCategoryId: db.uuid({ optional: true }).relation({
@@ -4,8 +4,10 @@ import { task } from "./task";
4
4
  import { user } from "./user";
5
5
 
6
6
  export const comment = db
7
- .type("Comment", "A comment on a task", {
8
- body: db.string().validate([({ value }) => value.length >= 1, "Comment must not be empty"]),
7
+ .table("Comment", "A comment on a task", {
8
+ body: db
9
+ .string()
10
+ .validate(({ value }) => (value.length < 1 ? "Comment must not be empty" : undefined)),
9
11
  taskId: db.uuid().relation({
10
12
  type: "n-1",
11
13
  toward: { type: task },
@@ -4,13 +4,11 @@ import { rolePermission, roleGqlPermission } from "./permission";
4
4
  import { user } from "./user";
5
5
 
6
6
  export const task = db
7
- .type("Task", "A task with comprehensive features", {
8
- title: db
9
- .string()
10
- .validate(
11
- [({ value }) => value.length >= 3, "Title must be at least 3 characters"],
12
- [({ value }) => value.length <= 200, "Title must be at most 200 characters"],
13
- ),
7
+ .table("Task", "A task with comprehensive features", {
8
+ title: db.string().validate(
9
+ ({ value }) => (value.length >= 3 ? undefined : "Title must be at least 3 characters"),
10
+ ({ value }) => (value.length <= 200 ? undefined : "Title must be at most 200 characters"),
11
+ ),
14
12
  description: db.string({ optional: true }),
15
13
  status: db.enum([
16
14
  { value: "TODO", description: "Not started" },
@@ -18,12 +16,10 @@ export const task = db
18
16
  { value: "DONE", description: "Completed" },
19
17
  { value: "CANCELLED", description: "No longer needed" },
20
18
  ]),
21
- priority: db
22
- .int()
23
- .validate(
24
- [({ value }) => value >= 0, "Priority must be non-negative"],
25
- [({ value }) => value <= 4, "Priority must be at most 4"],
26
- ),
19
+ priority: db.int().validate(
20
+ ({ value }) => (value >= 0 ? undefined : "Priority must be non-negative"),
21
+ ({ value }) => (value <= 4 ? undefined : "Priority must be at most 4"),
22
+ ),
27
23
  dueDate: db.datetime({ optional: true }),
28
24
  assigneeId: db.uuid({ optional: true }).relation({
29
25
  type: "n-1",
@@ -33,26 +29,22 @@ export const task = db
33
29
  type: "n-1",
34
30
  toward: { type: category },
35
31
  }),
36
- isArchived: db.bool().description("Whether the task is archived"),
32
+ isArchived: db
33
+ .bool()
34
+ .description("Whether the task is archived")
35
+ .hooks({
36
+ create: () => false,
37
+ }),
37
38
  ...db.fields.timestamps(),
38
39
  })
39
- .hooks({
40
- isArchived: {
41
- create: () => false,
42
- },
43
- })
44
40
  .indexes(
45
41
  { fields: ["status", "priority"], unique: false },
46
42
  { fields: ["assigneeId", "status"], unique: false, name: "task_assignee_status_idx" },
47
43
  )
48
- .validate({
49
- status: [
50
- ({ value, data }) => {
51
- const d = data as { dueDate: string | null };
52
- return !(value === "DONE" && d.dueDate === null);
53
- },
54
- "Completed tasks must have a due date",
55
- ],
44
+ .validate(({ newRecord }, issues) => {
45
+ if (newRecord.status === "DONE" && !newRecord.dueDate) {
46
+ issues("status", "Completed tasks must have a due date");
47
+ }
56
48
  })
57
49
  .permission(rolePermission)
58
50
  .gqlPermission(roleGqlPermission);
@@ -2,7 +2,7 @@ import { db } from "@tailor-platform/sdk";
2
2
  import { allPermission, allGqlPermission } from "./permission";
3
3
 
4
4
  export const user = db
5
- .type("User", {
5
+ .table("User", {
6
6
  name: db.string(),
7
7
  email: db.string().unique(),
8
8
  role: db.enum([
@@ -32,7 +32,7 @@ export interface Namespace {
32
32
  isInternal: boolean;
33
33
  }>;
34
34
  createdAt: Generated<Timestamp>;
35
- updatedAt: Timestamp | null;
35
+ updatedAt: Generated<Timestamp>;
36
36
  }
37
37
 
38
38
  Task: {
@@ -46,7 +46,7 @@ export interface Namespace {
46
46
  categoryId: string | null;
47
47
  isArchived: Generated<boolean>;
48
48
  createdAt: Generated<Timestamp>;
49
- updatedAt: Timestamp | null;
49
+ updatedAt: Generated<Timestamp>;
50
50
  }
51
51
 
52
52
  User: {
@@ -56,7 +56,7 @@ export interface Namespace {
56
56
  role: "ADMIN" | "MEMBER" | "VIEWER";
57
57
  bio: string | null;
58
58
  createdAt: Generated<Timestamp>;
59
- updatedAt: Timestamp | null;
59
+ updatedAt: Generated<Timestamp>;
60
60
  }
61
61
  }
62
62
  }
@@ -1,9 +1,9 @@
1
1
  // This file is auto-generated by @tailor-platform/sdk
2
2
  // Do not edit this file manually
3
- // Regenerated automatically when running 'tailor-sdk deploy' or 'tailor-sdk generate'
3
+ // Regenerated automatically when running 'tailor deploy' or 'tailor generate'
4
4
 
5
5
  declare module "@tailor-platform/sdk" {
6
- interface AttributeMap {
6
+ interface Attributes {
7
7
  role: string;
8
8
  }
9
9
  interface AttributeList {
@@ -15,6 +15,8 @@ declare module "@tailor-platform/sdk" {
15
15
  viewer: true;
16
16
  }
17
17
  interface IdpNameRegistry {}
18
+ interface ConnectionNameRegistry {}
19
+ interface AIGatewayNameRegistry {}
18
20
  }
19
21
 
20
22
  export {};
@@ -1,14 +1,22 @@
1
1
  {
2
2
  "$schema": "./node_modules/oxlint/configuration_schema.json",
3
3
  "plugins": ["typescript"],
4
+ "jsPlugins": [
5
+ {
6
+ "name": "tailor-sdk",
7
+ "specifier": "@tailor-platform/eslint-plugin-sdk"
8
+ }
9
+ ],
4
10
  "categories": {
5
11
  "correctness": "error"
6
12
  },
7
13
  "env": {
8
14
  "builtin": true
9
15
  },
10
- "ignorePatterns": [".tailor-sdk/", "src/generated/", "tailor.d.ts"],
16
+ "ignorePatterns": [".tailor/", "src/generated/", "tailor.d.ts"],
11
17
  "rules": {
18
+ "tailor-sdk/no-api-prefix-in-path-pattern": "warn",
19
+ "tailor-sdk/no-unconditional-permit": "warn",
12
20
  "no-case-declarations": "error",
13
21
  "no-empty": "error",
14
22
  "no-fallthrough": "error",
@@ -1,11 +1,11 @@
1
1
  # Workflow Template
2
2
 
3
- Demonstrates workflow patterns with job chaining, trigger testing, and dependency injection.
3
+ Demonstrates workflow patterns with job chaining, start testing, and dependency injection.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - Workflow with multiple jobs (`createWorkflow`, `createWorkflowJob`)
8
- - Job chaining via `.trigger()`
8
+ - Job chaining via `.start()`
9
9
  - Database operations in workflow jobs (DI pattern)
10
10
  - Integration testing with `runWorkflowLocally()`
11
11
 
@@ -1,2 +1,2 @@
1
1
  node_modules/
2
- .tailor-sdk/
2
+ .tailor/
@@ -55,7 +55,7 @@ export async function setup(project: TestProject): Promise<void> {
55
55
  process.env.TAILOR_PLATFORM_WORKSPACE_ID = createdWorkspace.id;
56
56
  // This pipeline deploys a fresh app into a per-run workspace, so let the
57
57
  // SDK inject a missing app id even in CI (normally a hard error there).
58
- process.env.TAILOR_PLATFORM_SDK_ALLOW_CI_ID_INJECTION = "true";
58
+ process.env.TAILOR_CI_ALLOW_ID_INJECTION = "true";
59
59
  await deployApplication();
60
60
  }
61
61
 
@@ -10,7 +10,7 @@ describe("workflow", () => {
10
10
 
11
11
  const { executionId, wait } = await startWorkflow({
12
12
  workflow: userProfileSyncWorkflow,
13
- authInvoker: "admin",
13
+ invoker: "admin",
14
14
  arg: {
15
15
  name: "workflow-test-user",
16
16
  email: testEmail,