n8n-nodes-pocketbase 2.0.0 → 2.2.0

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 (51) hide show
  1. package/README.md +19 -1
  2. package/dist/credentials/PocketbaseHttpApi.credentials.js +1 -1
  3. package/dist/credentials/PocketbaseHttpApi.credentials.js.map +1 -1
  4. package/dist/nodes/{PocketbaseHttp → Common}/GenericFunctions.d.ts +3 -2
  5. package/dist/nodes/Common/GenericFunctions.js +85 -0
  6. package/dist/nodes/Common/GenericFunctions.js.map +1 -0
  7. package/dist/nodes/{PocketbaseHttp → Common}/LoadOptions.d.ts +1 -1
  8. package/dist/nodes/{PocketbaseHttp → Common}/LoadOptions.js +47 -20
  9. package/dist/nodes/Common/LoadOptions.js.map +1 -0
  10. package/dist/nodes/{PocketbaseHttp → Common}/PocketbaseAuth.d.ts +3 -0
  11. package/dist/nodes/Common/PocketbaseAuth.js +122 -0
  12. package/dist/nodes/Common/PocketbaseAuth.js.map +1 -0
  13. package/dist/nodes/Common/RequestBodyFunctions.js +131 -0
  14. package/dist/nodes/Common/RequestBodyFunctions.js.map +1 -0
  15. package/dist/nodes/PocketbaseHttp/PocketbaseHttp.node.js +4 -3
  16. package/dist/nodes/PocketbaseHttp/PocketbaseHttp.node.js.map +1 -1
  17. package/dist/nodes/PocketbaseHttp/PocketbaseHttp.node.json +2 -2
  18. package/dist/nodes/PocketbaseTrigger/PocketbaseTrigger.node.d.ts +13 -0
  19. package/dist/nodes/PocketbaseTrigger/PocketbaseTrigger.node.js +239 -0
  20. package/dist/nodes/PocketbaseTrigger/PocketbaseTrigger.node.js.map +1 -0
  21. package/dist/nodes/PocketbaseTrigger/PocketbaseTrigger.node.json +18 -0
  22. package/dist/nodes/PocketbaseTrigger/pocketbaseTrigger.dark.svg +10 -0
  23. package/dist/nodes/PocketbaseTrigger/pocketbaseTrigger.svg +10 -0
  24. package/dist/package.json +11 -7
  25. package/dist/tests/GenericFunctions.spec.d.ts +1 -0
  26. package/dist/tests/GenericFunctions.spec.js +177 -0
  27. package/dist/tests/GenericFunctions.spec.js.map +1 -0
  28. package/dist/tests/PocketbaseAuth.spec.js +80 -50
  29. package/dist/tests/PocketbaseAuth.spec.js.map +1 -1
  30. package/dist/tests/PocketbaseAuthIntegration.spec.d.ts +1 -0
  31. package/dist/tests/PocketbaseAuthIntegration.spec.js +202 -0
  32. package/dist/tests/PocketbaseAuthIntegration.spec.js.map +1 -0
  33. package/dist/tests/PocketbaseTrigger.spec.d.ts +1 -0
  34. package/dist/tests/PocketbaseTrigger.spec.js +243 -0
  35. package/dist/tests/PocketbaseTrigger.spec.js.map +1 -0
  36. package/dist/tests/PocketbaseTriggerIntegration.spec.d.ts +1 -0
  37. package/dist/tests/PocketbaseTriggerIntegration.spec.js +125 -0
  38. package/dist/tests/PocketbaseTriggerIntegration.spec.js.map +1 -0
  39. package/dist/tests/RequestBodyFunctions.spec.d.ts +1 -0
  40. package/dist/tests/RequestBodyFunctions.spec.js +232 -0
  41. package/dist/tests/RequestBodyFunctions.spec.js.map +1 -0
  42. package/dist/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +11 -7
  44. package/dist/nodes/PocketbaseHttp/GenericFunctions.js +0 -42
  45. package/dist/nodes/PocketbaseHttp/GenericFunctions.js.map +0 -1
  46. package/dist/nodes/PocketbaseHttp/LoadOptions.js.map +0 -1
  47. package/dist/nodes/PocketbaseHttp/PocketbaseAuth.js +0 -50
  48. package/dist/nodes/PocketbaseHttp/PocketbaseAuth.js.map +0 -1
  49. package/dist/nodes/PocketbaseHttp/RequestBodyFunctions.js +0 -62
  50. package/dist/nodes/PocketbaseHttp/RequestBodyFunctions.js.map +0 -1
  51. /package/dist/nodes/{PocketbaseHttp → Common}/RequestBodyFunctions.d.ts +0 -0
