@tailor-platform/create-sdk 2.0.0-next.1 → 2.0.0-next.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/package.json +2 -2
  3. package/templates/executor/package.json +2 -2
  4. package/templates/executor/src/generated/db.ts +3 -3
  5. package/templates/generators/package.json +2 -2
  6. package/templates/generators/src/generated/db.ts +3 -3
  7. package/templates/generators/src/generated/files.ts +4 -4
  8. package/templates/generators/src/resolver/getProduct.test.ts +4 -3
  9. package/templates/generators/src/seed/data/Order.schema.ts +2 -2
  10. package/templates/generators/src/seed/data/Product.schema.ts +2 -2
  11. package/templates/generators/src/seed/data/User.schema.ts +2 -2
  12. package/templates/generators/src/seed/exec.mjs +1 -1
  13. package/templates/hello-world/package.json +2 -2
  14. package/templates/hello-world/src/generated/kysely-tailordb.ts +1 -1
  15. package/templates/inventory-management/package.json +2 -2
  16. package/templates/inventory-management/src/executor/checkInventory.ts +1 -1
  17. package/templates/inventory-management/src/generated/kysely-tailordb.ts +8 -8
  18. package/templates/inventory-management/src/resolver/registerOrder.ts +2 -2
  19. package/templates/multi-application/apps/admin/db/adminNote.ts +1 -1
  20. package/templates/multi-application/package.json +2 -2
  21. package/templates/resolver/README.md +2 -2
  22. package/templates/resolver/package.json +2 -2
  23. package/templates/resolver/src/generated/db.ts +1 -1
  24. package/templates/resolver/src/resolver/add.test.ts +4 -3
  25. package/templates/resolver/src/resolver/incrementUserAge.test.ts +4 -3
  26. package/templates/resolver/src/resolver/showEnv.test.ts +2 -2
  27. package/templates/resolver/src/resolver/showUserInfo.test.ts +12 -9
  28. package/templates/resolver/src/resolver/showUserInfo.ts +3 -3
  29. package/templates/resolver/src/resolver/upsertUsers.test.ts +2 -2
  30. package/templates/static-web-site/package.json +2 -2
  31. package/templates/tailordb/package.json +2 -2
  32. package/templates/tailordb/src/generated/db.ts +3 -3
  33. package/templates/workflow/e2e/workflow.test.ts +1 -1
  34. package/templates/workflow/package.json +2 -2
  35. package/templates/workflow/src/generated/db.ts +2 -2
  36. package/templates/workflow/src/resolver/resolveApproval.test.ts +4 -3
  37. package/templates/workflow/src/workflow/approval.test.ts +8 -2
  38. package/templates/workflow/src/workflow/order-fulfillment.test.ts +20 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @tailor-platform/create-sdk
2
2
 
