@zapier/policy-context 2.0.0 → 3.0.0-mr.39.da73fd4a
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/README.md +28 -2
- package/dist/index.cjs +229 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +728 -6
- package/dist/index.d.ts +728 -6
- package/dist/index.js +229 -28
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
// src/types.ts
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
function containsUnsafeInteger(value) {
|
|
4
|
+
if (typeof value === "number") {
|
|
5
|
+
return Number.isInteger(value) && !Number.isSafeInteger(value);
|
|
6
|
+
}
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
return value.some(containsUnsafeInteger);
|
|
9
|
+
}
|
|
10
|
+
if (value !== null && typeof value === "object") {
|
|
11
|
+
return Object.values(value).some(containsUnsafeInteger);
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
var SafeJsonValueSchema = z.json().refine((value) => !containsUnsafeInteger(value), {
|
|
16
|
+
message: "JSON integers must be within the IEEE-754 safe range; encode larger identifiers as strings"
|
|
17
|
+
});
|
|
3
18
|
var ParsedUrlSchema = z.object({
|
|
4
19
|
scheme: z.string().describe('URL scheme, e.g. "https"'),
|
|
5
20
|
host: z.string().describe('Hostname, e.g. "api.example.com"'),
|
|
@@ -58,7 +73,7 @@ var HttpRequestContextSchema = z.object({
|
|
|
58
73
|
* `z.json()` still rejects non-JSON values (`Date`, `undefined`,
|
|
59
74
|
* functions) at parse time. Same inferred `JsonValue` type either way.
|
|
60
75
|
*/
|
|
61
|
-
body_json: z.unknown().pipe(
|
|
76
|
+
body_json: z.unknown().pipe(SafeJsonValueSchema).nullable().describe("Parsed JSON body (if applicable)"),
|
|
62
77
|
/** Zapier connection ID used for this request */
|
|
63
78
|
connection_id: z.string().max(255).optional().describe("Zapier connection ID used for this request"),
|
|
64
79
|
/** Optional human-readable reason for the request */
|
|
@@ -76,6 +91,11 @@ var ActionTypeSchema = z.enum([
|
|
|
76
91
|
]).meta({ id: "action_type", description: "Canonical Zapier action type." });
|
|
77
92
|
var ACTION_RESOURCE_SEGMENT_PATTERN = /^[A-Za-z0-9._+-]+(?:@[A-Za-z0-9._+-]+)?$/;
|
|
78
93
|
var ACTION_KEY_SEGMENT_PATTERN = /^[A-Za-z0-9._+:-]+(?:@[A-Za-z0-9._+:-]+)?$/;
|
|
94
|
+
var CONNECTION_ID_CHARS = "[^/*\\x00-\\x20\\x7f-\\xa0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff]";
|
|
95
|
+
var CONNECTION_ID_PATTERN = new RegExp(`^${CONNECTION_ID_CHARS}+$`);
|
|
96
|
+
var CONNECTION_RESOURCE_PATTERN = new RegExp(
|
|
97
|
+
`^connection/(?:\\*|${CONNECTION_ID_CHARS}+)$`
|
|
98
|
+
);
|
|
79
99
|
function parseActionResource(resource) {
|
|
80
100
|
const segments = resource.split("/");
|
|
81
101
|
if (segments.length !== 4 || segments[0] !== "action") {
|
|
@@ -136,7 +156,7 @@ var ActionRunContextInputSchema = z.object({
|
|
|
136
156
|
}),
|
|
137
157
|
connection_id: z.string().max(255).optional().describe("Zapier connection ID used for this request"),
|
|
138
158
|
/** Action input parameters. See body_json above for the pipe rationale. */
|
|
139
|
-
inputs: z.unknown().pipe(
|
|
159
|
+
inputs: z.unknown().pipe(SafeJsonValueSchema).optional().describe("Action input parameters"),
|
|
140
160
|
reason: z.string().max(1024).optional().describe("Optional human-readable reason for the request")
|
|
141
161
|
}).meta({
|
|
142
162
|
id: "ActionRunContext",
|
|
@@ -167,7 +187,7 @@ var ActionRunContextSchema = ActionRunContextInputSchema.transform(
|
|
|
167
187
|
...input.connection_id !== void 0 && {
|
|
168
188
|
connection_id: input.connection_id
|
|
169
189
|
},
|
|
170
|
-
...input.inputs !== void 0 && { inputs: input.inputs },
|
|
190
|
+
...input.inputs !== void 0 && input.inputs !== null && { inputs: input.inputs },
|
|
171
191
|
...input.reason !== void 0 && { reason: input.reason }
|
|
172
192
|
};
|
|
173
193
|
}
|
|
@@ -242,14 +262,14 @@ function buildExactHttpConditions(context) {
|
|
|
242
262
|
conditions.push({
|
|
243
263
|
path: ["url", "query", key],
|
|
244
264
|
operator: "equals",
|
|
245
|
-
value: values
|
|
265
|
+
value: structuredClone(values)
|
|
246
266
|
});
|
|
247
267
|
}
|
|
248
268
|
if (context.body_json !== null) {
|
|
249
269
|
conditions.push({
|
|
250
270
|
path: ["body_json"],
|
|
251
271
|
operator: "equals",
|
|
252
|
-
value: context.body_json
|
|
272
|
+
value: structuredClone(context.body_json)
|
|
253
273
|
});
|
|
254
274
|
} else if (context.body !== null) {
|
|
255
275
|
conditions.push({
|
|
@@ -284,7 +304,7 @@ function buildExactActionConditions(context) {
|
|
|
284
304
|
conditions.push({
|
|
285
305
|
path: ["inputs"],
|
|
286
306
|
operator: "equals",
|
|
287
|
-
value: context.inputs
|
|
307
|
+
value: structuredClone(context.inputs)
|
|
288
308
|
});
|
|
289
309
|
}
|
|
290
310
|
return conditions;
|
|
@@ -309,7 +329,7 @@ var BuildHttpRequestContextOptionsSchema = z2.object({
|
|
|
309
329
|
/** Raw body string */
|
|
310
330
|
body: z2.string().nullable().optional(),
|
|
311
331
|
/** Pre-parsed JSON body (e.g. from Fastify's automatic JSON parsing) */
|
|
312
|
-
body_json:
|
|
332
|
+
body_json: SafeJsonValueSchema.optional(),
|
|
313
333
|
/** Connection ID associated with this request */
|
|
314
334
|
connection_id: z2.string().optional()
|
|
315
335
|
});
|
|
@@ -358,7 +378,7 @@ var BuildActionRunContextOptionsSchema = z2.object({
|
|
|
358
378
|
message: "action_key must contain only [A-Za-z0-9._@:+-] (no globs, slashes, or whitespace)"
|
|
359
379
|
}),
|
|
360
380
|
connection_id: z2.string().optional(),
|
|
361
|
-
inputs:
|
|
381
|
+
inputs: SafeJsonValueSchema.optional(),
|
|
362
382
|
reason: z2.string().optional()
|
|
363
383
|
});
|
|
364
384
|
function buildActionRunContext(options) {
|
|
@@ -379,6 +399,7 @@ function buildActionRunContext(options) {
|
|
|
379
399
|
// src/policies.ts
|
|
380
400
|
function buildAuthStatement(authenticationId) {
|
|
381
401
|
return {
|
|
402
|
+
id: `r_${crypto.randomUUID()}`,
|
|
382
403
|
effect: "allow",
|
|
383
404
|
permissions: ["can_use"],
|
|
384
405
|
resources: [`connection/${authenticationId}`],
|
|
@@ -386,36 +407,38 @@ function buildAuthStatement(authenticationId) {
|
|
|
386
407
|
};
|
|
387
408
|
}
|
|
388
409
|
function httpContextToPolicy(context) {
|
|
389
|
-
const statements = [];
|
|
390
|
-
if (context.connection_id) {
|
|
391
|
-
statements.push(buildAuthStatement(context.connection_id));
|
|
392
|
-
}
|
|
393
410
|
const conditions = buildExactHttpConditions(context);
|
|
394
411
|
conditions.push({
|
|
395
412
|
path: ["url", "query"],
|
|
396
413
|
operator: "keys_in",
|
|
397
414
|
value: Object.keys(context.url.query)
|
|
398
415
|
});
|
|
399
|
-
|
|
416
|
+
const statement = {
|
|
417
|
+
id: `r_${crypto.randomUUID()}`,
|
|
400
418
|
effect: "allow",
|
|
401
419
|
permissions: ["can_execute"],
|
|
402
420
|
resources: ["http"],
|
|
403
421
|
conditions
|
|
404
|
-
}
|
|
405
|
-
|
|
422
|
+
};
|
|
423
|
+
const statements = context.connection_id ? [buildAuthStatement(context.connection_id), statement] : [statement];
|
|
424
|
+
return {
|
|
425
|
+
version: 4,
|
|
426
|
+
rules: [statements]
|
|
427
|
+
};
|
|
406
428
|
}
|
|
407
429
|
function actionContextToPolicy(context) {
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
statements.push(buildAuthStatement(context.connection_id));
|
|
411
|
-
}
|
|
412
|
-
statements.push({
|
|
430
|
+
const statement = {
|
|
431
|
+
id: `r_${crypto.randomUUID()}`,
|
|
413
432
|
effect: "allow",
|
|
414
433
|
permissions: ["can_execute"],
|
|
415
434
|
resources: [context.resource],
|
|
416
435
|
conditions: buildExactActionConditions(context)
|
|
417
|
-
}
|
|
418
|
-
|
|
436
|
+
};
|
|
437
|
+
const statements = context.connection_id ? [buildAuthStatement(context.connection_id), statement] : [statement];
|
|
438
|
+
return {
|
|
439
|
+
version: 4,
|
|
440
|
+
rules: [statements]
|
|
441
|
+
};
|
|
419
442
|
}
|
|
420
443
|
function toExactPolicy(context) {
|
|
421
444
|
if (context.request_type === "http_request") {
|
|
@@ -424,9 +447,162 @@ function toExactPolicy(context) {
|
|
|
424
447
|
return actionContextToPolicy(context);
|
|
425
448
|
}
|
|
426
449
|
|
|
427
|
-
// src/
|
|
450
|
+
// src/zapier-policy.ts
|
|
451
|
+
import { isStatementSubsumedBy } from "@zapier/policy";
|
|
452
|
+
import {
|
|
453
|
+
PolicySchema
|
|
454
|
+
} from "@zapier/policy-schema";
|
|
428
455
|
import { z as z3 } from "zod";
|
|
429
|
-
var
|
|
456
|
+
var SELECTED_API_GLOB_PART_PATTERN = /^[A-Za-z0-9._+*-]+$/;
|
|
457
|
+
var ACTION_KEY_GLOB_PART_PATTERN = /^[A-Za-z0-9._+:*-]+$/;
|
|
458
|
+
var PERMISSIONS = /* @__PURE__ */ new Set([
|
|
459
|
+
"can_execute",
|
|
460
|
+
"can_use",
|
|
461
|
+
"can_view",
|
|
462
|
+
"can_edit",
|
|
463
|
+
"*"
|
|
464
|
+
]);
|
|
465
|
+
var EFFECT_PRECEDENCE = { allow: 0, ask: 1, deny: 2 };
|
|
466
|
+
function isSelectedApiPattern(value) {
|
|
467
|
+
return isGlobSegment(
|
|
468
|
+
value,
|
|
469
|
+
ACTION_RESOURCE_SEGMENT_PATTERN,
|
|
470
|
+
SELECTED_API_GLOB_PART_PATTERN
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
function isActionKeyPattern(value) {
|
|
474
|
+
return isGlobSegment(
|
|
475
|
+
value,
|
|
476
|
+
ACTION_KEY_SEGMENT_PATTERN,
|
|
477
|
+
ACTION_KEY_GLOB_PART_PATTERN
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
function isGlobSegment(value, exactPattern, globPartPattern) {
|
|
481
|
+
if (exactPattern.test(value)) {
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
if (!value.includes("*") || value.includes("**")) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
const parts = value.split("@");
|
|
488
|
+
return parts.length <= 2 && parts.every((part) => globPartPattern.test(part));
|
|
489
|
+
}
|
|
490
|
+
function isActionResourcePattern(value) {
|
|
491
|
+
const segments = value.split("/");
|
|
492
|
+
if (segments.length !== 4 || segments[0] !== "action") {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
const [, selectedApi, actionType, actionKey] = segments;
|
|
496
|
+
return selectedApi !== void 0 && actionType !== void 0 && actionKey !== void 0 && isSelectedApiPattern(selectedApi) && (actionType === "*" || ActionTypeSchema.safeParse(actionType).success) && isActionKeyPattern(actionKey);
|
|
497
|
+
}
|
|
498
|
+
var ActionResourcePatternSchema = z3.string().refine(isActionResourcePattern, {
|
|
499
|
+
message: "Expected action/{selected_api}/{canonical_action_type|*}/{action_key_pattern}"
|
|
500
|
+
});
|
|
501
|
+
function resourceFamily(resource) {
|
|
502
|
+
if (resource === "*" || resource === "http") {
|
|
503
|
+
return resource;
|
|
504
|
+
}
|
|
505
|
+
if (ActionResourcePatternSchema.safeParse(resource).success) {
|
|
506
|
+
return "action";
|
|
507
|
+
}
|
|
508
|
+
if (CONNECTION_RESOURCE_PATTERN.test(resource)) {
|
|
509
|
+
return "connection";
|
|
510
|
+
}
|
|
511
|
+
return void 0;
|
|
512
|
+
}
|
|
513
|
+
function permissionAppliesTo(permission, family) {
|
|
514
|
+
if (permission === "*" || family === "*") {
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
return permission === "can_execute" ? family === "action" || family === "http" : family === "connection";
|
|
518
|
+
}
|
|
519
|
+
function statementGroups(policy) {
|
|
520
|
+
if (policy.version === 4) {
|
|
521
|
+
return policy.rules.map((rules, tierIndex) => ({
|
|
522
|
+
statements: rules,
|
|
523
|
+
path: ["rules", tierIndex],
|
|
524
|
+
entry: "rule"
|
|
525
|
+
}));
|
|
526
|
+
}
|
|
527
|
+
if (policy.version === 3) {
|
|
528
|
+
return policy.statements.map((statements, tierIndex) => ({
|
|
529
|
+
statements,
|
|
530
|
+
path: ["statements", tierIndex],
|
|
531
|
+
entry: "statement"
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
534
|
+
return [
|
|
535
|
+
{
|
|
536
|
+
statements: policy.statements,
|
|
537
|
+
path: ["statements"],
|
|
538
|
+
entry: "statement"
|
|
539
|
+
}
|
|
540
|
+
];
|
|
541
|
+
}
|
|
542
|
+
var ZapierPolicySchema = PolicySchema.superRefine((policy, ctx) => {
|
|
543
|
+
statementGroups(policy).forEach(({ statements, path, entry }) => {
|
|
544
|
+
const Entry = entry === "rule" ? "Rule" : "Statement";
|
|
545
|
+
statements.forEach((statement, statementIndex) => {
|
|
546
|
+
const families = statement.resources.map((resource, resourceIndex) => {
|
|
547
|
+
const family = resourceFamily(resource);
|
|
548
|
+
if (family === void 0) {
|
|
549
|
+
ctx.addIssue({
|
|
550
|
+
code: "custom",
|
|
551
|
+
message: 'Expected "http", "connection/{id|*}", a valid action pattern, or "*"',
|
|
552
|
+
path: [...path, statementIndex, "resources", resourceIndex]
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
return family;
|
|
556
|
+
});
|
|
557
|
+
statement.permissions.forEach((permission, permissionIndex) => {
|
|
558
|
+
if (!PERMISSIONS.has(permission)) {
|
|
559
|
+
ctx.addIssue({
|
|
560
|
+
code: "custom",
|
|
561
|
+
message: `Unknown Zapier permission "${permission}"`,
|
|
562
|
+
path: [...path, statementIndex, "permissions", permissionIndex]
|
|
563
|
+
});
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const incompatibleFamily = families.find(
|
|
567
|
+
(family) => family !== void 0 && !permissionAppliesTo(permission, family)
|
|
568
|
+
);
|
|
569
|
+
if (incompatibleFamily !== void 0) {
|
|
570
|
+
ctx.addIssue({
|
|
571
|
+
code: "custom",
|
|
572
|
+
message: `Permission "${permission}" cannot apply to ${incompatibleFamily} resources`,
|
|
573
|
+
path: [...path, statementIndex, "permissions", permissionIndex]
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
const maskingStatementIndex = statements.findIndex(
|
|
578
|
+
(maskingStatement, maskingIndex) => maskingIndex !== statementIndex && EFFECT_PRECEDENCE[maskingStatement.effect] > EFFECT_PRECEDENCE[statement.effect] && isStatementSubsumedBy(statement, {
|
|
579
|
+
...maskingStatement,
|
|
580
|
+
effect: statement.effect
|
|
581
|
+
})
|
|
582
|
+
);
|
|
583
|
+
if (maskingStatementIndex !== -1) {
|
|
584
|
+
const maskingStatement = statements[maskingStatementIndex];
|
|
585
|
+
const maskingId = maskingStatement.id ? ` (id "${maskingStatement.id}")` : "";
|
|
586
|
+
ctx.addIssue({
|
|
587
|
+
code: "custom",
|
|
588
|
+
message: `${Entry} is entirely masked by higher-precedence ${entry} at index ${maskingStatementIndex}${maskingId}`,
|
|
589
|
+
path: [...path, statementIndex]
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// src/connection-policy.ts
|
|
597
|
+
import { z as z4 } from "zod";
|
|
598
|
+
var AccessLevelSchema = z4.enum(["read", "read_write"]);
|
|
599
|
+
function requireAccessLevel(accessLevel) {
|
|
600
|
+
if (!AccessLevelSchema.safeParse(accessLevel).success) {
|
|
601
|
+
throw new Error(
|
|
602
|
+
`invalid access_level "${accessLevel}": expected "read" or "read_write"`
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
430
606
|
var READ_HTTP_METHODS = ["GET", "HEAD", "OPTIONS"];
|
|
431
607
|
var READ_ACTION_TYPES = [
|
|
432
608
|
"read",
|
|
@@ -446,7 +622,19 @@ function isWriteRequest(context) {
|
|
|
446
622
|
}
|
|
447
623
|
function buildConnectionPolicy(options) {
|
|
448
624
|
const { connectionId, selectedApi, accessLevel } = options;
|
|
625
|
+
requireAccessLevel(accessLevel);
|
|
626
|
+
if (!CONNECTION_ID_PATTERN.test(connectionId)) {
|
|
627
|
+
throw new Error(
|
|
628
|
+
`invalid connection_id "${connectionId}": must not contain "/", "*", or whitespace`
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
if (!ACTION_RESOURCE_SEGMENT_PATTERN.test(selectedApi)) {
|
|
632
|
+
throw new Error(
|
|
633
|
+
`invalid selected_api "${selectedApi}": must not contain "/", "*", or whitespace`
|
|
634
|
+
);
|
|
635
|
+
}
|
|
449
636
|
const authStatement = {
|
|
637
|
+
id: `r_${crypto.randomUUID()}`,
|
|
450
638
|
effect: "allow",
|
|
451
639
|
permissions: ["can_use"],
|
|
452
640
|
resources: [`connection/${connectionId}`],
|
|
@@ -466,6 +654,7 @@ function buildConnectionPolicy(options) {
|
|
|
466
654
|
});
|
|
467
655
|
}
|
|
468
656
|
const httpStatement = {
|
|
657
|
+
id: `r_${crypto.randomUUID()}`,
|
|
469
658
|
effect: "allow",
|
|
470
659
|
permissions: ["can_execute"],
|
|
471
660
|
resources: ["http"],
|
|
@@ -474,20 +663,22 @@ function buildConnectionPolicy(options) {
|
|
|
474
663
|
const apiPattern = globSelectedApiVersion(selectedApi);
|
|
475
664
|
const actionResources = accessLevel === "read" ? READ_ACTION_TYPES.map((t) => `action/${apiPattern}/${t}/*`) : [`action/${apiPattern}/*/*`];
|
|
476
665
|
const actionStatement = {
|
|
666
|
+
id: `r_${crypto.randomUUID()}`,
|
|
477
667
|
effect: "allow",
|
|
478
668
|
permissions: ["can_execute"],
|
|
479
669
|
resources: actionResources,
|
|
480
670
|
conditions: [connectionCondition]
|
|
481
671
|
};
|
|
482
672
|
return {
|
|
483
|
-
version:
|
|
484
|
-
|
|
673
|
+
version: 4,
|
|
674
|
+
rules: [[authStatement, httpStatement, actionStatement]]
|
|
485
675
|
};
|
|
486
676
|
}
|
|
487
677
|
|
|
488
678
|
// src/connectionless-policy.ts
|
|
489
679
|
function buildConnectionlessPolicy(options) {
|
|
490
680
|
const { context, accessLevel } = options;
|
|
681
|
+
requireAccessLevel(accessLevel);
|
|
491
682
|
if (context.request_type === "http_request") {
|
|
492
683
|
const conditions = [
|
|
493
684
|
{
|
|
@@ -504,26 +695,35 @@ function buildConnectionlessPolicy(options) {
|
|
|
504
695
|
});
|
|
505
696
|
}
|
|
506
697
|
const statement2 = {
|
|
698
|
+
id: `r_${crypto.randomUUID()}`,
|
|
507
699
|
effect: "allow",
|
|
508
700
|
permissions: ["can_execute"],
|
|
509
701
|
resources: ["http"],
|
|
510
702
|
conditions
|
|
511
703
|
};
|
|
512
|
-
return {
|
|
704
|
+
return {
|
|
705
|
+
version: 4,
|
|
706
|
+
rules: [[statement2]]
|
|
707
|
+
};
|
|
513
708
|
}
|
|
514
709
|
const { selected_api } = parseActionResource(context.resource);
|
|
515
710
|
const apiPattern = globSelectedApiVersion(selected_api);
|
|
516
711
|
const resources = accessLevel === "read" ? READ_ACTION_TYPES.map((t) => `action/${apiPattern}/${t}/*`) : [`action/${apiPattern}/*/*`];
|
|
517
712
|
const statement = {
|
|
713
|
+
id: `r_${crypto.randomUUID()}`,
|
|
518
714
|
effect: "allow",
|
|
519
715
|
permissions: ["can_execute"],
|
|
520
716
|
resources,
|
|
521
717
|
conditions: []
|
|
522
718
|
};
|
|
523
|
-
return {
|
|
719
|
+
return {
|
|
720
|
+
version: 4,
|
|
721
|
+
rules: [[statement]]
|
|
722
|
+
};
|
|
524
723
|
}
|
|
525
724
|
export {
|
|
526
725
|
AccessLevelSchema,
|
|
726
|
+
ActionResourcePatternSchema,
|
|
527
727
|
ActionRunContextInputSchema,
|
|
528
728
|
ActionRunContextSchema,
|
|
529
729
|
ActionTypeSchema,
|
|
@@ -536,6 +736,7 @@ export {
|
|
|
536
736
|
READ_ACTION_TYPES,
|
|
537
737
|
READ_HTTP_METHODS,
|
|
538
738
|
RequestContextSchema,
|
|
739
|
+
ZapierPolicySchema,
|
|
539
740
|
buildActionResource,
|
|
540
741
|
buildActionRunContext,
|
|
541
742
|
buildBroadActionResource,
|