@zapier/policy-schema 0.15.0 → 0.18.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,14 @@ 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, RUBBERDUCK_POLICY_VERSION];
7
+ var VALID_VERSIONS = [1, 2, 3, RUBBERDUCK_POLICY_VERSION];
8
+ var ID_BASED_VERSIONS = /* @__PURE__ */ new Set([
9
+ 3,
10
+ RUBBERDUCK_POLICY_VERSION
11
+ ]);
8
12
  var VALID_EFFECTS = ["allow", "ask", "deny"];
9
13
  var VALID_OPERATOR_LIST = [
14
+ "all",
10
15
  "equals",
11
16
  "exists",
12
17
  "in",
@@ -15,37 +20,47 @@ var VALID_OPERATOR_LIST = [
15
20
  "matches_host",
16
21
  "matches_path",
17
22
  "matches_url",
23
+ "none",
18
24
  "range",
19
25
  "size",
26
+ "some",
20
27
  "values_in"
21
28
  ];
22
29
  var ScalarSchema = zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean()]);
23
- var PathSchema = zod.z.array(zod.z.union([zod.z.string(), zod.z.number()])).min(1);
30
+ var PathSegmentSchema = zod.z.union([zod.z.string(), zod.z.number().int()]);
31
+ var PathSchema = zod.z.array(PathSegmentSchema).min(1);
32
+ var RelativePathSchema = zod.z.array(PathSegmentSchema);
33
+ var NegateField = { negate: zod.z.boolean().optional() };
24
34
  var ConditionValueSchema = zod.z.json();
25
35
  var EqualsConditionSchema = zod.z.object({
26
36
  path: PathSchema,
27
37
  operator: zod.z.literal("equals"),
28
- value: ConditionValueSchema
38
+ value: ConditionValueSchema,
39
+ ...NegateField
29
40
  }).strict();
30
41
  var InConditionSchema = zod.z.object({
31
42
  path: PathSchema,
32
43
  operator: zod.z.literal("in"),
33
- value: zod.z.array(ScalarSchema).min(1)
44
+ value: zod.z.array(ScalarSchema).min(1),
45
+ ...NegateField
34
46
  }).strict();
35
47
  var MatchesConditionSchema = zod.z.object({
36
48
  path: PathSchema,
37
49
  operator: zod.z.literal("matches"),
38
- value: zod.z.string()
50
+ value: zod.z.string(),
51
+ ...NegateField
39
52
  }).strict();
40
53
  var MatchesHostConditionSchema = zod.z.object({
41
54
  path: PathSchema,
42
55
  operator: zod.z.literal("matches_host"),
43
- value: zod.z.string()
56
+ value: zod.z.string(),
57
+ ...NegateField
44
58
  }).strict();
45
59
  var MatchesPathConditionSchema = zod.z.object({
46
60
  path: PathSchema,
47
61
  operator: zod.z.literal("matches_path"),
48
- value: zod.z.string()
62
+ value: zod.z.string(),
63
+ ...NegateField
49
64
  }).strict();