3
+ ## 2.0.0-next.2
4
+ ### Major Changes
5
+
6
+
7
+
8
+ - [#1498](https://github.com/tailor-platform/sdk/pull/1498) [`83145db`](https://github.com/tailor-platform/sdk/commit/83145db9a0d243aa68c1b641c2b6026771a62188) Thanks [@dqn](https://github.com/dqn)! - Set `db.fields.timestamps()` `updatedAt` when records are created and make the generated field non-null. `createdAt` keeps its existing create-time behavior, while `updatedAt` keeps its update-time behavior and now also gets a create hook that preserves provided values and falls back to the current time.
9
+
10
+ Update create-sdk templates so scaffolded projects use the new non-null `updatedAt` Kysely types and seed schemas.
11
+
12
+ Existing TailorDB schemas that already use this helper will change `updatedAt` from optional to required. Backfill existing records that have `updatedAt: null` before applying the schema change.
13
+
14
+ ### Patch Changes
15
+
16
+
17
+
18
+ - [#1509](https://github.com/tailor-platform/sdk/pull/1509) [`7cadaa7`](https://github.com/tailor-platform/sdk/commit/7cadaa7c4987b81130ca80ba80bc5d5b26276394) Thanks [@dqn](https://github.com/dqn)! - Rename resolver, executor, workflow trigger, and typed workflow start machine-user options from `authInvoker` to `invoker`.
19
+
20
+ Update create-sdk templates and the v2 auth invoker codemod to generate the new `invoker` option.
21
+
22
+
23
+ - [#1484](https://github.com/tailor-platform/sdk/pull/1484) [`a376dc8`](https://github.com/tailor-platform/sdk/commit/a376dc8cd053d20744c90104e8b44ed2729ffe8c) Thanks [@dqn](https://github.com/dqn)! - Remove the deprecated `openDownloadStream` file streaming API. Use `downloadStream` for streamed file downloads.
24
+
25
+ The generated file utilities now emit `downloadFileStream`, which calls `downloadStream` and returns `FileDownloadStreamResponse`, instead of the removed `openFileDownloadStream` helper.
26
+
3
27
  ## 2.0.0-next.1
4
28
 
5
29
  ## 2.0.0-next.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/create-sdk",
3
- "version": "2.0.0-next.1",
3
+ "version": "2.0.0-next.2",
4
4
  "description": "A CLI tool to quickly create a new Tailor Platform SDK project",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -29,7 +29,7 @@
29
29
  "oxlint": "1.69.0",
30
30
  "oxlint-tsgolint": "0.23.0",
31
31
  "tsdown": "0.22.2",
32
- "typescript": "5.9.3"
32
+ "typescript": "6.0.3"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "tsdown",
@@ -14,12 +14,12 @@
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
16
16
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
17
+ "@tailor-platform/sdk": "2.0.0-next.2",
18
18
  "@types/node": "24.13.2",
19
19
  "oxfmt": "0.54.0",
20
20
  "oxlint": "1.69.0",
21
21
  "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
22
+ "typescript": "6.0.3",
23
23
  "vitest": "4.1.8"
24
24
  }
25
25
  }
@@ -20,7 +20,7 @@ export interface Namespace {
20
20
  entityId: string;
21
21
  message: string;
22
22
  createdAt: Generated<Timestamp>;
23
- updatedAt: Timestamp | null;
23
+ updatedAt: Generated<Timestamp>;
24
24
  }
25
25
 
26
26
  Notification: {
@@ -30,7 +30,7 @@ export interface Namespace {
30
30
  body: string;
31
31
  isRead: boolean;
32
32
  createdAt: Generated<Timestamp>;
33
- updatedAt: Timestamp | null;
33
+ updatedAt: Generated<Timestamp>;
34
34
  }
35
35
 
36
36
  User: {
@@ -39,7 +39,7 @@ export interface Namespace {
39
39
  email: string;
40
40
  role: "ADMIN" | "MEMBER";
41
41
  createdAt: Generated<Timestamp>;
42
- updatedAt: Timestamp | null;
42
+ updatedAt: Generated<Timestamp>;
43
43
  }
44
44
  }
45
45
  }
@@ -14,12 +14,12 @@
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
16
16
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
17
+ "@tailor-platform/sdk": "2.0.0-next.2",
18
18
  "@types/node": "24.13.2",
19
19
  "oxfmt": "0.54.0",
20
20
  "oxlint": "1.69.0",
21
21
  "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
22
+ "typescript": "6.0.3",
23
23
  "vitest": "4.1.8"
24
24
  }
25
25
  }
@@ -28,7 +28,7 @@ export interface Namespace {
28
28
  totalPrice: number;
29
29
  status: "PENDING" | "CONFIRMED" | "SHIPPED" | "DELIVERED" | "CANCELLED";
30
30
  createdAt: Generated<Timestamp>;
31
- updatedAt: Timestamp | null;
31
+ updatedAt: Generated<Timestamp>;
32
32
  }
33
33
 
