@spotify/backstage-plugin-rbac-common 0.6.13 → 0.6.15

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @spotify/backstage-plugin-rbac-common
2
2
 
3
+ ## 0.6.15
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependency `backstage` to `1.49.0`.
8
+ - Updated package to be compatible with zod versions 3 and 4.
9
+
10
+ ## 0.6.14
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependency `backstage` to `1.48.0`.
15
+
3
16
  ## 0.6.13
4
17
 
5
18
  ### Patch Changes
package/dist/api.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("zod"),s=require("./permissionSchema.cjs.js"),r=require("./schema.cjs.js");const a=r.PolicyConfigParser,o=r.PolicyConfigParser.extend({name:r.PolicyTitleParser.optional(),options:r.PolicyConfigOptionsParser.optional(),roles:r.RolesParser.optional()}),t=e.z.object({description:e.z.string().optional(),update:o.optional()}),n=e.z.object({decision:s.PolicyDecisionParser,decisionOrigin:e.z.array(r.RoleDecisionParser)}),P=e.z.object({permission:s.PermissionParser,policyConfig:r.PolicyConfigParser,roleIds:e.z.array(e.z.string())}),p=e.z.object({id:e.z.string()}),c=e.z.object({authorized:e.z.boolean()}),i=e.z.object({name:e.z.string().optional(),namespace:e.z.string().optional(),description:e.z.string().optional(),type:e.z.enum(["user","group","all","unknown"]),entityRef:e.z.string(),spec:e.z.object({type:e.z.string().optional(),profile:e.z.object({displayName:e.z.string().optional()}).optional()}).optional()}),l=e.z.object({members:e.z.array(i)}),z=e.z.object({items:e.z.array(r.PolicyParser),nextCursor:e.z.string().optional(),prevCursor:e.z.string().optional(),totalItems:e.z.number()});exports.AuthorizeResponseParser=c,exports.CreateDraftRequestParser=a,exports.DraftResponseParser=p,exports.MemberResponseParser=i,exports.PolicyResponseParser=z,exports.PublishVersionRequestParser=t,exports.SearchMemberResponseParser=l,exports.TestPolicyDecisionRequestParser=P,exports.TestPolicyDecisionResponseParser=n,exports.UpdateDraftRequestParser=o;
1
+ "use strict";var e=require("zod/v3"),s=require("./permissionSchema.cjs.js"),r=require("./schema.cjs.js");const a=r.PolicyConfigParser,o=r.PolicyConfigParser.extend({name:r.PolicyTitleParser.optional(),options:r.PolicyConfigOptionsParser.optional(),roles:r.RolesParser.optional()}),t=e.z.object({description:e.z.string().optional(),update:o.optional()}),n=e.z.object({decision:s.PolicyDecisionParser,decisionOrigin:e.z.array(r.RoleDecisionParser)}),P=e.z.object({permission:s.PermissionParser,policyConfig:r.PolicyConfigParser,roleIds:e.z.array(e.z.string())}),p=e.z.object({id:e.z.string()}),c=e.z.object({authorized:e.z.boolean()}),i=e.z.object({name:e.z.string().optional(),namespace:e.z.string().optional(),description:e.z.string().optional(),type:e.z.enum(["user","group","all","unknown"]),entityRef:e.z.string(),spec:e.z.object({type:e.z.string().optional(),profile:e.z.object({displayName:e.z.string().optional()}).optional()}).optional()}),l=e.z.object({members:e.z.array(i)}),z=e.z.object({items:e.z.array(r.PolicyParser),nextCursor:e.z.string().optional(),prevCursor:e.z.string().optional(),totalItems:e.z.number()});exports.AuthorizeResponseParser=c,exports.CreateDraftRequestParser=a,exports.DraftResponseParser=p,exports.MemberResponseParser=i,exports.PolicyResponseParser=z,exports.PublishVersionRequestParser=t,exports.SearchMemberResponseParser=l,exports.TestPolicyDecisionRequestParser=P,exports.TestPolicyDecisionResponseParser=n,exports.UpdateDraftRequestParser=o;
2
2
  //# sourceMappingURL=api.cjs.js.map
