@zapier/policy-schema 0.15.0 → 0.17.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.mjs CHANGED
@@ -2,9 +2,14 @@ import { z } from 'zod';
2
2
 
3
3
  // src/schema.ts
4
4
  var RUBBERDUCK_POLICY_VERSION = "rc-rubberduck";
5
- var VALID_VERSIONS = [1, 2, RUBBERDUCK_POLICY_VERSION];
5
+ var VALID_VERSIONS = [1, 2, 3, RUBBERDUCK_POLICY_VERSION];
6
+ var ID_BASED_VERSIONS = /* @__PURE__ */ new Set([
7
+ 3,
8
+ RUBBERDUCK_POLICY_VERSION
9
+ ]);
6
10
  var VALID_EFFECTS = ["allow", "ask", "deny"];
7
11
  var VALID_OPERATOR_LIST = [
12
+ "all",
8
13
  "equals",
9
14
  "exists",
10
15
  "in",
@@ -13,12 +18,15 @@ var VALID_OPERATOR_LIST = [
13
18
  "matches_host",
14
19
  "matches_path",
15
20
  "matches_url",
21
+ "none",
16
22
  "range",
17
23
  "size",
24
+ "some",
18
25
  "values_in"
19
26
  ];
20
27
  var ScalarSchema = z.union([z.string(), z.number(), z.boolean()]);
21
28
  var PathSchema = z.array(z.union([z.string(), z.number()])).min(1);
29
+ var RelativePathSchema = z.array(z.union([z.string(), z.number()]));
22
30
  var ConditionValueSchema = z.json();
23
31
  var EqualsConditionSchema = z.object({
24
32
  path: PathSchema,
@@ -84,6 +92,24 @@ var SizeConditionSchema = z.object({
84
92
  operator: z.literal("size"),
85
93
  value: SizeValueSchema
86
94
  }).strict();
95
+ var RelativeConditionSchema = z.union([
96
+ EqualsConditionSchema.extend({ path: RelativePathSchema }),
97
+ InConditionSchema.extend({ path: RelativePathSchema }),
98
+ MatchesConditionSchema.extend({ path: RelativePathSchema }),
99
+ MatchesHostConditionSchema.extend({ path: RelativePathSchema }),
100
+ MatchesPathConditionSchema.extend({ path: RelativePathSchema }),
101
+ RangeConditionSchema.extend({ path: RelativePathSchema }),
102
+ MatchesUrlConditionSchema.extend({ path: RelativePathSchema }),
103
+ ValuesInConditionSchema.extend({ path: RelativePathSchema }),
104
+ ExistsConditionSchema.extend({ path: RelativePathSchema }),
105
+ KeysInConditionSchema.extend({ path: RelativePathSchema }),
106
+ SizeConditionSchema.extend({ path: RelativePathSchema })
107
+ ]);
108
+ var QuantifierConditionSchema = z.object({
109
+ path: PathSchema,
110
+ operator: z.enum(["some", "all", "none"]),
111
+ where: z.array(RelativeConditionSchema).min(1)
112
+ }).strict();
87
113
  var ConditionSchema = z.union([
88
114
  // Scalar operators
89
115
  EqualsConditionSchema,
@@ -99,7 +125,8 @@ var ConditionSchema = z.union([
99
125
  // Other operators
100
126
  ExistsConditionSchema,
101
127
  KeysInConditionSchema,
102
- SizeConditionSchema
128
+ SizeConditionSchema,
129
+ QuantifierConditionSchema
103
130
  ]);
104
131
  var ScalarOperatorSchema = z.enum([
105
132
  "equals",
@@ -109,7 +136,7 @@ var ScalarOperatorSchema = z.enum([
109
136
  "matches_path",
110
137
  "range"
111
138
  ]);
112
- var ArrayOperatorSchema = z.enum(["values_in"]);
139
+ var ArrayOperatorSchema = z.enum(["values_in", "some", "all", "none"]);
113
140
  var UrlOperatorSchema = z.enum(["matches_url"]);
114
141
  var OtherOperatorSchema = z.enum(["exists", "keys_in", "size"]);
115
142
  var OperatorSchema = z.enum([
@@ -124,6 +151,9 @@ var OperatorSchema = z.enum([
124
151
  "matches_url",
125
152
  // Array
126
153
  "values_in",
154
+ "some",
155
+ "all",
156
+ "none",
127
157
  // Other
128
158
  "exists",
129
159
  "keys_in",
@@ -168,9 +198,24 @@ var RcRubberduckPolicySchema = z.object({
168
198
  defaultEffect: DefaultEffectSchema,
169
199
  statements: z.array(RcRubberduckStatementSchema)
170
200
  }).strict();
201
+ var V3_MAX_TIERS = 3;
202
+ var V3StatementSchema = z.object({
203
+ id: StatementIdSchema,
204
+ effect: z.enum(["allow", "ask", "deny"]),
205
+ permissions: z.array(z.string()).min(1),
206
+ resources: z.array(z.string()).min(1),
207
+ conditions: z.array(ConditionSchema).optional()
208
+ }).strict();
209
+ var V3PolicySchema = z.object({
210
+ version: z.literal(3),
211
+ // Ordered tiers, in priority order. 1..V3_MAX_TIERS tiers; a tier may be
212
+ // empty (e.g. `[[]]` denies everything).
213
+ statements: z.array(z.array(V3StatementSchema)).min(1).max(V3_MAX_TIERS)
214
+ }).strict();
171
215
  var PolicySchema = z.union([
172
216
  V1PolicySchema,
173
217
  V2PolicySchema,
218
+ V3PolicySchema,
174
219
  RcRubberduckPolicySchema
175
220
  ]);
176
221
  var CanonicalHashSchema = z.custom(
@@ -235,73 +280,76 @@ var OverrideSchema = z.union([
235
280
  }).strict()
236
281
  ]);
237
282
  function getOpenApiSchema() {
238
- return {
283
+ const statementItems = {
239
284
  type: "object",
240
- required: ["version", "statements"],
285
+ required: ["effect", "permissions", "resources"],
241
286
  properties: {
242
- version: {
243
- anyOf: [
244
- { type: "integer", enum: [1, 2] },
245
- { type: "string", enum: [RUBBERDUCK_POLICY_VERSION] }
246
- ],
247
- description: "Policy schema version. Stable versions are 1 and 2; supported release candidates are rc-rubberduck."
248
- },
249
287
  id: {
250
288
  type: "string",
251
- description: "Policy id (required for rc-rubberduck policies). Must use the p_ prefix and contain no whitespace."
289
+ 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."
252
290
  },
253
- defaultEffect: {
291
+ effect: {
254
292
  type: "string",
255
- enum: [...DefaultEffectSchema.options],
256
- description: "Effect applied when no statement matches. Required on rc-rubberduck policies; deny equals implicit deny."
293
+ enum: [...VALID_EFFECTS].sort(),
294
+ description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2, version 3, and rc-rubberduck policies."
257
295
  },
258
- statements: {
296
+ permissions: {
297
+ type: "array",
298
+ minItems: 1,
299
+ items: { type: "string" },
300
+ description: "List of permission identifiers."
301
+ },
302
+ resources: {
259
303
  type: "array",
260
- description: "List of policy statements defining permissions.",
304
+ minItems: 1,
305
+ items: { type: "string" },
306
+ description: "List of resource identifiers the statement applies to."
307
+ },
308
+ conditions: {
309
+ type: "array",
310
+ description: "Optional conditions that must be met for the statement to apply.",
261
311
  items: {
262
312
  type: "object",
263
- required: ["effect", "permissions", "resources"],
313
+ required: ["path", "operator"],
264
314
  properties: {
265
- id: {
266
- type: "string",
267
- description: "Statement identifier. Required for rc-rubberduck policies; must use the s_ prefix with no whitespace. Optional on v1/v2 for debugging and provenance."
315
+ path: {
316
+ type: "array",
317
+ minItems: 1,
318
+ description: "Path to the value to evaluate in the request context.",
319
+ items: {
320
+ anyOf: [{ type: "string" }, { type: "integer" }]
321
+ }
268
322
  },
269
- effect: {
323
+ operator: {
270
324
  type: "string",
271
- enum: [...VALID_EFFECTS].sort(),
272
- description: "Whether to allow, ask, or deny the specified permissions. The 'ask' effect is valid in version 2 and rc-rubberduck policies."
325
+ enum: [...VALID_OPERATOR_LIST],
326
+ description: "Comparison operator used to evaluate the condition."
273
327
  },
274
- permissions: {
275
- type: "array",
276
- minItems: 1,
277
- items: { type: "string" },
278
- description: "List of permission identifiers."
328
+ value: {
329
+ description: "Value to compare against using the operator."
279
330
  },
280
- resources: {
331
+ where: {
281
332
  type: "array",
282
333
  minItems: 1,
283
- items: { type: "string" },
284
- description: "List of resource identifiers the statement applies to."
285
- },
286
- conditions: {
287
- type: "array",
288
- description: "Optional conditions that must be met for the statement to apply.",
334
+ description: "Conditions evaluated relative to each collection element for some, all, and none.",
289
335
  items: {
290
336
  type: "object",
291
337
  required: ["path", "operator"],
292
338
  properties: {
293
339
  path: {
294
340
  type: "array",
295
- minItems: 1,
296
- description: "Path to the value to evaluate in the request context.",
341
+ minItems: 0,
342
+ description: "Path relative to the collection element; an empty path selects the element itself.",
297
343
  items: {
298
344
  anyOf: [{ type: "string" }, { type: "integer" }]
299
345
  }
300
346
  },
301
347
  operator: {
302
348
  type: "string",
303
- enum: [...VALID_OPERATOR_LIST],
304
- description: "Comparison operator used to evaluate the condition."
349
+ enum: [...VALID_OPERATOR_LIST].filter(
350
+ (operator) => operator !== "some" && operator !== "all" && operator !== "none"
351
+ ),
352
+ description: "Non-quantifier operator evaluated against the collection element."
305
353
  },
306
354
  value: {
307
355
  description: "Value to compare against using the operator."
@@ -314,6 +362,42 @@ function getOpenApiSchema() {
314
362
  }
315
363
  }
316
364
  };
365
+ return {
366
+ type: "object",
367
+ required: ["version", "statements"],
368
+ properties: {
369
+ version: {
370
+ anyOf: [
371
+ { type: "integer", enum: [1, 2, 3] },
372
+ { type: "string", enum: [RUBBERDUCK_POLICY_VERSION] }
373
+ ],
374
+ description: "Policy schema version. Stable versions are 1, 2, and 3; supported release candidates are rc-rubberduck."
375
+ },
376
+ id: {
377
+ type: "string",
378
+ description: "Policy id (required for rc-rubberduck policies; not permitted on any other version). Must use the p_ prefix and contain no whitespace."
379
+ },
380
+ defaultEffect: {
381
+ type: "string",
382
+ enum: [...DefaultEffectSchema.options],
383
+ description: "Effect applied when no statement matches. Required on rc-rubberduck policies (deny equals implicit deny); not permitted on any other version."
384
+ },
385
+ statements: {
386
+ type: "array",
387
+ 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.",
388
+ items: {
389
+ anyOf: [
390
+ statementItems,
391
+ {
392
+ type: "array",
393
+ description: "A v3 tier: statements evaluated together with deny > ask > allow precedence.",
394
+ items: statementItems
395
+ }
396
+ ]
397
+ }
398
+ }
399
+ }
400
+ };
317
401
  }
318
402
 
319
- export { ArrayOperatorSchema, CanonicalHashSchema, ConditionSchema, ConditionValueSchema, DefaultEffectSchema, OperatorSchema, OtherOperatorSchema, OverrideSchema, PolicyIdSchema, PolicySchema, RUBBERDUCK_POLICY_VERSION, RangeValueSchema, ScalarOperatorSchema, SizeValueSchema, StatementIdSchema, StatementSchema, UrlOperatorSchema, VALID_EFFECTS, VALID_OPERATOR_LIST, VALID_VERSIONS, getOpenApiSchema };
403
+ export { ArrayOperatorSchema, CanonicalHashSchema, ConditionSchema, ConditionValueSchema, DefaultEffectSchema, ID_BASED_VERSIONS, OperatorSchema, OtherOperatorSchema, OverrideSchema, PolicyIdSchema, PolicySchema, RUBBERDUCK_POLICY_VERSION, RangeValueSchema, ScalarOperatorSchema, SizeValueSchema, StatementIdSchema, StatementSchema, UrlOperatorSchema, V3_MAX_TIERS, VALID_EFFECTS, VALID_OPERATOR_LIST, VALID_VERSIONS, getOpenApiSchema };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/policy-schema",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Zod schemas and TypeScript types for the Zapier policy engine",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",