34
34
  Product: {
@@ -39,7 +39,7 @@ export interface Namespace {
39
39
  status: "DRAFT" | "ACTIVE" | "DISCONTINUED";
40
40
  categoryId: string | null;
41
41
  createdAt: Generated<Timestamp>;
42
- updatedAt: Timestamp | null;
42
+ updatedAt: Generated<Timestamp>;
43
43
  }
44
44
 
45
45
  User: {
@@ -48,7 +48,7 @@ export interface Namespace {
48
48
  email: string;
49
49
  role: "ADMIN" | "MEMBER" | "VIEWER";
50
50
  createdAt: Generated<Timestamp>;
51
- updatedAt: Timestamp | null;
51
+ updatedAt: Generated<Timestamp>;
52
52
  }
53
53
  }
54
54
  }
@@ -3,7 +3,7 @@ import type {
3
3
  FileUploadOptions,
4
4
  FileUploadResponse,
5
5
  FileMetadata,
6
- FileStreamIterator,
6
+ FileDownloadStreamResponse,
7
7
  } from "@tailor-platform/sdk/runtime/file";
8
8
 
9
9
  export interface TypeWithFiles {
@@ -50,10 +50,10 @@ export async function getFileMetadata<T extends keyof TypeWithFiles>(
50
50
  return await file.getMetadata(namespaces[type], type, field, recordId);
51
51
  }
52
52
 
53
- export async function openFileDownloadStream<T extends keyof TypeWithFiles>(
53
+ export async function downloadFileStream<T extends keyof TypeWithFiles>(
54
54
  type: T,
55
55
  field: TypeWithFiles[T]["fields"],
56
56
  recordId: string,
57
- ): Promise<FileStreamIterator> {
58
- return await file.openDownloadStream(namespaces[type], type, field, recordId);
57
+ ): Promise<FileDownloadStreamResponse> {
58
+ return await file.downloadStream(namespaces[type], type, field, recordId);
59
59
  }
@@ -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 "./getProduct";
@@ -22,7 +21,8 @@ describe("getProduct resolver", () => {
22
21
 
23
22
  const result = await resolver.body({
24
23
  input: { productId: "product-1" },
25
- user: unauthenticatedTailorUser,
24
+ caller: null,
25
+ invoker: null,
26
26
  env: {},
27
27
  });
28
28
 
@@ -51,7 +51,8 @@ describe("getProduct resolver", () => {
51
51
 
52
52
  const result = await resolver.body({
53
53
  input: { productId: "product-2" },
54
- user: unauthenticatedTailorUser,
54
+ caller: null,
55
+ invoker: null,
55
56
  env: {},
56
57
  });
57
58
 
@@ -4,8 +4,8 @@ import { createTailorDBHook, createStandardSchema } from "@tailor-platform/sdk/t
4
4
  import { order } from "../../db/order";
5
5
 
6
6
  const schemaType = t.object({
7
- ...order.pickFields(["id","createdAt"], { optional: true }),
8
- ...order.omitFields(["id","createdAt"]),
7
+ ...order.pickFields(["id","createdAt","updatedAt"], { optional: true }),
8
+ ...order.omitFields(["id","createdAt","updatedAt"]),
9
9
  });
10
10
 
11
11
  const hook = createTailorDBHook(order);
@@ -4,8 +4,8 @@ import { createTailorDBHook, createStandardSchema } from "@tailor-platform/sdk/t
4
4
  import { product } from "../../db/product";
5
5
 
6
6
  const schemaType = t.object({
7
- ...product.pickFields(["id","createdAt"], { optional: true }),
8
- ...product.omitFields(["id","createdAt"]),
7
+ ...product.pickFields(["id","createdAt","updatedAt"], { optional: true }),
8
+ ...product.omitFields(["id","createdAt","updatedAt"]),
9
9
  });
10
10
 
11
11
  const hook = createTailorDBHook(product);
@@ -4,8 +4,8 @@ import { createTailorDBHook, createStandardSchema } from "@tailor-platform/sdk/t
4
4
  import { user } from "../../db/user";
5
5
 
6
6
  const schemaType = t.object({
7
- ...user.pickFields(["id","createdAt"], { optional: true }),
8
- ...user.omitFields(["id","createdAt"]),
7
+ ...user.pickFields(["id","createdAt","updatedAt"], { optional: true }),
8
+ ...user.omitFields(["id","createdAt","updatedAt"]),
9
9
  });
10
10
 
11
11
  const hook = createTailorDBHook(user);
@@ -388,7 +388,7 @@ const seedViaTestExecScript = async (namespace, typesToSeed, deps, selfRefTypes)
388
388
  workspaceId,
389
389
  name: `seed-${namespace}.ts`,
390
390
  code: bundled.bundledCode,
391
- arg: JSON.stringify({ data: chunk.data, order: chunk.order, selfRefTypes }),
391
+ arg: { data: chunk.data, order: chunk.order, selfRefTypes },
392
392
  invoker: {
393
393
  namespace: authNamespace,
394
394
  machineUserName,
@@ -12,11 +12,11 @@
12
12
  "typecheck": "tsc --noEmit"
13
13
  },
14
14
  "devDependencies": {
15
- "@tailor-platform/sdk": "2.0.0-next.1",
15
+ "@tailor-platform/sdk": "2.0.0-next.2",
16
16
  "@types/node": "24.13.2",
17
17
  "oxfmt": "0.54.0",
18
18
  "oxlint": "1.69.0",
19
19
  "oxlint-tsgolint": "0.23.0",
20
- "typescript": "5.9.3"
20
+ "typescript": "6.0.3"
21
21
  }
22
22
  }
@@ -19,7 +19,7 @@ export interface Namespace {
19
19
  email: string;
20
20
  role: "MANAGER" | "STAFF";
21
21
  createdAt: Generated<Timestamp>;
22
- updatedAt: Timestamp | null;
22
+ updatedAt: Generated<Timestamp>;
23
23
  }
24
24
  }
25
25
  }
@@ -12,11 +12,11 @@
12
12
  "typecheck": "tsc --noEmit"
13
13
  },
14
14
  "devDependencies": {
15
- "@tailor-platform/sdk": "2.0.0-next.1",
15
+ "@tailor-platform/sdk": "2.0.0-next.2",
16
16
  "@types/node": "24.13.2",
17
17
  "oxfmt": "0.54.0",
18
18
  "oxlint": "1.69.0",
19
19
  "oxlint-tsgolint": "0.23.0",
20
- "typescript": "5.9.3"
20
+ "typescript": "6.0.3"
21
21
  }
22
22
  }
@@ -21,6 +21,6 @@ export default createExecutor({
21
21
  })
22
22
  .execute();
23
23
  },
