@zapier/zapier-sdk 0.15.3 → 0.15.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/CHANGELOG.md +6 -0
- package/dist/api/auth.d.ts +10 -0
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +35 -0
- package/dist/api/schemas.d.ts +38 -38
- package/dist/index.cjs +112 -23
- package/dist/index.d.mts +28 -28
- package/dist/index.mjs +112 -23
- package/dist/plugins/eventEmission/index.d.ts +1 -1
- package/dist/plugins/eventEmission/index.d.ts.map +1 -1
- package/dist/plugins/eventEmission/index.js +90 -22
- package/dist/plugins/eventEmission/index.test.js +179 -2
- package/dist/schemas/Action.d.ts +1 -1
- package/dist/schemas/Auth.d.ts +6 -6
- package/package.json +1 -1
|
@@ -6,14 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { createTransport } from "./transport";
|
|
8
8
|
import { generateEventId, getCurrentTimestamp, getReleaseId } from "./utils";
|
|
9
|
+
import { extractUserIdsFromJwt } from "../../api/auth";
|
|
9
10
|
import { buildApplicationLifecycleEvent, buildErrorEventWithContext, } from "./builders";
|
|
10
11
|
import { getTrackingBaseUrl } from "../../utils/url-utils";
|
|
12
|
+
// Maximum time to wait for telemetry emission before allowing process to exit
|
|
13
|
+
const TELEMETRY_EMIT_TIMEOUT_MS = 300;
|
|
11
14
|
const APPLICATION_LIFECYCLE_EVENT_SUBJECT = "platform.sdk.ApplicationLifecycleEvent";
|
|
12
15
|
const ERROR_OCCURRED_EVENT_SUBJECT = "platform.sdk.ErrorOccurredEvent";
|
|
13
16
|
// Track transport success/failure so we only log failure once.
|
|
14
17
|
const transportStates = new WeakMap();
|
|
15
18
|
// Silent emission wrapper with smart first-failure logging
|
|
16
|
-
async function silentEmit(transport, subject, event) {
|
|
19
|
+
async function silentEmit(transport, subject, event, userContextPromise) {
|
|
17
20
|
try {
|
|
18
21
|
// Get or initialize state for this transport
|
|
19
22
|
let state = transportStates.get(transport);
|
|
@@ -21,9 +24,21 @@ async function silentEmit(transport, subject, event) {
|
|
|
21
24
|
state = { hasWorked: false, hasLoggedFailure: false };
|
|
22
25
|
transportStates.set(transport, state);
|
|
23
26
|
}
|
|
27
|
+
// Resolve user context and merge into event
|
|
28
|
+
let enrichedEvent = event;
|
|
29
|
+
if (userContextPromise) {
|
|
30
|
+
try {
|
|
31
|
+
const userContext = await userContextPromise;
|
|
32
|
+
// Use Object.assign to safely merge user context into event
|
|
33
|
+
enrichedEvent = Object.assign({}, event, userContext);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// If user context promise fails, continue with original event
|
|
37
|
+
}
|
|
38
|
+
}
|
|
24
39
|
// Fire and forget - don't await the transport
|
|
25
40
|
transport
|
|
26
|
-
.emit(subject,
|
|
41
|
+
.emit(subject, enrichedEvent)
|
|
27
42
|
.then(() => {
|
|
28
43
|
// Mark as working if any emit succeeds
|
|
29
44
|
state.hasWorked = true;
|
|
@@ -76,6 +91,24 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
76
91
|
: // Otherwise, use option transport or default
|
|
77
92
|
(context.options.eventEmission?.transport ?? defaultTransport),
|
|
78
93
|
};
|
|
94
|
+
// Create getUserContext promise for dynamic user context injection
|
|
95
|
+
const getUserContext = (async () => {
|
|
96
|
+
try {
|
|
97
|
+
// Dynamically import the CLI login package if available
|
|
98
|
+
const { getToken } = await import("@zapier/zapier-sdk-cli-login");
|
|
99
|
+
// Pass baseUrl for potential token refresh operations
|
|
100
|
+
const token = await getToken({
|
|
101
|
+
baseUrl: context.options.baseUrl,
|
|
102
|
+
});
|
|
103
|
+
if (token) {
|
|
104
|
+
return extractUserIdsFromJwt(token);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// CLI login package not available or getToken failed, fall back to null context
|
|
109
|
+
}
|
|
110
|
+
return { customuser_id: null, account_id: null };
|
|
111
|
+
})();
|
|
79
112
|
const startupTime = Date.now();
|
|
80
113
|
let shutdownStartTime = null;
|
|
81
114
|
// If disabled, return noop implementations
|
|
@@ -86,7 +119,7 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
86
119
|
transport: createTransport({ type: "noop" }),
|
|
87
120
|
config,
|
|
88
121
|
emit: () => { },
|
|
89
|
-
createBaseEvent: () => ({
|
|
122
|
+
createBaseEvent: async () => ({
|
|
90
123
|
event_id: generateEventId(),
|
|
91
124
|
timestamp_ms: getCurrentTimestamp(),
|
|
92
125
|
release_id: getReleaseId(),
|
|
@@ -109,23 +142,34 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
109
142
|
transport = createTransport({ type: "noop" });
|
|
110
143
|
}
|
|
111
144
|
// Helper to create base event
|
|
112
|
-
const createBaseEventHelper = () =>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const createBaseEventHelper = async () => {
|
|
146
|
+
const baseEvent = {
|
|
147
|
+
event_id: generateEventId(),
|
|
148
|
+
timestamp_ms: getCurrentTimestamp(),
|
|
149
|
+
release_id: getReleaseId(),
|
|
150
|
+
customuser_id: null,
|
|
151
|
+
account_id: null,
|
|
152
|
+
identity_id: null,
|
|
153
|
+
visitor_id: null,
|
|
154
|
+
correlation_id: null,
|
|
155
|
+
};
|
|
156
|
+
// Enrich with user context if available
|
|
157
|
+
try {
|
|
158
|
+
const userContext = await getUserContext;
|
|
159
|
+
return { ...baseEvent, ...userContext };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Return base event if user context fails
|
|
163
|
+
return baseEvent;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
122
166
|
// Register lifecycle event handlers if enabled
|
|
123
167
|
if (config.enabled) {
|
|
124
168
|
// Emit startup event
|
|
125
169
|
const startupEvent = buildApplicationLifecycleEvent({
|
|
126
170
|
lifecycle_event_type: "startup",
|
|
127
171
|
});
|
|
128
|
-
silentEmit(transport, APPLICATION_LIFECYCLE_EVENT_SUBJECT, startupEvent);
|
|
172
|
+
silentEmit(transport, APPLICATION_LIFECYCLE_EVENT_SUBJECT, startupEvent, getUserContext);
|
|
129
173
|
// Register process event handlers (Node.js only)
|
|
130
174
|
if (typeof process?.on === "function") {
|
|
131
175
|
// Handle normal process exit
|
|
@@ -141,11 +185,11 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
141
185
|
is_graceful_shutdown: code === 0,
|
|
142
186
|
shutdown_duration_ms: shutdownDuration,
|
|
143
187
|
});
|
|
144
|
-
silentEmit(transport, APPLICATION_LIFECYCLE_EVENT_SUBJECT, exitEvent);
|
|
188
|
+
silentEmit(transport, APPLICATION_LIFECYCLE_EVENT_SUBJECT, exitEvent, getUserContext);
|
|
145
189
|
});
|
|
146
190
|
// Handle uncaught exceptions
|
|
147
191
|
process.on("uncaughtException", async (error) => {
|
|
148
|
-
|
|
192
|
+
let errorEvent = buildErrorEventWithContext({
|
|
149
193
|
error_message: error.message || "Unknown error",
|
|
150
194
|
error_type: "UncaughtException",
|
|
151
195
|
error_stack_trace: error.stack || null,
|
|
@@ -154,11 +198,19 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
154
198
|
is_recoverable: false,
|
|
155
199
|
execution_start_time: startupTime,
|
|
156
200
|
});
|
|
201
|
+
// Enrich with user context if available
|
|
202
|
+
try {
|
|
203
|
+
const userContext = await getUserContext;
|
|
204
|
+
errorEvent = { ...errorEvent, ...userContext };
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Continue with original event if user context fails
|
|
208
|
+
}
|
|
157
209
|
// Wait up to 300ms for telemetry to send before allowing process to exit
|
|
158
210
|
try {
|
|
159
211
|
await Promise.race([
|
|
160
212
|
transport.emit(ERROR_OCCURRED_EVENT_SUBJECT, errorEvent),
|
|
161
|
-
new Promise((resolve) => setTimeout(resolve,
|
|
213
|
+
new Promise((resolve) => setTimeout(resolve, TELEMETRY_EMIT_TIMEOUT_MS)),
|
|
162
214
|
]);
|
|
163
215
|
}
|
|
164
216
|
catch {
|
|
@@ -174,7 +226,7 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
174
226
|
? reason
|
|
175
227
|
: "Unhandled promise rejection";
|
|
176
228
|
const errorStack = reason instanceof Error ? reason.stack : null;
|
|
177
|
-
|
|
229
|
+
let errorEvent = buildErrorEventWithContext({
|
|
178
230
|
error_message: errorMessage,
|
|
179
231
|
error_type: "UnhandledRejection",
|
|
180
232
|
error_stack_trace: errorStack,
|
|
@@ -186,11 +238,19 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
186
238
|
promise: String(promise),
|
|
187
239
|
},
|
|
188
240
|
});
|
|
241
|
+
// Enrich with user context if available
|
|
242
|
+
try {
|
|
243
|
+
const userContext = await getUserContext;
|
|
244
|
+
errorEvent = { ...errorEvent, ...userContext };
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// Continue with original event if user context fails
|
|
248
|
+
}
|
|
189
249
|
// Wait up to 300ms for telemetry to send
|
|
190
250
|
try {
|
|
191
251
|
await Promise.race([
|
|
192
252
|
transport.emit(ERROR_OCCURRED_EVENT_SUBJECT, errorEvent),
|
|
193
|
-
new Promise((resolve) => setTimeout(resolve,
|
|
253
|
+
new Promise((resolve) => setTimeout(resolve, TELEMETRY_EMIT_TIMEOUT_MS)),
|
|
194
254
|
]);
|
|
195
255
|
}
|
|
196
256
|
catch {
|
|
@@ -201,17 +261,25 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
201
261
|
const handleSignal = async (signal) => {
|
|
202
262
|
shutdownStartTime = Date.now();
|
|
203
263
|
const uptime = Date.now() - startupTime;
|
|
204
|
-
|
|
264
|
+
let signalEvent = buildApplicationLifecycleEvent({
|
|
205
265
|
lifecycle_event_type: "signal_termination",
|
|
206
266
|
signal_name: signal,
|
|
207
267
|
uptime_ms: uptime,
|
|
208
268
|
is_graceful_shutdown: true,
|
|
209
269
|
});
|
|
270
|
+
// Enrich with user context if available
|
|
271
|
+
try {
|
|
272
|
+
const userContext = await getUserContext;
|
|
273
|
+
signalEvent = { ...signalEvent, ...userContext };
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// Continue with original event if user context fails
|
|
277
|
+
}
|
|
210
278
|
// Wait up to 300ms for telemetry to send
|
|
211
279
|
try {
|
|
212
280
|
await Promise.race([
|
|
213
281
|
transport.emit(APPLICATION_LIFECYCLE_EVENT_SUBJECT, signalEvent),
|
|
214
|
-
new Promise((resolve) => setTimeout(resolve,
|
|
282
|
+
new Promise((resolve) => setTimeout(resolve, TELEMETRY_EMIT_TIMEOUT_MS)),
|
|
215
283
|
]);
|
|
216
284
|
}
|
|
217
285
|
catch {
|
|
@@ -231,7 +299,7 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
231
299
|
transport,
|
|
232
300
|
config,
|
|
233
301
|
emit: (subject, event) => {
|
|
234
|
-
silentEmit(transport, subject, event);
|
|
302
|
+
silentEmit(transport, subject, event, getUserContext);
|
|
235
303
|
},
|
|
236
304
|
createBaseEvent: createBaseEventHelper,
|
|
237
305
|
},
|
|
@@ -12,9 +12,16 @@ const mockTransport = {
|
|
|
12
12
|
vi.mock("./transport", () => ({
|
|
13
13
|
createTransport: vi.fn(() => mockTransport),
|
|
14
14
|
}));
|
|
15
|
+
// Mock CLI login package - default to returning null context
|
|
16
|
+
const mockGetToken = vi.fn().mockResolvedValue(undefined);
|
|
17
|
+
vi.mock("@zapier/zapier-sdk-cli-login", () => ({
|
|
18
|
+
getToken: mockGetToken,
|
|
19
|
+
}));
|
|
15
20
|
describe("eventEmissionPlugin", () => {
|
|
16
21
|
beforeEach(() => {
|
|
17
22
|
vi.clearAllMocks();
|
|
23
|
+
// Reset to default behavior - no token available
|
|
24
|
+
mockGetToken.mockResolvedValue(undefined);
|
|
18
25
|
});
|
|
19
26
|
it("should create plugin with default configuration", () => {
|
|
20
27
|
const plugin = eventEmissionPlugin({
|
|
@@ -64,8 +71,13 @@ describe("eventEmissionPlugin", () => {
|
|
|
64
71
|
const testSubject = "test.event.TestEvent";
|
|
65
72
|
plugin.context.eventEmission.emit(testSubject, testEvent);
|
|
66
73
|
// Give async emission time to complete
|
|
67
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
68
|
-
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
75
|
+
// The event will be enriched with user context (null values)
|
|
76
|
+
expect(mockTransport.emit).toHaveBeenCalledWith(testSubject, {
|
|
77
|
+
...testEvent,
|
|
78
|
+
customuser_id: null,
|
|
79
|
+
account_id: null,
|
|
80
|
+
});
|
|
69
81
|
});
|
|
70
82
|
it("should handle transport creation failures silently", () => {
|
|
71
83
|
// Mock createTransport to throw an error
|
|
@@ -220,6 +232,8 @@ describe("eventEmissionPlugin", () => {
|
|
|
220
232
|
mockConsoleWarn.mockRestore();
|
|
221
233
|
});
|
|
222
234
|
it("should merge options with defaults", () => {
|
|
235
|
+
// Override env var to ensure proper transport is used
|
|
236
|
+
vi.stubEnv("ZAPIER_SDK_TELEMETRY_TRANSPORT", undefined);
|
|
223
237
|
const plugin = eventEmissionPlugin({
|
|
224
238
|
sdk: {},
|
|
225
239
|
context: {
|
|
@@ -239,5 +253,168 @@ describe("eventEmissionPlugin", () => {
|
|
|
239
253
|
type: "http",
|
|
240
254
|
endpoint: "https://example.com",
|
|
241
255
|
});
|
|
256
|
+
vi.unstubAllEnvs();
|
|
257
|
+
});
|
|
258
|
+
it("should extract user IDs from JWT token and include in events", async () => {
|
|
259
|
+
// Create a test JWT token with user data
|
|
260
|
+
// JWT format: header.payload.signature
|
|
261
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
262
|
+
const payload = {
|
|
263
|
+
"zap:acc": "12345",
|
|
264
|
+
sub: "67890",
|
|
265
|
+
sub_type: "customuser",
|
|
266
|
+
"zap:uname": "test@example.com",
|
|
267
|
+
};
|
|
268
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
269
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
270
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.fake-signature`;
|
|
271
|
+
// Mock getToken to return the JWT
|
|
272
|
+
mockGetToken.mockResolvedValue(testJwt);
|
|
273
|
+
const plugin = eventEmissionPlugin({
|
|
274
|
+
sdk: {},
|
|
275
|
+
context: {
|
|
276
|
+
meta: {},
|
|
277
|
+
options: {
|
|
278
|
+
eventEmission: {
|
|
279
|
+
enabled: true,
|
|
280
|
+
transport: { type: "console" },
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
// Test that createBaseEvent includes the extracted user IDs
|
|
286
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
287
|
+
expect(baseEvent.customuser_id).toBe(67890);
|
|
288
|
+
expect(baseEvent.account_id).toBe(12345);
|
|
289
|
+
});
|
|
290
|
+
it("should handle service tokens with nested JWT", async () => {
|
|
291
|
+
// Create a nested JWT for service token testing
|
|
292
|
+
const nestedHeader = { alg: "HS256", typ: "JWT" };
|
|
293
|
+
const nestedPayload = {
|
|
294
|
+
"zap:acc": "99999",
|
|
295
|
+
sub: "88888",
|
|
296
|
+
sub_type: "customuser",
|
|
297
|
+
};
|
|
298
|
+
const nestedEncodedHeader = Buffer.from(JSON.stringify(nestedHeader)).toString("base64url");
|
|
299
|
+
const nestedEncodedPayload = Buffer.from(JSON.stringify(nestedPayload)).toString("base64url");
|
|
300
|
+
const nestedJwt = `${nestedEncodedHeader}.${nestedEncodedPayload}.nested-signature`;
|
|
301
|
+
// Create the service token that wraps the nested JWT
|
|
302
|
+
const serviceHeader = { alg: "HS256", typ: "JWT" };
|
|
303
|
+
const servicePayload = {
|
|
304
|
+
"zap:acc": "11111",
|
|
305
|
+
sub: "22222",
|
|
306
|
+
sub_type: "service",
|
|
307
|
+
njwt: nestedJwt,
|
|
308
|
+
};
|
|
309
|
+
const serviceEncodedHeader = Buffer.from(JSON.stringify(serviceHeader)).toString("base64url");
|
|
310
|
+
const serviceEncodedPayload = Buffer.from(JSON.stringify(servicePayload)).toString("base64url");
|
|
311
|
+
const serviceJwt = `${serviceEncodedHeader}.${serviceEncodedPayload}.service-signature`;
|
|
312
|
+
// Mock getToken to return the service JWT
|
|
313
|
+
mockGetToken.mockResolvedValue(serviceJwt);
|
|
314
|
+
const plugin = eventEmissionPlugin({
|
|
315
|
+
sdk: {},
|
|
316
|
+
context: {
|
|
317
|
+
meta: {},
|
|
318
|
+
options: {
|
|
319
|
+
eventEmission: {
|
|
320
|
+
enabled: true,
|
|
321
|
+
transport: { type: "console" },
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
327
|
+
// Should extract from nested JWT, not the service token
|
|
328
|
+
expect(baseEvent.customuser_id).toBe(88888);
|
|
329
|
+
expect(baseEvent.account_id).toBe(99999);
|
|
330
|
+
});
|
|
331
|
+
it("should handle invalid JWT tokens gracefully", async () => {
|
|
332
|
+
// Mock getToken to return an invalid JWT
|
|
333
|
+
mockGetToken.mockResolvedValue("not-a-valid-jwt-token");
|
|
334
|
+
const plugin = eventEmissionPlugin({
|
|
335
|
+
sdk: {},
|
|
336
|
+
context: {
|
|
337
|
+
meta: {},
|
|
338
|
+
options: {
|
|
339
|
+
eventEmission: {
|
|
340
|
+
enabled: true,
|
|
341
|
+
transport: { type: "console" },
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
347
|
+
// Should default to null when JWT is invalid
|
|
348
|
+
expect(baseEvent.customuser_id).toBe(null);
|
|
349
|
+
expect(baseEvent.account_id).toBe(null);
|
|
350
|
+
});
|
|
351
|
+
it("should handle missing token gracefully", async () => {
|
|
352
|
+
// mockGetToken defaults to returning undefined (no token)
|
|
353
|
+
const plugin = eventEmissionPlugin({
|
|
354
|
+
sdk: {},
|
|
355
|
+
context: {
|
|
356
|
+
meta: {},
|
|
357
|
+
options: {
|
|
358
|
+
eventEmission: {
|
|
359
|
+
enabled: true,
|
|
360
|
+
transport: { type: "console" },
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
});
|
|
365
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
366
|
+
// Should default to null when no token is provided
|
|
367
|
+
expect(baseEvent.customuser_id).toBe(null);
|
|
368
|
+
expect(baseEvent.account_id).toBe(null);
|
|
369
|
+
});
|
|
370
|
+
it("should extract user IDs when getToken returns valid JWT", async () => {
|
|
371
|
+
// Create a test JWT token
|
|
372
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
373
|
+
const payload = {
|
|
374
|
+
"zap:acc": "98765",
|
|
375
|
+
sub: "54321",
|
|
376
|
+
sub_type: "customuser",
|
|
377
|
+
};
|
|
378
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
379
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
380
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.test-signature`;
|
|
381
|
+
// Mock getToken to return the JWT
|
|
382
|
+
mockGetToken.mockResolvedValue(testJwt);
|
|
383
|
+
const plugin = eventEmissionPlugin({
|
|
384
|
+
sdk: {},
|
|
385
|
+
context: {
|
|
386
|
+
meta: {},
|
|
387
|
+
options: {
|
|
388
|
+
eventEmission: {
|
|
389
|
+
enabled: true,
|
|
390
|
+
transport: { type: "console" },
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
// Test that createBaseEvent includes the extracted user IDs
|
|
396
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
397
|
+
expect(baseEvent.customuser_id).toBe(54321);
|
|
398
|
+
expect(baseEvent.account_id).toBe(98765);
|
|
399
|
+
});
|
|
400
|
+
it("should handle getToken failures gracefully", async () => {
|
|
401
|
+
// Mock getToken to reject/throw
|
|
402
|
+
mockGetToken.mockRejectedValue(new Error("Token fetch failed"));
|
|
403
|
+
const plugin = eventEmissionPlugin({
|
|
404
|
+
sdk: {},
|
|
405
|
+
context: {
|
|
406
|
+
meta: {},
|
|
407
|
+
options: {
|
|
408
|
+
eventEmission: {
|
|
409
|
+
enabled: true,
|
|
410
|
+
transport: { type: "console" },
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
416
|
+
// Should gracefully fall back to null context
|
|
417
|
+
expect(baseEvent.customuser_id).toBe(null);
|
|
418
|
+
expect(baseEvent.account_id).toBe(null);
|
|
242
419
|
});
|
|
243
420
|
});
|
package/dist/schemas/Action.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare const ActionItemSchema: z.ZodObject<Omit<{
|
|
|
8
8
|
is_important: z.ZodOptional<z.ZodBoolean>;
|
|
9
9
|
is_hidden: z.ZodOptional<z.ZodBoolean>;
|
|
10
10
|
selected_api: z.ZodOptional<z.ZodString>;
|
|
11
|
-
}, "type" | "
|
|
11
|
+
}, "type" | "selected_api" | "name"> & {
|
|
12
12
|
app_key: z.ZodString;
|
|
13
13
|
app_version: z.ZodOptional<z.ZodString>;
|
|
14
14
|
action_type: z.ZodEnum<["filter", "read", "read_bulk", "run", "search", "search_and_write", "search_or_write", "write"]>;
|
package/dist/schemas/Auth.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
20
20
|
groups: z.ZodOptional<z.ZodString>;
|
|
21
21
|
members: z.ZodOptional<z.ZodString>;
|
|
22
22
|
permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
23
|
-
}, "
|
|
23
|
+
}, "customuser_id" | "selected_api"> & {
|
|
24
24
|
implementation_id: z.ZodOptional<z.ZodString>;
|
|
25
25
|
is_expired: z.ZodOptional<z.ZodString>;
|
|
26
26
|
expired_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -28,9 +28,9 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
28
28
|
app_version: z.ZodOptional<z.ZodString>;
|
|
29
29
|
user_id: z.ZodOptional<z.ZodNumber>;
|
|
30
30
|
}, "strip", z.ZodTypeAny, {
|
|
31
|
+
account_id: number;
|
|
31
32
|
id: number;
|
|
32
33
|
date: string;
|
|
33
|
-
account_id: number;
|
|
34
34
|
is_invite_only: boolean;
|
|
35
35
|
is_private: boolean;
|
|
36
36
|
shared_with_all: boolean;
|
|
@@ -53,9 +53,9 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
53
53
|
app_key?: string | undefined;
|
|
54
54
|
app_version?: string | undefined;
|
|
55
55
|
}, {
|
|
56
|
+
account_id: number;
|
|
56
57
|
id: number;
|
|
57
58
|
date: string;
|
|
58
|
-
account_id: number;
|
|
59
59
|
is_invite_only: boolean;
|
|
60
60
|
is_private: boolean;
|
|
61
61
|
shared_with_all: boolean;
|
|
@@ -99,7 +99,7 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
99
99
|
groups: z.ZodOptional<z.ZodString>;
|
|
100
100
|
members: z.ZodOptional<z.ZodString>;
|
|
101
101
|
permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
102
|
-
}, "
|
|
102
|
+
}, "customuser_id" | "selected_api"> & {
|
|
103
103
|
implementation_id: z.ZodOptional<z.ZodString>;
|
|
104
104
|
is_expired: z.ZodOptional<z.ZodString>;
|
|
105
105
|
expired_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -107,9 +107,9 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
107
107
|
app_version: z.ZodOptional<z.ZodString>;
|
|
108
108
|
user_id: z.ZodOptional<z.ZodNumber>;
|
|
109
109
|
}, "strip", z.ZodTypeAny, {
|
|
110
|
+
account_id: number;
|
|
110
111
|
id: number;
|
|
111
112
|
date: string;
|
|
112
|
-
account_id: number;
|
|
113
113
|
is_invite_only: boolean;
|
|
114
114
|
is_private: boolean;
|
|
115
115
|
shared_with_all: boolean;
|
|
@@ -132,9 +132,9 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
132
132
|
app_key?: string | undefined;
|
|
133
133
|
app_version?: string | undefined;
|
|
134
134
|
}, {
|
|
135
|
+
account_id: number;
|
|
135
136
|
id: number;
|
|
136
137
|
date: string;
|
|
137
|
-
account_id: number;
|
|
138
138
|
is_invite_only: boolean;
|
|
139
139
|
is_private: boolean;
|
|
140
140
|
shared_with_all: boolean;
|