@@ -1,75 +1,105 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const vitest_1 = require("vitest");
4
- const PocketbaseAuth_1 = require("../nodes/PocketbaseHttp/PocketbaseAuth");
4
+ const PocketbaseAuth_1 = require("../nodes/Common/PocketbaseAuth");
5
5
  (0, vitest_1.describe)("PocketbaseAuth", () => {
6
- (0, vitest_1.it)("should login and return a token", async () => {
7
- const mockHttpRequest = vitest_1.vi.fn().mockResolvedValue({ token: "mock-token" });
8
- const mockThis = {
6
+ let mockThis;
7
+ const credentials = {
8
+ url: "http://localhost:8090",
9
+ username: "test@example.com",
10
+ password: "password123",
11
+ };
12
+ (0, vitest_1.beforeEach)(() => {
13
+ vitest_1.vi.clearAllMocks();
14
+ PocketbaseAuth_1.inFlightRequests.clear();
15
+ mockThis = {
9
16
  helpers: {
10
- httpRequest: mockHttpRequest,
17
+ httpRequest: vitest_1.vi.fn(),
11
18
  },
12
19
  };
13
- const credentials = {
14
- url: "http://localhost:8090",
15
- username: "test@example.com",
16
- password: "password123",
17
- };
20
+ });
21
+ (0, vitest_1.it)("should perform login and return token", async () => {
22
+ mockThis.helpers.httpRequest.mockResolvedValue({ token: "mock-token" });
18
23
  const result = await PocketbaseAuth_1.login.call(mockThis, credentials);
19
- (0, vitest_1.expect)(result).toEqual({ token: "mock-token" });
20
- (0, vitest_1.expect)(mockHttpRequest).toHaveBeenCalledWith({
24
+ (0, vitest_1.expect)(result.token).toBe("mock-token");
25
+ (0, vitest_1.expect)(mockThis.helpers.httpRequest).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
21
26
  method: "POST",
22
27
  url: "http://localhost:8090/api/collections/_superusers/auth-with-password",
23
28
  body: {
24
29
  identity: "test@example.com",
25
30
  password: "password123",
26
31
  },
32
+ }));
33
+ });
34
+ (0, vitest_1.it)("should deduplicate concurrent login requests", async () => {
35
+ let resolvePromise;
36
+ const pendingPromise = new Promise((resolve) => {
37
+ resolvePromise = resolve;
27
38
  });
39
+ mockThis.helpers.httpRequest.mockReturnValue(pendingPromise);
40
+ const call1 = PocketbaseAuth_1.login.call(mockThis, credentials);
41
+ const call2 = PocketbaseAuth_1.login.call(mockThis, credentials);
42
+ (0, vitest_1.expect)(mockThis.helpers.httpRequest).toHaveBeenCalledTimes(1);
43
+ resolvePromise({ token: "deduped-token" });
44
+ const [res1, res2] = await Promise.all([call1, call2]);
45
+ (0, vitest_1.expect)(res1.token).toBe("deduped-token");
46
+ (0, vitest_1.expect)(res2.token).toBe("deduped-token");
28
47
  });
29
- (0, vitest_1.it)("should handle URL with trailing slash correctly", async () => {
30
- const mockHttpRequest = vitest_1.vi.fn().mockResolvedValue({ token: "mock-token" });
31
- const mockThis = {
32
- helpers: {
33
- httpRequest: mockHttpRequest,
34
- },
35
- };
36
- const credentials = {
37
- url: "http://localhost:8090/",
38
- username: "test@example.com",
39
- password: "password123",
48
+ (0, vitest_1.it)("should refresh token if expired", async () => {
49
+ const expiredTime = Math.floor(Date.now() / 1000) - 60;
50
+ const payload = Buffer.from(JSON.stringify({ exp: expiredTime }))
51
+ .toString("base64")
52
+ .replace(/\+/g, "-")
53
+ .replace(/\//g, "_")
54
+ .replace(/=+$/, "");
55
+ const expiredToken = `header.${payload}.signature`;
56
+ const credsWithToken = {
57
+ ...credentials,
58
+ token: expiredToken,
40
59
  };
41
- const result = await PocketbaseAuth_1.login.call(mockThis, credentials);
42
- (0, vitest_1.expect)(result).toEqual({ token: "mock-token" });
43
- (0, vitest_1.expect)(mockHttpRequest).toHaveBeenCalledWith({
60
+ mockThis.helpers.httpRequest.mockResolvedValue({ token: "new-token" });
61
+ const result = await PocketbaseAuth_1.refresh.call(mockThis, credsWithToken);
62
+ (0, vitest_1.expect)(result.token).toBe("new-token");
63
+ (0, vitest_1.expect)(mockThis.helpers.httpRequest).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
44
64
  method: "POST",
45
- url: "http://localhost:8090/api/collections/_superusers/auth-with-password",
46
- body: {
47
- identity: "test@example.com",
48
- password: "password123",
49
- },
50
- });
65
+ url: "http://localhost:8090/api/collections/_superusers/auth-refresh",
66
+ }));
51
67
  });
52
- (0, vitest_1.it)("should throw error if url is missing", async () => {
53
- const mockThis = {};
54
- const credentials = {
55
- username: "test@example.com",
56
- password: "password123",
68
+ (0, vitest_1.it)("should return existing token if not expired", async () => {
69
+ const futureTime = Math.floor(Date.now() / 1000) + 3600;
70
+ const payload = Buffer.from(JSON.stringify({ exp: futureTime }))
71
+ .toString("base64")
72
+ .replace(/\+/g, "-")
73
+ .replace(/\//g, "_")
74
+ .replace(/=+$/, "");
75
+ const validToken = `header.${payload}.signature`;
76
+ const credsWithToken = {
77
+ ...credentials,
78
+ token: validToken,
57
79
  };
58
- await (0, vitest_1.expect)(PocketbaseAuth_1.login.call(mockThis, credentials)).rejects.toThrow("PocketBase URL is missing or invalid in Credentials");
80
+ const result = await PocketbaseAuth_1.refresh.call(mockThis, credsWithToken);
81
+ (0, vitest_1.expect)(result.token).toBe(validToken);
82
+ (0, vitest_1.expect)(mockThis.helpers.httpRequest).not.toHaveBeenCalled();
59
83
  });
60
- (0, vitest_1.it)("should handle auth failure", async () => {
61
- const mockHttpRequest = vitest_1.vi.fn().mockRejectedValue({ status: 401, message: "Unauthorized" });
62
- const mockThis = {
63
- helpers: {
64
- httpRequest: mockHttpRequest,
65
- },
66
- };
67
- const credentials = {
68
- url: "http://localhost:8090",
69
- username: "test@example.com",
70
- password: "wrongpassword",
84
+ (0, vitest_1.it)("should fallback to login if refresh fails with 401", async () => {
85
+ const expiredTime = Math.floor(Date.now() / 1000) - 60;
86
+ const payload = Buffer.from(JSON.stringify({ exp: expiredTime }))
87
+ .toString("base64")
88
+ .replace(/\+/g, "-")
89
+ .replace(/\//g, "_")
90
+ .replace(/=+$/, "");
91
+ const expiredToken = `header.${payload}.signature`;
92
+ const credsWithToken = {
93
+ ...credentials,
94
+ token: expiredToken,
71
95
  };
72
- await (0, vitest_1.expect)(PocketbaseAuth_1.login.call(mockThis, credentials)).rejects.toMatchObject({ status: 401 });
96
+ const error = new Error("Unauthorized");
97
+ error.status = 401;
98
+ mockThis.helpers.httpRequest.mockRejectedValueOnce(error);
99
+ mockThis.helpers.httpRequest.mockResolvedValueOnce({ token: "login-token" });
100
+ const result = await PocketbaseAuth_1.refresh.call(mockThis, credsWithToken);
101
+ (0, vitest_1.expect)(result.token).toBe("login-token");
102
+ (0, vitest_1.expect)(mockThis.helpers.httpRequest).toHaveBeenCalledTimes(2);
73
103
  });
74
104
  });
75
105
  //# sourceMappingURL=PocketbaseAuth.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PocketbaseAuth.spec.js","sourceRoot":"","sources":["../../tests/PocketbaseAuth.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PocketbaseAuth.spec.js","sourceRoot":"","sources":["../../tests/PocketbaseAuth.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const PocketbaseAuth_1 = require("../nodes/Common/PocketbaseAuth");
5
+ const runIntegration = process.env.RUN_POCKETBASE_INTEGRATION === "true";
6
+ vitest_1.describe.skipIf(!runIntegration)("PocketbaseAuth Integration", () => {
7
+ (0, vitest_1.beforeEach)(() => {
8
+ PocketbaseAuth_1.inFlightRequests.clear();
9
+ });
10
+ const baseUrl = process.env.POCKETBASE_TEST_URL || "http://localhost:8090";
11
+ const email = process.env.POCKETBASE_TEST_USER || "test@example.com";
12
+ const oldPassword = process.env.POCKETBASE_TEST_PASS || "password123";
13
+ const newPassword = "newPassword123";
14
+ (0, vitest_1.it)("should refresh token, and fall back to login if password changed", async () => {
15
+ const authRes = await fetch(`${baseUrl}/api/collections/_superusers/auth-with-password`, {
16
+ method: "POST",
17
+ headers: { "Content-Type": "application/json" },
18
+ body: JSON.stringify({ identity: email, password: oldPassword }),
19
+ });
20
+ (0, vitest_1.expect)(authRes.ok).toBe(true);
21
+ const { token: initialToken, record } = (await authRes.json());
22
+ const mockThis = {
23
+ helpers: {
24
+ httpRequest: async (options) => {
25
+ const headers = { ...options.headers };
26
+ let body = options.body;
27
+ if (body &&
28
+ typeof body === "object" &&
29
+ !(body instanceof Buffer) &&
30
+ !(typeof body.append === "function" && typeof body.getHeaders === "function")) {
31
+ body = JSON.stringify(body);
32
+ if (!headers["Content-Type"]) {
33
+ headers["Content-Type"] = "application/json";
34
+ }
35
+ }
36
+ const res = await fetch(options.url, {
37
+ method: options.method,
38
+ headers,
39
+ body,
40
+ });
41
+ const data = (await res.json());
42
+ if (!res.ok) {
43
+ const error = new Error(data.message || "Request failed");
44
+ error.status = res.status;
45
+ throw error;
46
+ }
47
+ return data;
48
+ },
49
+ },
50
+ };
51
+ let finalResultToken;
52
+ try {
53
+ const credentials = {
54
+ url: baseUrl,
55
+ username: email,
56
+ password: oldPassword,
57
+ token: initialToken,
58
+ };
59
+ const refreshResult = await PocketbaseAuth_1.refresh.call(mockThis, credentials);
60
+ (0, vitest_1.expect)(refreshResult.token).toBeDefined();
61
+ const middleToken = refreshResult.token;
62
+ const updateRes = await fetch(`${baseUrl}/api/collections/_superusers/records/${record.id}`, {
63
+ method: "PATCH",
64
+ headers: {
65
+ "Content-Type": "application/json",
66
+ Authorization: middleToken,
67
+ },
68
+ body: JSON.stringify({
69
+ password: newPassword,
70
+ passwordConfirm: newPassword,
71
+ }),
72
+ });
73
+ (0, vitest_1.expect)(updateRes.ok).toBe(true);
74
+ const expiredTime = Math.floor(Date.now() / 1000) - 3600;
75
+ const expiredPayload = Buffer.from(JSON.stringify({ exp: expiredTime }))
76
+ .toString("base64")
77
+ .replace(/\+/g, "-")
78
+ .replace(/\//g, "_")
79
+ .replace(/=+$/, "");
80
+ const forcedExpiredToken = `header.${expiredPayload}.signature`;
81
+ const credentialsWithNewPass = {
82
+ url: baseUrl,
83
+ username: email,
84
+ password: newPassword,
85
+ token: forcedExpiredToken,
86
+ };
87
+ const finalResult = await PocketbaseAuth_1.refresh.call(mockThis, credentialsWithNewPass);
88
+ (0, vitest_1.expect)(finalResult.token).toBeDefined();
89
+ (0, vitest_1.expect)(finalResult.token).not.toBe(middleToken);
90
+ (0, vitest_1.expect)(finalResult.token).not.toBe(forcedExpiredToken);
91
+ finalResultToken = finalResult.token;
92
+ const finalVerifyRes = await fetch(`${baseUrl}/api/collections/_superusers/auth-refresh`, {
93
+ method: "POST",
94
+ headers: {
95
+ "Content-Type": "application/json",
96
+ Authorization: finalResult.token,
97
+ },
98
+ });
99
+ (0, vitest_1.expect)(finalVerifyRes.ok).toBe(true);
100
+ }
101
+ finally {
102
+ if (record && record.id) {
103
+ let cleanupToken = finalResultToken;
104
+ if (!cleanupToken) {
105
+ try {
106
+ const authRes = await fetch(`${baseUrl}/api/collections/_superusers/auth-with-password`, {
107
+ method: "POST",
108
+ headers: { "Content-Type": "application/json" },
109
+ body: JSON.stringify({ identity: email, password: newPassword }),
110
+ });
111
+ if (authRes.ok) {
112
+ const data = (await authRes.json());
113
+ cleanupToken = data.token;
114
+ }
115
+ else {
116
+ const authResOld = await fetch(`${baseUrl}/api/collections/_superusers/auth-with-password`, {
117
+ method: "POST",
118
+ headers: { "Content-Type": "application/json" },
119
+ body: JSON.stringify({ identity: email, password: oldPassword }),
120
+ });
121
+ if (authResOld.ok) {
122
+ const data = (await authResOld.json());
123
+ cleanupToken = data.token;
124
+ }
125
+ }
126
+ }
127
+ catch (err) {
128
+ console.warn("Authentication cleanup failed to re-auth", err);
129
+ }
130
+ }
131
+ if (cleanupToken) {
132
+ const cleanupRes = await fetch(`${baseUrl}/api/collections/_superusers/records/${record.id}`, {
133
+ method: "PATCH",
134
+ headers: {
135
+ "Content-Type": "application/json",
136
+ Authorization: cleanupToken,
137
+ },
138
+ body: JSON.stringify({
139
+ password: oldPassword,
140
+ passwordConfirm: oldPassword,
141
+ }),
142
+ });
143
+ if (!cleanupRes.ok) {
144
+ console.warn("Failed to revert password during cleanup:", await cleanupRes.text());
145
+ }
146
+ }
147
+ else {
148
+ console.warn("Skipping cleanup: No valid token available");
149
+ }
150
+ }
151
+ }
152
+ }, 20000);
153
+ (0, vitest_1.it)("should deduplicate multiple concurrent login calls to the same PocketBase instance", async () => {
154
+ let httpRequestCount = 0;
155
+ const mockThis = {
156
+ helpers: {
157
+ httpRequest: async (options) => {
158
+ httpRequestCount++;
159
+ await new Promise((resolve) => setTimeout(resolve, 100));
160
+ const res = await fetch(options.url, {
161
+ method: options.method,
162
+ headers: { "Content-Type": "application/json", ...options.headers },
163
+ body: JSON.stringify(options.body),
164
+ });
165
+ const data = (await res.json());
166
+ if (!res.ok) {
167
+ const error = new Error(data.message || "Request failed");
168
+ error.status = res.status;
169
+ throw error;
170
+ }
171
+ return data;
172
+ },
173
+ },
174
+ };
175
+ const credentials = {
176
+ url: baseUrl,
177
+ username: email,
178
+ password: oldPassword,
179
+ };
180
+ const results = await Promise.all([
181
+ PocketbaseAuth_1.login.call(mockThis, credentials),
182
+ PocketbaseAuth_1.login.call(mockThis, credentials),
183
+ PocketbaseAuth_1.login.call(mockThis, credentials),
184
+ PocketbaseAuth_1.login.call(mockThis, credentials),
185
+ PocketbaseAuth_1.login.call(mockThis, credentials),
186
+ ]);
187
+ (0, vitest_1.expect)(httpRequestCount).toBe(1);
188
+ results.forEach((res) => {
189
+ (0, vitest_1.expect)(res.token).toBeDefined();
190
+ (0, vitest_1.expect)(typeof res.token).toBe("string");
191
+ });
192
+ const verifyRes = await fetch(`${baseUrl}/api/collections/_superusers/auth-refresh`, {
193
+ method: "POST",
194
+ headers: {
195
+ "Content-Type": "application/json",
196
+ Authorization: results[0].token,
197
+ },
198
+ });
199
+ (0, vitest_1.expect)(verifyRes.ok).toBe(true);
200
+ }, 10000);
201
+ });
202
+ //# sourceMappingURL=PocketbaseAuthIntegration.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PocketbaseAuthIntegration.spec.js","sourceRoot":"","sources":["../../tests/PocketbaseAuthIntegration.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const PocketbaseTrigger_node_1 = require("../nodes/PocketbaseTrigger/PocketbaseTrigger.node");
5
+ const eventsource_1 = require("eventsource");
6
+ vitest_1.vi.mock("eventsource", () => {
7
+ return {
8
+ EventSource: vitest_1.vi.fn(),
9
+ };
10
+ });
11
+ (0, vitest_1.describe)("PocketbaseTrigger", () => {
12
+ let triggerFunctions;
13
+ let node;
14
+ let esInstance;
15
+ (0, vitest_1.beforeEach)(() => {
16
+ vitest_1.vi.clearAllMocks();
17
+ node = new PocketbaseTrigger_node_1.PocketbaseTrigger();
18
+ triggerFunctions = {
19
+ getCredentials: vitest_1.vi.fn().mockResolvedValue({ url: "http://localhost:8090" }),
20
+ getNodeParameter: vitest_1.vi.fn(),
21
+ helpers: {
22
+ requestWithAuthentication: vitest_1.vi.fn(),
23
+ returnJsonArray: vitest_1.vi.fn((data) => [{ json: data }]),
24
+ },
25
+ emit: vitest_1.vi.fn(),
26
+ emitError: vitest_1.vi.fn(),
27
+ logger: {
28
+ error: vitest_1.vi.fn(),
29
+ },
30
+ };
31
+ esInstance = {
32
+ addEventListener: vitest_1.vi.fn(),
33
+ removeEventListener: vitest_1.vi.fn(),
34
+ close: vitest_1.vi.fn(),
35
+ };
36
+ vitest_1.vi.mocked(eventsource_1.EventSource).mockImplementation(function () {
37
+ return esInstance;
38
+ });
39
+ });
40
+ (0, vitest_1.it)("should perform handshake on PB_CONNECT", async () => {
41
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
42
+ if (name === "collection")
43
+ return "posts";
44
+ if (name === "events")
45
+ return ["create", "update", "delete"];
46
+ return undefined;
47
+ });
48
+ await node.trigger.call(triggerFunctions);
49
+ (0, vitest_1.expect)(eventsource_1.EventSource).toHaveBeenCalledWith("http://localhost:8090/api/realtime");
50
+ (0, vitest_1.expect)(esInstance.addEventListener).toHaveBeenCalledWith("PB_CONNECT", vitest_1.expect.any(Function));
51
+ const pbConnectCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "PB_CONNECT")[1];
52
+ await pbConnectCallback({ data: JSON.stringify({ clientId: "mock-client-id" }) });
53
+ (0, vitest_1.expect)(triggerFunctions.helpers.requestWithAuthentication).toHaveBeenCalledWith("pocketbaseHttpApi", {
54
+ method: "POST",
55
+ url: "http://localhost:8090/api/realtime",
56
+ body: {
57
+ clientId: "mock-client-id",
58
+ subscriptions: ["posts"],
59
+ },
60
+ });
61
+ });
62
+ (0, vitest_1.it)("should emit data on matching event", async () => {
63
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
64
+ if (name === "collection")
65
+ return "posts";
66
+ if (name === "events")
67
+ return ["create"];
68
+ return undefined;
69
+ });
70
+ await node.trigger.call(triggerFunctions);
71
+ const collectionCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "posts")[1];
72
+ await collectionCallback({
73
+ data: JSON.stringify({
74
+ action: "create",
75
+ record: { id: "1", title: "Hello" },
76
+ }),
77
+ });
78
+ (0, vitest_1.expect)(triggerFunctions.emit).toHaveBeenCalledWith([
79
+ [{ json: { __action: "create", id: "1", title: "Hello" } }],
80
+ ]);
81
+ });
82
+ (0, vitest_1.it)("should handle record action collisions in onMessage", async () => {
83
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
84
+ if (name === "collection")
85
+ return "posts";
86
+ if (name === "events")
87
+ return ["create"];
88
+ return undefined;
89
+ });
90
+ await node.trigger.call(triggerFunctions);
91
+ const collectionCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "posts")[1];
92
+ await collectionCallback({
93
+ data: JSON.stringify({
94
+ action: "create",
95
+ record: { id: "1", action: "original-action-value" },
96
+ }),
97
+ });
98
+ (0, vitest_1.expect)(triggerFunctions.emit).toHaveBeenCalledWith([
99
+ [
100
+ {
101
+ json: {
102
+ id: "1",
103
+ action: "original-action-value",
104
+ __original_action: "original-action-value",
105
+ __action: "create",
106
+ },
107
+ },
108
+ ],
109
+ ]);
110
+ });
111
+ (0, vitest_1.it)("should emit sample data on manualTriggerFunction", async () => {
112
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
113
+ if (name === "collection")
114
+ return "posts";
115
+ if (name === "events")
116
+ return ["create", "update", "delete"];
117
+ return undefined;
118
+ });
119
+ const response = await node.trigger.call(triggerFunctions);
120
+ if (response.manualTriggerFunction) {
121
+ await response.manualTriggerFunction();
122
+ (0, vitest_1.expect)(triggerFunctions.emit).toHaveBeenCalledWith([
123
+ [
124
+ {
125
+ json: vitest_1.expect.objectContaining({
126
+ __action: "create",
127
+ collectionName: "posts",
128
+ }),
129
+ },
130
+ ],
131
+ ]);
132
+ }
133
+ else {
134
+ throw new Error("manualTriggerFunction should be defined");
135
+ }
136
+ });
137
+ (0, vitest_1.it)("should not emit data on non-matching event", async () => {
138
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
139
+ if (name === "collection")
140
+ return "posts";
141
+ if (name === "events")
142
+ return ["create"];
143
+ return undefined;
144
+ });
145
+ await node.trigger.call(triggerFunctions);
146
+ const collectionCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "posts")[1];
147
+ await collectionCallback({
148
+ data: JSON.stringify({
149
+ action: "update",
150
+ record: { id: "1", title: "Hello" },
151
+ }),
152
+ });
153
+ (0, vitest_1.expect)(triggerFunctions.emit).not.toHaveBeenCalled();
154
+ });
155
+ (0, vitest_1.it)("should close EventSource on closeFunction", async () => {
156
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
157
+ if (name === "collection")
158
+ return "posts";
159
+ if (name === "events")
160
+ return ["create"];
161
+ return undefined;
162
+ });
163
+ const response = await node.trigger.call(triggerFunctions);
164
+ await response.closeFunction();
165
+ (0, vitest_1.expect)(esInstance.close).toHaveBeenCalled();
166
+ });
167
+ (0, vitest_1.it)("should handle EventSource connection failure", async () => {
168
+ vitest_1.vi.useFakeTimers();
169
+ try {
170
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
171
+ if (name === "collection")
172
+ return "posts";
173
+ if (name === "events")
174
+ return ["create"];
175
+ return undefined;
176
+ });
177
+ const response = await node.trigger.call(triggerFunctions);
178
+ const errorCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "error")[1];
179
+ const mockError = new Error("Connection failed");
180
+ errorCallback(mockError);
181
+ (0, vitest_1.expect)(triggerFunctions.logger.error).toHaveBeenCalledWith("PocketBase SSE connection failure", vitest_1.expect.objectContaining({ error: mockError, baseUrl: "http://localhost:8090" }));
182
+ (0, vitest_1.expect)(triggerFunctions.emitError).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
183
+ message: "Connection failed",
184
+ originalErrorEvent: mockError,
185
+ }));
186
+ (0, vitest_1.expect)(esInstance.close).toHaveBeenCalled();
187
+ await response.closeFunction();
188
+ }
189
+ finally {
190
+ vitest_1.vi.useRealTimers();
191
+ }
192
+ });
193
+ (0, vitest_1.it)("should handle EventSource delivering a non-Error error event", async () => {
194
+ vitest_1.vi.useFakeTimers();
195
+ try {
196
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
197
+ if (name === "collection")
198
+ return "posts";
199
+ if (name === "events")
200
+ return ["create"];
201
+ return undefined;
202
+ });
203
+ const response = await node.trigger.call(triggerFunctions);
204
+ const errorCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "error")[1];
205
+ const mockError = { message: "Conn failed", code: 500 };
206
+ errorCallback(mockError);
207
+ (0, vitest_1.expect)(triggerFunctions.logger.error).toHaveBeenCalledWith("PocketBase SSE connection failure", vitest_1.expect.objectContaining({ error: mockError, baseUrl: "http://localhost:8090" }));
208
+ (0, vitest_1.expect)(triggerFunctions.emitError).toHaveBeenCalledWith(vitest_1.expect.objectContaining({
209
+ message: "Conn failed",
210
+ code: 500,
211
+ originalErrorEvent: mockError,
212
+ }));
213
+ (0, vitest_1.expect)(esInstance.close).toHaveBeenCalled();
214
+ await response.closeFunction();
215
+ }
216
+ finally {
217
+ vitest_1.vi.useRealTimers();
218
+ }
219
+ });
220
+ (0, vitest_1.it)("should redact sensitive data on parse failure", async () => {
221
+ triggerFunctions.getNodeParameter.mockImplementation((name) => {
222
+ if (name === "collection")
223
+ return "posts";
224
+ if (name === "events")
225
+ return ["create"];
226
+ return undefined;
227
+ });
228
+ await node.trigger.call(triggerFunctions);
229
+ const collectionCallback = esInstance.addEventListener.mock.calls.find((call) => call[0] === "posts")[1];
230
+ const invalidData = '{ "action": "create", "password": "secret", "token": "xyz", "email": "test@example.com", "msg": "Send it to someone@else.com", "invalid": ';
231
+ collectionCallback({ data: invalidData });
232
+ (0, vitest_1.expect)(triggerFunctions.logger.error).toHaveBeenCalledWith("Failed to parse PocketBase SSE message", vitest_1.expect.objectContaining({
233
+ collection: "posts",
234
+ }));
235
+ const loggedMeta = triggerFunctions.logger.error.mock.calls[0][1];
236
+ (0, vitest_1.expect)(loggedMeta.redactedPreview).toContain('"password": "[REDACTED]"');
237
+ (0, vitest_1.expect)(loggedMeta.redactedPreview).toContain('"token": "[REDACTED]"');
238
+ (0, vitest_1.expect)(loggedMeta.redactedPreview).toContain('"email": "[REDACTED]"');
239
+ (0, vitest_1.expect)(loggedMeta.redactedPreview).toContain("Send it to [REDACTED]");
240
+ (0, vitest_1.expect)(loggedMeta.redactedPreview.length).toBeLessThanOrEqual(200);
241
+ });
242
+ });
243
+ //# sourceMappingURL=PocketbaseTrigger.spec.js.map