24
- authInvoker: "manager",
24
+ invoker: "manager",
25
25
  },
26
26
  });
@@ -18,7 +18,7 @@ export interface Namespace {
18
18
  name: string;
19
19
  description: string | null;
20
20
  createdAt: Generated<Timestamp>;
21
- updatedAt: Timestamp | null;
21
+ updatedAt: Generated<Timestamp>;
22
22
  }
23
23
 
24
24
  Contact: {
@@ -28,7 +28,7 @@ export interface Namespace {
28
28
  phone: string | null;
29
29
  address: string | null;
30
30
  createdAt: Generated<Timestamp>;
31
- updatedAt: Timestamp | null;
31
+ updatedAt: Generated<Timestamp>;
32
32
  }
33
33
 
34
34
  Inventory: {
@@ -36,14 +36,14 @@ export interface Namespace {
36
36
  productId: string;
37
37
  quantity: number;
38
38
  createdAt: Generated<Timestamp>;
39
- updatedAt: Timestamp | null;
39
+ updatedAt: Generated<Timestamp>;
40
40
  }
41
41
 
42
42
  Notification: {
43
43
  id: Generated<string>;
44
44
  message: string;
45
45
  createdAt: Generated<Timestamp>;
46
- updatedAt: Timestamp | null;
46
+ updatedAt: Generated<Timestamp>;
47
47
  }
48
48
 
49
49
  Order: {
@@ -54,7 +54,7 @@ export interface Namespace {
54
54
  orderType: "PURCHASE" | "SALES";
55
55
  contactId: string;
56
56
  createdAt: Generated<Timestamp>;
57
- updatedAt: Timestamp | null;
57
+ updatedAt: Generated<Timestamp>;
58
58
  }
59
59
 
60
60
  OrderItem: {
@@ -65,7 +65,7 @@ export interface Namespace {
65
65
  unitPrice: number;
66
66
  totalPrice: Generated<number | null>;
67
67
  createdAt: Generated<Timestamp>;
68
- updatedAt: Timestamp | null;
68
+ updatedAt: Generated<Timestamp>;
69
69
  }
70
70
 
71
71
  Product: {
@@ -74,7 +74,7 @@ export interface Namespace {
74
74
  description: string | null;
75
75
  categoryId: string;
76
76
  createdAt: Generated<Timestamp>;
77
- updatedAt: Timestamp | null;
77
+ updatedAt: Generated<Timestamp>;
78
78
  }
79
79
 
80
80
  User: {
@@ -83,7 +83,7 @@ export interface Namespace {
83
83
  email: string;
84
84
  role: "MANAGER" | "STAFF";
85
85
  createdAt: Generated<Timestamp>;
86
- updatedAt: Timestamp | null;
86
+ updatedAt: Generated<Timestamp>;
87
87
  }
88
88
  }
89
89
  }
@@ -4,8 +4,8 @@ import { orderItem } from "../db/orderItem";
4
4
  import { type DB, getDB } from "../generated/kysely-tailordb";
5
5
 
6
6
  const input = {
7
- order: t.object(order.omitFields(["id", "createdAt"])),
8
- items: t.object(orderItem.omitFields(["id", "createdAt"]), { array: true }),
7
+ order: t.object(order.omitFields(["id", "createdAt", "updatedAt"])),
8
+ items: t.object(orderItem.omitFields(["id", "createdAt", "updatedAt"]), { array: true }),
9
9
  };
10
10
  interface Input {
11
11
  order: t.infer<typeof input.order>;
@@ -8,7 +8,7 @@ export const adminNote = db
8
8
  .type("AdminNote", {
9
9
  title: db.string(),
10
10
  content: db.string(),
11
- authorId: db.uuid().hooks({ create: ({ user }) => user.id }),
11
+ authorId: db.uuid().hooks({ create: ({ invoker }) => invoker?.id ?? crypto.randomUUID() }),
12
12
  ...db.fields.timestamps(),
13
13
  })
14
14
  // NOTE: This permits all operations for simplicity.
@@ -13,11 +13,11 @@
13
13
  "typecheck": "tsc --noEmit"
14
14
  },
15
15
  "devDependencies": {
16
- "@tailor-platform/sdk": "2.0.0-next.1",
16
+ "@tailor-platform/sdk": "2.0.0-next.2",
17
17
  "@types/node": "24.13.2",
18
18
  "oxfmt": "0.54.0",
19
19
  "oxlint": "1.69.0",
20
20
  "oxlint-tsgolint": "0.23.0",
21
- "typescript": "5.9.3"
21
+ "typescript": "6.0.3"
22
22
  }
23
23
  }
@@ -8,11 +8,11 @@ Demonstrates all resolver patterns with comprehensive testing approaches.
8
8
  - Database query resolver (Kysely with transactions)
9
9
  - Database mutation resolver (dependency injection pattern)
10
10
  - Environment variable access
11
- - User context access
11
+ - Caller and invoker context access
12
12
 
13
13
  ## Testing Approaches
14
14
 
15
- 1. **Direct `body()` call** - Simple resolvers with `unauthenticatedTailorUser`
15
+ 1. **Direct `body()` call** - Simple resolvers with explicit `caller` / `invoker` context values
16
16
  2. **`tailor-runtime` environment + `mockTailordb`** - Database resolvers via `mockTailordb` from `@tailor-platform/sdk/vitest` (no `vi.stubGlobal` needed)
17
17
  3. **Dependency injection** - Extract `DbOperations` interface for testability
18
18
 
@@ -14,12 +14,12 @@
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
16
16
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
17
+ "@tailor-platform/sdk": "2.0.0-next.2",
18
18
  "@types/node": "24.13.2",
19
19
  "oxfmt": "0.54.0",
20
20
  "oxlint": "1.69.0",
21
21
  "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
22
+ "typescript": "6.0.3",
23
23
  "vitest": "4.1.8"
24
24
  }
25
25
  }
@@ -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";
@@ -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 });
@@ -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
 