package/dist/api.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{z as e}from"zod";import{PolicyDecisionParser as i,PermissionParser as t}from"./permissionSchema.esm.js";import{PolicyConfigParser as o,PolicyTitleParser as n,PolicyConfigOptionsParser as a,RolesParser as p,RoleDecisionParser as l,PolicyParser as c}from"./schema.esm.js";const P=o,r=o.extend({name:n.optional(),options:a.optional(),roles:p.optional()}),m=e.object({description:e.string().optional(),update:r.optional()}),y=e.object({decision:i,decisionOrigin:e.array(l)}),b=e.object({permission:t,policyConfig:o,roleIds:e.array(e.string())}),g=e.object({id:e.string()}),u=e.object({authorized:e.boolean()}),s=e.object({name:e.string().optional(),namespace:e.string().optional(),description:e.string().optional(),type:e.enum(["user","group","all","unknown"]),entityRef:e.string(),spec:e.object({type:e.string().optional(),profile:e.object({displayName:e.string().optional()}).optional()}).optional()}),R=e.object({members:e.array(s)}),d=e.object({items:e.array(c),nextCursor:e.string().optional(),prevCursor:e.string().optional(),totalItems:e.number()});export{u as AuthorizeResponseParser,P as CreateDraftRequestParser,g as DraftResponseParser,s as MemberResponseParser,d as PolicyResponseParser,m as PublishVersionRequestParser,R as SearchMemberResponseParser,b as TestPolicyDecisionRequestParser,y as TestPolicyDecisionResponseParser,r as UpdateDraftRequestParser};
1
+ import{z as e}from"zod/v3";import{PolicyDecisionParser as i,PermissionParser as t}from"./permissionSchema.esm.js";import{PolicyConfigParser as o,PolicyTitleParser as n,PolicyConfigOptionsParser as a,RolesParser as p,RoleDecisionParser as l,PolicyParser as c}from"./schema.esm.js";const P=o,r=o.extend({name:n.optional(),options:a.optional(),roles:p.optional()}),m=e.object({description:e.string().optional(),update:r.optional()}),y=e.object({decision:i,decisionOrigin:e.array(l)}),b=e.object({permission:t,policyConfig:o,roleIds:e.array(e.string())}),g=e.object({id:e.string()}),u=e.object({authorized:e.boolean()}),s=e.object({name:e.string().optional(),namespace:e.string().optional(),description:e.string().optional(),type:e.enum(["user","group","all","unknown"]),entityRef:e.string(),spec:e.object({type:e.string().optional(),profile:e.object({displayName:e.string().optional()}).optional()}).optional()}),R=e.object({members:e.array(s)}),d=e.object({items:e.array(c),nextCursor:e.string().optional(),prevCursor:e.string().optional(),totalItems:e.number()});export{u as AuthorizeResponseParser,P as CreateDraftRequestParser,g as DraftResponseParser,s as MemberResponseParser,d as PolicyResponseParser,m as PublishVersionRequestParser,R as SearchMemberResponseParser,b as TestPolicyDecisionRequestParser,y as TestPolicyDecisionResponseParser,r as UpdateDraftRequestParser};
2
2
  //# sourceMappingURL=api.esm.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _backstage_plugin_permission_common from '@backstage/plugin-permission-common';
2
2
  import { PermissionCondition, PermissionCriteria, AllOfCriteria, AnyOfCriteria, NotCriteria, Permission, PermissionRuleParam, PermissionRuleParams } from '@backstage/plugin-permission-common';
3
- import { z } from 'zod';
3
+ import { z } from 'zod/v3';
4
4
  import { CompoundEntityRef } from '@backstage/catalog-model';
5
5
 
6
6
  /** @public */
