@salesforce/webapp-template-feature-graphql-experimental 1.33.2 → 1.33.4

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/dist/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.33.4](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.33.3...v1.33.4) (2026-02-17)
7
+
8
+ **Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.33.3](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.33.2...v1.33.3) (2026-02-17)
15
+
16
+ **Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
17
+
18
+
19
+
20
+
21
+
6
22
  ## [1.33.2](https://github.com/salesforce-experience-platform-emu/webapps/compare/v1.33.1...v1.33.2) (2026-02-17)
7
23
 
8
24
  **Note:** Version bump only for package @salesforce/webapp-template-base-sfdx-project-experimental
@@ -8,7 +8,7 @@
8
8
  "name": "base-react-app",
9
9
  "version": "1.0.0",
10
10
  "dependencies": {
11
- "@salesforce/sdk-data": "^1.33.1",
11
+ "@salesforce/sdk-data": "^1.33.3",
12
12
  "@salesforce/webapp-experimental": "*",
13
13
  "@tailwindcss/vite": "^4.1.17",
14
14
  "react": "^19.2.0",
@@ -3689,19 +3689,19 @@
3689
3689
  }
3690
3690
  },
3691
3691
  "node_modules/@salesforce/sdk-core": {
3692
- "version": "1.33.1",
3693
- "resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.33.1.tgz",
3694
- "integrity": "sha512-gaod4EPVKiKVR3PoRwlgXSTikNhA/uwUmGq6+EzFx1vfPOzMQMTnKz8RfUfDg1M+6H00OSDqtoSwxXWkBS4Asw==",
3692
+ "version": "1.33.3",
3693
+ "resolved": "https://registry.npmjs.org/@salesforce/sdk-core/-/sdk-core-1.33.3.tgz",
3694
+ "integrity": "sha512-siFvEnv1gLXSh1UZjl7QCqvfyYmJc/XkXZ5Pho0K48324cGDL94dkIxWnHSn9HqeAprB7dR2GR/TjuPekyN56A==",
3695
3695
  "license": "SEE LICENSE IN LICENSE.txt"
3696
3696
  },
3697
3697
  "node_modules/@salesforce/sdk-data": {
3698
- "version": "1.33.1",
3699
- "resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.33.1.tgz",
3700
- "integrity": "sha512-+PhRvT9fbXPCMy6P/nxBlPNQo3lt00Iir3XkmNUF683e2sFm9VtY/5ejFjOzpU3ohwBdPw4XPV3aEW+S+3SHVQ==",
3698
+ "version": "1.33.3",
3699
+ "resolved": "https://registry.npmjs.org/@salesforce/sdk-data/-/sdk-data-1.33.3.tgz",
3700
+ "integrity": "sha512-qdwQKHmymF0smw+kQ0a5VvhnvrFolPmzFA1OmwNEqZcJyqjvs+5ktxQhGEgsDfYWFqqlPulQtDIW8ckjnyu/8g==",
3701
3701
  "license": "SEE LICENSE IN LICENSE.txt",
3702
3702
  "dependencies": {
3703
3703
  "@conduit-client/salesforce-lightning-service-worker": "^3.7.0",
3704
- "@salesforce/sdk-core": "^1.33.1"
3704
+ "@salesforce/sdk-core": "^1.33.3"
3705
3705
  }
3706
3706
  },
3707
3707
  "node_modules/@salesforce/ts-types": {
@@ -12,7 +12,7 @@
12
12
  "test": "vitest"
13
13
  },
14
14
  "dependencies": {
15
- "@salesforce/sdk-data": "^1.33.1",
15
+ "@salesforce/sdk-data": "^1.33.3",
16
16
  "@salesforce/webapp-experimental": "*",
17
17
  "@tailwindcss/vite": "^4.1.17",
18
18
  "react": "^19.2.0",
@@ -116,9 +116,3 @@ export type GetHighRevenueAccountsQuery = {
116
116
  };
117
117
  };
118
118
  };