@@ -12,11 +12,11 @@
12
12
  "typecheck": "tsc --noEmit"
13
13
  },
14
14
  "devDependencies": {
15
- "@tailor-platform/sdk": "2.0.0-next.1",
15
+ "@tailor-platform/sdk": "2.0.0-next.2",
16
16
  "@types/node": "24.13.2",
17
17
  "oxfmt": "0.54.0",
18
18
  "oxlint": "1.69.0",
19
19
  "oxlint-tsgolint": "0.23.0",
20
- "typescript": "5.9.3"
20
+ "typescript": "6.0.3"
21
21
  }
22
22
  }
@@ -14,12 +14,12 @@
14
14
  "typecheck": "tsc --noEmit"
15
15
  },
16
16
  "devDependencies": {
17
- "@tailor-platform/sdk": "2.0.0-next.1",
17
+ "@tailor-platform/sdk": "2.0.0-next.2",
18
18
  "@types/node": "24.13.2",
19
19
  "oxfmt": "0.54.0",
20
20
  "oxlint": "1.69.0",
21
21
  "oxlint-tsgolint": "0.23.0",
22
- "typescript": "5.9.3",
22
+ "typescript": "6.0.3",
23
23
  "vitest": "4.1.8"
24
24
  }
25
25
  }
@@ -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
  }