@@ -1,2 +1,2 @@
1
- "use strict";var i=require("@backstage/plugin-permission-common"),e=require("zod"),n=require("./schema.cjs.js");const t=e.z.object({action:e.z.union([e.z.literal("create"),e.z.literal("read"),e.z.literal("update"),e.z.literal("delete")]).optional()}),a=e.z.union([e.z.object({type:e.z.literal("basic"),name:e.z.string(),attributes:t}),e.z.object({type:e.z.literal("resource"),name:e.z.string(),attributes:t,resourceType:e.z.string()})]),r=e.z.lazy(()=>e.z.object({rule:e.z.string(),resourceType:e.z.string(),params:e.z.record(e.z.any()).optional()}).or(e.z.object({anyOf:e.z.array(r).nonempty()})).or(e.z.object({allOf:e.z.array(r).nonempty()})).or(e.z.object({not:r}))),o=e.z.object({result:e.z.union([e.z.literal(i.AuthorizeResult.ALLOW),e.z.literal(i.AuthorizeResult.DENY)])}),s=n.ConditionalDecisionParser.extend({result:e.z.literal(i.AuthorizeResult.CONDITIONAL),conditions:r}),l=e.z.union([o,s]);exports.ConditionalPolicyDecisionParser=s,exports.DefinitivePolicyDecisionParser=o,exports.PermissionAttributesParser=t,exports.PermissionCriteriaParser=r,exports.PermissionParser=a,exports.PolicyDecisionParser=l;
1
+ "use strict";var i=require("@backstage/plugin-permission-common"),e=require("zod/v3"),n=require("./schema.cjs.js");const t=e.z.object({action:e.z.union([e.z.literal("create"),e.z.literal("read"),e.z.literal("update"),e.z.literal("delete")]).optional()}),a=e.z.union([e.z.object({type:e.z.literal("basic"),name:e.z.string(),attributes:t}),e.z.object({type:e.z.literal("resource"),name:e.z.string(),attributes:t,resourceType:e.z.string()})]),r=e.z.lazy(()=>e.z.object({rule:e.z.string(),resourceType:e.z.string(),params:e.z.record(e.z.any()).optional()}).or(e.z.object({anyOf:e.z.array(r).nonempty()})).or(e.z.object({allOf:e.z.array(r).nonempty()})).or(e.z.object({not:r}))),o=e.z.object({result:e.z.union([e.z.literal(i.AuthorizeResult.ALLOW),e.z.literal(i.AuthorizeResult.DENY)])}),s=n.ConditionalDecisionParser.extend({result:e.z.literal(i.AuthorizeResult.CONDITIONAL),conditions:r}),l=e.z.union([o,s]);exports.ConditionalPolicyDecisionParser=s,exports.DefinitivePolicyDecisionParser=o,exports.PermissionAttributesParser=t,exports.PermissionCriteriaParser=r,exports.PermissionParser=a,exports.PolicyDecisionParser=l;
2
2
  //# sourceMappingURL=permissionSchema.cjs.js.map
@@ -1,2 +1,2 @@
1
- import{AuthorizeResult as i}from"@backstage/plugin-permission-common";import{z as e}from"zod";import{ConditionalDecisionParser as a}from"./schema.esm.js";const t=e.object({action:e.union([e.literal("create"),e.literal("read"),e.literal("update"),e.literal("delete")]).optional()}),s=e.union([e.object({type:e.literal("basic"),name:e.string(),attributes:t}),e.object({type:e.literal("resource"),name:e.string(),attributes:t,resourceType:e.string()})]),r=e.lazy(()=>e.object({rule:e.string(),resourceType:e.string(),params:e.record(e.any()).optional()}).or(e.object({anyOf:e.array(r).nonempty()})).or(e.object({allOf:e.array(r).nonempty()})).or(e.object({not:r}))),o=e.object({result:e.union([e.literal(i.ALLOW),e.literal(i.DENY)])}),n=a.extend({result:e.literal(i.CONDITIONAL),conditions:r}),l=e.union([o,n]);export{n as ConditionalPolicyDecisionParser,o as DefinitivePolicyDecisionParser,t as PermissionAttributesParser,r as PermissionCriteriaParser,s as PermissionParser,l as PolicyDecisionParser};
1
+ import{AuthorizeResult as i}from"@backstage/plugin-permission-common";import{z as e}from"zod/v3";import{ConditionalDecisionParser as a}from"./schema.esm.js";const t=e.object({action:e.union([e.literal("create"),e.literal("read"),e.literal("update"),e.literal("delete")]).optional()}),s=e.union([e.object({type:e.literal("basic"),name:e.string(),attributes:t}),e.object({type:e.literal("resource"),name:e.string(),attributes:t,resourceType:e.string()})]),r=e.lazy(()=>e.object({rule:e.string(),resourceType:e.string(),params:e.record(e.any()).optional()}).or(e.object({anyOf:e.array(r).nonempty()})).or(e.object({allOf:e.array(r).nonempty()})).or(e.object({not:r}))),o=e.object({result:e.union([e.literal(i.ALLOW),e.literal(i.DENY)])}),n=a.extend({result:e.literal(i.CONDITIONAL),conditions:r}),l=e.union([o,n]);export{n as ConditionalPolicyDecisionParser,o as DefinitivePolicyDecisionParser,t as PermissionAttributesParser,r as PermissionCriteriaParser,s as PermissionParser,l as PolicyDecisionParser};
2
2
  //# sourceMappingURL=permissionSchema.esm.js.map
