@canopy-io/node 0.9.0 → 0.10.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.cts CHANGED
@@ -6470,7 +6470,7 @@ interface operations {
6470
6470
  "application/json": components["schemas"]["ErrorResponseDto"];
6471
6471
  };
6472
6472
  };
6473
- /** @description The email or external_id already belongs to an identity in this Account, or the Account has reached its plan's identity signup ceiling */
6473
+ /** @description The email or external_id already belongs to an identity in this Account, the Account has reached its plan's identity signup ceiling, or the starting role is placed beneath an organization, where a new identity holds no membership yet */
6474
6474
  409: {
6475
6475
  headers: {
6476
6476
  [name: string]: unknown;
@@ -6481,7 +6481,7 @@ interface operations {
6481
6481
  * "error": {
6482
6482
  * "statusCode": 409,
6483
6483
  * "code": null,
6484
- * "message": "The email or external_id already belongs to an identity in this Account, or the Account has reached its plan's identity signup ceiling",
6484
+ * "message": "The email or external_id already belongs to an identity in this Account, the Account has reached its plan's identity signup ceiling, or the starting role is placed beneath an organization, where a new identity holds no membership yet",
6485
6485
  * "timestamp": "2026-04-20T12:00:00.000Z",
6486
6486
  * "path": "/api/v1/identities",
6487
6487
  * "method": "POST"
@@ -8487,6 +8487,8 @@ interface operations {
8487
8487
  };
8488
8488
  content: {
8489
8489
  "application/json": {
8490
+ /** @description The version of the authorization model these rows describe. A client that evaluates from them refuses a version it does not know rather than guessing. */
8491
+ model_version: number;
8490
8492
  items: components["schemas"]["IdentityGrantResponseDto"][];
8491
8493
  pagination: components["schemas"]["PageMetaDto"];
8492
8494
  };
@@ -9491,6 +9493,8 @@ interface operations {
9491
9493
  };
9492
9494
  content: {
9493
9495
  "application/json": {
9496
+ /** @description The version of the authorization model these rows describe. A client that evaluates from them refuses a version it does not know rather than guessing. */
9497
+ model_version: number;
9494
9498
  items: components["schemas"]["NodeParentEdgeResponseDto"][];
9495
9499
  pagination: components["schemas"]["PageMetaDto"];
9496
9500
  };
@@ -17646,7 +17650,7 @@ interface operations {
17646
17650
  "application/json": components["schemas"]["ErrorResponseDto"];
17647
17651
  };
17648
17652
  };
17649
- /** @description The identity already has this role at this node, or the node belongs to an organization the identity is not a member of */
17653
+ /** @description The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at */
17650
17654
  409: {
17651
17655
  headers: {
17652
17656
  [name: string]: unknown;
@@ -17657,7 +17661,7 @@ interface operations {
17657
17661
  * "error": {
17658
17662
  * "statusCode": 409,
17659
17663
  * "code": null,
17660
- * "message": "The identity already has this role at this node, or the node belongs to an organization the identity is not a member of",
17664
+ * "message": "The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at",
17661
17665
  * "timestamp": "2026-04-20T12:00:00.000Z",
17662
17666
  * "path": "/api/v1/assignments",
17663
17667
  * "method": "POST"
package/dist/index.d.ts CHANGED
@@ -6470,7 +6470,7 @@ interface operations {
6470
6470
  "application/json": components["schemas"]["ErrorResponseDto"];
6471
6471
  };
6472
6472
  };
6473
- /** @description The email or external_id already belongs to an identity in this Account, or the Account has reached its plan's identity signup ceiling */
6473
+ /** @description The email or external_id already belongs to an identity in this Account, the Account has reached its plan's identity signup ceiling, or the starting role is placed beneath an organization, where a new identity holds no membership yet */
6474
6474
  409: {
6475
6475
  headers: {
6476
6476
  [name: string]: unknown;
@@ -6481,7 +6481,7 @@ interface operations {
6481
6481
  * "error": {
6482
6482
  * "statusCode": 409,
6483
6483
  * "code": null,
6484
- * "message": "The email or external_id already belongs to an identity in this Account, or the Account has reached its plan's identity signup ceiling",
6484
+ * "message": "The email or external_id already belongs to an identity in this Account, the Account has reached its plan's identity signup ceiling, or the starting role is placed beneath an organization, where a new identity holds no membership yet",
6485
6485
  * "timestamp": "2026-04-20T12:00:00.000Z",
6486
6486
  * "path": "/api/v1/identities",
6487
6487
  * "method": "POST"
@@ -8487,6 +8487,8 @@ interface operations {
8487
8487
  };
8488
8488
  content: {
8489
8489
  "application/json": {
8490
+ /** @description The version of the authorization model these rows describe. A client that evaluates from them refuses a version it does not know rather than guessing. */
8491
+ model_version: number;
8490
8492
  items: components["schemas"]["IdentityGrantResponseDto"][];
8491
8493
  pagination: components["schemas"]["PageMetaDto"];
8492
8494
  };
@@ -9491,6 +9493,8 @@ interface operations {
9491
9493
  };
9492
9494
  content: {
9493
9495
  "application/json": {
9496
+ /** @description The version of the authorization model these rows describe. A client that evaluates from them refuses a version it does not know rather than guessing. */
9497
+ model_version: number;
9494
9498
  items: components["schemas"]["NodeParentEdgeResponseDto"][];
9495
9499
  pagination: components["schemas"]["PageMetaDto"];
9496
9500
  };
@@ -17646,7 +17650,7 @@ interface operations {
17646
17650
  "application/json": components["schemas"]["ErrorResponseDto"];
17647
17651
  };
17648
17652
  };
17649
- /** @description The identity already has this role at this node, or the node belongs to an organization the identity is not a member of */
17653
+ /** @description The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at */
17650
17654
  409: {
17651
17655
  headers: {
17652
17656
  [name: string]: unknown;
@@ -17657,7 +17661,7 @@ interface operations {
17657
17661
  * "error": {
17658
17662
  * "statusCode": 409,
17659
17663
  * "code": null,
17660
- * "message": "The identity already has this role at this node, or the node belongs to an organization the identity is not a member of",
17664
+ * "message": "The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at",
17661
17665
  * "timestamp": "2026-04-20T12:00:00.000Z",
17662
17666
  * "path": "/api/v1/assignments",
17663
17667
  * "method": "POST"
package/dist/index.js CHANGED
@@ -1153,6 +1153,16 @@ var MAX_WALK_DEPTH = 256;
1153
1153
  var PAGE_SIZE = 100;
1154
1154
  var MAX_PAGES = 1e4;
1155
1155
  var MAX_TREE_WALKS = 3;
1156
+ var KNOWN_MODEL_VERSIONS = /* @__PURE__ */ new Set([1]);
1157
+ function understood(page, path) {
1158
+ if (!KNOWN_MODEL_VERSIONS.has(page.model_version)) {
1159
+ throw new CanopyAuthorizerError(
1160
+ "authorizer.model_version_unknown",
1161
+ `${path} describes authorization model version ${page.model_version}, which this version of @canopy-io/node does not understand. It knows ${[...KNOWN_MODEL_VERSIONS].join(", ")}. Upgrade @canopy-io/node; until then this authorizer cannot decide, rather than guess.`
1162
+ );
1163
+ }
1164
+ return page;
1165
+ }
1156
1166
  var GRANTS_PATH = (identityId) => `/api/v1/identities/${encodeURIComponent(identityId)}/grants`;
1157
1167
  var PARENTS_PATH = "/api/v1/nodes/parents";
1158
1168
  var LocalAuthorizer = class {
@@ -1328,7 +1338,7 @@ var LocalAuthorizer = class {
1328
1338
  return this.client.request("GET", path, {
1329
1339
  ...this.readOptions,
1330
1340
  query
1331
- });
1341
+ }).then((page) => understood(page, path));
1332
1342
  },
1333
1343
  { page: 1, take: PAGE_SIZE },
1334
1344
  { maxPages: MAX_PAGES }
@@ -1408,12 +1418,15 @@ var LocalAuthorizer = class {
1408
1418
  }
1409
1419
  parentsFirstPage(etag) {
1410
1420
  this.stats.treePages += 1;
1411
- return this.client.requestConditional(
1412
- "GET",
1413
- PARENTS_PATH,
1414
- etag,
1415
- { ...this.readOptions, query: { page: 1, take: PAGE_SIZE } }
1416
- );
1421
+ return this.client.requestConditional("GET", PARENTS_PATH, etag, {
1422
+ ...this.readOptions,
1423
+ query: { page: 1, take: PAGE_SIZE }
1424
+ }).then((result) => {
1425
+ if (result.modified) {
1426
+ understood(result.data, PARENTS_PATH);
1427
+ }
1428
+ return result;
1429
+ });
1417
1430
  }
1418
1431
  /** The first page's edges followed by every later page's. */
1419
1432
  async parentsRemainingPages(first) {
@@ -1427,7 +1440,7 @@ var LocalAuthorizer = class {
1427
1440
  return this.client.request("GET", PARENTS_PATH, {
1428
1441
  ...this.readOptions,
1429
1442
  query
1430
- });
1443
+ }).then((page) => understood(page, PARENTS_PATH));
1431
1444
  },
1432
1445
  { page: first.pagination.page + 1, take: PAGE_SIZE },
1433
1446
  { maxPages: MAX_PAGES - 1 }