@zapier/zapier-sdk 0.13.7 → 0.13.9
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 +15 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +5 -5
- package/dist/api/client.test.d.ts +2 -0
- package/dist/api/client.test.d.ts.map +1 -0
- package/dist/api/client.test.js +80 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -1
- package/dist/api/polling.d.ts.map +1 -1
- package/dist/api/polling.js +1 -11
- package/dist/api/schemas.d.ts +20 -20
- package/dist/api/types.d.ts +2 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth.d.ts +3 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.test.d.ts +2 -0
- package/dist/auth.test.d.ts.map +1 -0
- package/dist/auth.test.js +102 -0
- package/dist/constants.d.ts +4 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/index.cjs +194 -33
- package/dist/index.d.mts +93 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.mjs +192 -34
- package/dist/plugins/api/index.d.ts.map +1 -1
- package/dist/plugins/api/index.js +4 -1
- package/dist/plugins/eventEmission/index.d.ts +2 -0
- package/dist/plugins/eventEmission/index.d.ts.map +1 -1
- package/dist/plugins/eventEmission/index.js +35 -9
- package/dist/plugins/eventEmission/index.test.js +100 -0
- package/dist/schemas/Action.d.ts +2 -2
- package/dist/schemas/Auth.d.ts +4 -4
- package/dist/schemas/Field.d.ts +10 -10
- package/dist/sdk.test.js +121 -1
- package/dist/types/sdk.d.ts +3 -0
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/batch-utils.d.ts +72 -0
- package/dist/utils/batch-utils.d.ts.map +1 -0
- package/dist/utils/batch-utils.js +162 -0
- package/dist/utils/batch-utils.test.d.ts +2 -0
- package/dist/utils/batch-utils.test.d.ts.map +1 -0
- package/dist/utils/batch-utils.test.js +476 -0
- package/dist/utils/retry-utils.d.ts +45 -0
- package/dist/utils/retry-utils.d.ts.map +1 -0
- package/dist/utils/retry-utils.js +51 -0
- package/dist/utils/retry-utils.test.d.ts +2 -0
- package/dist/utils/retry-utils.test.d.ts.map +1 -0
- package/dist/utils/retry-utils.test.js +90 -0
- package/dist/utils/url-utils.d.ts +19 -0
- package/dist/utils/url-utils.d.ts.map +1 -0
- package/dist/utils/url-utils.js +62 -0
- package/dist/utils/url-utils.test.d.ts +2 -0
- package/dist/utils/url-utils.test.d.ts.map +1 -0
- package/dist/utils/url-utils.test.js +103 -0
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -32,8 +32,8 @@ function isPositional(schema) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// src/constants.ts
|
|
35
|
+
var ZAPIER_BASE_URL = process.env.ZAPIER_BASE_URL || "https://zapier.com";
|
|
35
36
|
var MAX_PAGE_LIMIT = 1e4;
|
|
36
|
-
var TRACKING_API_ENDPOINT = "https://zapier.com/api/v4/tracking/event/";
|
|
37
37
|
|
|
38
38
|
// src/types/properties.ts
|
|
39
39
|
var AppKeyPropertySchema = withPositional(
|
|
@@ -3079,15 +3079,28 @@ function createDebugFetch(options) {
|
|
|
3079
3079
|
}
|
|
3080
3080
|
};
|
|
3081
3081
|
}
|
|
3082
|
+
|
|
3083
|
+
// src/utils/retry-utils.ts
|
|
3084
|
+
var MAX_CONSECUTIVE_ERRORS = 3;
|
|
3085
|
+
var BASE_ERROR_BACKOFF_MS = 1e3;
|
|
3086
|
+
var JITTER_FACTOR = 0.5;
|
|
3087
|
+
function calculateWaitTime(baseInterval, errorCount) {
|
|
3088
|
+
const jitter = Math.random() * JITTER_FACTOR * baseInterval;
|
|
3089
|
+
const errorBackoff = Math.min(
|
|
3090
|
+
BASE_ERROR_BACKOFF_MS * (errorCount / 2),
|
|
3091
|
+
baseInterval * 2
|
|
3092
|
+
// Cap error backoff at 2x the base interval
|
|
3093
|
+
);
|
|
3094
|
+
return Math.floor(baseInterval + jitter + errorBackoff);
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
// src/api/polling.ts
|
|
3082
3098
|
var DEFAULT_TIMEOUT_MS = 18e4;
|
|
3083
3099
|
var DEFAULT_SUCCESS_STATUS = 200;
|
|
3084
3100
|
var DEFAULT_PENDING_STATUS = 202;
|
|
3085
3101
|
var DEFAULT_INITIAL_DELAY_MS = 50;
|
|
3086
3102
|
var DEFAULT_MAX_POLLING_INTERVAL_MS = 1e4;
|
|
3087
|
-
var MAX_CONSECUTIVE_ERRORS = 3;
|
|
3088
3103
|
var MAX_TIMEOUT_BUFFER_MS = 1e4;
|
|
3089
|
-
var BASE_ERROR_BACKOFF_MS = 1e3;
|
|
3090
|
-
var JITTER_FACTOR = 0.5;
|
|
3091
3104
|
var DEFAULT_POLLING_STAGES = [
|
|
3092
3105
|
[125, 125],
|
|
3093
3106
|
// Up to 125ms: poll every 125ms
|
|
@@ -3102,15 +3115,6 @@ var DEFAULT_POLLING_STAGES = [
|
|
|
3102
3115
|
[6e4, 5e3]
|
|
3103
3116
|
// Up to 60s: poll every 5s
|
|
3104
3117
|
];
|
|
3105
|
-
var calculateWaitTime = (baseInterval, errorCount) => {
|
|
3106
|
-
const jitter = Math.random() * JITTER_FACTOR * baseInterval;
|
|
3107
|
-
const errorBackoff = Math.min(
|
|
3108
|
-
BASE_ERROR_BACKOFF_MS * (errorCount / 2),
|
|
3109
|
-
baseInterval * 2
|
|
3110
|
-
// Cap error backoff at 2x the base interval
|
|
3111
|
-
);
|
|
3112
|
-
return Math.floor(baseInterval + jitter + errorBackoff);
|
|
3113
|
-
};
|
|
3114
3118
|
var processResponse = async (response, successStatus, pendingStatus, resultExtractor, errorCount) => {
|
|
3115
3119
|
if (!response.ok) {
|
|
3116
3120
|
return {
|
|
@@ -3318,7 +3322,10 @@ var ZapierApiClient = class {
|
|
|
3318
3322
|
}
|
|
3319
3323
|
return getTokenFromEnvOrConfig({
|
|
3320
3324
|
onEvent: this.options.onEvent,
|
|
3321
|
-
fetch: this.options.fetch
|
|
3325
|
+
fetch: this.options.fetch,
|
|
3326
|
+
baseUrl: this.options.baseUrl,
|
|
3327
|
+
authBaseUrl: this.options.authBaseUrl,
|
|
3328
|
+
authClientId: this.options.authClientId
|
|
3322
3329
|
});
|
|
3323
3330
|
}
|
|
3324
3331
|
// Helper to handle responses
|
|
@@ -3549,23 +3556,13 @@ var ZapierApiClient = class {
|
|
|
3549
3556
|
}
|
|
3550
3557
|
};
|
|
3551
3558
|
var createZapierApi = (options) => {
|
|
3552
|
-
const {
|
|
3553
|
-
baseUrl,
|
|
3554
|
-
token,
|
|
3555
|
-
getToken,
|
|
3556
|
-
debug = false,
|
|
3557
|
-
fetch: originalFetch = globalThis.fetch,
|
|
3558
|
-
onEvent
|
|
3559
|
-
} = options;
|
|
3559
|
+
const { debug = false, fetch: originalFetch = globalThis.fetch } = options;
|
|
3560
3560
|
const debugLog = createDebugLogger(debug);
|
|
3561
3561
|
const debugFetch = createDebugFetch({ originalFetch, debugLog });
|
|
3562
3562
|
return new ZapierApiClient({
|
|
3563
|
-
|
|
3564
|
-
token,
|
|
3565
|
-
getToken,
|
|
3563
|
+
...options,
|
|
3566
3564
|
debug,
|
|
3567
|
-
fetch: debugFetch
|
|
3568
|
-
onEvent
|
|
3565
|
+
fetch: debugFetch
|
|
3569
3566
|
});
|
|
3570
3567
|
};
|
|
3571
3568
|
|
|
@@ -3573,7 +3570,9 @@ var createZapierApi = (options) => {
|
|
|
3573
3570
|
var apiPlugin = (params) => {
|
|
3574
3571
|
const {
|
|
3575
3572
|
fetch: customFetch = globalThis.fetch,
|
|
3576
|
-
baseUrl =
|
|
3573
|
+
baseUrl = ZAPIER_BASE_URL,
|
|
3574
|
+
authBaseUrl,
|
|
3575
|
+
authClientId,
|
|
3577
3576
|
token,
|
|
3578
3577
|
getToken,
|
|
3579
3578
|
onEvent,
|
|
@@ -3581,6 +3580,8 @@ var apiPlugin = (params) => {
|
|
|
3581
3580
|
} = params.context.options;
|
|
3582
3581
|
const api = createZapierApi({
|
|
3583
3582
|
baseUrl,
|
|
3583
|
+
authBaseUrl,
|
|
3584
|
+
authClientId,
|
|
3584
3585
|
token,
|
|
3585
3586
|
getToken,
|
|
3586
3587
|
debug,
|
|
@@ -3594,6 +3595,94 @@ var apiPlugin = (params) => {
|
|
|
3594
3595
|
}
|
|
3595
3596
|
};
|
|
3596
3597
|
};
|
|
3598
|
+
var DEFAULT_CONCURRENCY = 10;
|
|
3599
|
+
var BATCH_START_DELAY_MS = 25;
|
|
3600
|
+
var DEFAULT_BATCH_TIMEOUT_MS = 18e4;
|
|
3601
|
+
async function batch(tasks, options = {}) {
|
|
3602
|
+
const {
|
|
3603
|
+
concurrency = DEFAULT_CONCURRENCY,
|
|
3604
|
+
retry = true,
|
|
3605
|
+
batchDelay = BATCH_START_DELAY_MS,
|
|
3606
|
+
timeoutMs = DEFAULT_BATCH_TIMEOUT_MS,
|
|
3607
|
+
taskTimeoutMs
|
|
3608
|
+
} = options;
|
|
3609
|
+
if (concurrency <= 0) {
|
|
3610
|
+
throw new Error("Concurrency must be greater than 0");
|
|
3611
|
+
}
|
|
3612
|
+
if (timeoutMs <= 0) {
|
|
3613
|
+
throw new Error("Timeout must be greater than 0");
|
|
3614
|
+
}
|
|
3615
|
+
if (taskTimeoutMs !== void 0 && taskTimeoutMs <= 0) {
|
|
3616
|
+
throw new Error("Task timeout must be greater than 0");
|
|
3617
|
+
}
|
|
3618
|
+
if (tasks.length === 0) {
|
|
3619
|
+
return [];
|
|
3620
|
+
}
|
|
3621
|
+
const startTime = Date.now();
|
|
3622
|
+
const results = new Array(tasks.length);
|
|
3623
|
+
const taskQueue = tasks.map((task, index) => ({
|
|
3624
|
+
index,
|
|
3625
|
+
task,
|
|
3626
|
+
errorCount: 0
|
|
3627
|
+
}));
|
|
3628
|
+
async function executeTask(taskState) {
|
|
3629
|
+
const { index, task, errorCount } = taskState;
|
|
3630
|
+
try {
|
|
3631
|
+
let result;
|
|
3632
|
+
if (taskTimeoutMs !== void 0) {
|
|
3633
|
+
const timeoutPromise = setTimeout$1(taskTimeoutMs).then(() => {
|
|
3634
|
+
throw new ZapierTimeoutError(
|
|
3635
|
+
`Task timed out after ${taskTimeoutMs}ms`
|
|
3636
|
+
);
|
|
3637
|
+
});
|
|
3638
|
+
result = await Promise.race([task(), timeoutPromise]);
|
|
3639
|
+
} else {
|
|
3640
|
+
result = await task();
|
|
3641
|
+
}
|
|
3642
|
+
results[index] = { status: "fulfilled", value: result };
|
|
3643
|
+
} catch (error) {
|
|
3644
|
+
const newErrorCount = errorCount + 1;
|
|
3645
|
+
const isTimeout = error instanceof ZapierTimeoutError;
|
|
3646
|
+
if (retry && !isTimeout && newErrorCount < MAX_CONSECUTIVE_ERRORS) {
|
|
3647
|
+
const waitTime = calculateWaitTime(1e3, newErrorCount);
|
|
3648
|
+
await setTimeout$1(waitTime);
|
|
3649
|
+
taskQueue.push({
|
|
3650
|
+
index,
|
|
3651
|
+
task,
|
|
3652
|
+
errorCount: newErrorCount
|
|
3653
|
+
});
|
|
3654
|
+
} else {
|
|
3655
|
+
results[index] = { status: "rejected", reason: error };
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
async function worker() {
|
|
3660
|
+
while (taskQueue.length > 0) {
|
|
3661
|
+
const elapsedTime = Date.now() - startTime;
|
|
3662
|
+
if (elapsedTime >= timeoutMs) {
|
|
3663
|
+
throw new ZapierTimeoutError(
|
|
3664
|
+
`Batch operation timed out after ${Math.floor(elapsedTime / 1e3)}s. ${taskQueue.length} task(s) not completed.`
|
|
3665
|
+
);
|
|
3666
|
+
}
|
|
3667
|
+
const taskState = taskQueue.shift();
|
|
3668
|
+
if (!taskState) break;
|
|
3669
|
+
await executeTask(taskState);
|
|
3670
|
+
if (taskQueue.length > 0 && batchDelay > 0) {
|
|
3671
|
+
await setTimeout$1(batchDelay);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
const workerCount = Math.min(concurrency, tasks.length);
|
|
3676
|
+
const workers = [];
|
|
3677
|
+
for (let i = 0; i < workerCount; i++) {
|
|
3678
|
+
workers.push(worker());
|
|
3679
|
+
if (i < workerCount - 1 && batchDelay > 0) {
|
|
3680
|
+
await setTimeout$1(batchDelay / 10);
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
await Promise.all(workers);
|
|
3684
|
+
return results;
|
|
3685
|
+
}
|
|
3597
3686
|
|
|
3598
3687
|
// src/plugins/registry/index.ts
|
|
3599
3688
|
var registryPlugin = ({ sdk, context }) => {
|
|
@@ -3978,7 +4067,7 @@ function getCpuTime() {
|
|
|
3978
4067
|
|
|
3979
4068
|
// package.json
|
|
3980
4069
|
var package_default = {
|
|
3981
|
-
version: "0.13.
|
|
4070
|
+
version: "0.13.9"};
|
|
3982
4071
|
|
|
3983
4072
|
// src/plugins/eventEmission/builders.ts
|
|
3984
4073
|
function createBaseEvent(context = {}) {
|
|
@@ -4048,17 +4137,80 @@ function buildErrorEventWithContext(data, context = {}) {
|
|
|
4048
4137
|
};
|
|
4049
4138
|
}
|
|
4050
4139
|
|
|
4140
|
+
// src/utils/url-utils.ts
|
|
4141
|
+
function getZapierBaseUrl(baseUrl) {
|
|
4142
|
+
if (!baseUrl) {
|
|
4143
|
+
return void 0;
|
|
4144
|
+
}
|
|
4145
|
+
try {
|
|
4146
|
+
const url = new URL(baseUrl);
|
|
4147
|
+
const hostname = url.hostname;
|
|
4148
|
+
const hostParts = hostname.split(".");
|
|
4149
|
+
if (hostParts.length < 2) {
|
|
4150
|
+
return void 0;
|
|
4151
|
+
}
|
|
4152
|
+
const hasZapierPart = hostParts.some(
|
|
4153
|
+
(part) => part === "zapier" || part.startsWith("zapier-")
|
|
4154
|
+
);
|
|
4155
|
+
if (!hasZapierPart) {
|
|
4156
|
+
return void 0;
|
|
4157
|
+
}
|
|
4158
|
+
const rootDomain = hostParts.slice(-2).join(".");
|
|
4159
|
+
return `${url.protocol}//${rootDomain}`;
|
|
4160
|
+
} catch {
|
|
4161
|
+
return void 0;
|
|
4162
|
+
}
|
|
4163
|
+
}
|
|
4164
|
+
function getTrackingBaseUrl({
|
|
4165
|
+
trackingBaseUrl,
|
|
4166
|
+
baseUrl
|
|
4167
|
+
}) {
|
|
4168
|
+
if (trackingBaseUrl) {
|
|
4169
|
+
return trackingBaseUrl;
|
|
4170
|
+
}
|
|
4171
|
+
if (process.env.ZAPIER_TRACKING_BASE_URL) {
|
|
4172
|
+
return process.env.ZAPIER_TRACKING_BASE_URL;
|
|
4173
|
+
}
|
|
4174
|
+
if (baseUrl) {
|
|
4175
|
+
const zapierBaseUrl = getZapierBaseUrl(baseUrl);
|
|
4176
|
+
if (zapierBaseUrl) {
|
|
4177
|
+
return zapierBaseUrl;
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
if (baseUrl) {
|
|
4181
|
+
return baseUrl;
|
|
4182
|
+
}
|
|
4183
|
+
return ZAPIER_BASE_URL;
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4051
4186
|
// src/plugins/eventEmission/index.ts
|
|
4052
4187
|
var APPLICATION_LIFECYCLE_EVENT_SUBJECT = "platform.sdk.ApplicationLifecycleEvent";
|
|
4053
4188
|
var ERROR_OCCURRED_EVENT_SUBJECT = "platform.sdk.ErrorOccurredEvent";
|
|
4189
|
+
var transportStates = /* @__PURE__ */ new WeakMap();
|
|
4054
4190
|
async function silentEmit(transport, subject, event) {
|
|
4055
4191
|
try {
|
|
4056
|
-
|
|
4192
|
+
let state = transportStates.get(transport);
|
|
4193
|
+
if (!state) {
|
|
4194
|
+
state = { hasWorked: false, hasLoggedFailure: false };
|
|
4195
|
+
transportStates.set(transport, state);
|
|
4196
|
+
}
|
|
4197
|
+
transport.emit(subject, event).then(() => {
|
|
4198
|
+
state.hasWorked = true;
|
|
4199
|
+
}).catch((error) => {
|
|
4200
|
+
if (!state.hasWorked && !state.hasLoggedFailure) {
|
|
4201
|
+
state.hasLoggedFailure = true;
|
|
4202
|
+
console.warn(
|
|
4203
|
+
`[zapier-sdk] Tracking failed: ${error.message || "Unknown error"}`
|
|
4204
|
+
);
|
|
4205
|
+
console.warn(
|
|
4206
|
+
`[zapier-sdk] Hint: Set trackingBaseUrl parameter or ZAPIER_TRACKING_BASE_URL environment variable if using custom domains`
|
|
4207
|
+
);
|
|
4208
|
+
}
|
|
4057
4209
|
});
|
|
4058
4210
|
} catch {
|
|
4059
4211
|
}
|
|
4060
4212
|
}
|
|
4061
|
-
function getTransportConfig() {
|
|
4213
|
+
function getTransportConfig(options) {
|
|
4062
4214
|
const envTransport = process?.env?.ZAPIER_SDK_TELEMETRY_TRANSPORT;
|
|
4063
4215
|
if (envTransport === "noop" || envTransport === "disabled") {
|
|
4064
4216
|
return { type: "noop" };
|
|
@@ -4066,14 +4218,20 @@ function getTransportConfig() {
|
|
|
4066
4218
|
if (envTransport === "console") {
|
|
4067
4219
|
return { type: "console" };
|
|
4068
4220
|
}
|
|
4069
|
-
const endpoint = process?.env?.ZAPIER_SDK_TELEMETRY_ENDPOINT ||
|
|
4221
|
+
const endpoint = process?.env?.ZAPIER_SDK_TELEMETRY_ENDPOINT || `${getTrackingBaseUrl({
|
|
4222
|
+
trackingBaseUrl: options?.trackingBaseUrl,
|
|
4223
|
+
baseUrl: options?.baseUrl
|
|
4224
|
+
})}/api/v4/tracking/event/`;
|
|
4070
4225
|
return {
|
|
4071
4226
|
type: "http",
|
|
4072
4227
|
endpoint
|
|
4073
4228
|
};
|
|
4074
4229
|
}
|
|
4075
4230
|
var eventEmissionPlugin = ({ context }) => {
|
|
4076
|
-
const defaultTransport = getTransportConfig(
|
|
4231
|
+
const defaultTransport = getTransportConfig({
|
|
4232
|
+
trackingBaseUrl: context.options.trackingBaseUrl,
|
|
4233
|
+
baseUrl: context.options.baseUrl
|
|
4234
|
+
});
|
|
4077
4235
|
const config = {
|
|
4078
4236
|
enabled: context.options.eventEmission?.enabled ?? true,
|
|
4079
4237
|
transport: (
|
|
@@ -4277,4 +4435,4 @@ function createZapierSdk(options = {}) {
|
|
|
4277
4435
|
return createZapierSdkWithoutRegistry(options).addPlugin(registryPlugin);
|
|
4278
4436
|
}
|
|
4279
4437
|
|
|
4280
|
-
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
|
|
4438
|
+
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG;AAG3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE;QACP,GAAG,EAAE,SAAS,CAAC;KAChB,CAAC;CACH;AAGD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,iBAAiB,CA+BvD,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { createZapierApi } from "../../api";
|
|
2
|
+
import { ZAPIER_BASE_URL } from "../../constants";
|
|
2
3
|
// API plugin requires no context and provides api in context
|
|
3
4
|
export const apiPlugin = (params) => {
|
|
4
5
|
// Extract all options - everything passed to the plugin
|
|
5
|
-
const { fetch: customFetch = globalThis.fetch, baseUrl =
|
|
6
|
+
const { fetch: customFetch = globalThis.fetch, baseUrl = ZAPIER_BASE_URL, authBaseUrl, authClientId, token, getToken, onEvent, debug = false, } = params.context.options;
|
|
6
7
|
// Create the API client - it will handle token resolution internally
|
|
7
8
|
const api = createZapierApi({
|
|
8
9
|
baseUrl,
|
|
10
|
+
authBaseUrl,
|
|
11
|
+
authClientId,
|
|
9
12
|
token,
|
|
10
13
|
getToken,
|
|
11
14
|
debug,
|
|
@@ -25,6 +25,8 @@ export interface EventEmissionProvides {
|
|
|
25
25
|
export declare const eventEmissionPlugin: Plugin<{}, {
|
|
26
26
|
options: {
|
|
27
27
|
eventEmission?: EventEmissionConfig;
|
|
28
|
+
trackingBaseUrl?: string;
|
|
29
|
+
baseUrl?: string;
|
|
28
30
|
};
|
|
29
31
|
}, EventEmissionProvides>;
|
|
30
32
|
export type { EventContext, ApplicationLifecycleEventData, EnhancedErrorEventData, } from "./types";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/eventEmission/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAUnE,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAGD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE;QACb,SAAS,EAAE,cAAc,CAAC;QAC1B,MAAM,EAAE,mBAAmB,CAAC;QAE5B,IAAI,CAAC,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;QAErD,eAAe,IAAI,SAAS,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,oBAAoB,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/eventEmission/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAUnE,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAGD,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE;QACb,SAAS,EAAE,cAAc,CAAC;QAC1B,MAAM,EAAE,mBAAmB,CAAC;QAE5B,IAAI,CAAC,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;QAErD,eAAe,IAAI,SAAS,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AA+ED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CACtC,EAAE,EACF;IACE,OAAO,EAAE;QACP,aAAa,CAAC,EAAE,mBAAmB,CAAC;QACpC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,EACD,qBAAqB,CAoMtB,CAAC;AAGF,YAAY,EACV,YAAY,EACZ,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,EAC1B,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,cAAc,SAAS,CAAC"}
|
|
@@ -7,23 +7,42 @@
|
|
|
7
7
|
import { createTransport } from "./transport";
|
|
8
8
|
import { generateEventId, getCurrentTimestamp, getReleaseId } from "./utils";
|
|
9
9
|
import { buildApplicationLifecycleEvent, buildErrorEventWithContext, } from "./builders";
|
|
10
|
-
import {
|
|
10
|
+
import { getTrackingBaseUrl } from "../../utils/url-utils";
|
|
11
11
|
const APPLICATION_LIFECYCLE_EVENT_SUBJECT = "platform.sdk.ApplicationLifecycleEvent";
|
|
12
12
|
const ERROR_OCCURRED_EVENT_SUBJECT = "platform.sdk.ErrorOccurredEvent";
|
|
13
|
-
//
|
|
13
|
+
// Track transport success/failure so we only log failure once.
|
|
14
|
+
const transportStates = new WeakMap();
|
|
15
|
+
// Silent emission wrapper with smart first-failure logging
|
|
14
16
|
async function silentEmit(transport, subject, event) {
|
|
15
17
|
try {
|
|
18
|
+
// Get or initialize state for this transport
|
|
19
|
+
let state = transportStates.get(transport);
|
|
20
|
+
if (!state) {
|
|
21
|
+
state = { hasWorked: false, hasLoggedFailure: false };
|
|
22
|
+
transportStates.set(transport, state);
|
|
23
|
+
}
|
|
16
24
|
// Fire and forget - don't await the transport
|
|
17
|
-
transport
|
|
18
|
-
|
|
25
|
+
transport
|
|
26
|
+
.emit(subject, event)
|
|
27
|
+
.then(() => {
|
|
28
|
+
// Mark as working if any emit succeeds
|
|
29
|
+
state.hasWorked = true;
|
|
30
|
+
})
|
|
31
|
+
.catch((error) => {
|
|
32
|
+
// Only log if we haven't seen it work and haven't logged yet
|
|
33
|
+
if (!state.hasWorked && !state.hasLoggedFailure) {
|
|
34
|
+
state.hasLoggedFailure = true;
|
|
35
|
+
console.warn(`[zapier-sdk] Tracking failed: ${error.message || "Unknown error"}`);
|
|
36
|
+
console.warn(`[zapier-sdk] Hint: Set trackingBaseUrl parameter or ZAPIER_TRACKING_BASE_URL environment variable if using custom domains`);
|
|
37
|
+
}
|
|
19
38
|
});
|
|
20
39
|
}
|
|
21
40
|
catch {
|
|
22
41
|
// Silently ignore all errors
|
|
23
42
|
}
|
|
24
43
|
}
|
|
25
|
-
// Helper to get transport config from environment or
|
|
26
|
-
function getTransportConfig() {
|
|
44
|
+
// Helper to get transport config from environment or options
|
|
45
|
+
function getTransportConfig(options) {
|
|
27
46
|
const envTransport = process?.env?.ZAPIER_SDK_TELEMETRY_TRANSPORT;
|
|
28
47
|
if (envTransport === "noop" || envTransport === "disabled") {
|
|
29
48
|
return { type: "noop" };
|
|
@@ -31,15 +50,22 @@ function getTransportConfig() {
|
|
|
31
50
|
if (envTransport === "console") {
|
|
32
51
|
return { type: "console" };
|
|
33
52
|
}
|
|
34
|
-
// Default to HTTP transport
|
|
35
|
-
const endpoint = process?.env?.ZAPIER_SDK_TELEMETRY_ENDPOINT ||
|
|
53
|
+
// Default to HTTP transport with resolved tracking URL
|
|
54
|
+
const endpoint = process?.env?.ZAPIER_SDK_TELEMETRY_ENDPOINT ||
|
|
55
|
+
`${getTrackingBaseUrl({
|
|
56
|
+
trackingBaseUrl: options?.trackingBaseUrl,
|
|
57
|
+
baseUrl: options?.baseUrl,
|
|
58
|
+
})}/api/v4/tracking/event/`;
|
|
36
59
|
return {
|
|
37
60
|
type: "http",
|
|
38
61
|
endpoint,
|
|
39
62
|
};
|
|
40
63
|
}
|
|
41
64
|
export const eventEmissionPlugin = ({ context }) => {
|
|
42
|
-
const defaultTransport = getTransportConfig(
|
|
65
|
+
const defaultTransport = getTransportConfig({
|
|
66
|
+
trackingBaseUrl: context.options.trackingBaseUrl,
|
|
67
|
+
baseUrl: context.options.baseUrl,
|
|
68
|
+
});
|
|
43
69
|
// Merge config: env var takes precedence over options, options take precedence over defaults
|
|
44
70
|
const config = {
|
|
45
71
|
enabled: context.options.eventEmission?.enabled ?? true,
|
|
@@ -119,6 +119,106 @@ describe("eventEmissionPlugin", () => {
|
|
|
119
119
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
120
120
|
expect(failingTransport.emit).toHaveBeenCalled();
|
|
121
121
|
});
|
|
122
|
+
it("should log tracking failure only on first occurrence", async () => {
|
|
123
|
+
// Mock console.warn to track logging calls
|
|
124
|
+
const mockConsoleWarn = vi
|
|
125
|
+
.spyOn(console, "warn")
|
|
126
|
+
.mockImplementation(() => { });
|
|
127
|
+
// Mock transport to throw error
|
|
128
|
+
const failingTransport = {
|
|
129
|
+
emit: vi.fn().mockRejectedValue(new Error("Network error")),
|
|
130
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
131
|
+
};
|
|
132
|
+
vi.mocked(createTransport).mockReturnValueOnce(failingTransport);
|
|
133
|
+
const plugin = eventEmissionPlugin({
|
|
134
|
+
sdk: {},
|
|
135
|
+
context: {
|
|
136
|
+
meta: {},
|
|
137
|
+
options: {
|
|
138
|
+
eventEmission: {
|
|
139
|
+
enabled: true,
|
|
140
|
+
transport: {
|
|
141
|
+
type: "http",
|
|
142
|
+
endpoint: "https://example.com",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
// First event should trigger logging
|
|
149
|
+
plugin.context.eventEmission.emit("test.event.FirstEvent", {
|
|
150
|
+
data: "first",
|
|
151
|
+
});
|
|
152
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
153
|
+
// Verify logging occurred
|
|
154
|
+
const initialLogCount = mockConsoleWarn.mock.calls.length;
|
|
155
|
+
expect(initialLogCount).toBeGreaterThan(0);
|
|
156
|
+
// Second and third events should not trigger additional logging
|
|
157
|
+
plugin.context.eventEmission.emit("test.event.SecondEvent", {
|
|
158
|
+
data: "second",
|
|
159
|
+
});
|
|
160
|
+
plugin.context.eventEmission.emit("test.event.ThirdEvent", {
|
|
161
|
+
data: "third",
|
|
162
|
+
});
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
164
|
+
// Verify no additional logging occurred
|
|
165
|
+
expect(mockConsoleWarn).toHaveBeenCalledTimes(initialLogCount);
|
|
166
|
+
mockConsoleWarn.mockRestore();
|
|
167
|
+
});
|
|
168
|
+
it("should not log failures after a successful emit", async () => {
|
|
169
|
+
// Mock console.warn to track logging calls
|
|
170
|
+
const mockConsoleWarn = vi
|
|
171
|
+
.spyOn(console, "warn")
|
|
172
|
+
.mockImplementation(() => { });
|
|
173
|
+
// Mock transport that succeeds first, then fails
|
|
174
|
+
let callCount = 0;
|
|
175
|
+
const mixedTransport = {
|
|
176
|
+
emit: vi.fn().mockImplementation(() => {
|
|
177
|
+
callCount++;
|
|
178
|
+
if (callCount === 1) {
|
|
179
|
+
return Promise.resolve(); // First call succeeds
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
return Promise.reject(new Error("Network error")); // Subsequent calls fail
|
|
183
|
+
}
|
|
184
|
+
}),
|
|
185
|
+
close: vi.fn().mockResolvedValue(undefined),
|
|
186
|
+
};
|
|
187
|
+
vi.mocked(createTransport).mockReturnValueOnce(mixedTransport);
|
|
188
|
+
const plugin = eventEmissionPlugin({
|
|
189
|
+
sdk: {},
|
|
190
|
+
context: {
|
|
191
|
+
meta: {},
|
|
192
|
+
options: {
|
|
193
|
+
eventEmission: {
|
|
194
|
+
enabled: true,
|
|
195
|
+
transport: {
|
|
196
|
+
type: "http",
|
|
197
|
+
endpoint: "https://example.com",
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
// First emit should succeed
|
|
204
|
+
plugin.context.eventEmission.emit("test.event.SuccessfulEvent", {
|
|
205
|
+
data: "success",
|
|
206
|
+
});
|
|
207
|
+
// Give time for success to be recorded
|
|
208
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
209
|
+
// Subsequent emits should fail but not log
|
|
210
|
+
plugin.context.eventEmission.emit("test.event.FailingEvent1", {
|
|
211
|
+
data: "fail1",
|
|
212
|
+
});
|
|
213
|
+
plugin.context.eventEmission.emit("test.event.FailingEvent2", {
|
|
214
|
+
data: "fail2",
|
|
215
|
+
});
|
|
216
|
+
// Give async emissions time to complete
|
|
217
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
218
|
+
// Should not have logged any warnings because tracking worked initially
|
|
219
|
+
expect(mockConsoleWarn).toHaveBeenCalledTimes(0);
|
|
220
|
+
mockConsoleWarn.mockRestore();
|
|
221
|
+
});
|
|
122
222
|
it("should merge options with defaults", () => {
|
|
123
223
|
const plugin = eventEmissionPlugin({
|
|
124
224
|
sdk: {},
|
package/dist/schemas/Action.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export declare const ActionItemSchema: z.ZodObject<Omit<{
|
|
|
15
15
|
title: z.ZodString;
|
|
16
16
|
type: z.ZodLiteral<"action">;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
|
-
type: "action";
|
|
19
18
|
key: string;
|
|
19
|
+
type: "action";
|
|
20
20
|
description: string;
|
|
21
21
|
title: string;
|
|
22
22
|
app_key: string;
|
|
@@ -26,8 +26,8 @@ export declare const ActionItemSchema: z.ZodObject<Omit<{
|
|
|
26
26
|
is_hidden?: boolean | undefined;
|
|
27
27
|
app_version?: string | undefined;
|
|
28
28
|
}, {
|
|
29
|
-
type: "action";
|
|
30
29
|
key: string;
|
|
30
|
+
type: "action";
|
|
31
31
|
description: string;
|
|
32
32
|
title: string;
|
|
33
33
|
app_key: string;
|
package/dist/schemas/Auth.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
35
35
|
is_private: boolean;
|
|
36
36
|
shared_with_all: boolean;
|
|
37
37
|
url?: string | undefined;
|
|
38
|
+
members?: string | undefined;
|
|
38
39
|
label?: string | null | undefined;
|
|
39
40
|
lastchanged?: string | undefined;
|
|
40
41
|
destination_selected_api?: string | null | undefined;
|
|
@@ -44,7 +45,6 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
44
45
|
identifier?: string | null | undefined;
|
|
45
46
|
title?: string | null | undefined;
|
|
46
47
|
groups?: string | undefined;
|
|
47
|
-
members?: string | undefined;
|
|
48
48
|
permissions?: Record<string, boolean> | undefined;
|
|
49
49
|
user_id?: number | undefined;
|
|
50
50
|
implementation_id?: string | undefined;
|
|
@@ -60,6 +60,7 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
60
60
|
is_private: boolean;
|
|
61
61
|
shared_with_all: boolean;
|
|
62
62
|
url?: string | undefined;
|
|
63
|
+
members?: string | undefined;
|
|
63
64
|
label?: string | null | undefined;
|
|
64
65
|
lastchanged?: string | undefined;
|
|
65
66
|
destination_selected_api?: string | null | undefined;
|
|
@@ -69,7 +70,6 @@ export declare const AuthenticationItemSchema: z.ZodObject<Omit<{
|
|
|
69
70
|
identifier?: string | null | undefined;
|
|
70
71
|
title?: string | null | undefined;
|
|
71
72
|
groups?: string | undefined;
|
|
72
|
-
members?: string | undefined;
|
|
73
73
|
permissions?: Record<string, boolean> | undefined;
|
|
74
74
|
user_id?: number | undefined;
|
|
75
75
|
implementation_id?: string | undefined;
|
|
@@ -114,6 +114,7 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
114
114
|
is_private: boolean;
|
|
115
115
|
shared_with_all: boolean;
|
|
116
116
|
url?: string | undefined;
|
|
117
|
+
members?: string | undefined;
|
|
117
118
|
label?: string | null | undefined;
|
|
118
119
|
lastchanged?: string | undefined;
|
|
119
120
|
destination_selected_api?: string | null | undefined;
|
|
@@ -123,7 +124,6 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
123
124
|
identifier?: string | null | undefined;
|
|
124
125
|
title?: string | null | undefined;
|
|
125
126
|
groups?: string | undefined;
|
|
126
|
-
members?: string | undefined;
|
|
127
127
|
permissions?: Record<string, boolean> | undefined;
|
|
128
128
|
user_id?: number | undefined;
|
|
129
129
|
implementation_id?: string | undefined;
|
|
@@ -139,6 +139,7 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
139
139
|
is_private: boolean;
|
|
140
140
|
shared_with_all: boolean;
|
|
141
141
|
url?: string | undefined;
|
|
142
|
+
members?: string | undefined;
|
|
142
143
|
label?: string | null | undefined;
|
|
143
144
|
lastchanged?: string | undefined;
|
|
144
145
|
destination_selected_api?: string | null | undefined;
|
|
@@ -148,7 +149,6 @@ export declare const AuthItemSchema: z.ZodObject<Omit<{
|
|
|
148
149
|
identifier?: string | null | undefined;
|
|
149
150
|
title?: string | null | undefined;
|
|
150
151
|
groups?: string | undefined;
|
|
151
|
-
members?: string | undefined;
|
|
152
152
|
permissions?: Record<string, boolean> | undefined;
|
|
153
153
|
user_id?: number | undefined;
|
|
154
154
|
implementation_id?: string | undefined;
|