50
65
  var RangeValueSchema = zod.z.object({
51
66
  min: zod.z.number().finite().optional(),
@@ -56,26 +71,31 @@ var RangeValueSchema = zod.z.object({
56
71
  var RangeConditionSchema = zod.z.object({
57
72
  path: PathSchema,
58
73
  operator: zod.z.literal("range"),
59
- value: RangeValueSchema
74
+ value: RangeValueSchema,
75
+ ...NegateField
60
76
  }).strict();
61
77
  var MatchesUrlConditionSchema = zod.z.object({
62
78
  path: PathSchema,
63
79
  operator: zod.z.literal("matches_url"),
64
- value: zod.z.string()
80
+ value: zod.z.string(),
81
+ ...NegateField
65
82
  }).strict();
66
83
  var ValuesInConditionSchema = zod.z.object({
67
84
  path: PathSchema,
68
85
  operator: zod.z.literal("values_in"),
69
- value: zod.z.array(ScalarSchema).min(1)
86
+ value: zod.z.array(ScalarSchema).min(1),
87
+ ...NegateField
70
88
  }).strict();
71
89
  var ExistsConditionSchema = zod.z.object({
72
90
  path: PathSchema,
73
- operator: zod.z.literal("exists")
91
+ operator: zod.z.literal("exists"),
92
+ ...NegateField
74
93
  }).strict();
75
94
  var KeysInConditionSchema = zod.z.object({
76
95
  path: PathSchema,
77
96
  operator: zod.z.literal("keys_in"),
78
- value: zod.z.array(zod.z.string())
97
+ value: zod.z.array(zod.z.string()),
98
+ ...NegateField
79
99
  }).strict();
80
100
  var SizeValueSchema = zod.z.union([
81
101
  zod.z.number().int().nonnegative(),
@@ -84,7 +104,26 @@ var SizeValueSchema = zod.z.union([
84
104
  var SizeConditionSchema = zod.z.object({
85
105
  path: PathSchema,
86
106
  operator: zod.z.literal("size"),
87
- value: SizeValueSchema
107
+ value: SizeValueSchema,
108
+ ...NegateField
109
+ }).strict();
110
+ var RelativeConditionSchema = zod.z.union([
111
+ EqualsConditionSchema.extend({ path: RelativePathSchema }),
112
+ InConditionSchema.extend({ path: RelativePathSchema }),
113
+ MatchesConditionSchema.extend({ path: RelativePathSchema }),
114
+ MatchesHostConditionSchema.extend({ path: RelativePathSchema }),
115
+ MatchesPathConditionSchema.extend({ path: RelativePathSchema }),
116
+ RangeConditionSchema.extend({ path: RelativePathSchema }),
117
+ MatchesUrlConditionSchema.extend({ path: RelativePathSchema }),
118
+ ValuesInConditionSchema.extend({ path: RelativePathSchema }),
119
+ ExistsConditionSchema.extend({ path: RelativePathSchema }),
120
+ KeysInConditionSchema.extend({ path: RelativePathSchema }),
121
+ SizeConditionSchema.extend({ path: RelativePathSchema })
122
+ ]);
123
+ var QuantifierConditionSchema = zod.z.object({
124
+ path: PathSchema,
125
+ operator: zod.z.enum(["some", "all", "none"]),
126
+ where: zod.z.array(RelativeConditionSchema).min(1)
88
127
  }).strict();
89
128
  var ConditionSchema = zod.z.union([
90
129
  // Scalar operators
@@ -101,7 +140,8 @@ var ConditionSchema = zod.z.union([
101
140
  // Other operators
102
141
  ExistsConditionSchema,
103
142
  KeysInConditionSchema,
104
- SizeConditionSchema
143
+ SizeConditionSchema,
144
+ QuantifierConditionSchema
105
145
  ]);
106
146
  var ScalarOperatorSchema = zod.z.enum([
107
147
  "equals",
@@ -111,7 +151,7 @@ var ScalarOperatorSchema = zod.z.enum([
111
151
  "matches_path",
112
152
  "range"
113
153
  ]);
114
- var ArrayOperatorSchema = zod.z.enum(["values_in"]);
154
+ var ArrayOperatorSchema = zod.z.enum(["values_in", "some", "all", "none"]);
115
155
  var UrlOperatorSchema = zod.z.enum(["matches_url"]);
116
156
  var OtherOperatorSchema = zod.z.enum(["exists", "keys_in", "size"]);
117
157
  var OperatorSchema = zod.z.enum([
@@ -126,6 +166,9 @@ var OperatorSchema = zod.z.enum([
126
166
  "matches_url",
127
167
  // Array
128
168
  "values_in",
169
+ "some",
170
+ "all",
171
+ "none",
129
172
  // Other
130
173
  "exists",
131
174
  "keys_in",
@@ -170,9 +213,24 @@ var RcRubberduckPolicySchema = zod.z.object({
170
213
  defaultEffect: DefaultEffectSchema,
171
214
  statements: zod.z.array(RcRubberduckStatementSchema)
172
215
  }).strict();
216
+ var V3_MAX_TIERS = 3;
217
+ var V3StatementSchema = zod.z.object({
218
+ id: StatementIdSchema,
219
+ effect: zod.z.enum(["allow", "ask", "deny"]),
220
+ permissions: zod.z.array(zod.z.string()).min(1),
221
+ resources: zod.z.array(zod.z.string()).min(1),
222
+ conditions: zod.z.array(ConditionSchema).optional()
223
+ }).strict();
224
+ var V3PolicySchema = zod.z.object({
225
+ version: zod.z.literal(3),
226
+ // Ordered tiers, in priority order. 1..V3_MAX_TIERS tiers; a tier may be
227
+ // empty (e.g. `[[]]` denies everything).
228
+ statements: zod.z.array(zod.z.array(V3StatementSchema)).min(1).max(V3_MAX_TIERS)
229
+ }).strict();
173
230
  var PolicySchema = zod.z.union([
174
231
  V1PolicySchema,
175
232
  V2PolicySchema,
233
+ V3PolicySchema,
176
234
  RcRubberduckPolicySchema
177
235
  ]);
178
236
  var CanonicalHashSchema = zod.z.custom(
@@ -237,76 +295,87 @@ var OverrideSchema = zod.z.union([
237
295
  }).strict()
238
296
  ]);
239
297
  function getOpenApiSchema() {
240
- return {
298
+ const statementItems = {
241
299
  type: "object",
242
- required: ["version", "statements"],
300
+ required: ["effect", "permissions", "resources"],
243
301
  properties: {
244
- version: {
245
- anyOf: [
246
- { type: "integer", enum: [1, 2] },
247
- { type: "string", enum: [RUBBERDUCK_POLICY_VERSION] }
248
- ],
249
- description: "Policy schema version. Stable versions are 1 and 2; supported release candidates are rc-rubberduck."
250
- },
251
302
  id: {
252
303
  type: "string",
253
- description: "Policy id (required for rc-rubberduck policies). Must use the p_ prefix and contain no whitespace."
304
+ description: "Statement identifier. Required for v3 and rc-rubberduck policies; must use the s_ prefix with no whitespace. Optional on v1/v2 for debugging and provenance."
254
305
  },
255
- defaultEffect: {
306
+ effect: {
256
307
  type: "string",
257
- enum: [...DefaultEffectSchema.options],
258
- description: "Effect applied when no statement matches. Required on rc-rubberduck policies; deny equals implicit deny."
308
+ enum: [...VALID_EFFECTS].sort(),
309
+ description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2, version 3, and rc-rubberduck policies."
259
310
  },
260
- statements: {
311
+ permissions: {
312
+ type: "array",
313
+ minItems: 1,
314
+ items: { type: "string" },
315
+ description: "List of permission identifiers."
316
+ },
317
+ resources: {
261
318
  type: "array",
262
- description: "List of policy statements defining permissions.",
319
+ minItems: 1,
320
+ items: { type: "string" },
321
+ description: "List of resource identifiers the statement applies to."
322
+ },
323
+ conditions: {
324
+ type: "array",
325
+ description: "Optional conditions that must be met for the statement to apply.",
263
326
  items: {
264
327
  type: "object",
265
- required: ["effect", "permissions", "resources"],
328
+ required: ["path", "operator"],
266
329
  properties: {
267
- id: {
268
- type: "string",
269
- description: "Statement identifier. Required for rc-rubberduck policies; must use the s_ prefix with no whitespace. Optional on v1/v2 for debugging and provenance."
330
+ path: {
331
+ type: "array",
332
+ minItems: 1,
333
+ description: "Path to the value to evaluate in the request context.",
334
+ items: {
335
+ anyOf: [{ type: "string" }, { type: "integer" }]
336
+ }
270
337
  },
271
- effect: {
338
+ operator: {
272
339
  type: "string",
273
- enum: [...VALID_EFFECTS].sort(),
274
- description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2 and rc-rubberduck policies."
340
+ enum: [...VALID_OPERATOR_LIST],
341
+ description: "Comparison operator used to evaluate the condition."
275
342
  },
276
- permissions: {
277
- type: "array",
278
- minItems: 1,
279
- items: { type: "string" },
280
- description: "List of permission identifiers."
343
+ value: {
344
+ description: "Value to compare against using the operator."
281
345
  },
282
- resources: {
283
- type: "array",
284
- minItems: 1,
285
- items: { type: "string" },
286
- description: "List of resource identifiers the statement applies to."
346
+ negate: {
347
+ type: "boolean",
348
+ description: "When true, the condition passes only if the operator would have failed. Not permitted on the some, all, and none quantifiers."
287
349
  },
288
- conditions: {
350
+ where: {
289
351
  type: "array",
290
- description: "Optional conditions that must be met for the statement to apply.",
352
+ minItems: 1,
353
+ description: "Conditions evaluated relative to each collection element for some, all, and none.",
291
354
  items: {
292
355
  type: "object",
293
356
  required: ["path", "operator"],
294
357
  properties: {
295
358
  path: {
296
359
  type: "array",
297
- minItems: 1,
298
- description: "Path to the value to evaluate in the request context.",
360
+ minItems: 0,
361
+ description: "Path relative to the collection element; an empty path selects the element itself.",
299
362
  items: {
300
363
  anyOf: [{ type: "string" }, { type: "integer" }]
301
364
  }
302
365
  },
303
366
  operator: {
304
367
  type: "string",
305
- enum: [...VALID_OPERATOR_LIST],
306
- description: "Comparison operator used to evaluate the condition."
368
+ enum: [...VALID_OPERATOR_LIST].filter(
369
+ (operator) => operator !== "some" && operator !== "all" && operator !== "none"
370
+ ),
371
+ description: "Non-quantifier operator evaluated against the collection element."
307
372
  },
308
373
  value: {
309
374
  description: "Value to compare against using the operator."
375
+ },
376
+ negate: {
377
+ type: "boolean",
378
+ description: "When true, the relative condition passes only if the operator would have failed."
310
379
  }
311
380
  }
312
381
  }
@@ -316,6 +385,42 @@ function getOpenApiSchema() {
316
385
  }
317
386
  }
318
387
  };
388
+ return {
389
+ type: "object",
390
+ required: ["version", "statements"],
391
+ properties: {
392
+ version: {
393
+ anyOf: [
394
+ { type: "integer", enum: [1, 2, 3] },
395
+ { type: "string", enum: [RUBBERDUCK_POLICY_VERSION] }
396
+ ],
397
+ description: "Policy schema version. Stable versions are 1, 2, and 3; supported release candidates are rc-rubberduck."
398
+ },
399
+ id: {
400
+ type: "string",
401
+ description: "Policy id (required for rc-rubberduck policies; not permitted on any other version). Must use the p_ prefix and contain no whitespace."
402
+ },
403
+ defaultEffect: {
404
+ type: "string",
405
+ enum: [...DefaultEffectSchema.options],
406
+ description: "Effect applied when no statement matches. Required on rc-rubberduck policies (deny equals implicit deny); not permitted on any other version."
407
+ },
408
+ statements: {
409
+ type: "array",
410
+ 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.",
411
+ items: {
412
+ anyOf: [
413
+ statementItems,
414
+ {
415
+ type: "array",
416
+ description: "A v3 tier: statements evaluated together with deny > ask > allow precedence.",
417
+ items: statementItems
418
+ }
419
+ ]
420
+ }
421
+ }
422
+ }
423
+ };
319
424
  }
320
425
 
321
426
  exports.ArrayOperatorSchema = ArrayOperatorSchema;
@@ -323,6 +428,7 @@ exports.CanonicalHashSchema = CanonicalHashSchema;
323
428
  exports.ConditionSchema = ConditionSchema;
324
429
  exports.ConditionValueSchema = ConditionValueSchema;
325
430
  exports.DefaultEffectSchema = DefaultEffectSchema;
431
+ exports.ID_BASED_VERSIONS = ID_BASED_VERSIONS;
326
432
  exports.OperatorSchema = OperatorSchema;
327
433
  exports.OtherOperatorSchema = OtherOperatorSchema;
328
434
  exports.OverrideSchema = OverrideSchema;
@@ -335,6 +441,7 @@ exports.SizeValueSchema = SizeValueSchema;
335
441
  exports.StatementIdSchema = StatementIdSchema;
336
442
  exports.StatementSchema = StatementSchema;
337
443
  exports.UrlOperatorSchema = UrlOperatorSchema;
444
+ exports.V3_MAX_TIERS = V3_MAX_TIERS;
338
445
  exports.VALID_EFFECTS = VALID_EFFECTS;
339
446
  exports.VALID_OPERATOR_LIST = VALID_OPERATOR_LIST;
340
447
  exports.VALID_VERSIONS = VALID_VERSIONS;