@@ -1,2 +1,2 @@
1
- "use strict";var a=require("@backstage/catalog-model"),m=require("uuid"),e=require("zod"),o=require("./validationMessages.cjs.js");const P="Untitled policy",q=":backstageUser",f=e.z.object({rule:e.z.string(),params:e.z.record(e.z.any()).optional()}),n=e.z.lazy(()=>e.z.union([e.z.object({allOf:e.z.array(n).nonempty()}).strict(),e.z.object({anyOf:e.z.array(n).nonempty()}).strict(),e.z.object({not:n}).strict(),f])),h=e.z.object({pluginId:e.z.string().min(1).describe("Plugin ID that defines the permission and rules used."),resourceType:e.z.string().min(1).describe("Resource type associated with the conditions used."),conditions:n}),g=e.z.union([e.z.literal("allow"),e.z.literal("deny")]),c=e.z.union([g,h]),y=e.z.union([e.z.literal("*"),e.z.object({name:e.z.string().optional().describe("Name that must match the incoming permission request."),actions:e.z.array(e.z.string()).optional().describe("Actions that must be present on the incoming permission's attributes."),resourceType:e.z.string().min(1).optional().describe("Resource type that must match that of the incoming permission request.")})]),z=e.z.string().default(()=>m.v4().split("-")[0]).describe("ID of the permission."),p=e.z.object({id:z,match:y.describe("Values used to match against the incoming permission request."),decision:c.describe("Authorization result or conditions to send if this role permission applies.")}).refine(({decision:i,match:s})=>O(i)?s!=="*"&&s?.resourceType!==void 0:!0,{path:["match","resourceType"],message:"match.resourceType is required for conditional decisions."}),b=e.z.array(p).superRefine((i,s)=>{const r=d(i,"id");r>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Permission ids must be unique",path:[r,"id"]})}).describe("Permission decisions used to determine authorization responses."),v=e.z.string().refine(x,{message:"Invalid entity ref for member.",path:[]}).transform(i=>a.stringifyEntityRef(a.parseEntityRef(i,{defaultKind:"group",defaultNamespace:"default"}))),C=e.z.string().default(()=>m.v4().split("-")[0]).describe("ID of the role."),R=e.z.object({name:e.z.string().min(1,{message:o.minCharacters("Role name",1)}).max(1024,{message:o.maxCharacters("Role name",1024)}).describe("Name of the role."),description:e.z.string().optional().describe("Description of the role."),id:C,members:e.z.union([e.z.literal("*"),e.z.array(v).min(1)]).describe("Entity references used to map users to this role. These entities don't need to exist in the catalog."),permissions:b}),D=e.z.array(R).default([]).superRefine((i,s)=>{const r=d(i,"name");r>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Role names must be unique",path:[r,"name"]});const t=d(i,"id");t>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Role ids must be unique",path:[t,"id"]})}),T=e.z.object({decision:c.describe("The authorization result or conditions the corresponding role resulted in"),roleId:C.describe("The id of the role that resulted in the decision"),rolePermissionId:z.describe("The id of the role permission that resulted in the decisions.")}),A=e.z.string().min(1,{message:o.minCharacters("Policy name",1)}).max(1024,{message:o.maxCharacters("Policy name",1024)}).default(P).describe("Name of the policy."),j=e.z.union([e.z.literal("first-match"),e.z.literal("any-allow")]),I=e.z.object({resolutionStrategy:j}).default({resolutionStrategy:"first-match"}),l=e.z.object({name:A,options:I,roles:D}),N=l.default({roles:[]});function x(i){try{return a.parseEntityRef(i,{defaultKind:"group",defaultNamespace:"default"}),!0}catch{return!1}}function d(i,s){let r=0;const t=new Set;for(;r<i.length;){const u=i[r][s];if(t.has(u))return r;t.add(u),r++}return-1}function O(i){return typeof i!="string"}function B(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="allOf"&&Array.isArray(s[0][1])}function S(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="anyOf"&&Array.isArray(s[0][1])}function w(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="not"&&!Array.isArray(s[0][1])}const E=l.extend({id:e.z.string(),createdAt:e.z.string(),createdBy:e.z.string(),updatedAt:e.z.string(),updatedBy:e.z.string(),description:e.z.string().optional().nullable(),lastPublishedAt:e.z.string().optional().nullable(),lastPublishedBy:e.z.string().optional().nullable(),status:e.z.enum(["draft","active","inactive"])});exports.BackstageUserPlaceholder=q,exports.ConditionalDecisionParser=h,exports.DefaultingPolicyConfigParser=N,exports.LiteralDecisionParser=g,exports.PermissionConditionParser=f,exports.PermissionDecisionParser=c,exports.PermissionMatchParser=y,exports.PolicyConfigOptionsParser=I,exports.PolicyConfigParser=l,exports.PolicyDefaultName=P,exports.PolicyParser=E,exports.PolicyRoleResolutionStrategyParser=j,exports.PolicyTitleParser=A,exports.RoleDecisionParser=T,exports.RoleParser=R,exports.RolePermissionParser=p,exports.RolePermissionsParser=b,exports.RolesParser=D,exports.isAllOfPermissionCriteria=B,exports.isAnyOfPermissionCriteria=S,exports.isConditionalDecision=O,exports.isNotPermissionCriteria=w;
1
+ "use strict";var a=require("@backstage/catalog-model"),m=require("uuid"),e=require("zod/v3"),o=require("./validationMessages.cjs.js");const P="Untitled policy",v=":backstageUser",f=e.z.object({rule:e.z.string(),params:e.z.record(e.z.any()).optional()}),n=e.z.lazy(()=>e.z.union([e.z.object({allOf:e.z.array(n).nonempty()}).strict(),e.z.object({anyOf:e.z.array(n).nonempty()}).strict(),e.z.object({not:n}).strict(),f])),h=e.z.object({pluginId:e.z.string().min(1).describe("Plugin ID that defines the permission and rules used."),resourceType:e.z.string().min(1).describe("Resource type associated with the conditions used."),conditions:n}),g=e.z.union([e.z.literal("allow"),e.z.literal("deny")]),c=e.z.union([g,h]),y=e.z.union([e.z.literal("*"),e.z.object({name:e.z.string().optional().describe("Name that must match the incoming permission request."),actions:e.z.array(e.z.string()).optional().describe("Actions that must be present on the incoming permission's attributes."),resourceType:e.z.string().min(1).optional().describe("Resource type that must match that of the incoming permission request.")})]),p=e.z.string().default(()=>m.v4().split("-")[0]).describe("ID of the permission."),z=e.z.object({id:p,match:y.describe("Values used to match against the incoming permission request."),decision:c.describe("Authorization result or conditions to send if this role permission applies.")}).refine(({decision:i,match:s})=>O(i)?s!=="*"&&s?.resourceType!==void 0:!0,{path:["match","resourceType"],message:"match.resourceType is required for conditional decisions."}),b=e.z.array(z).superRefine((i,s)=>{const r=d(i,"id");r>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Permission ids must be unique",path:[r,"id"]})}).describe("Permission decisions used to determine authorization responses."),q=e.z.string().refine(x,{message:"Invalid entity ref for member.",path:[]}).transform(i=>a.stringifyEntityRef(a.parseEntityRef(i,{defaultKind:"group",defaultNamespace:"default"}))),C=e.z.string().default(()=>m.v4().split("-")[0]).describe("ID of the role."),R=e.z.object({name:e.z.string().min(1,{message:o.minCharacters("Role name",1)}).max(1024,{message:o.maxCharacters("Role name",1024)}).describe("Name of the role."),description:e.z.string().optional().describe("Description of the role."),id:C,members:e.z.union([e.z.literal("*"),e.z.array(q).min(1)]).describe("Entity references used to map users to this role. These entities don't need to exist in the catalog."),permissions:b}),D=e.z.array(R).default([]).superRefine((i,s)=>{const r=d(i,"name");r>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Role names must be unique",path:[r,"name"]});const t=d(i,"id");t>=0&&s.addIssue({code:e.z.ZodIssueCode.custom,message:"Role ids must be unique",path:[t,"id"]})}),T=e.z.object({decision:c.describe("The authorization result or conditions the corresponding role resulted in"),roleId:C.describe("The id of the role that resulted in the decision"),rolePermissionId:p.describe("The id of the role permission that resulted in the decisions.")}),A=e.z.string().min(1,{message:o.minCharacters("Policy name",1)}).max(1024,{message:o.maxCharacters("Policy name",1024)}).default(P).describe("Name of the policy."),j=e.z.union([e.z.literal("first-match"),e.z.literal("any-allow")]),I=e.z.object({resolutionStrategy:j}).default({resolutionStrategy:"first-match"}),l=e.z.object({name:A,options:I,roles:D}),N=l.default({roles:[]});function x(i){try{return a.parseEntityRef(i,{defaultKind:"group",defaultNamespace:"default"}),!0}catch{return!1}}function d(i,s){let r=0;const t=new Set;for(;r<i.length;){const u=i[r][s];if(t.has(u))return r;t.add(u),r++}return-1}function O(i){return typeof i!="string"}function B(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="allOf"&&Array.isArray(s[0][1])}function S(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="anyOf"&&Array.isArray(s[0][1])}function w(i){const s=Object.entries(i);return s.length===1&&s[0][0]==="not"&&!Array.isArray(s[0][1])}const E=l.extend({id:e.z.string(),createdAt:e.z.string(),createdBy:e.z.string(),updatedAt:e.z.string(),updatedBy:e.z.string(),description:e.z.string().optional().nullable(),lastPublishedAt:e.z.string().optional().nullable(),lastPublishedBy:e.z.string().optional().nullable(),status:e.z.enum(["draft","active","inactive"])});exports.BackstageUserPlaceholder=v,exports.ConditionalDecisionParser=h,exports.DefaultingPolicyConfigParser=N,exports.LiteralDecisionParser=g,exports.PermissionConditionParser=f,exports.PermissionDecisionParser=c,exports.PermissionMatchParser=y,exports.PolicyConfigOptionsParser=I,exports.PolicyConfigParser=l,exports.PolicyDefaultName=P,exports.PolicyParser=E,exports.PolicyRoleResolutionStrategyParser=j,exports.PolicyTitleParser=A,exports.RoleDecisionParser=T,exports.RoleParser=R,exports.RolePermissionParser=z,exports.RolePermissionsParser=b,exports.RolesParser=D,exports.isAllOfPermissionCriteria=B,exports.isAnyOfPermissionCriteria=S,exports.isConditionalDecision=O,exports.isNotPermissionCriteria=w;
2
2
  //# sourceMappingURL=schema.cjs.js.map
@@ -1,2 +1,2 @@
1
- import{stringifyEntityRef as N,parseEntityRef as d}from"@backstage/catalog-model";import{v4 as u}from"uuid";import{z as e}from"zod";import{minCharacters as m,maxCharacters as p}from"./validationMessages.esm.js";const f="Untitled policy",x=":backstageUser",h=e.object({rule:e.string(),params:e.record(e.any()).optional()}),o=e.lazy(()=>e.union([e.object({allOf:e.array(o).nonempty()}).strict(),e.object({anyOf:e.array(o).nonempty()}).strict(),e.object({not:o}).strict(),h])),g=e.object({pluginId:e.string().min(1).describe("Plugin ID that defines the permission and rules used."),resourceType:e.string().min(1).describe("Resource type associated with the conditions used."),conditions:o}),y=e.union([e.literal("allow"),e.literal("deny")]),n=e.union([y,g]),b=e.union([e.literal("*"),e.object({name:e.string().optional().describe("Name that must match the incoming permission request."),actions:e.array(e.string()).optional().describe("Actions that must be present on the incoming permission's attributes."),resourceType:e.string().min(1).optional().describe("Resource type that must match that of the incoming permission request.")})]),P=e.string().default(()=>u().split("-")[0]).describe("ID of the permission."),R=e.object({id:P,match:b.describe("Values used to match against the incoming permission request."),decision:n.describe("Authorization result or conditions to send if this role permission applies.")}).refine(({decision:t,match:i})=>q(t)?i!=="*"&&i?.resourceType!==void 0:!0,{path:["match","resourceType"],message:"match.resourceType is required for conditional decisions."}),j=e.array(R).superRefine((t,i)=>{const s=c(t,"id");s>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Permission ids must be unique",path:[s,"id"]})}).describe("Permission decisions used to determine authorization responses."),v=e.string().refine(B,{message:"Invalid entity ref for member.",path:[]}).transform(t=>N(d(t,{defaultKind:"group",defaultNamespace:"default"}))),C=e.string().default(()=>u().split("-")[0]).describe("ID of the role."),A=e.object({name:e.string().min(1,{message:m("Role name",1)}).max(1024,{message:p("Role name",1024)}).describe("Name of the role."),description:e.string().optional().describe("Description of the role."),id:C,members:e.union([e.literal("*"),e.array(v).min(1)]).describe("Entity references used to map users to this role. These entities don't need to exist in the catalog."),permissions:j}),I=e.array(A).default([]).superRefine((t,i)=>{const s=c(t,"name");s>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Role names must be unique",path:[s,"name"]});const r=c(t,"id");r>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Role ids must be unique",path:[r,"id"]})}),z=e.object({decision:n.describe("The authorization result or conditions the corresponding role resulted in"),roleId:C.describe("The id of the role that resulted in the decision"),rolePermissionId:P.describe("The id of the role permission that resulted in the decisions.")}),D=e.string().min(1,{message:m("Policy name",1)}).max(1024,{message:p("Policy name",1024)}).default(f).describe("Name of the policy."),O=e.union([e.literal("first-match"),e.literal("any-allow")]),T=e.object({resolutionStrategy:O}).default({resolutionStrategy:"first-match"}),a=e.object({name:D,options:T,roles:I}),w=a.default({roles:[]});function B(t){try{return d(t,{defaultKind:"group",defaultNamespace:"default"}),!0}catch{return!1}}function c(t,i){let s=0;const r=new Set;for(;s<t.length;){const l=t[s][i];if(r.has(l))return s;r.add(l),s++}return-1}function q(t){return typeof t!="string"}function S(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="allOf"&&Array.isArray(i[0][1])}function E(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="anyOf"&&Array.isArray(i[0][1])}function U(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="not"&&!Array.isArray(i[0][1])}const Z=a.extend({id:e.string(),createdAt:e.string(),createdBy:e.string(),updatedAt:e.string(),updatedBy:e.string(),description:e.string().optional().nullable(),lastPublishedAt:e.string().optional().nullable(),lastPublishedBy:e.string().optional().nullable(),status:e.enum(["draft","active","inactive"])});export{x as BackstageUserPlaceholder,g as ConditionalDecisionParser,w as DefaultingPolicyConfigParser,y as LiteralDecisionParser,h as PermissionConditionParser,n as PermissionDecisionParser,b as PermissionMatchParser,T as PolicyConfigOptionsParser,a as PolicyConfigParser,f as PolicyDefaultName,Z as PolicyParser,O as PolicyRoleResolutionStrategyParser,D as PolicyTitleParser,z as RoleDecisionParser,A as RoleParser,R as RolePermissionParser,j as RolePermissionsParser,I as RolesParser,S as isAllOfPermissionCriteria,E as isAnyOfPermissionCriteria,q as isConditionalDecision,U as isNotPermissionCriteria};
1
+ import{stringifyEntityRef as N,parseEntityRef as d}from"@backstage/catalog-model";import{v4 as u}from"uuid";import{z as e}from"zod/v3";import{minCharacters as m,maxCharacters as p}from"./validationMessages.esm.js";const f="Untitled policy",x=":backstageUser",h=e.object({rule:e.string(),params:e.record(e.any()).optional()}),o=e.lazy(()=>e.union([e.object({allOf:e.array(o).nonempty()}).strict(),e.object({anyOf:e.array(o).nonempty()}).strict(),e.object({not:o}).strict(),h])),g=e.object({pluginId:e.string().min(1).describe("Plugin ID that defines the permission and rules used."),resourceType:e.string().min(1).describe("Resource type associated with the conditions used."),conditions:o}),y=e.union([e.literal("allow"),e.literal("deny")]),n=e.union([y,g]),b=e.union([e.literal("*"),e.object({name:e.string().optional().describe("Name that must match the incoming permission request."),actions:e.array(e.string()).optional().describe("Actions that must be present on the incoming permission's attributes."),resourceType:e.string().min(1).optional().describe("Resource type that must match that of the incoming permission request.")})]),P=e.string().default(()=>u().split("-")[0]).describe("ID of the permission."),R=e.object({id:P,match:b.describe("Values used to match against the incoming permission request."),decision:n.describe("Authorization result or conditions to send if this role permission applies.")}).refine(({decision:t,match:i})=>q(t)?i!=="*"&&i?.resourceType!==void 0:!0,{path:["match","resourceType"],message:"match.resourceType is required for conditional decisions."}),j=e.array(R).superRefine((t,i)=>{const s=c(t,"id");s>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Permission ids must be unique",path:[s,"id"]})}).describe("Permission decisions used to determine authorization responses."),v=e.string().refine(B,{message:"Invalid entity ref for member.",path:[]}).transform(t=>N(d(t,{defaultKind:"group",defaultNamespace:"default"}))),C=e.string().default(()=>u().split("-")[0]).describe("ID of the role."),A=e.object({name:e.string().min(1,{message:m("Role name",1)}).max(1024,{message:p("Role name",1024)}).describe("Name of the role."),description:e.string().optional().describe("Description of the role."),id:C,members:e.union([e.literal("*"),e.array(v).min(1)]).describe("Entity references used to map users to this role. These entities don't need to exist in the catalog."),permissions:j}),I=e.array(A).default([]).superRefine((t,i)=>{const s=c(t,"name");s>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Role names must be unique",path:[s,"name"]});const r=c(t,"id");r>=0&&i.addIssue({code:e.ZodIssueCode.custom,message:"Role ids must be unique",path:[r,"id"]})}),z=e.object({decision:n.describe("The authorization result or conditions the corresponding role resulted in"),roleId:C.describe("The id of the role that resulted in the decision"),rolePermissionId:P.describe("The id of the role permission that resulted in the decisions.")}),D=e.string().min(1,{message:m("Policy name",1)}).max(1024,{message:p("Policy name",1024)}).default(f).describe("Name of the policy."),O=e.union([e.literal("first-match"),e.literal("any-allow")]),T=e.object({resolutionStrategy:O}).default({resolutionStrategy:"first-match"}),a=e.object({name:D,options:T,roles:I}),w=a.default({roles:[]});function B(t){try{return d(t,{defaultKind:"group",defaultNamespace:"default"}),!0}catch{return!1}}function c(t,i){let s=0;const r=new Set;for(;s<t.length;){const l=t[s][i];if(r.has(l))return s;r.add(l),s++}return-1}function q(t){return typeof t!="string"}function S(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="allOf"&&Array.isArray(i[0][1])}function E(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="anyOf"&&Array.isArray(i[0][1])}function U(t){const i=Object.entries(t);return i.length===1&&i[0][0]==="not"&&!Array.isArray(i[0][1])}const Z=a.extend({id:e.string(),createdAt:e.string(),createdBy:e.string(),updatedAt:e.string(),updatedBy:e.string(),description:e.string().optional().nullable(),lastPublishedAt:e.string().optional().nullable(),lastPublishedBy:e.string().optional().nullable(),status:e.enum(["draft","active","inactive"])});export{x as BackstageUserPlaceholder,g as ConditionalDecisionParser,w as DefaultingPolicyConfigParser,y as LiteralDecisionParser,h as PermissionConditionParser,n as PermissionDecisionParser,b as PermissionMatchParser,T as PolicyConfigOptionsParser,a as PolicyConfigParser,f as PolicyDefaultName,Z as PolicyParser,O as PolicyRoleResolutionStrategyParser,D as PolicyTitleParser,z as RoleDecisionParser,A as RoleParser,R as RolePermissionParser,j as RolePermissionsParser,I as RolesParser,S as isAllOfPermissionCriteria,E as isAnyOfPermissionCriteria,q as isConditionalDecision,U as isNotPermissionCriteria};
2
2
  //# sourceMappingURL=schema.esm.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-rbac-common",
3
3
  "description": "Control access to actions and data in Backstage with ease.",
4
- "version": "0.6.13",
4
+ "version": "0.6.15",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "homepage": "https://backstage.spotify.com",
7
7
  "main": "dist/index.cjs.js",
@@ -31,14 +31,14 @@
31
31
  "postpack": "backstage-cli package postpack"
32
32
  },
33
33
  "dependencies": {
34
- "@backstage/catalog-model": "^1.7.6",
35
- "@backstage/plugin-permission-common": "^0.9.4",
34
+ "@backstage/catalog-model": "^1.7.7",
35
+ "@backstage/plugin-permission-common": "^0.9.7",
36
36
  "@backstage/types": "^1.2.2",
37
37
  "uuid": "^11.0.0",
38
- "zod": "^3.20.0"
38
+ "zod": "^3.25.76 || ^4.0.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@backstage/cli": "^0.35.2"
41
+ "@backstage/cli": "^0.36.0"
42
42
  },
43
43
  "files": [
44
44
  "dist",