119
-
120
- export type CurrentUserQueryVariables = Exact<{ [key: string]: never }>;
121
-
122
- export type CurrentUserQuery = {
123
- uiapi: { currentUser?: { Id: string; Name?: { value?: string | null } | null } | null };
124
- };
@@ -1,20 +1,13 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import { getCurrentUser } from "./user";
3
- import { executeGraphQL } from "../graphql";
4
-
5
- vi.mock("../graphql", async () => {
6
- return {
7
- gql: vi.fn((strings: TemplateStringsArray, ...values: unknown[]) => {
8
- return strings.reduce((prev, curr, i) => {
9
- return prev + curr + (values[i] ?? "");
10
- }, "");
11
- }),
12
- executeGraphQL: vi.fn(),
13
- };
14
- });
3
+ import { createDataSDK } from "@salesforce/sdk-data";
4
+
5
+ vi.mock("@salesforce/sdk-data", () => ({
6
+ createDataSDK: vi.fn(),
7
+ }));
15
8
 
16
- // Get reference to the mocked function for assertions
17
- const mockGraphql = vi.mocked(executeGraphQL);
9
+ const mockFetch = vi.fn();
10
+ const mockSDK = { fetch: mockFetch };
18
11
 
19
12
  // Mock console.error to avoid noise in test output
20
13
  const mockConsoleError = vi.spyOn(console, "error").mockImplementation(() => {});
