@zapier/policy-schema 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4,9 +4,10 @@ var zod = require('zod');
4
4
 
5
5
  // src/schema.ts
6
6
  var RUBBERDUCK_POLICY_VERSION = "rc-rubberduck";
7
- var VALID_VERSIONS = [1, 2, 3, RUBBERDUCK_POLICY_VERSION];
7
+ var VALID_VERSIONS = [1, 2, 3, 4, RUBBERDUCK_POLICY_VERSION];
8
8
  var ID_BASED_VERSIONS = /* @__PURE__ */ new Set([
9
9
  3,
10
+ 4,
10
11
  RUBBERDUCK_POLICY_VERSION
11
12
  ]);
12
13
  var VALID_EFFECTS = ["allow", "ask", "deny"];
@@ -27,33 +28,40 @@ var VALID_OPERATOR_LIST = [
27
28
  "values_in"
28
29
  ];
29
30
  var ScalarSchema = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean()]);
30
- var PathSchema = zod.z.array(zod.z.union([zod.z.string(), zod.z.number()])).min(1);
31
- var RelativePathSchema = zod.z.array(zod.z.union([zod.z.string(), zod.z.number()]));
31
+ var PathSegmentSchema = zod.z.union([zod.z.string(), zod.z.number().int()]);
32
+ var PathSchema = zod.z.array(PathSegmentSchema).min(1);
33
+ var RelativePathSchema = zod.z.array(PathSegmentSchema);
34
+ var NegateField = { negate: zod.z.boolean().optional() };
32
35
  var ConditionValueSchema = zod.z.json();
33
36
  var EqualsConditionSchema = zod.z.object({
34
37
  path: PathSchema,
35
38
  operator: zod.z.literal("equals"),
36
- value: ConditionValueSchema
39
+ value: ConditionValueSchema,
40
+ ...NegateField
37
41
  }).strict();
38
42
  var InConditionSchema = zod.z.object({
39
43
  path: PathSchema,
40
44
  operator: zod.z.literal("in"),
41
- value: zod.z.array(ScalarSchema).min(1)
45
+ value: zod.z.array(ScalarSchema).min(1),
46
+ ...NegateField
42
47
  }).strict();
43
48
  var MatchesConditionSchema = zod.z.object({
44
49
  path: PathSchema,
45
50
  operator: zod.z.literal("matches"),
46
- value: zod.z.string()
51
+ value: zod.z.string(),
52
+ ...NegateField
47
53
  }).strict();
48
54
  var MatchesHostConditionSchema = zod.z.object({
49
55
  path: PathSchema,
50
56
  operator: zod.z.literal("matches_host"),
51
- value: zod.z.string()
57
+ value: zod.z.string(),
58
+ ...NegateField
52
59
  }).strict();
53
60
  var MatchesPathConditionSchema = zod.z.object({
54
61
  path: PathSchema,
55
62
  operator: zod.z.literal("matches_path"),
56
- value: zod.z.string()
63
+ value: zod.z.string(),
64
+ ...NegateField
57
65
  }).strict();
