@canopy-io/node 0.10.0 → 0.11.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.d.ts CHANGED
@@ -748,7 +748,7 @@ interface paths {
748
748
  };
749
749
  /**
750
750
  * Get identity's effective permissions
751
- * @description Returns the identity's effective Application-wide permission keys for the current Environment as a flat `items` array of strings, resolved across all of its role assignments. Use this to answer "what can this identity do" without replaying individual assignments. Returns `404` when the identity has no membership in this Environment.
751
+ * @description Returns the identity's effective permission keys for the current Environment as a flat `items` array of strings. Without `node_id`, the Application-wide answer: every permission its role assignments grant anywhere. With `node_id`, the answer at that node: the permissions granted by assignments on the node's lineage, the list a screen renders its controls from. Returns `404` when the identity has no membership in this Environment, or when `node_id` names no node in it.
752
752
  */
753
753
  get: operations["ApiIdentitiesController_getIdentityPermissions"];
754
754
  put?: never;
@@ -759,6 +759,26 @@ interface paths {
759
759
  patch?: never;
760
760
  trace?: never;
761
761
  };
762
+ "/api/v1/identities/{id}/accessible-nodes": {
763
+ parameters: {
764
+ query?: never;
765
+ header?: never;
766
+ path?: never;
767
+ cookie?: never;
768
+ };
769
+ /**
770
+ * Get where an identity may act with one permission
771
+ * @description Returns where the identity may act with `permission`, for a list query: `roots`, the nodes it holds the permission at that no other such node already covers, and `nodes`, every node beneath those roots, the roots included, when there are at most `max_nodes` of them (default 10,000; at most 50,000). Past the cap `nodes` is null and `complete` false, and the caller filters by `roots` against its own closure table or materialised path. `env_wide` is true when a root is the Environment's own root, so every node qualifies and no filter is needed; `nodes` is null then too. The same rules as `evaluate` decide the roots, so a list filtered by this answer agrees with the check a write makes. Returns `404` when the identity has no membership in this Environment.
772
+ */
773
+ get: operations["ApiIdentitiesController_getIdentityAccessibleNodes"];
774
+ put?: never;
775
+ post?: never;
776
+ delete?: never;
777
+ options?: never;
778
+ head?: never;
779
+ patch?: never;
780
+ trace?: never;
781
+ };
762
782
  "/api/v1/identities/{id}/grants": {
763
783
  parameters: {
764
784
  query?: never;
@@ -768,7 +788,7 @@ interface paths {
768
788
  };
769
789
  /**
770
790
  * Get where an identity holds each permission
771
- * @description Returns, for the current Environment, one page of `(permission, node_id)` rows: every permission the identity holds, paired with each hierarchy node its grants were made at — the nodes themselves, **not** expanded through their descendants. Rows are ordered by permission, then node; a caller building the whole map walks every page. A grant already means "this node and everything beneath it", so a caller answers a node-scoped question by walking up from the node in question and looking for one of these roots, using a copy of the parent edges fetched once from `GET /api/v1/nodes/parents` and shared across identities. Answers both scopes without a further call: the permission appearing at all is the Application-wide answer, and the walk is the node-scoped one. Scheduled assignments outside their effective window are excluded. Returns `404` when the identity has no membership in this Environment.
791
+ * @description Returns, for the current Environment, one page of `(permission, node_id)` rows: every permission the identity holds, paired with each hierarchy node its grants were made at — the nodes themselves, **not** expanded through their descendants. Rows are ordered by permission, then node; a caller building the whole map walks every page. A grant already means "this node and everything beneath it", so a caller answers a node-scoped question by walking up from the node in question and looking for one of these roots, using a copy of the parent edges fetched once from `GET /api/v1/nodes/parents` and shared across identities. Answers both scopes without a further call: the permission appearing at all is the Application-wide answer, and the walk is the node-scoped one. By default, assignments outside their effective window are excluded. With `include=windows`, every assignment is a row carrying `effective_from` and `effective_to` (null for an unbounded side), in effect or not, so a caller applies the window itself: it can say why a check fails (the grant has ended, or has not begun) and drop a grant at its boundary without reading again. Returns `404` when the identity has no membership in this Environment.
772
792
  */
773
793
  get: operations["ApiIdentitiesController_getIdentityGrants"];
774
794
  put?: never;
@@ -2739,6 +2759,18 @@ interface components {
2739
2759
  /** Format: date-time */
2740
2760
  updated_at: string;
2741
2761
  };
2762
+ IdentityAccessibleNodesResponseDto: {
2763
+ /** @example reports.view */
2764
+ permission: string;
2765
+ /** @description True when a root is the Environment's own root, so every node qualifies and a list needs no filter. `nodes` is null then. */
2766
+ env_wide: boolean;
2767
+ /** @description The nodes the permission is granted at, in effect now, that no other such node already covers. Each reaches everything beneath it. */
2768
+ roots: string[];
2769
+ /** @description Every node beneath the roots, the roots included, for an `IN (...)` filter. Null when `env_wide`, or when there are more than `max_nodes` (then `complete` is false and the caller filters by `roots` instead). */
2770
+ nodes: string[] | null;
2771
+ /** @description False when the set beneath the roots was larger than `max_nodes` and was not sent. */
2772
+ complete: boolean;
2773
+ };
2742
2774
  IdentityGrantResponseDto: {
2743
2775
  /** @example reports.view */
2744
2776
  permission: string;
@@ -2747,6 +2779,16 @@ interface components {
2747
2779
  * @description The hierarchy node the permission was granted at. Not expanded through descendants.
2748
2780
  */
2749
2781
  node_id: string;
2782
+ /**
2783
+ * Format: date-time
2784
+ * @description When the assignment behind this root begins, or null for no start. Present only with `include=windows`.
2785
+ */
2786
+ effective_from?: string | null;
2787
+ /**
2788
+ * Format: date-time
2789
+ * @description When the assignment behind this root ends, or null for no end. Present only with `include=windows`.
2790
+ */
2791
+ effective_to?: string | null;
2750
2792
  };
2751
2793
  IdentityInviteResponseDto: {
2752
2794
  id: string;
@@ -8358,7 +8400,10 @@ interface operations {
8358
8400
  };
8359
8401
  ApiIdentitiesController_getIdentityPermissions: {
8360
8402
  parameters: {
8361
- query?: never;
8403
+ query?: {
8404
+ /** @description Answer at this node: the permissions granted by assignments on its lineage. Omit for the Application-wide answer. */
8405
+ node_id?: string;
8406
+ };
8362
8407
  header?: never;
8363
8408
  path: {
8364
8409
  id: string;
@@ -8464,6 +8509,119 @@ interface operations {
8464
8509
  };
8465
8510
  };
8466
8511
  };
8512
+ ApiIdentitiesController_getIdentityAccessibleNodes: {
8513
+ parameters: {
8514
+ query: {
8515
+ /** @description The permission to answer for, by key. */
8516
+ permission: string;
8517
+ /** @description The largest `nodes` set to return. Past it, `nodes` is null and `complete` false. */
8518
+ max_nodes?: number;
8519
+ };
8520
+ header?: never;
8521
+ path: {
8522
+ id: string;
8523
+ };
8524
+ cookie?: never;
8525
+ };
8526
+ requestBody?: never;
8527
+ responses: {
8528
+ /** @description The minimal grant roots for the permission, and the nodes beneath them up to the cap */
8529
+ 200: {
8530
+ headers: {
8531
+ [name: string]: unknown;
8532
+ };
8533
+ content: {
8534
+ "application/json": {
8535
+ data: components["schemas"]["IdentityAccessibleNodesResponseDto"];
8536
+ };
8537
+ };
8538
+ };
8539
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
8540
+ 400: {
8541
+ headers: {
8542
+ [name: string]: unknown;
8543
+ };
8544
+ content: {
8545
+ /**
8546
+ * @example {
8547
+ * "error": {
8548
+ * "statusCode": 400,
8549
+ * "code": null,
8550
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
8551
+ * "timestamp": "2026-04-20T12:00:00.000Z",
8552
+ * "path": "/api/v1/identities/{id}/accessible-nodes",
8553
+ * "method": "GET"
8554
+ * }
8555
+ * }
8556
+ */
8557
+ "application/json": components["schemas"]["ErrorResponseDto"];
8558
+ };
8559
+ };
8560
+ /** @description Invalid or expired token */
8561
+ 401: {
8562
+ headers: {
8563
+ [name: string]: unknown;
8564
+ };
8565
+ content: {
8566
+ /**
8567
+ * @example {
8568
+ * "error": {
8569
+ * "statusCode": 401,
8570
+ * "code": null,
8571
+ * "message": "Invalid or expired token",
8572
+ * "timestamp": "2026-04-20T12:00:00.000Z",
8573
+ * "path": "/api/v1/identities",
8574
+ * "method": "GET"
8575
+ * }
8576
+ * }
8577
+ */
8578
+ "application/json": components["schemas"]["ErrorResponseDto"];
8579
+ };
8580
+ };
8581
+ /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
8582
+ 403: {
8583
+ headers: {
8584
+ [name: string]: unknown;
8585
+ };
8586
+ content: {
8587
+ /**
8588
+ * @example {
8589
+ * "error": {
8590
+ * "statusCode": 403,
8591
+ * "code": null,
8592
+ * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
8593
+ * "timestamp": "2026-04-20T12:00:00.000Z",
8594
+ * "path": "/api/v1/identities",
8595
+ * "method": "GET"
8596
+ * }
8597
+ * }
8598
+ */
8599
+ "application/json": components["schemas"]["ErrorResponseDto"];
8600
+ };
8601
+ };
8602
+ /** @description No identity with that id has a membership in this Environment */
8603
+ 404: {
8604
+ headers: {
8605
+ [name: string]: unknown;
8606
+ };
8607
+ content: {
8608
+ /**
8609
+ * @example {
8610
+ * "error": {
8611
+ * "statusCode": 404,
8612
+ * "code": null,
8613
+ * "message": "No identity with that id has a membership in this Environment",
8614
+ * "timestamp": "2026-04-20T12:00:00.000Z",
8615
+ * "path": "/api/v1/identities/{id}/accessible-nodes",
8616
+ * "method": "GET"
8617
+ * }
8618
+ * }
8619
+ */
8620
+ "application/json": components["schemas"]["ErrorResponseDto"];
8621
+ };
8622
+ };
8623
+ };
8624
+ };
8467
8625
  ApiIdentitiesController_getIdentityGrants: {
8468
8626
  parameters: {
8469
8627
  query?: {
@@ -8471,6 +8629,8 @@ interface operations {
8471
8629
  page?: number;
8472
8630
  /** @description Items per page (1-100, default 20) */
8473
8631
  take?: number;
8632
+ /** @description `windows` adds `effective_from` and `effective_to` to every row and includes assignments outside their window, so the caller applies the window itself. */
8633
+ include?: "windows";
8474
8634
  };
8475
8635
  header?: never;
8476
8636
  path: {
@@ -21539,7 +21699,18 @@ declare class Identities {
21539
21699
  * question at the node that matters. This is for showing a person what
21540
21700
  * someone can do.
21541
21701
  */
21542
- permissions(id: string): Promise<ResponseBody<"ApiIdentitiesController_getIdentityPermissions">>;
21702
+ permissions(id: string, query?: QueryParams<"ApiIdentitiesController_getIdentityPermissions">): Promise<ResponseBody<"ApiIdentitiesController_getIdentityPermissions">>;
21703
+ /**
21704
+ * Where the identity may act with one permission, answered by Canopy for a
21705
+ * list query: the minimal grant roots, and every node beneath them up to
21706
+ * `max_nodes` (null past it, with `complete: false`), or `env_wide` when a
21707
+ * root is the Environment's own root and no filter is needed.
21708
+ *
21709
+ * `LocalAuthorizer.accessibleNodes` answers the same question from its
21710
+ * cache without a call; this is the fresh answer, and the one for a process
21711
+ * that does not run the authorizer.
21712
+ */
21713
+ accessibleNodes(id: string, query: QueryParams<"ApiIdentitiesController_getIdentityAccessibleNodes">): Promise<ResponseBody<"ApiIdentitiesController_getIdentityAccessibleNodes">>;
21543
21714
  /**
21544
21715
  * Every session the identity holds that is neither revoked nor expired,
21545
21716
  * newest first: when and where it was signed in, when it expires, and the
@@ -21839,6 +22010,39 @@ declare class Canopy {
21839
22010
  * delay is short, so a longer value is refused rather than honoured.
21840
22011
  */
21841
22012
  declare const MAX_TTL_MS = 300000;
22013
+ /**
22014
+ * The largest node set `accessibleNodes` builds unless told otherwise. Past
22015
+ * it the answer carries the roots alone, and the caller filters against its
22016
+ * own closure table or materialised path instead of an `IN (...)` list.
22017
+ */
22018
+ declare const DEFAULT_MAX_NODES = 10000;
22019
+ /**
22020
+ * Why a check was denied, as far as the grant roots and the tree can say.
22021
+ *
22022
+ * - `permission_not_held`: no assignment grants the permission anywhere, in
22023
+ * effect or not.
22024
+ * - `outside_grants`: it is granted, but at no node on the lineage of the
22025
+ * node asked about.
22026
+ * - `expired`: a grant that would answer has ended, and none is in effect.
22027
+ * - `not_yet_effective`: a grant that would answer has not begun, and none
22028
+ * is in effect.
22029
+ * - `node_missing`: a `node` check named no node, which is a denial rather
22030
+ * than an error, because a request whose subject cannot be established
22031
+ * must not pass.
22032
+ */
22033
+ type LocalDenialReason = "permission_not_held" | "outside_grants" | "expired" | "not_yet_effective" | "node_missing";
22034
+ /** The answer to a check: the verdict, and why when it is no. */
22035
+ interface LocalDecision {
22036
+ allowed: boolean;
22037
+ reason: LocalDenialReason | null;
22038
+ }
22039
+ /** What a decision hook receives, after the verdict is in. */
22040
+ interface LocalDecisionEvent {
22041
+ query: LocalAuthorizationQuery;
22042
+ decision: LocalDecision;
22043
+ /** How long the check took, reads included. */
22044
+ durationMs: number;
22045
+ }
21842
22046
  interface LocalAuthorizerOptions {
21843
22047
  /**
21844
22048
  * How long grant roots and the hierarchy are reused, in milliseconds.
@@ -21871,6 +22075,19 @@ interface LocalAuthorizerOptions {
21871
22075
  timeoutMs?: number;
21872
22076
  /** Retries for those reads. */
21873
22077
  maxRetries?: number;
22078
+ /**
22079
+ * The largest node set {@link LocalAuthorizer.accessibleNodes} builds
22080
+ * unless a call says otherwise. Defaults to {@link DEFAULT_MAX_NODES}.
22081
+ */
22082
+ maxNodes?: number;
22083
+ /**
22084
+ * Called after every decision, allowed or not, with the question and the
22085
+ * answer. Never awaited and never allowed to fail the check: a hook that
22086
+ * throws is ignored. For audit trails and metrics.
22087
+ */
22088
+ onDecision?: (event: LocalDecisionEvent) => void;
22089
+ /** Called after every denial, the same way. For alerting on refusals. */
22090
+ onDenied?: (event: LocalDecisionEvent) => void;
21874
22091
  /** Injectable clock, for tests. */
21875
22092
  now?: () => number;
21876
22093
  }
@@ -21881,6 +22098,26 @@ interface LocalAuthorizationQuery {
21881
22098
  scope?: "node" | "app_wide";
21882
22099
  node_id?: string;
21883
22100
  }
22101
+ /** Where an identity may act with one permission, shaped for a list query. */
22102
+ interface AccessibleNodes {
22103
+ /**
22104
+ * The nodes the permission is granted at, in effect now, that no other
22105
+ * such node already covers. Each reaches everything beneath it.
22106
+ */
22107
+ roots: string[];
22108
+ /**
22109
+ * Every node beneath the roots, the roots included, for an `IN (...)`
22110
+ * filter. Null when `envWide`, or when the set would exceed the cap.
22111
+ */
22112
+ nodes: Set<string> | null;
22113
+ /** False when the set exceeded the cap and `nodes` was not built. */
22114
+ complete: boolean;
22115
+ /**
22116
+ * True when a root is the Environment's own root: every node qualifies, so
22117
+ * a list needs no filter at all.
22118
+ */
22119
+ envWide: boolean;
22120
+ }
21884
22121
  interface LocalAuthorizerStats {
21885
22122
  /** Reads of an identity's grant roots, one per refresh however many pages it took. */
21886
22123
  grantFetches: number;
@@ -21900,8 +22137,11 @@ interface LocalAuthorizerStats {
21900
22137
  declare class LocalAuthorizer {
21901
22138
  private readonly client;
21902
22139
  private readonly ttlMs;
22140
+ private readonly maxNodes;
21903
22141
  private readonly now;
21904
22142
  private readonly readOptions;
22143
+ private readonly onDecision;
22144
+ private readonly onDenied;
21905
22145
  private readonly grants;
21906
22146
  private tree;
21907
22147
  /**
@@ -21917,7 +22157,7 @@ declare class LocalAuthorizer {
21917
22157
  private stats;
21918
22158
  constructor(client: CanopyClient, options?: LocalAuthorizerOptions);
21919
22159
  /**
21920
- * Whether the identity holds the permission.
22160
+ * Whether the identity holds the permission, and why not when it does not.
21921
22161
  *
21922
22162
  * Shaped like the API's own evaluate so a caller can swap one for the other.
21923
22163
  * A `node` check with no node is a denial rather than an error: a request
@@ -21925,9 +22165,51 @@ declare class LocalAuthorizer {
21925
22165
  */
21926
22166
  evaluate(query: LocalAuthorizationQuery, options?: {
21927
22167
  signal?: AbortSignal;
21928
- }): Promise<{
21929
- allowed: boolean;
22168
+ }): Promise<LocalDecision>;
22169
+ /**
22170
+ * The nodes the identity holds the permission at, in effect now, reduced to
22171
+ * the ones no other such node already covers, and whether one of them is
22172
+ * the Environment's root. The roots alone are enough for an application
22173
+ * that keeps a closure table or a materialised path: it filters by "beneath
22174
+ * one of these" without an expanded set.
22175
+ *
22176
+ * Reads the tree, since minimality and `envWide` are questions about it; a
22177
+ * root the readable hierarchy does not contain raises
22178
+ * `authorizer.hierarchy_incomplete`, as a check at such a node does.
22179
+ */
22180
+ grantRoots(identityId: string, permission: string): Promise<{
22181
+ roots: string[];
22182
+ envWide: boolean;
21930
22183
  }>;
22184
+ /**
22185
+ * Where the identity may act with the permission, as the set a list query
22186
+ * filters by: {@link grantRoots} expanded through their descendants, up to
22187
+ * `maxNodes` (the authorizer's default unless given here).
22188
+ *
22189
+ * Past the cap `nodes` is null and `complete` false: the set is too large
22190
+ * to be worth an `IN (...)` list, and the caller filters by `roots`
22191
+ * instead. An `envWide` answer carries no set either, since every node
22192
+ * qualifies and a filter would only slow the query down.
22193
+ *
22194
+ * Computed from the same cached grant roots and tree a check uses, so a
22195
+ * list filtered by it and the check on a write cannot disagree, and it goes
22196
+ * stale on the same `ttlMs`.
22197
+ */
22198
+ accessibleNodes(identityId: string, permission: string, options?: {
22199
+ maxNodes?: number;
22200
+ }): Promise<AccessibleNodes>;
22201
+ /**
22202
+ * Every permission the identity holds at the node, by grant or by
22203
+ * inheritance: the list a screen renders its controls from, answered from
22204
+ * the same cached grant roots and tree a check uses.
22205
+ */
22206
+ permissionsAt(identityId: string, nodeId: string): Promise<string[]>;
22207
+ /**
22208
+ * {@link permissionsAt} for several nodes at once, as node → permissions:
22209
+ * the rows of a list each with their own controls, answered from one read
22210
+ * of the grant roots and one walk per node.
22211
+ */
22212
+ permissionsAtMany(identityId: string, nodeIds: readonly string[]): Promise<Map<string, string[]>>;
21931
22213
  private decide;
21932
22214
  /** Counters for observability — how much traffic the cache is actually saving. */
21933
22215
  snapshot(): LocalAuthorizerStats;
@@ -21954,19 +22236,29 @@ declare class LocalAuthorizer {
21954
22236
  * top of it — size the TTL to the revocation latency you can promise.
21955
22237
  */
21956
22238
  invalidate(identityId?: string): void;
21957
- /** Climb from `nodeId` and look for a grant root among its ancestors. */
21958
- private holdsAtNode;
22239
+ /** Fire the decision hooks, after the verdict and without waiting on them. */
22240
+ private announce;
22241
+ /** The node and its ancestors, from the tree this client can read. */
22242
+ private lineageOf;
22243
+ private hierarchyIncomplete;
21959
22244
  private grantRootsFor;
21960
22245
  /**
21961
- * Every page of the identity's grant roots, folded into permission → nodes.
22246
+ * Every page of the identity's grant roots, with their windows, folded
22247
+ * into permission → roots.
22248
+ *
22249
+ * Each row is one permission at one node for one assignment, so a
22250
+ * permission granted at three nodes arrives as three rows, possibly on
22251
+ * different pages. Stopping after the first page would under-report what
22252
+ * the identity holds: a false deny, the safe direction, but a wrong answer
22253
+ * all the same.
21962
22254
  *
21963
- * Each row is one permission at one node, so a permission granted at three
21964
- * nodes arrives as three rows, possibly on different pages. Stopping after
21965
- * the first page would under-report what the identity holds: a false deny,
21966
- * the safe direction, but a wrong answer all the same.
22255
+ * Rows outside their window are kept: they are what lets a denial say
22256
+ * `expired` or `not_yet_effective`, and the entry expires at the nearest
22257
+ * window boundary when that comes before the TTL, so a grant takes effect
22258
+ * or ends on time rather than up to `ttlMs` late.
21967
22259
  */
21968
22260
  private fetchGrantRoots;
21969
- private parents;
22261
+ private treeEntry;
21970
22262
  /**
21971
22263
  * Revalidate rather than re-read. The hierarchy is the expensive half and
21972
22264
  * the one that changes least, so the common case is a `304` and no transfer
@@ -22432,4 +22724,4 @@ type WebhookEventData<Name extends WebhookEventName> = WebhookEvent<Name>["data"
22432
22724
  */
22433
22725
  declare function isWebhookEvent<Name extends WebhookEventName>(delivery: WebhookDelivery, name: Name): delivery is WebhookEvent<Name>;
22434
22726
 
22435
- export { type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, type FailureStatus, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationDirectoryGroupItem, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, authorizationErrorStatus, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, tokenErrorStatus, withConcurrency };
22727
+ export { type AccessibleNodes, type AssignmentItem, Assignments, type CallOptions, Canopy, CanopyAuthorizerError, CanopyClient, type CanopyClientOptions, CanopyConnectionError, CanopyError, type CanopyErrorBody, type CanopyOrgContext, type CanopyTokenClaims, CanopyTokenError, type Collection, type ConcurrencyOptions, type ConditionalResult, type CursorPagination, DEFAULT_MAX_NODES, type FailureStatus, Identities, type IdentityAssignmentItem, type IdentityItem, type IdentitySessionItem, type LocalAuthorizationQuery, LocalAuthorizer, type LocalAuthorizerOptions, type LocalAuthorizerStats, type LocalDecision, type LocalDecisionEvent, type LocalDenialReason, MAX_TTL_MS, type OffsetPagination, type OperationId, type OrganizationDirectoryGroupItem, type OrganizationInviteItem, type OrganizationItem, type OrganizationMemberItem, Organizations, type PageFetcher, type PageParams, type PaginateOptions, type Pagination, Paginator, type PartialSuccess, type PermissionItem, Permissions, type QueryParams, type RequestBody, type RequestOptions, type ResponseBody, type RoleItem, Roles, type Schema, TokenVerifier, type TokenVerifierOptions, type WebhookDelivery, type WebhookEvent, type WebhookEventData, type WebhookEventName, authorizationErrorStatus, type components, isCanopyAuthorizerError, isCanopyConnectionError, isCanopyError, isCanopyTokenError, isCursorPagination, isWebhookEvent, type operations, orgContext, paginate, type paths, tokenErrorStatus, withConcurrency };