@@ -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,
@@ -15,14 +15,14 @@
15
15
  "typecheck": "tsc --noEmit"
16
16
  },
17
17
  "devDependencies": {
18
- "@tailor-platform/sdk": "2.0.0-next.1",
18
+ "@tailor-platform/sdk": "2.0.0-next.2",
19
19
  "@types/node": "24.13.2",
20
20
  "graphql": "16.14.2",
21
21
  "graphql-request": "7.4.0",
22
22
  "oxfmt": "0.54.0",
23
23
  "oxlint": "1.69.0",
24
24
  "oxlint-tsgolint": "0.23.0",
25
- "typescript": "5.9.3",
25
+ "typescript": "6.0.3",
26
26
  "vitest": "4.1.8"
27
27
  }
28
28
  }
@@ -19,7 +19,7 @@ export interface Namespace {
19
19
  amount: number;
20
20
  status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED";
21
21
  createdAt: Generated<Timestamp>;
22
- updatedAt: Timestamp | null;
22
+ updatedAt: Generated<Timestamp>;
23
23
  }
24
24
 
25
25
  User: {
@@ -28,7 +28,7 @@ export interface Namespace {
28
28
  email: string;
29
29
  age: number;
30
30
  createdAt: Generated<Timestamp>;
31
- updatedAt: Timestamp | null;
31
+ updatedAt: Generated<Timestamp>;
32
32
  }
33
33
  }
34
34
  }
@@ -1,6 +1,5 @@
1
1
  import { describe, expect, test } from "vitest";
2
2
  import { mockWorkflow } from "@tailor-platform/sdk/vitest";
3
- import { unauthenticatedTailorUser } from "@tailor-platform/sdk/test";
4
3
  import resolver from "./resolveApproval";
5
4
 
