@zapier/zapier-sdk 0.15.4 → 0.15.8
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 +24 -0
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +14 -4
- package/dist/api/auth.test.d.ts +2 -0
- package/dist/api/auth.test.d.ts.map +1 -0
- package/dist/api/auth.test.js +220 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +18 -32
- package/dist/api/client.methods.test.d.ts +2 -0
- package/dist/api/client.methods.test.d.ts.map +1 -0
- package/dist/api/client.methods.test.js +158 -0
- package/dist/api/client.test.js +27 -11
- package/dist/api/router.d.ts +16 -0
- package/dist/api/router.d.ts.map +1 -0
- package/dist/api/router.js +37 -0
- package/dist/api/router.test.d.ts +2 -0
- package/dist/api/router.test.d.ts.map +1 -0
- package/dist/api/router.test.js +109 -0
- package/dist/auth.d.ts +15 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +25 -0
- package/dist/index.cjs +246 -72
- package/dist/index.d.mts +402 -241
- package/dist/index.mjs +246 -73
- package/dist/plugins/eventEmission/index.d.ts.map +1 -1
- package/dist/plugins/eventEmission/index.js +9 -5
- package/dist/plugins/eventEmission/index.test.js +161 -0
- package/dist/plugins/getAuthentication/index.d.ts +2 -5
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/index.js +3 -24
- package/dist/plugins/getAuthentication/index.test.js +32 -144
- package/dist/plugins/getAuthentication/schemas.d.ts +4 -13
- package/dist/plugins/getAuthentication/schemas.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/schemas.js +1 -11
- package/dist/sdk.d.ts +1 -1
- package/dist/temporary-internal-core/handlers/getAuthentication.d.ts +94 -0
- package/dist/temporary-internal-core/handlers/getAuthentication.d.ts.map +1 -0
- package/dist/temporary-internal-core/handlers/getAuthentication.js +68 -0
- package/dist/temporary-internal-core/handlers/getAuthentication.test.d.ts +2 -0
- package/dist/temporary-internal-core/handlers/getAuthentication.test.d.ts.map +1 -0
- package/dist/temporary-internal-core/handlers/getAuthentication.test.js +248 -0
- package/dist/temporary-internal-core/handlers/listApps.js +1 -1
- package/dist/temporary-internal-core/index.d.ts +2 -0
- package/dist/temporary-internal-core/index.d.ts.map +1 -1
- package/dist/temporary-internal-core/index.js +2 -0
- package/dist/temporary-internal-core/schemas/authentications/index.d.ts +454 -0
- package/dist/temporary-internal-core/schemas/authentications/index.d.ts.map +1 -0
- package/dist/temporary-internal-core/schemas/authentications/index.js +96 -0
- package/dist/temporary-internal-core/schemas/errors/index.d.ts +139 -0
- package/dist/temporary-internal-core/schemas/errors/index.d.ts.map +1 -0
- package/dist/temporary-internal-core/schemas/errors/index.js +129 -0
- package/dist/temporary-internal-core/utils/app-locators.d.ts +0 -20
- package/dist/temporary-internal-core/utils/app-locators.d.ts.map +1 -1
- package/dist/temporary-internal-core/utils/app-locators.js +1 -45
- package/dist/temporary-internal-core/utils/string-utils.d.ts +28 -0
- package/dist/temporary-internal-core/utils/string-utils.d.ts.map +1 -0
- package/dist/temporary-internal-core/utils/string-utils.js +52 -0
- package/dist/temporary-internal-core/utils/transformations.d.ts +14 -0
- package/dist/temporary-internal-core/utils/transformations.d.ts.map +1 -1
- package/dist/temporary-internal-core/utils/transformations.js +37 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2283,49 +2283,68 @@ var getActionPlugin = ({ sdk }) => {
|
|
|
2283
2283
|
}
|
|
2284
2284
|
};
|
|
2285
2285
|
};
|
|
2286
|
-
var
|
|
2286
|
+
var AuthenticationSchema2 = z.object({
|
|
2287
|
+
id: z.number(),
|
|
2288
|
+
date: z.string(),
|
|
2289
|
+
lastchanged: z.string().optional(),
|
|
2290
|
+
account_id: z.number(),
|
|
2291
|
+
customuser_id: z.number().optional(),
|
|
2292
|
+
selected_api: z.string(),
|
|
2293
|
+
destination_selected_api: z.string().nullable().optional(),
|
|
2294
|
+
is_invite_only: z.boolean(),
|
|
2295
|
+
is_private: z.boolean(),
|
|
2296
|
+
shared_with_all: z.boolean(),
|
|
2297
|
+
is_stale: z.string().optional(),
|
|
2298
|
+
is_shared: z.string().optional(),
|
|
2299
|
+
marked_stale_at: z.string().nullable().optional(),
|
|
2300
|
+
label: z.string().nullable().optional(),
|
|
2301
|
+
identifier: z.string().nullable().optional(),
|
|
2302
|
+
title: z.string().nullable().optional(),
|
|
2303
|
+
url: z.string().optional(),
|
|
2304
|
+
groups: z.string().optional(),
|
|
2305
|
+
members: z.string().optional(),
|
|
2306
|
+
permissions: z.record(z.boolean()).optional()
|
|
2307
|
+
});
|
|
2308
|
+
z.object({
|
|
2309
|
+
count: z.number(),
|
|
2310
|
+
next: z.string().nullable().optional(),
|
|
2311
|
+
previous: z.string().nullable().optional(),
|
|
2312
|
+
results: z.array(AuthenticationSchema2)
|
|
2313
|
+
});
|
|
2314
|
+
var AuthenticationItemSchema2 = AuthenticationSchema2.omit({
|
|
2315
|
+
selected_api: true,
|
|
2316
|
+
customuser_id: true
|
|
2317
|
+
}).extend({
|
|
2318
|
+
// Renamed fields
|
|
2319
|
+
implementation_id: z.string().optional(),
|
|
2320
|
+
user_id: z.number().optional(),
|
|
2321
|
+
// Mapped fields (originals preserved in ...restOfAuth)
|
|
2322
|
+
is_expired: z.string().optional(),
|
|
2323
|
+
expired_at: z.string().nullable().optional(),
|
|
2324
|
+
// Computed fields
|
|
2325
|
+
app_key: z.string().optional(),
|
|
2326
|
+
app_version: z.string().optional()
|
|
2327
|
+
});
|
|
2328
|
+
var GetAuthenticationOptionsSchema = z.object({
|
|
2287
2329
|
authenticationId: z.number().int().positive().describe("Authentication ID to retrieve")
|
|
2288
2330
|
}).describe("Get a specific authentication by ID");
|
|
2331
|
+
var GetAuthenticationHandlerRequestSchema = z.object({
|
|
2332
|
+
authenticationId: z.union([z.string(), z.number()]).describe("Authentication ID - string from searchParams or number")
|
|
2333
|
+
}).transform((data) => ({
|
|
2334
|
+
authenticationId: typeof data.authenticationId === "string" ? parseInt(data.authenticationId, 10) : data.authenticationId
|
|
2335
|
+
}));
|
|
2336
|
+
z.object({
|
|
2337
|
+
data: z.lazy(() => AuthenticationItemSchema2)
|
|
2338
|
+
});
|
|
2289
2339
|
|
|
2290
2340
|
// src/plugins/getAuthentication/index.ts
|
|
2291
2341
|
var getAuthenticationPlugin = ({ context }) => {
|
|
2292
2342
|
const getAuthentication = createFunction(async function getAuthentication2(options) {
|
|
2293
2343
|
const { api } = context;
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
`/zapier/api/v4/authentications/${authenticationId}/`,
|
|
2297
|
-
{
|
|
2298
|
-
customErrorHandler: ({ status }) => {
|
|
2299
|
-
if (status === 401) {
|
|
2300
|
-
return new ZapierAuthenticationError(
|
|
2301
|
-
`Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
|
|
2302
|
-
{ statusCode: status }
|
|
2303
|
-
);
|
|
2304
|
-
}
|
|
2305
|
-
if (status === 403) {
|
|
2306
|
-
return new ZapierAuthenticationError(
|
|
2307
|
-
`Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${status})`,
|
|
2308
|
-
{ statusCode: status }
|
|
2309
|
-
);
|
|
2310
|
-
}
|
|
2311
|
-
if (status === 404) {
|
|
2312
|
-
return new ZapierResourceNotFoundError(
|
|
2313
|
-
`Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${status})`,
|
|
2314
|
-
{
|
|
2315
|
-
resourceType: "Authentication",
|
|
2316
|
-
resourceId: String(authenticationId)
|
|
2317
|
-
}
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
|
-
return void 0;
|
|
2321
|
-
},
|
|
2322
|
-
authRequired: true
|
|
2323
|
-
}
|
|
2344
|
+
return await api.get(
|
|
2345
|
+
`/api/v0/authentications/${options.authenticationId}`
|
|
2324
2346
|
);
|
|
2325
|
-
|
|
2326
|
-
data: normalizeAuthenticationItem(data)
|
|
2327
|
-
};
|
|
2328
|
-
}, GetAuthenticationSchema);
|
|
2347
|
+
}, GetAuthenticationOptionsSchema);
|
|
2329
2348
|
return {
|
|
2330
2349
|
getAuthentication,
|
|
2331
2350
|
context: {
|
|
@@ -2334,7 +2353,7 @@ var getAuthenticationPlugin = ({ context }) => {
|
|
|
2334
2353
|
categories: ["authentication"],
|
|
2335
2354
|
type: "item",
|
|
2336
2355
|
itemType: "Authentication",
|
|
2337
|
-
inputSchema:
|
|
2356
|
+
inputSchema: GetAuthenticationOptionsSchema,
|
|
2338
2357
|
outputSchema: AuthenticationItemSchema,
|
|
2339
2358
|
resolvers: {
|
|
2340
2359
|
authenticationId: authenticationIdGenericResolver
|
|
@@ -3171,6 +3190,12 @@ function isJwt(token) {
|
|
|
3171
3190
|
const base64UrlPattern = /^[A-Za-z0-9_-]+$/;
|
|
3172
3191
|
return parts.every((part) => part.length > 0 && base64UrlPattern.test(part));
|
|
3173
3192
|
}
|
|
3193
|
+
function parseJwt(token) {
|
|
3194
|
+
if (!isJwt(token)) {
|
|
3195
|
+
return null;
|
|
3196
|
+
}
|
|
3197
|
+
return token.split(".");
|
|
3198
|
+
}
|
|
3174
3199
|
function getAuthorizationHeader(token) {
|
|
3175
3200
|
if (isJwt(token)) {
|
|
3176
3201
|
return `JWT ${token}`;
|
|
@@ -3178,11 +3203,11 @@ function getAuthorizationHeader(token) {
|
|
|
3178
3203
|
return `Bearer ${token}`;
|
|
3179
3204
|
}
|
|
3180
3205
|
function extractUserIdsFromJwt(token) {
|
|
3206
|
+
const parts = parseJwt(token);
|
|
3207
|
+
if (!parts) {
|
|
3208
|
+
return { customuser_id: null, account_id: null };
|
|
3209
|
+
}
|
|
3181
3210
|
try {
|
|
3182
|
-
const parts = token.split(".");
|
|
3183
|
-
if (parts.length !== 3) {
|
|
3184
|
-
return { customuser_id: null, account_id: null };
|
|
3185
|
-
}
|
|
3186
3211
|
const payload = JSON.parse(
|
|
3187
3212
|
Buffer.from(parts[1], "base64url").toString("utf-8")
|
|
3188
3213
|
);
|
|
@@ -3489,6 +3514,18 @@ async function getTokenFromEnvOrConfig(options = {}) {
|
|
|
3489
3514
|
}
|
|
3490
3515
|
return getTokenFromCliLogin(options);
|
|
3491
3516
|
}
|
|
3517
|
+
async function resolveAuthToken(options = {}) {
|
|
3518
|
+
if (options.token) {
|
|
3519
|
+
return options.token;
|
|
3520
|
+
}
|
|
3521
|
+
if (options.getToken) {
|
|
3522
|
+
const token = await options.getToken();
|
|
3523
|
+
if (token) {
|
|
3524
|
+
return token;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
return getTokenFromEnvOrConfig(options);
|
|
3528
|
+
}
|
|
3492
3529
|
|
|
3493
3530
|
// src/utils/url-utils.ts
|
|
3494
3531
|
function getZapierBaseUrl(baseUrl) {
|
|
@@ -3536,7 +3573,7 @@ function getTrackingBaseUrl({
|
|
|
3536
3573
|
return ZAPIER_BASE_URL;
|
|
3537
3574
|
}
|
|
3538
3575
|
|
|
3539
|
-
// src/temporary-internal-core/utils/
|
|
3576
|
+
// src/temporary-internal-core/utils/string-utils.ts
|
|
3540
3577
|
function splitVersionedKey2(versionedKey) {
|
|
3541
3578
|
const parts = versionedKey.split("@");
|
|
3542
3579
|
if (parts.length >= 2) {
|
|
@@ -3571,6 +3608,44 @@ function extractPaginationCursor(response) {
|
|
|
3571
3608
|
return void 0;
|
|
3572
3609
|
}
|
|
3573
3610
|
}
|
|
3611
|
+
function normalizeAuthenticationItem2(auth, options = {}) {
|
|
3612
|
+
let appKey = options.app_key;
|
|
3613
|
+
let appVersion = options.app_version;
|
|
3614
|
+
if (auth.selected_api) {
|
|
3615
|
+
const [extractedAppKey, extractedVersion] = splitVersionedKey2(
|
|
3616
|
+
auth.selected_api
|
|
3617
|
+
);
|
|
3618
|
+
if (!appKey) {
|
|
3619
|
+
appKey = extractedAppKey;
|
|
3620
|
+
}
|
|
3621
|
+
if (!appVersion) {
|
|
3622
|
+
appVersion = extractedVersion;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
const {
|
|
3626
|
+
selected_api: selectedApi,
|
|
3627
|
+
customuser_id: userId,
|
|
3628
|
+
...restOfAuth
|
|
3629
|
+
} = auth;
|
|
3630
|
+
return {
|
|
3631
|
+
...restOfAuth,
|
|
3632
|
+
// Pass through all other API response fields except selected_api
|
|
3633
|
+
implementation_id: selectedApi,
|
|
3634
|
+
// Rename selected_api to implementation_id
|
|
3635
|
+
title: auth.title || auth.label || void 0,
|
|
3636
|
+
// Coerce title from label if missing
|
|
3637
|
+
is_expired: auth.is_stale,
|
|
3638
|
+
// Map is_stale to is_expired
|
|
3639
|
+
expired_at: auth.marked_stale_at,
|
|
3640
|
+
// Map marked_stale_at to expired_at
|
|
3641
|
+
app_key: appKey,
|
|
3642
|
+
// App key from implementations endpoint or parsed from selected_api
|
|
3643
|
+
app_version: appVersion,
|
|
3644
|
+
// Version from selected_api or provided
|
|
3645
|
+
user_id: userId
|
|
3646
|
+
// Map customuser_id to user_id
|
|
3647
|
+
};
|
|
3648
|
+
}
|
|
3574
3649
|
|
|
3575
3650
|
// src/temporary-internal-core/handlers/listApps.ts
|
|
3576
3651
|
var DEFAULT_PAGE_SIZE = 20;
|
|
@@ -3665,6 +3740,111 @@ var handleListApps = async ({ request, deps }) => {
|
|
|
3665
3740
|
};
|
|
3666
3741
|
};
|
|
3667
3742
|
|
|
3743
|
+
// src/temporary-internal-core/schemas/errors/index.ts
|
|
3744
|
+
var ZapierError2 = class extends Error {
|
|
3745
|
+
constructor(message, options = {}) {
|
|
3746
|
+
super(message);
|
|
3747
|
+
this.statusCode = options.statusCode;
|
|
3748
|
+
this.errors = options.errors;
|
|
3749
|
+
this.cause = options.cause;
|
|
3750
|
+
this.response = options.response;
|
|
3751
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
3752
|
+
}
|
|
3753
|
+
};
|
|
3754
|
+
var ZapierAuthenticationError2 = class extends ZapierError2 {
|
|
3755
|
+
constructor(message, options = {}) {
|
|
3756
|
+
super(message, options);
|
|
3757
|
+
this.name = "ZapierAuthenticationError";
|
|
3758
|
+
}
|
|
3759
|
+
};
|
|
3760
|
+
var ZapierResourceNotFoundError2 = class extends ZapierError2 {
|
|
3761
|
+
constructor(message, options = {}) {
|
|
3762
|
+
super(message, options);
|
|
3763
|
+
this.name = "ZapierResourceNotFoundError";
|
|
3764
|
+
this.resourceType = options.resourceType;
|
|
3765
|
+
this.resourceId = options.resourceId;
|
|
3766
|
+
}
|
|
3767
|
+
};
|
|
3768
|
+
|
|
3769
|
+
// src/temporary-internal-core/handlers/getAuthentication.ts
|
|
3770
|
+
var handleGetAuthentication = async ({ request, deps }) => {
|
|
3771
|
+
const validatedRequest = GetAuthenticationHandlerRequestSchema.parse(request);
|
|
3772
|
+
const { httpClient } = deps;
|
|
3773
|
+
const { authenticationId } = validatedRequest;
|
|
3774
|
+
const authentication = await httpClient.get(
|
|
3775
|
+
`/zapier/api/v4/authentications/${authenticationId}/`,
|
|
3776
|
+
{
|
|
3777
|
+
authRequired: true,
|
|
3778
|
+
customErrorHandler: ({ status }) => {
|
|
3779
|
+
if (status === 401) {
|
|
3780
|
+
return new ZapierAuthenticationError2(
|
|
3781
|
+
`Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
|
|
3782
|
+
{ statusCode: status }
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
if (status === 403) {
|
|
3786
|
+
return new ZapierAuthenticationError2(
|
|
3787
|
+
`Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${status})`,
|
|
3788
|
+
{ statusCode: status }
|
|
3789
|
+
);
|
|
3790
|
+
}
|
|
3791
|
+
if (status === 404) {
|
|
3792
|
+
return new ZapierResourceNotFoundError2(
|
|
3793
|
+
`Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${status})`,
|
|
3794
|
+
{
|
|
3795
|
+
resourceType: "Authentication",
|
|
3796
|
+
resourceId: String(authenticationId)
|
|
3797
|
+
}
|
|
3798
|
+
);
|
|
3799
|
+
}
|
|
3800
|
+
return void 0;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
);
|
|
3804
|
+
const normalizedAuthentication = normalizeAuthenticationItem2(authentication);
|
|
3805
|
+
return {
|
|
3806
|
+
data: normalizedAuthentication
|
|
3807
|
+
};
|
|
3808
|
+
};
|
|
3809
|
+
|
|
3810
|
+
// src/api/router.ts
|
|
3811
|
+
var routes = [
|
|
3812
|
+
{
|
|
3813
|
+
method: "GET",
|
|
3814
|
+
pattern: /^\/api\/v0\/apps$/,
|
|
3815
|
+
handler: handleListApps,
|
|
3816
|
+
paramMap: []
|
|
3817
|
+
},
|
|
3818
|
+
{
|
|
3819
|
+
method: "GET",
|
|
3820
|
+
pattern: /^\/api\/v0\/authentications\/([^\/]+)$/,
|
|
3821
|
+
handler: handleGetAuthentication,
|
|
3822
|
+
paramMap: ["authenticationId"]
|
|
3823
|
+
}
|
|
3824
|
+
];
|
|
3825
|
+
function findMatchingRoute(routeList, method, path) {
|
|
3826
|
+
for (const route of routeList) {
|
|
3827
|
+
if (route.method !== method) {
|
|
3828
|
+
continue;
|
|
3829
|
+
}
|
|
3830
|
+
const match = path.match(route.pattern);
|
|
3831
|
+
if (match) {
|
|
3832
|
+
const params = {};
|
|
3833
|
+
route.paramMap.forEach((name, index) => {
|
|
3834
|
+
params[name] = match[index + 1];
|
|
3835
|
+
});
|
|
3836
|
+
return {
|
|
3837
|
+
handler: route.handler,
|
|
3838
|
+
params
|
|
3839
|
+
};
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
return null;
|
|
3843
|
+
}
|
|
3844
|
+
function matchRoute(method, path) {
|
|
3845
|
+
return findMatchingRoute(routes, method, path);
|
|
3846
|
+
}
|
|
3847
|
+
|
|
3668
3848
|
// src/api/client.ts
|
|
3669
3849
|
var pathConfig = {
|
|
3670
3850
|
// e.g. /relay -> https://sdkapi.zapier.com/api/v0/sdk/relay/...
|
|
@@ -3676,9 +3856,6 @@ var pathConfig = {
|
|
|
3676
3856
|
"/zapier": {
|
|
3677
3857
|
authHeader: "Authorization",
|
|
3678
3858
|
pathPrefix: "/api/v0/sdk/zapier"
|
|
3679
|
-
},
|
|
3680
|
-
"/api/v0/apps": {
|
|
3681
|
-
handlerOverride: handleListApps
|
|
3682
3859
|
}
|
|
3683
3860
|
};
|
|
3684
3861
|
var ZapierApiClient = class {
|
|
@@ -3724,16 +3901,9 @@ var ZapierApiClient = class {
|
|
|
3724
3901
|
}
|
|
3725
3902
|
// Helper to get a token from the different places it could be gotten
|
|
3726
3903
|
async getAuthToken() {
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
if (this.options.getToken) {
|
|
3731
|
-
const token = await this.options.getToken();
|
|
3732
|
-
if (token) {
|
|
3733
|
-
return token;
|
|
3734
|
-
}
|
|
3735
|
-
}
|
|
3736
|
-
return getTokenFromEnvOrConfig({
|
|
3904
|
+
return resolveAuthToken({
|
|
3905
|
+
token: this.options.token,
|
|
3906
|
+
getToken: this.options.getToken,
|
|
3737
3907
|
onEvent: this.options.onEvent,
|
|
3738
3908
|
fetch: this.options.fetch,
|
|
3739
3909
|
baseUrl: this.options.baseUrl,
|
|
@@ -3836,14 +4006,6 @@ var ZapierApiClient = class {
|
|
|
3836
4006
|
}
|
|
3837
4007
|
return void 0;
|
|
3838
4008
|
}
|
|
3839
|
-
// Helper to check if a path config has a handler override
|
|
3840
|
-
hasHandlerOverride(pathConfig2) {
|
|
3841
|
-
return pathConfig2 !== void 0 && "handlerOverride" in pathConfig2 && typeof pathConfig2.handlerOverride === "function";
|
|
3842
|
-
}
|
|
3843
|
-
// Helper to check if a path config is a standard path config
|
|
3844
|
-
isStandardPathConfig(pathConfig2) {
|
|
3845
|
-
return pathConfig2 !== void 0 && !this.hasHandlerOverride(pathConfig2);
|
|
3846
|
-
}
|
|
3847
4009
|
// Helper to parse API error response
|
|
3848
4010
|
parseErrorResponse(errorInfo) {
|
|
3849
4011
|
const fallbackMessage = `HTTP ${errorInfo.status}: ${errorInfo.statusText}`;
|
|
@@ -3895,8 +4057,10 @@ var ZapierApiClient = class {
|
|
|
3895
4057
|
pathConfig: config
|
|
3896
4058
|
};
|
|
3897
4059
|
}
|
|
4060
|
+
const baseUrl = new URL(this.options.baseUrl);
|
|
4061
|
+
const fullPath = baseUrl.pathname.replace(/\/$/, "") + path;
|
|
3898
4062
|
return {
|
|
3899
|
-
url: new URL(
|
|
4063
|
+
url: new URL(fullPath, baseUrl.origin),
|
|
3900
4064
|
pathConfig: config
|
|
3901
4065
|
};
|
|
3902
4066
|
}
|
|
@@ -3915,7 +4079,7 @@ var ZapierApiClient = class {
|
|
|
3915
4079
|
const headers = new Headers(options.headers ?? {});
|
|
3916
4080
|
const authToken = await this.getAuthToken();
|
|
3917
4081
|
if (authToken) {
|
|
3918
|
-
const authHeaderName =
|
|
4082
|
+
const authHeaderName = pathConfig2 && pathConfig2.authHeader ? pathConfig2.authHeader : "Authorization";
|
|
3919
4083
|
headers.set(authHeaderName, getAuthorizationHeader(authToken));
|
|
3920
4084
|
}
|
|
3921
4085
|
if (options.authRequired) {
|
|
@@ -3929,10 +4093,14 @@ var ZapierApiClient = class {
|
|
|
3929
4093
|
}
|
|
3930
4094
|
// Helper to perform HTTP requests with JSON handling
|
|
3931
4095
|
async fetchJson(method, path, data, options = {}) {
|
|
3932
|
-
const
|
|
3933
|
-
if (
|
|
3934
|
-
const handlerRequest =
|
|
3935
|
-
|
|
4096
|
+
const routeMatch = matchRoute(method, path);
|
|
4097
|
+
if (routeMatch) {
|
|
4098
|
+
const handlerRequest = {
|
|
4099
|
+
...typeof data === "object" ? data : {},
|
|
4100
|
+
...options.searchParams,
|
|
4101
|
+
...routeMatch.params
|
|
4102
|
+
};
|
|
4103
|
+
return routeMatch.handler({
|
|
3936
4104
|
request: handlerRequest,
|
|
3937
4105
|
deps: {
|
|
3938
4106
|
httpClient: this
|
|
@@ -4601,7 +4769,7 @@ function getCpuTime() {
|
|
|
4601
4769
|
|
|
4602
4770
|
// package.json
|
|
4603
4771
|
var package_default = {
|
|
4604
|
-
version: "0.15.
|
|
4772
|
+
version: "0.15.8"};
|
|
4605
4773
|
|
|
4606
4774
|
// src/plugins/eventEmission/builders.ts
|
|
4607
4775
|
function createBaseEvent(context = {}) {
|
|
@@ -4741,9 +4909,14 @@ var eventEmissionPlugin = ({ context }) => {
|
|
|
4741
4909
|
};
|
|
4742
4910
|
const getUserContext = (async () => {
|
|
4743
4911
|
try {
|
|
4744
|
-
const
|
|
4745
|
-
|
|
4746
|
-
|
|
4912
|
+
const token = await resolveAuthToken({
|
|
4913
|
+
token: context.options.token,
|
|
4914
|
+
getToken: context.options.getToken,
|
|
4915
|
+
baseUrl: context.options.baseUrl,
|
|
4916
|
+
authBaseUrl: context.options.authBaseUrl,
|
|
4917
|
+
authClientId: context.options.authClientId,
|
|
4918
|
+
onEvent: context.options.onEvent,
|
|
4919
|
+
fetch: context.options.fetch
|
|
4747
4920
|
});
|
|
4748
4921
|
if (token) {
|
|
4749
4922
|
return extractUserIdsFromJwt(token);
|
|
@@ -4984,4 +5157,4 @@ function createZapierSdk(options = {}) {
|
|
|
4984
5157
|
return createZapierSdkWithoutRegistry(options).addPlugin(registryPlugin);
|
|
4985
5158
|
}
|
|
4986
5159
|
|
|
4987
|
-
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 };
|
|
5160
|
+
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, resolveAuthToken, runActionPlugin, toSnakeCase, toTitleCase };
|
|
@@ -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;
|
|
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;AAgBnE,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,OAAO,CAAC,SAAS,CAAC,CAAC;KACvC,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AA4FD,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,CA6QtB,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,6 +7,7 @@
|
|
|
7
7
|
import { createTransport } from "./transport";
|
|
8
8
|
import { generateEventId, getCurrentTimestamp, getReleaseId } from "./utils";
|
|
9
9
|
import { extractUserIdsFromJwt } from "../../api/auth";
|
|
10
|
+
import { resolveAuthToken } from "../../auth";
|
|
10
11
|
import { buildApplicationLifecycleEvent, buildErrorEventWithContext, } from "./builders";
|
|
11
12
|
import { getTrackingBaseUrl } from "../../utils/url-utils";
|
|
12
13
|
// Maximum time to wait for telemetry emission before allowing process to exit
|
|
@@ -94,18 +95,21 @@ export const eventEmissionPlugin = ({ context }) => {
|
|
|
94
95
|
// Create getUserContext promise for dynamic user context injection
|
|
95
96
|
const getUserContext = (async () => {
|
|
96
97
|
try {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const token = await getToken({
|
|
98
|
+
const token = await resolveAuthToken({
|
|
99
|
+
token: context.options.token,
|
|
100
|
+
getToken: context.options.getToken,
|
|
101
101
|
baseUrl: context.options.baseUrl,
|
|
102
|
+
authBaseUrl: context.options.authBaseUrl,
|
|
103
|
+
authClientId: context.options.authClientId,
|
|
104
|
+
onEvent: context.options.onEvent,
|
|
105
|
+
fetch: context.options.fetch,
|
|
102
106
|
});
|
|
103
107
|
if (token) {
|
|
104
108
|
return extractUserIdsFromJwt(token);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
catch {
|
|
108
|
-
//
|
|
112
|
+
// Fall back to null context on any error
|
|
109
113
|
}
|
|
110
114
|
return { customuser_id: null, account_id: null };
|
|
111
115
|
})();
|
|
@@ -417,4 +417,165 @@ describe("eventEmissionPlugin", () => {
|
|
|
417
417
|
expect(baseEvent.customuser_id).toBe(null);
|
|
418
418
|
expect(baseEvent.account_id).toBe(null);
|
|
419
419
|
});
|
|
420
|
+
it("should extract user IDs from static token in SDK options", async () => {
|
|
421
|
+
// Create a test JWT token
|
|
422
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
423
|
+
const payload = {
|
|
424
|
+
"zap:acc": "11111",
|
|
425
|
+
sub: "22222",
|
|
426
|
+
sub_type: "customuser",
|
|
427
|
+
};
|
|
428
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
429
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
430
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.static-signature`;
|
|
431
|
+
const plugin = eventEmissionPlugin({
|
|
432
|
+
sdk: {},
|
|
433
|
+
context: {
|
|
434
|
+
meta: {},
|
|
435
|
+
options: {
|
|
436
|
+
token: testJwt,
|
|
437
|
+
eventEmission: {
|
|
438
|
+
enabled: true,
|
|
439
|
+
transport: { type: "console" },
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
445
|
+
// Should extract from static token in options
|
|
446
|
+
expect(baseEvent.customuser_id).toBe(22222);
|
|
447
|
+
expect(baseEvent.account_id).toBe(11111);
|
|
448
|
+
// CLI login package should not be called when token is in options
|
|
449
|
+
expect(mockGetToken).not.toHaveBeenCalled();
|
|
450
|
+
});
|
|
451
|
+
it("should extract user IDs from getToken function in SDK options", async () => {
|
|
452
|
+
// Create a test JWT token
|
|
453
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
454
|
+
const payload = {
|
|
455
|
+
"zap:acc": "33333",
|
|
456
|
+
sub: "44444",
|
|
457
|
+
sub_type: "customuser",
|
|
458
|
+
};
|
|
459
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
460
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
461
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.custom-signature`;
|
|
462
|
+
const customGetToken = vi.fn().mockResolvedValue(testJwt);
|
|
463
|
+
const plugin = eventEmissionPlugin({
|
|
464
|
+
sdk: {},
|
|
465
|
+
context: {
|
|
466
|
+
meta: {},
|
|
467
|
+
options: {
|
|
468
|
+
getToken: customGetToken,
|
|
469
|
+
eventEmission: {
|
|
470
|
+
enabled: true,
|
|
471
|
+
transport: { type: "console" },
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
477
|
+
// Should extract from custom getToken function
|
|
478
|
+
expect(baseEvent.customuser_id).toBe(44444);
|
|
479
|
+
expect(baseEvent.account_id).toBe(33333);
|
|
480
|
+
expect(customGetToken).toHaveBeenCalled();
|
|
481
|
+
// CLI login package should not be called when getToken is in options
|
|
482
|
+
expect(mockGetToken).not.toHaveBeenCalled();
|
|
483
|
+
});
|
|
484
|
+
it("should prioritize static token over getToken function", async () => {
|
|
485
|
+
// Create test JWT tokens
|
|
486
|
+
const staticHeader = { alg: "HS256", typ: "JWT" };
|
|
487
|
+
const staticPayload = {
|
|
488
|
+
"zap:acc": "55555",
|
|
489
|
+
sub: "66666",
|
|
490
|
+
sub_type: "customuser",
|
|
491
|
+
};
|
|
492
|
+
const staticEncodedHeader = Buffer.from(JSON.stringify(staticHeader)).toString("base64url");
|
|
493
|
+
const staticEncodedPayload = Buffer.from(JSON.stringify(staticPayload)).toString("base64url");
|
|
494
|
+
const staticJwt = `${staticEncodedHeader}.${staticEncodedPayload}.static-sig`;
|
|
495
|
+
const customGetToken = vi.fn().mockResolvedValue("should-not-be-used");
|
|
496
|
+
const plugin = eventEmissionPlugin({
|
|
497
|
+
sdk: {},
|
|
498
|
+
context: {
|
|
499
|
+
meta: {},
|
|
500
|
+
options: {
|
|
501
|
+
token: staticJwt,
|
|
502
|
+
getToken: customGetToken,
|
|
503
|
+
eventEmission: {
|
|
504
|
+
enabled: true,
|
|
505
|
+
transport: { type: "console" },
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
});
|
|
510
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
511
|
+
// Should use static token, not getToken
|
|
512
|
+
expect(baseEvent.customuser_id).toBe(66666);
|
|
513
|
+
expect(baseEvent.account_id).toBe(55555);
|
|
514
|
+
expect(customGetToken).not.toHaveBeenCalled();
|
|
515
|
+
expect(mockGetToken).not.toHaveBeenCalled();
|
|
516
|
+
});
|
|
517
|
+
it("should fall back to CLI login when SDK options have no token", async () => {
|
|
518
|
+
// Create a test JWT token for CLI login
|
|
519
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
520
|
+
const payload = {
|
|
521
|
+
"zap:acc": "77777",
|
|
522
|
+
sub: "88888",
|
|
523
|
+
sub_type: "customuser",
|
|
524
|
+
};
|
|
525
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
526
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
527
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.cli-signature`;
|
|
528
|
+
mockGetToken.mockResolvedValue(testJwt);
|
|
529
|
+
const plugin = eventEmissionPlugin({
|
|
530
|
+
sdk: {},
|
|
531
|
+
context: {
|
|
532
|
+
meta: {},
|
|
533
|
+
options: {
|
|
534
|
+
// No token or getToken in options
|
|
535
|
+
eventEmission: {
|
|
536
|
+
enabled: true,
|
|
537
|
+
transport: { type: "console" },
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
543
|
+
// Should fall back to CLI login package
|
|
544
|
+
expect(baseEvent.customuser_id).toBe(88888);
|
|
545
|
+
expect(baseEvent.account_id).toBe(77777);
|
|
546
|
+
expect(mockGetToken).toHaveBeenCalled();
|
|
547
|
+
});
|
|
548
|
+
it("should handle custom getToken returning undefined", async () => {
|
|
549
|
+
const customGetToken = vi.fn().mockResolvedValue(undefined);
|
|
550
|
+
// Also mock CLI login to return a token
|
|
551
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
552
|
+
const payload = {
|
|
553
|
+
"zap:acc": "99999",
|
|
554
|
+
sub: "10101",
|
|
555
|
+
sub_type: "customuser",
|
|
556
|
+
};
|
|
557
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
558
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
559
|
+
const testJwt = `${encodedHeader}.${encodedPayload}.fallback-signature`;
|
|
560
|
+
mockGetToken.mockResolvedValue(testJwt);
|
|
561
|
+
const plugin = eventEmissionPlugin({
|
|
562
|
+
sdk: {},
|
|
563
|
+
context: {
|
|
564
|
+
meta: {},
|
|
565
|
+
options: {
|
|
566
|
+
getToken: customGetToken,
|
|
567
|
+
eventEmission: {
|
|
568
|
+
enabled: true,
|
|
569
|
+
transport: { type: "console" },
|
|
570
|
+
},
|
|
571
|
+
},
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
const baseEvent = await plugin.context.eventEmission.createBaseEvent();
|
|
575
|
+
// Should fall back to CLI login when custom getToken returns undefined
|
|
576
|
+
expect(baseEvent.customuser_id).toBe(10101);
|
|
577
|
+
expect(baseEvent.account_id).toBe(99999);
|
|
578
|
+
expect(customGetToken).toHaveBeenCalled();
|
|
579
|
+
expect(mockGetToken).toHaveBeenCalled();
|
|
580
|
+
});
|
|
420
581
|
});
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { Plugin } from "../../types/plugin";
|
|
2
2
|
import type { ApiClient } from "../../api";
|
|
3
|
-
import type
|
|
4
|
-
import { GetAuthenticationSchema, type GetAuthenticationOptions } from "./schemas";
|
|
3
|
+
import { GetAuthenticationSchema, type GetAuthenticationOptions, type GetAuthenticationResponse } from "./schemas";
|
|
5
4
|
export interface GetAuthenticationPluginProvides {
|
|
6
|
-
getAuthentication: (options: GetAuthenticationOptions) => Promise<
|
|
7
|
-
data: AuthenticationItem;
|
|
8
|
-
}>;
|
|
5
|
+
getAuthentication: (options: GetAuthenticationOptions) => Promise<GetAuthenticationResponse>;
|
|
9
6
|
context: {
|
|
10
7
|
meta: {
|
|
11
8
|
getAuthentication: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/getAuthentication/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/getAuthentication/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,WAAW,CAAC;AAKnB,MAAM,WAAW,+BAA+B;IAC9C,iBAAiB,EAAE,CACjB,OAAO,EAAE,wBAAwB,KAC9B,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,iBAAiB,EAAE;gBACjB,WAAW,EAAE,OAAO,uBAAuB,CAAC;aAC7C,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,EAAE,EAAE,sBAAsB;AAC1B;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAAE,0BAA0B;AAC9C,+BAA+B,CA+BhC,CAAC"}
|