@@ -22,6 +15,7 @@ const mockConsoleError = vi.spyOn(console, "error").mockImplementation(() => {})
22
15
  describe("User API Utils", () => {
23
16
  beforeEach(() => {
24
17
  vi.clearAllMocks();
18
+ vi.mocked(createDataSDK).mockResolvedValue(mockSDK);
25
19
  });
26
20
 
27
21
  afterEach(() => {
@@ -29,21 +23,22 @@ describe("User API Utils", () => {
29
23
  });
30
24
 
31
25
  describe("getCurrentUser", () => {
32
- const mockResponse = {
33
- uiapi: {
34
- currentUser: {
35
- Id: "005000000000001",
36
- Name: { value: "John Doe" },
37
- },
38
- },
39
- } as any;
26
+ const mockChatterUser = {
27
+ id: "005000000000001",
28
+ name: "John Doe",
29
+ email: "john@example.com",
30
+ username: "john@example.com",
31
+ };
40
32
 
41
33
  it("successfully fetches current user", async () => {
42
- mockGraphql.mockResolvedValue(mockResponse);
34
+ mockFetch.mockResolvedValue({
35
+ ok: true,
36
+ json: () => Promise.resolve(mockChatterUser),
37
+ });
43
38
 
44
39
  const result = await getCurrentUser();
45
40
 
46
- expect(mockGraphql).toHaveBeenCalledWith(expect.any(String));
41
+ expect(mockFetch).toHaveBeenCalledWith("/services/data/v65.0/chatter/users/me");
47
42
  expect(result).toEqual({
48
43
  id: "005000000000001",
49
44
  name: "John Doe",
@@ -51,14 +46,14 @@ describe("User API Utils", () => {
51
46
  });
52
47
 
53
48
  it('falls back to "User" when name is empty', async () => {
54
- mockGraphql.mockResolvedValue({
55
- uiapi: {
56
- currentUser: {
57
- Id: "005000000000003",
58
- Name: { value: "" },
59
- },
60
- },
61
- } as any);
49
+ mockFetch.mockResolvedValue({
50
+ ok: true,
51
+ json: () =>
52
+ Promise.resolve({
53
+ id: "005000000000003",
54
+ name: "",
55
+ }),
56
+ });
62
57
 
63
58
  const result = await getCurrentUser();
64
59
 
@@ -69,14 +64,14 @@ describe("User API Utils", () => {
69
64
  });
70
65
 
71
66
  it('falls back to "User" when name is null', async () => {
72
- mockGraphql.mockResolvedValue({
73
- uiapi: {
74
- currentUser: {
75
- Id: "005000000000004",
76
- Name: { value: null },
77
- },
78
- },
79
- } as any);
67
+ mockFetch.mockResolvedValue({
68
+ ok: true,
69
+ json: () =>
70
+ Promise.resolve({
71
+ id: "005000000000004",
72
+ name: null,
73
+ }),
74
+ });
80
75
 
81
76
  const result = await getCurrentUser();
82
77
 
@@ -87,14 +82,13 @@ describe("User API Utils", () => {
87
82
  });
88
83
 
89
84
  it('falls back to "User" when name is undefined', async () => {
90
- mockGraphql.mockResolvedValue({
91
- uiapi: {
92
- currentUser: {
93
- Id: "005000000000005",
94
- Name: { value: undefined },
95
- },
96
- },
97
- } as any);
85
+ mockFetch.mockResolvedValue({
86
+ ok: true,
87
+ json: () =>
88
+ Promise.resolve({
89
+ id: "005000000000005",
90
+ }),
91
+ });
98
92
 
99
93
  const result = await getCurrentUser();
100
94
 
@@ -105,20 +99,31 @@ describe("User API Utils", () => {
105
99
  });
106
100
 
107
101
  it("throws error when request fails", async () => {
108
- const apiError = new Error("Bad stuff");
109
- mockGraphql.mockRejectedValue(apiError);
102
+ mockFetch.mockResolvedValue({
103
+ ok: false,
104
+ status: 500,
105
+ });
110
106
 
111
- await expect(getCurrentUser()).rejects.toThrow("Bad stuff");
112
- expect(mockConsoleError).toHaveBeenCalledWith("Error fetching user data:", apiError);
107
+ await expect(getCurrentUser()).rejects.toThrow("HTTP 500");
108
+ expect(mockConsoleError).toHaveBeenCalled();
113
109
  });
114
110
 
115
111
  it("throws error when no user data is found", async () => {
116
- mockGraphql.mockResolvedValue({
117
- uiapi: {},
118
- } as any);
112
+ mockFetch.mockResolvedValue({
113
+ ok: true,
114
+ json: () => Promise.resolve({}),
115
+ });
119
116
 
120
- await expect(getCurrentUser()).rejects.toThrow("No user data found");
117
+ await expect(getCurrentUser()).rejects.toThrow("No user data found in Chatter API response");
121
118
  expect(mockConsoleError).toHaveBeenCalled();
122
119
  });
120
+
121
+ it("throws error when fetch rejects", async () => {
122
+ const apiError = new Error("Network error");
123
+ mockFetch.mockRejectedValue(apiError);
124
+
125
+ await expect(getCurrentUser()).rejects.toThrow("Network error");
126
+ expect(mockConsoleError).toHaveBeenCalledWith("Error fetching user data:", apiError);
127
+ });
123
128
  });
124
129
  });
@@ -1,23 +1,26 @@
1
- import { executeGraphQL, gql } from "../graphql";
2
- import { type CurrentUserQuery } from "../graphql-operations-types";
1
+ import { createDataSDK, type DataSDK } from "@salesforce/sdk-data";
3
2
 
4
3
  interface User {
5
4
  id: string;
6
5
  name: string;
7
6
  }
8
7
 
9
- const CURRENT_USER_QUERY = gql`
10
- query CurrentUser {
11
- uiapi {
12
- currentUser {
13
- Id
14
- Name {
15
- value
16
- }
17
- }
18
- }
8
+ interface ChatterUser {
9
+ id: string;
10
+ name: string;
11
+ email?: string;
12
+ username?: string;
13
+ }
14
+
15
+ // Lazy-initialized SDK instance
16
+ let sdkInstance: DataSDK | null = null;
17
+
18
+ async function getSDK(): Promise<DataSDK> {
19
+ if (!sdkInstance) {
20
+ sdkInstance = await createDataSDK();
19
21
  }
20
- `;
22
+ return sdkInstance;
23
+ }
21
24
 
22
25
  /**
23
26
  * Fetch current user information from Salesforce
@@ -26,17 +29,22 @@ const CURRENT_USER_QUERY = gql`
26
29
  */
27
30
  export async function getCurrentUser(): Promise<User | null> {
28
31
  try {
29
- const response = await executeGraphQL<CurrentUserQuery>(CURRENT_USER_QUERY);
32
+ const sdk = await getSDK();
33
+ const response = await sdk.fetch!("/services/data/v65.0/chatter/users/me");
34
+
35
+ if (!response.ok) {
36
+ throw new Error(`HTTP ${response.status}`);
37
+ }
30
38
 
31
- const userData = response.uiapi.currentUser;
39
+ const userData: ChatterUser = await response.json();
32
40
 
33
- if (!userData) {
34
- throw new Error("No user data found");
41
+ if (!userData || !userData.id) {
42
+ throw new Error("No user data found in Chatter API response");
35
43
  }
36
44
 
37
45
  return {
38
- id: userData.Id,
39
- name: userData.Name?.value || "User",
46
+ id: userData.id,
47
+ name: userData.name || "User",
40
48
  };
41
49
  } catch (error) {
42
50
  console.error("Error fetching user data:", error);
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/webapp-template-base-sfdx-project-experimental",
3
- "version": "1.33.2",
3
+ "version": "1.33.4",
4
4
  "description": "Base SFDX project template",
5
5
  "private": true,
6
6
  "files": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/webapp-template-feature-graphql-experimental",
3
- "version": "1.33.2",
3
+ "version": "1.33.4",
4
4
  "description": "GraphQL data access feature with executeGraphQL utilities, codegen tooling, agent skills, and rules",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "author": "",
@@ -33,8 +33,8 @@
33
33
  "@graphql-codegen/cli": "^6.1.0",
34
34
  "@graphql-codegen/typescript": "^5.0.6",
35
35
  "@graphql-codegen/typescript-operations": "^5.0.6",
36
- "@salesforce/sdk-data": "^1.33.2",
37
- "@salesforce/webapp-experimental": "^1.33.2",
36
+ "@salesforce/sdk-data": "^1.33.4",
37
+ "@salesforce/webapp-experimental": "^1.33.4",
38
38
  "@types/react": "^19.2.7",
39
39
  "@types/react-dom": "^19.2.3",
40
40
  "graphql": "^16.11.0",
@@ -44,5 +44,5 @@
44
44
  "vite": "^7.3.1",
45
45
  "vite-plugin-graphql-codegen": "^3.6.3"
46
46
  },
47
- "gitHead": "bb8bb09df420bd823e210e09cf45a4bd8a4c4922"
47
+ "gitHead": "eeddfb5c8c8d44e2096b3196ca2ee902129e5655"
48
48
  }
@@ -116,9 +116,3 @@ export type GetHighRevenueAccountsQuery = {
116
116
  };
117
117
  };
118
118
  };
119
-
120
- export type CurrentUserQueryVariables = Exact<{ [key: string]: never }>;
121
-
122
- export type CurrentUserQuery = {
123
- uiapi: { currentUser?: { Id: string; Name?: { value?: string | null } | null } | null };
124
- };
@@ -1,20 +1,13 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
2
  import { getCurrentUser } from "./user";
3
- import { executeGraphQL } from "../graphql";
4
-
5
- vi.mock("../graphql", async () => {
6
- return {
7
- gql: vi.fn((strings: TemplateStringsArray, ...values: unknown[]) => {
8
- return strings.reduce((prev, curr, i) => {
9
- return prev + curr + (values[i] ?? "");
10
- }, "");
11
- }),
12
- executeGraphQL: vi.fn(),
13
- };
14
- });
3
+ import { createDataSDK } from "@salesforce/sdk-data";
4
+
5
+ vi.mock("@salesforce/sdk-data", () => ({
6
+ createDataSDK: vi.fn(),
7
+ }));
15
8
 
16
- // Get reference to the mocked function for assertions
17
- const mockGraphql = vi.mocked(executeGraphQL);
9
+ const mockFetch = vi.fn();
10
+ const mockSDK = { fetch: mockFetch };
18
11
 
19
12
  // Mock console.error to avoid noise in test output
20
13
  const mockConsoleError = vi.spyOn(console, "error").mockImplementation(() => {});
@@ -22,6 +15,7 @@ const mockConsoleError = vi.spyOn(console, "error").mockImplementation(() => {})
22
15
  describe("User API Utils", () => {
23
16
  beforeEach(() => {
24
17
  vi.clearAllMocks();
18
+ vi.mocked(createDataSDK).mockResolvedValue(mockSDK);
25
19
  });
26
20
 
27
21
  afterEach(() => {
@@ -29,21 +23,22 @@ describe("User API Utils", () => {
29
23
  });
30
24
 
31
25
  describe("getCurrentUser", () => {
32
- const mockResponse = {
33
- uiapi: {
34
- currentUser: {
35
- Id: "005000000000001",
36
- Name: { value: "John Doe" },
37
- },
38
- },
39
- } as any;
26
+ const mockChatterUser = {
27
+ id: "005000000000001",
28
+ name: "John Doe",
29
+ email: "john@example.com",
30
+ username: "john@example.com",
31
+ };
40
32
 
41
33
  it("successfully fetches current user", async () => {
42
- mockGraphql.mockResolvedValue(mockResponse);
34
+ mockFetch.mockResolvedValue({
35
+ ok: true,
36
+ json: () => Promise.resolve(mockChatterUser),
37
+ });
43
38
 
44
39
  const result = await getCurrentUser();
45
40
 
46
- expect(mockGraphql).toHaveBeenCalledWith(expect.any(String));
41
+ expect(mockFetch).toHaveBeenCalledWith("/services/data/v65.0/chatter/users/me");
47
42
  expect(result).toEqual({
48
43
  id: "005000000000001",
49
44
  name: "John Doe",
@@ -51,14 +46,14 @@ describe("User API Utils", () => {
51
46
  });
52
47
 
53
48
  it('falls back to "User" when name is empty', async () => {
54
- mockGraphql.mockResolvedValue({
55
- uiapi: {
56
- currentUser: {
57
- Id: "005000000000003",
58
- Name: { value: "" },
59
- },
60
- },
61
- } as any);
49
+ mockFetch.mockResolvedValue({
50
+ ok: true,
51
+ json: () =>
52
+ Promise.resolve({
53
+ id: "005000000000003",
54
+ name: "",
55
+ }),
56
+ });
62
57
 
63
58
  const result = await getCurrentUser();
64
59
 
@@ -69,14 +64,14 @@ describe("User API Utils", () => {
69
64
  });
70
65
 
71
66
  it('falls back to "User" when name is null', async () => {
72
- mockGraphql.mockResolvedValue({
73
- uiapi: {
74
- currentUser: {
75
- Id: "005000000000004",
76
- Name: { value: null },
77
- },
78
- },
79
- } as any);
67
+ mockFetch.mockResolvedValue({
68
+ ok: true,
69
+ json: () =>
70
+ Promise.resolve({
71
+ id: "005000000000004",
72
+ name: null,
73
+ }),
74
+ });
80
75
 
81
76
  const result = await getCurrentUser();
82
77
 
@@ -87,14 +82,13 @@ describe("User API Utils", () => {
87
82
  });
88
83
 
89
84
  it('falls back to "User" when name is undefined', async () => {
90
- mockGraphql.mockResolvedValue({
91
- uiapi: {
92
- currentUser: {
93
- Id: "005000000000005",
94
- Name: { value: undefined },
95
- },
96
- },
97
- } as any);
85
+ mockFetch.mockResolvedValue({
86
+ ok: true,
87
+ json: () =>
88
+ Promise.resolve({
89
+ id: "005000000000005",
90
+ }),
91
+ });
98
92
 
99
93
  const result = await getCurrentUser();
100
94
 
@@ -105,20 +99,31 @@ describe("User API Utils", () => {
105
99
  });
106
100
 
107
101
  it("throws error when request fails", async () => {
108
- const apiError = new Error("Bad stuff");
109
- mockGraphql.mockRejectedValue(apiError);
102
+ mockFetch.mockResolvedValue({
103
+ ok: false,
104
+ status: 500,
105
+ });
110
106
 
111
- await expect(getCurrentUser()).rejects.toThrow("Bad stuff");
112
- expect(mockConsoleError).toHaveBeenCalledWith("Error fetching user data:", apiError);
107
+ await expect(getCurrentUser()).rejects.toThrow("HTTP 500");
108
+ expect(mockConsoleError).toHaveBeenCalled();
113
109
  });
114
110
 
115
111
  it("throws error when no user data is found", async () => {
116
- mockGraphql.mockResolvedValue({
117
- uiapi: {},
118
- } as any);
112
+ mockFetch.mockResolvedValue({
113
+ ok: true,
114
+ json: () => Promise.resolve({}),
115
+ });
119
116
 
120
- await expect(getCurrentUser()).rejects.toThrow("No user data found");
117
+ await expect(getCurrentUser()).rejects.toThrow("No user data found in Chatter API response");
121
118
  expect(mockConsoleError).toHaveBeenCalled();
122
119
  });
120
+
121
+ it("throws error when fetch rejects", async () => {
122
+ const apiError = new Error("Network error");
123
+ mockFetch.mockRejectedValue(apiError);
124
+
125
+ await expect(getCurrentUser()).rejects.toThrow("Network error");
126
+ expect(mockConsoleError).toHaveBeenCalledWith("Error fetching user data:", apiError);
127
+ });
123
128
  });
124
129
  });
@@ -1,23 +1,26 @@
1
- import { executeGraphQL, gql } from "../graphql";
2
- import { type CurrentUserQuery } from "../graphql-operations-types";
1
+ import { createDataSDK, type DataSDK } from "@salesforce/sdk-data";
3
2
 
4
3
  interface User {
5
4
  id: string;
6
5
  name: string;
7
6
  }
8
7
 
9
- const CURRENT_USER_QUERY = gql`
10
- query CurrentUser {
11
- uiapi {
12
- currentUser {
13
- Id
14
- Name {
15
- value
16
- }
17
- }
18
- }
8
+ interface ChatterUser {
9
+ id: string;
10
+ name: string;
11
+ email?: string;
12
+ username?: string;
13
+ }
14
+
15
+ // Lazy-initialized SDK instance
16
+ let sdkInstance: DataSDK | null = null;
17
+
18
+ async function getSDK(): Promise<DataSDK> {
19
+ if (!sdkInstance) {
20
+ sdkInstance = await createDataSDK();
19
21
  }
20
- `;
22
+ return sdkInstance;
23
+ }
21
24
 
22
25
  /**
23
26
  * Fetch current user information from Salesforce
@@ -26,17 +29,22 @@ const CURRENT_USER_QUERY = gql`
26
29
  */
27
30
  export async function getCurrentUser(): Promise<User | null> {
28
31
  try {
29
- const response = await executeGraphQL<CurrentUserQuery>(CURRENT_USER_QUERY);
32
+ const sdk = await getSDK();
33
+ const response = await sdk.fetch!("/services/data/v65.0/chatter/users/me");
34
+
35
+ if (!response.ok) {
36
+ throw new Error(`HTTP ${response.status}`);
37
+ }
30
38
 
31
- const userData = response.uiapi.currentUser;
39
+ const userData: ChatterUser = await response.json();
32
40
 
33
- if (!userData) {
34
- throw new Error("No user data found");
41
+ if (!userData || !userData.id) {
42
+ throw new Error("No user data found in Chatter API response");
35
43
  }
36
44
 
37
45
  return {
38
- id: userData.Id,
39
- name: userData.Name?.value || "User",
46
+ id: userData.id,
47
+ name: userData.name || "User",
40
48
  };
41
49
  } catch (error) {
42
50
  console.error("Error fetching user data:", error);