6
5
  describe("resolveApproval resolver", () => {
@@ -16,7 +15,8 @@ describe("resolveApproval resolver", () => {
16
15
 
17
16
  const result = await resolver.body({
18
17
  input: { executionId: "exec-1", approved: true },
19
- user: unauthenticatedTailorUser,
18
+ caller: null,
19
+ invoker: null,
20
20
  env: {},
21
21
  });
22
22
 
@@ -33,7 +33,8 @@ describe("resolveApproval resolver", () => {
33
33
 
34
34
  const result = await resolver.body({
35
35
  input: { executionId: "exec-2", approved: false },
36
- user: unauthenticatedTailorUser,
36
+ caller: null,
37
+ invoker: null,
37
38
  env: {},
38
39
  });
39
40
 
@@ -7,7 +7,10 @@ describe("approval workflow", () => {
7
7
  using wf = mockWorkflow();
8
8
  wf.setWaitHandler((_key, _payload) => ({ approved: true }));
9
9
 
10
- const result = await processWithApproval.body({ orderId: "order-1" }, { env: {} });
10
+ const result = await processWithApproval.body(
11
+ { orderId: "order-1" },
12
+ { env: {}, invoker: null },
13
+ );
11
14
 
12
15
  expect(result).toEqual({ orderId: "order-1", status: "approved" });
13
16
  expect(wf.waitCalls).toEqual([
@@ -22,7 +25,10 @@ describe("approval workflow", () => {
22
25
  using wf = mockWorkflow();
23
26
  wf.setWaitHandler({ approved: false });
24
27
 
25
- const result = await processWithApproval.body({ orderId: "order-2" }, { env: {} });
28
+ const result = await processWithApproval.body(
29
+ { orderId: "order-2" },
30
+ { env: {}, invoker: null },
31
+ );
26
32
 
27
33
  expect(result).toEqual({ orderId: "order-2", status: "rejected" });
28
34
  });
@@ -10,18 +10,24 @@ import workflow, {
10
10
  describe("order fulfillment workflow", () => {
11
11
  describe("individual job tests with .body()", () => {
12
12
  test("validateOrder accepts valid order", () => {
13
- const result = validateOrder.body({ orderId: "order-1", amount: 100 }, { env: {} });
13
+ const result = validateOrder.body(
14
+ { orderId: "order-1", amount: 100 },
15
+ { env: {}, invoker: null },
16
+ );
14
17
  expect(result).toEqual({ valid: true, orderId: "order-1" });
15
18
  });
16
19
 
17
20
  test("validateOrder rejects zero amount", () => {
18
- expect(() => validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {} })).toThrow(
19
- "Order amount must be positive",
20
- );
21
+ expect(() =>
22
+ validateOrder.body({ orderId: "order-1", amount: 0 }, { env: {}, invoker: null }),
23
+ ).toThrow("Order amount must be positive");
21
24
  });
22
25
 
23
26
  test("processPayment returns transaction", () => {
24
- const result = processPayment.body({ orderId: "order-1", amount: 100 }, { env: {} });
27
+ const result = processPayment.body(
28
+ { orderId: "order-1", amount: 100 },
29
+ { env: {}, invoker: null },
30
+ );
25
31
  expect(result).toEqual({
26
32
  transactionId: "txn-order-1",
27
33
  amount: 100,
@@ -32,7 +38,7 @@ describe("order fulfillment workflow", () => {
32
38
  test("sendConfirmation returns confirmation", () => {
33
39
  const result = sendConfirmation.body(
34
40
  { orderId: "order-1", transactionId: "txn-1" },
35
- { env: {} },
41
+ { env: {}, invoker: null },
36
42
  );
37
43
  expect(result).toEqual({
38
44
  orderId: "order-1",
@@ -59,7 +65,10 @@ describe("order fulfillment workflow", () => {
59
65
  confirmed: true,
60
66
  });
61
67
 
62
- const result = await fulfillOrder.body({ orderId: "order-1", amount: 100 }, { env: {} });
68
+ const result = await fulfillOrder.body(
69
+ { orderId: "order-1", amount: 100 },
70
+ { env: {}, invoker: null },
71
+ );
63
72
 
64
73
  expect(validateOrder.trigger).toHaveBeenCalledWith({
65
74
  orderId: "order-1",
@@ -97,7 +106,10 @@ describe("order fulfillment workflow", () => {
97
106
  confirmed: true,
98
107
  });
99
108
 
100
- const result = await workflow.mainJob.body({ orderId: "order-2", amount: 200 }, { env: {} });
109
+ const result = await workflow.mainJob.body(
110
+ { orderId: "order-2", amount: 200 },
111
+ { env: {}, invoker: null },
112
+ );
101
113
 
102
114
  expect(result).toEqual({
103
115
  orderId: "order-2",