58
66
  var RangeValueSchema = zod.z.object({
59
67
  min: zod.z.number().finite().optional(),
@@ -64,26 +72,31 @@ var RangeValueSchema = zod.z.object({
64
72
  var RangeConditionSchema = zod.z.object({
65
73
  path: PathSchema,
66
74
  operator: zod.z.literal("range"),
67
- value: RangeValueSchema
75
+ value: RangeValueSchema,
76
+ ...NegateField
68
77
  }).strict();
69
78
  var MatchesUrlConditionSchema = zod.z.object({
70
79
  path: PathSchema,
71
80
  operator: zod.z.literal("matches_url"),
72
- value: zod.z.string()
81
+ value: zod.z.string(),
82
+ ...NegateField
73
83
  }).strict();
74
84
  var ValuesInConditionSchema = zod.z.object({
75
85
  path: PathSchema,
76
86
  operator: zod.z.literal("values_in"),
77
- value: zod.z.array(ScalarSchema).min(1)
87
+ value: zod.z.array(ScalarSchema).min(1),
88
+ ...NegateField
78
89
  }).strict();
79
90
  var ExistsConditionSchema = zod.z.object({
80
91
  path: PathSchema,
81
- operator: zod.z.literal("exists")
92
+ operator: zod.z.literal("exists"),
93
+ ...NegateField
82
94
  }).strict();
83
95
  var KeysInConditionSchema = zod.z.object({
84
96
  path: PathSchema,
85
97
  operator: zod.z.literal("keys_in"),
86
- value: zod.z.array(zod.z.string())
98
+ value: zod.z.array(zod.z.string()),
99
+ ...NegateField
87
100
  }).strict();
88
101
  var SizeValueSchema = zod.z.union([
89
102
  zod.z.number().int().nonnegative(),
@@ -92,7 +105,8 @@ var SizeValueSchema = zod.z.union([
92
105
  var SizeConditionSchema = zod.z.object({
93
106
  path: PathSchema,
94
107
  operator: zod.z.literal("size"),
95
- value: SizeValueSchema
108
+ value: SizeValueSchema,
109
+ ...NegateField
96
110
  }).strict();
97
111
  var RelativeConditionSchema = zod.z.union([
98
112
  EqualsConditionSchema.extend({ path: RelativePathSchema }),
@@ -178,6 +192,7 @@ var V2StatementSchema = zod.z.object({
178
192
  var StatementSchema = V2StatementSchema;
179
193
  var StatementIdSchema = zod.z.string().regex(/^s_\S+$/, { error: "Statement id must match ^s_\\S+$" }).max(512);
180
194
  var PolicyIdSchema = zod.z.string().regex(/^p_\S+$/, { error: "Policy id must match ^p_\\S+$" }).max(512);
195
+ var RuleIdSchema = zod.z.string().regex(/^r_\S+$/, { error: "Rule id must match ^r_\\S+$" }).max(512);
181
196
  var V1PolicySchema = zod.z.object({
182
197
  version: zod.z.literal(1),
183
198
  statements: zod.z.array(V1StatementSchema)
@@ -214,10 +229,25 @@ var V3PolicySchema = zod.z.object({
214
229
  // empty (e.g. `[[]]` denies everything).
215
230
  statements: zod.z.array(zod.z.array(V3StatementSchema)).min(1).max(V3_MAX_TIERS)
216
231
  }).strict();
232
+ var V4_MAX_TIERS = 3;
233
+ var V4RuleSchema = zod.z.object({
234
+ id: RuleIdSchema,
235
+ effect: zod.z.enum(["allow", "ask", "deny"]),
236
+ permissions: zod.z.array(zod.z.string()).min(1),
237
+ resources: zod.z.array(zod.z.string()).min(1),
238
+ conditions: zod.z.array(ConditionSchema).optional()
239
+ }).strict();
240
+ var V4PolicySchema = zod.z.object({
241
+ version: zod.z.literal(4),
242
+ // Ordered tiers, in priority order. 1..V4_MAX_TIERS tiers; a tier may be
243
+ // empty (e.g. `[[]]` denies everything). Renamed from v3's `statements`.
244
+ rules: zod.z.array(zod.z.array(V4RuleSchema)).min(1).max(V4_MAX_TIERS)
245
+ }).strict();
217
246
  var PolicySchema = zod.z.union([
218
247
  V1PolicySchema,
219
248
  V2PolicySchema,
220
249
  V3PolicySchema,
250
+ V4PolicySchema,
221
251
  RcRubberduckPolicySchema
222
252
  ]);
223
253
  var CanonicalHashSchema = zod.z.custom(
@@ -252,6 +282,12 @@ var OverridePolicyIdBaseShape = {
252
282
  policyId: PolicyIdSchema,
253
283
  effect: zod.z.literal("allow")
254
284
  };
285
+ var OverrideRuleIdBaseShape = {
286
+ id: zod.z.string().optional(),
287
+ /** Targets a v4 rule by id (r_ prefix, non-null). */
288
+ ruleId: RuleIdSchema,
289
+ effect: zod.z.literal("allow")
290
+ };
255
291
  var OverrideSchema = zod.z.union([
256
292
  // statementHash × match
257
293
  zod.z.object({ ...OverrideHashBaseShape, match: zod.z.literal("any") }).strict(),
@@ -279,6 +315,15 @@ var OverrideSchema = zod.z.union([
279
315
  zod.z.object({
280
316
  ...OverridePolicyIdBaseShape,
281
317
  conditionals: zod.z.array(ConditionSchema)
318
+ }).strict(),
319
+ // ruleId × match
320
+ zod.z.object({ ...OverrideRuleIdBaseShape, match: zod.z.literal("any") }).strict(),
321
+ // ruleId × contextHash
322
+ zod.z.object({ ...OverrideRuleIdBaseShape, contextHash: CanonicalHashSchema }).strict(),
323
+ // ruleId × conditionals
324
+ zod.z.object({
325
+ ...OverrideRuleIdBaseShape,
326
+ conditionals: zod.z.array(ConditionSchema)
282
327
  }).strict()
283
328
  ]);
284
329
  function getOpenApiSchema() {
@@ -293,7 +338,7 @@ function getOpenApiSchema() {
293
338
  effect: {
294
339
  type: "string",
295
340
  enum: [...VALID_EFFECTS].sort(),
296
- description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2, version 3, and rc-rubberduck policies."
341
+ description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2, version 3, version 4, and rc-rubberduck policies."
297
342
  },
298
343
  permissions: {
299
344
  type: "array",
@@ -330,6 +375,10 @@ function getOpenApiSchema() {
330
375
  value: {
331
376
  description: "Value to compare against using the operator."
332
377
  },
378
+ negate: {
379
+ type: "boolean",
380
+ description: "When true, the condition passes only if the operator would have failed. Not permitted on the some, all, and none quantifiers."
381
+ },
333
382
  where: {
334
383
  type: "array",
335
384
  minItems: 1,
@@ -355,6 +404,10 @@ function getOpenApiSchema() {
355
404
  },
356
405
  value: {
357
406
  description: "Value to compare against using the operator."
407
+ },
408
+ negate: {
409
+ type: "boolean",
410
+ description: "When true, the relative condition passes only if the operator would have failed."
358
411
  }
359
412
  }
360
413
  }
@@ -364,42 +417,123 @@ function getOpenApiSchema() {
364
417
  }
365
418
  }
366
419
  };
367
- return {
368
- type: "object",
369
- required: ["version", "statements"],
420
+ const ruleItems = {
421
+ ...statementItems,
370
422
  properties: {
371
- version: {
372
- anyOf: [
373
- { type: "integer", enum: [1, 2, 3] },
374
- { type: "string", enum: [RUBBERDUCK_POLICY_VERSION] }
375
- ],
376
- description: "Policy schema version. Stable versions are 1, 2, and 3; supported release candidates are rc-rubberduck."
377
- },
423
+ ...statementItems.properties,
378
424
  id: {
379
425
  type: "string",
380
- description: "Policy id (required for rc-rubberduck policies; not permitted on any other version). Must use the p_ prefix and contain no whitespace."
426
+ description: "Rule identifier. Required for v4 policies; must use the r_ prefix with no whitespace."
381
427
  },
382
- defaultEffect: {
383
- type: "string",
384
- enum: [...DefaultEffectSchema.options],
385
- description: "Effect applied when no statement matches. Required on rc-rubberduck policies (deny equals implicit deny); not permitted on any other version."
428
+ resources: {
429
+ ...statementItems.properties.resources,
430
+ description: "List of resource identifiers the rule applies to."
386
431
  },
387
- statements: {
388
- type: "array",
389
- description: "Policy statements. For v1/v2/rc-rubberduck each entry is a statement. For v3 each entry is a tier (a list of statements); tiers are in priority order and evaluated first-to-last (the first tier with a match decides), so `statements` is a list of lists.",
390
- items: {
391
- anyOf: [
392
- statementItems,
393
- {
394
- type: "array",
395
- description: "A v3 tier: statements evaluated together with deny > ask > allow precedence.",
396
- items: statementItems
397
- }
398
- ]
399
- }
432
+ conditions: {
433
+ ...statementItems.properties.conditions,
434
+ description: "Optional conditions that must be met for the rule to apply."
400
435
  }
401
436
  }
402
437
  };
438
+ const versionDescription = "Policy schema version. Stable versions are 1, 2, 3, and 4; supported release candidates are rc-rubberduck.";
439
+ const flatStatements = {
440
+ type: "array",
441
+ description: "Policy statements; each entry is a statement.",
442
+ items: statementItems
443
+ };
444
+ const statementTiers = {
445
+ type: "array",
446
+ description: "v3 tiers in priority order; each entry is a tier (a list of statements) evaluated first-to-last (the first tier with a match decides), so `statements` is a list of lists.",
447
+ items: {
448
+ type: "array",
449
+ description: "A v3 tier: statements evaluated together with deny > ask > allow precedence.",
450
+ items: statementItems
451
+ }
452
+ };
453
+ const ruleTiers = {
454
+ type: "array",
455
+ description: "v4 rules in priority order; each entry is a tier (a list of rules) evaluated first-to-last (the first tier with a match decides), so `rules` is a list of lists.",
456
+ items: {
457
+ type: "array",
458
+ description: "A v4 tier: rules evaluated together with deny > ask > allow precedence.",
459
+ items: ruleItems
460
+ }
461
+ };
462
+ const idProperty = {
463
+ type: "string",
464
+ description: "Policy id (rc-rubberduck only). Must use the p_ prefix and contain no whitespace."
465
+ };
466
+ const defaultEffectProperty = {
467
+ type: "string",
468
+ enum: [...DefaultEffectSchema.options],
469
+ description: "Effect applied when no statement matches (rc-rubberduck only; deny equals implicit deny)."
470
+ };
471
+ return {
472
+ oneOf: [
473
+ {
474
+ type: "object",
475
+ required: ["version", "statements"],
476
+ properties: {
477
+ version: {
478
+ type: "integer",
479
+ const: 1,
480
+ description: versionDescription
481
+ },
482
+ statements: flatStatements
483
+ }
484
+ },
485
+ {
486
+ type: "object",
487
+ required: ["version", "statements"],
488
+ properties: {
489
+ version: {
490
+ type: "integer",
491
+ const: 2,
492
+ description: versionDescription
493
+ },
494
+ statements: flatStatements
495
+ }
496
+ },
497
+ {
498
+ type: "object",
499
+ required: ["version", "statements"],
500
+ properties: {
501
+ version: {
502
+ type: "integer",
503
+ const: 3,
504
+ description: versionDescription
505
+ },
506
+ statements: statementTiers
507
+ }
508
+ },
509
+ {
510
+ type: "object",
511
+ required: ["version", "rules"],
512
+ properties: {
513
+ version: {
514
+ type: "integer",
515
+ const: 4,
516
+ description: versionDescription
517
+ },
518
+ rules: ruleTiers
519
+ }
520
+ },
521
+ {
522
+ type: "object",
523
+ required: ["version", "id", "defaultEffect", "statements"],
524
+ properties: {
525
+ version: {
526
+ type: "string",
527
+ const: RUBBERDUCK_POLICY_VERSION,
528
+ description: versionDescription
529
+ },
530
+ id: idProperty,
531
+ defaultEffect: defaultEffectProperty,
532
+ statements: flatStatements
533
+ }
534
+ }
535
+ ]
536
+ };
403
537
  }
404
538
 
405
539
  exports.ArrayOperatorSchema = ArrayOperatorSchema;
@@ -415,12 +549,14 @@ exports.PolicyIdSchema = PolicyIdSchema;
415
549
  exports.PolicySchema = PolicySchema;
416
550
  exports.RUBBERDUCK_POLICY_VERSION = RUBBERDUCK_POLICY_VERSION;
417
551
  exports.RangeValueSchema = RangeValueSchema;
552
+ exports.RuleIdSchema = RuleIdSchema;
418
553
  exports.ScalarOperatorSchema = ScalarOperatorSchema;
419
554
  exports.SizeValueSchema = SizeValueSchema;
420
555
  exports.StatementIdSchema = StatementIdSchema;
421
556
  exports.StatementSchema = StatementSchema;
422
557
  exports.UrlOperatorSchema = UrlOperatorSchema;
423
558
  exports.V3_MAX_TIERS = V3_MAX_TIERS;
559
+ exports.V4_MAX_TIERS = V4_MAX_TIERS;
424
560
  exports.VALID_EFFECTS = VALID_EFFECTS;
425
561
  exports.VALID_OPERATOR_LIST = VALID_OPERATOR_LIST;
426
562
  exports.VALID_VERSIONS = VALID_VERSIONS;