@zitadel/testing 1.0.0-alpha.22 → 1.0.0-alpha.23

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
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_src = require("./src-pZyQN7qD.cjs");
2
+ const require_src = require("./src-CFX_ayWr.cjs");
3
3
  const require_handshake = require("./handshake-BOsVBPtn.cjs");
4
4
  exports.SESSION_COOKIE_NAME = require_src.SESSION_COOKIE_NAME;
5
5
  exports.applyAppEnvTemplate = require_handshake.applyAppEnvTemplate;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_src = require("./src-pZyQN7qD.cjs");
2
+ const require_src = require("./src-CFX_ayWr.cjs");
3
3
  const require_handshake = require("./handshake-BOsVBPtn.cjs");
4
4
  const require_orchestration = require("./orchestration-D7QBgQ0l.cjs");
5
5
  let node_fs = require("node:fs");
@@ -137,16 +137,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
137
137
  createFlowDefinition: () => createFlowDefinition,
138
138
  createGrant: () => createGrant,
139
139
  createHandoff: () => createHandoff,
140
+ createIdp: () => createIdp,
140
141
  createProject: () => createProject,
141
142
  createRelease: () => createRelease,
142
143
  createSchema: () => createSchema,
143
144
  createSession: () => createSession,
144
145
  createTeam: () => createTeam,
145
146
  createUser: () => createUser,
146
- deleteFlowDefinition: () => deleteFlowDefinition,
147
147
  deleteGrant: () => deleteGrant,
148
148
  deleteTeam: () => deleteTeam,
149
149
  deleteUserByID: () => deleteUserByID,
150
+ deleteVariable: () => deleteVariable,
150
151
  exchangeHandoff: () => exchangeHandoff,
151
152
  finishUserPasskeyRegistration: () => finishUserPasskeyRegistration,
152
153
  getAuthAttempt: () => getAuthAttempt,
@@ -161,16 +162,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
161
162
  getCreateFlowUrl: () => getCreateFlowUrl,
162
163
  getCreateGrantUrl: () => getCreateGrantUrl,
163
164
  getCreateHandoffUrl: () => getCreateHandoffUrl,
165
+ getCreateIdpUrl: () => getCreateIdpUrl,
164
166
  getCreateProjectUrl: () => getCreateProjectUrl,
165
167
  getCreateReleaseUrl: () => getCreateReleaseUrl,
166
168
  getCreateSchemaUrl: () => getCreateSchemaUrl,
167
169
  getCreateSessionUrl: () => getCreateSessionUrl,
168
170
  getCreateTeamUrl: () => getCreateTeamUrl,
169
171
  getCreateUserUrl: () => getCreateUserUrl,
170
- getDeleteFlowDefinitionUrl: () => getDeleteFlowDefinitionUrl,
171
172
  getDeleteGrantUrl: () => getDeleteGrantUrl,
172
173
  getDeleteTeamUrl: () => getDeleteTeamUrl,
173
174
  getDeleteUserByIDUrl: () => getDeleteUserByIDUrl,
175
+ getDeleteVariableUrl: () => getDeleteVariableUrl,
174
176
  getEnvironmentByName: () => getEnvironmentByName,
175
177
  getEvent: () => getEvent,
176
178
  getExchangeHandoffUrl: () => getExchangeHandoffUrl,
@@ -187,6 +189,8 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
187
189
  getGetFlowStepUrl: () => getGetFlowStepUrl,
188
190
  getGetGrantUrl: () => getGetGrantUrl,
189
191
  getGetHealthUrl: () => getGetHealthUrl,
192
+ getGetIdpByIdUrl: () => getGetIdpByIdUrl,
193
+ getGetIdpRevisionByIdUrl: () => getGetIdpRevisionByIdUrl,
190
194
  getGetLiveUrl: () => getGetLiveUrl,
191
195
  getGetMySessionUrl: () => getGetMySessionUrl,
192
196
  getGetMyUserUrl: () => getGetMyUserUrl,
@@ -197,14 +201,20 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
197
201
  getGetSessionUrl: () => getGetSessionUrl,
198
202
  getGetTeamUrl: () => getGetTeamUrl,
199
203
  getGetUserByIDUrl: () => getGetUserByIDUrl,
204
+ getGetVariableUrl: () => getGetVariableUrl,
205
+ getGetVariablesUrl: () => getGetVariablesUrl,
200
206
  getGrant: () => getGrant,
201
207
  getHealth: () => getHealth,
208
+ getIdpById: () => getIdpById,
209
+ getIdpRevisionById: () => getIdpRevisionById,
202
210
  getInitClaimUrl: () => getInitClaimUrl,
203
211
  getIssueChallengeUrl: () => getIssueChallengeUrl,
204
212
  getListBrandingUrl: () => getListBrandingUrl,
205
213
  getListEnvironmentsUrl: () => getListEnvironmentsUrl,
206
214
  getListEventsUrl: () => getListEventsUrl,
207
215
  getListFlowDefinitionsUrl: () => getListFlowDefinitionsUrl,
216
+ getListIdpRevisionsUrl: () => getListIdpRevisionsUrl,
217
+ getListMyProjectsUrl: () => getListMyProjectsUrl,
208
218
  getListReleasesUrl: () => getListReleasesUrl,
209
219
  getListSchemasUrl: () => getListSchemasUrl,
210
220
  getListUserPasskeysUrl: () => getListUserPasskeysUrl,
@@ -212,9 +222,12 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
212
222
  getLive: () => getLive,
213
223
  getMySession: () => getMySession,
214
224
  getMyUser: () => getMyUser,
225
+ getPatchMyUserUrl: () => getPatchMyUserUrl,
215
226
  getPatchProjectUrl: () => getPatchProjectUrl,
227
+ getPatchUserByIDUrl: () => getPatchUserByIDUrl,
216
228
  getProject: () => getProject,
217
229
  getQueryGrantsUrl: () => getQueryGrantsUrl,
230
+ getQueryIdpsUrl: () => getQueryIdpsUrl,
218
231
  getQueryProjectsUrl: () => getQueryProjectsUrl,
219
232
  getQuerySessionsUrl: () => getQuerySessionsUrl,
220
233
  getQueryTeamsUrl: () => getQueryTeamsUrl,
@@ -228,9 +241,11 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
228
241
  getSetUserPasswordUrl: () => getSetUserPasswordUrl,
229
242
  getSubmitFlowStepUrl: () => getSubmitFlowStepUrl,
230
243
  getTeam: () => getTeam,
231
- getUpdateFlowDefinitionUrl: () => getUpdateFlowDefinitionUrl,
232
244
  getUpdateTeamUrl: () => getUpdateTeamUrl,
245
+ getUpdateVariablesUrl: () => getUpdateVariablesUrl,
233
246
  getUserByID: () => getUserByID,
247
+ getVariable: () => getVariable,
248
+ getVariables: () => getVariables,
234
249
  getVerifyChallengeProofUrl: () => getVerifyChallengeProofUrl,
235
250
  initClaim: () => initClaim,
236
251
  issueChallenge: () => issueChallenge,
@@ -238,12 +253,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
238
253
  listEnvironments: () => listEnvironments,
239
254
  listEvents: () => listEvents,
240
255
  listFlowDefinitions: () => listFlowDefinitions,
256
+ listIdpRevisions: () => listIdpRevisions,
257
+ listMyProjects: () => listMyProjects,
241
258
  listReleases: () => listReleases,
242
259
  listSchemas: () => listSchemas,
243
260
  listUserPasskeys: () => listUserPasskeys,
244
261
  listUserTeams: () => listUserTeams,
262
+ patchMyUser: () => patchMyUser,
245
263
  patchProject: () => patchProject,
264
+ patchUserByID: () => patchUserByID,
246
265
  queryGrants: () => queryGrants,
266
+ queryIdps: () => queryIdps,
247
267
  queryProjects: () => queryProjects,
248
268
  querySessions: () => querySessions,
249
269
  queryTeams: () => queryTeams,
@@ -252,8 +272,8 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
252
272
  revokeSession: () => revokeSession,
253
273
  setUserPassword: () => setUserPassword,
254
274
  submitFlowStep: () => submitFlowStep,
255
- updateFlowDefinition: () => updateFlowDefinition,
256
275
  updateTeam: () => updateTeam,
276
+ updateVariables: () => updateVariables,
257
277
  verifyChallengeProof: () => verifyChallengeProof
258
278
  });
259
279
  const getGetHealthUrl = () => {
@@ -323,9 +343,14 @@ const getQueryUsersUrl = () => {
323
343
  /**
324
344
  * Returns the users of a project, paginated with a cursor.
325
345
 
326
- The project comes from the credential, not from a parameter: the operation
327
- is bound to the token's own project by construction. This is why it takes
328
- no `project_id`, unlike the other query endpoints.
346
+ The project comes from the credential, not from a parameter: the
347
+ operation is bound to the credential's home project by construction
348
+ (oauth2 secret or user-bound session). This is why it takes no
349
+ `project_id`, unlike the other query endpoints.
350
+
351
+ Accepts either a project secret (`oauth2`) or a user-bound Console
352
+ session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
353
+ is a follow-up (#1140).
329
354
 
330
355
  * @summary Query users
331
356
  */
@@ -357,6 +382,28 @@ const getUserByID = async (userId, params, options) => {
357
382
  method: "GET"
358
383
  });
359
384
  };
385
+ const getPatchUserByIDUrl = (userId) => {
386
+ return `${getProxyPath()}/users/${userId}`;
387
+ };
388
+ /**
389
+ * Partially updates a user's schema-defined attributes, and optionally
390
+ moves the user to another registered schema. The merged result is
391
+ validated against the schema before commit. Concurrent writes are
392
+ last-write-wins.
393
+
394
+ * @summary Update user by ID
395
+ */
396
+ const patchUserByID = async (userId, patchUserByIDBody, options) => {
397
+ return customFetch(getPatchUserByIDUrl(userId), {
398
+ ...options,
399
+ method: "PATCH",
400
+ headers: {
401
+ "Content-Type": "application/json",
402
+ ...options?.headers
403
+ },
404
+ body: JSON.stringify(patchUserByIDBody)
405
+ });
406
+ };
360
407
  const getDeleteUserByIDUrl = (userId) => {
361
408
  return `${getProxyPath()}/users/${userId}`;
362
409
  };
@@ -487,6 +534,52 @@ const getMyUser = async (options) => {
487
534
  method: "GET"
488
535
  });
489
536
  };
537
+ const getPatchMyUserUrl = () => {
538
+ return `${getProxyPath()}/users/me`;
539
+ };
540
+ /**
541
+ * Partially updates the caller's own schema-defined attributes. The merged
542
+ result is validated against the user's schema before commit. Concurrent
543
+ writes are last-write-wins.
544
+
545
+ * @summary Update my user information
546
+ */
547
+ const patchMyUser = async (patchMyUserBody, options) => {
548
+ return customFetch(getPatchMyUserUrl(), {
549
+ ...options,
550
+ method: "PATCH",
551
+ headers: {
552
+ "Content-Type": "application/json",
553
+ ...options?.headers
554
+ },
555
+ body: JSON.stringify(patchMyUserBody)
556
+ });
557
+ };
558
+ const getListMyProjectsUrl = (params) => {
559
+ const normalizedParams = new URLSearchParams();
560
+ Object.entries(params || {}).forEach(([key, value]) => {
561
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
562
+ });
563
+ const stringifiedParams = normalizedParams.toString();
564
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/users/me/projects?${stringifiedParams}` : `${getProxyPath()}/users/me/projects`;
565
+ };
566
+ /**
567
+ * The projects the signed-in user holds an active grant on, either directly or
568
+ through a team they are a member of. Ordered by project id and paged with an
569
+ opaque cursor.
570
+
571
+ This is not the same question as `queryProjects`, which answers with the one
572
+ project the calling credential is bound to. Here the session is the caller
573
+ and the grants are the answer, so the list spans projects.
574
+
575
+ * @summary List the projects I can act on
576
+ */
577
+ const listMyProjects = async (params, options) => {
578
+ return customFetch(getListMyProjectsUrl(params), {
579
+ ...options,
580
+ method: "GET"
581
+ });
582
+ };
490
583
  const getCreateFlowUrl = () => {
491
584
  return `${getProxyPath()}/flow`;
492
585
  };
@@ -1172,42 +1265,6 @@ const getFlowDefinition = async (id, options) => {
1172
1265
  method: "GET"
1173
1266
  });
1174
1267
  };
1175
- const getUpdateFlowDefinitionUrl = (id) => {
1176
- return `${getProxyPath()}/flow_definitions/${id}`;
1177
- };
1178
- /**
1179
- * Update a flow definition by id. This endpoint replaces the existing flow definition.
1180
- If `flow_definition.status` is omitted, the current status is preserved
1181
-
1182
- * @summary Update a flow definition by id
1183
- */
1184
- const updateFlowDefinition = async (id, updateFlowDefinitionBody, options) => {
1185
- return customFetch(getUpdateFlowDefinitionUrl(id), {
1186
- ...options,
1187
- method: "PUT",
1188
- headers: {
1189
- "Content-Type": "application/json",
1190
- ...options?.headers
1191
- },
1192
- body: JSON.stringify(updateFlowDefinitionBody)
1193
- });
1194
- };
1195
- const getDeleteFlowDefinitionUrl = (id) => {
1196
- return `${getProxyPath()}/flow_definitions/${id}`;
1197
- };
1198
- /**
1199
- * Delete a flow definition by id.
1200
- If the flow definition is currently being used by a flow, the deletion will fail.
1201
- If the flow definition is the last active flow definition for a given purpose, the deletion will fail to prevent disruption of new flows being started for that purpose.
1202
-
1203
- * @summary Delete a flow definition by id
1204
- */
1205
- const deleteFlowDefinition = async (id, options) => {
1206
- return customFetch(getDeleteFlowDefinitionUrl(id), {
1207
- ...options,
1208
- method: "DELETE"
1209
- });
1210
- };
1211
1268
  const getCreateTeamUrl = (params) => {
1212
1269
  const normalizedParams = new URLSearchParams();
1213
1270
  Object.entries(params || {}).forEach(([key, value]) => {
@@ -1281,6 +1338,11 @@ users whose lifecycle it owns are deactivated with it.
1281
1338
  The request is idempotent. Deleting a team that is already deactivated
1282
1339
  or doesn't exist succeeds without changing anything.
1283
1340
 
1341
+ A team that still owns a project is refused with `409
1342
+ team.owns_project`: deactivating it would leave the project owned by a
1343
+ dead team and so unmanageable. No endpoint releases that ownership yet,
1344
+ so such a team cannot currently be deactivated through the API.
1345
+
1284
1346
  * @summary Delete team
1285
1347
  */
1286
1348
  const deleteTeam = async (teamId, options) => {
@@ -1360,8 +1422,7 @@ const getCreateBrandingUrl = (params) => {
1360
1422
  /**
1361
1423
  * Publishes a new immutable branding revision for the project. Branding
1362
1424
  revisions cannot be updated or deleted; every edit publishes a new
1363
- revision, and flow responses resolve the latest revision per project
1364
- (see ADR 040).
1425
+ revision, and flow responses resolve the latest revision per project.
1365
1426
 
1366
1427
  The `liquid_template` is validated lexically on save (size, encoding,
1367
1428
  banned patterns such as `<script>` tags, inline event handlers, and the
@@ -1392,9 +1453,9 @@ const getListBrandingUrl = (params) => {
1392
1453
  /**
1393
1454
  * Lists branding revisions for the project, newest first, capped at the
1394
1455
  100 most recent. The first entry is the revision flow responses
1395
- currently resolve. Deliberately unpaginated in v1 — list endpoints
1396
- gain a real query mechanism together (ADR 031); advertising pagination
1397
- parameters the server ignores would be worse than none.
1456
+ currently resolve. Deliberately unpaginated in v1 — list endpoints gain a
1457
+ real query mechanism together; advertising pagination parameters the
1458
+ server ignores would be worse than none.
1398
1459
 
1399
1460
  * @summary List branding revisions
1400
1461
  */
@@ -1417,6 +1478,142 @@ const getBrandingById = async (id, options) => {
1417
1478
  method: "GET"
1418
1479
  });
1419
1480
  };
1481
+ const getCreateIdpUrl = (params) => {
1482
+ const normalizedParams = new URLSearchParams();
1483
+ Object.entries(params || {}).forEach(([key, value]) => {
1484
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1485
+ });
1486
+ const stringifiedParams = normalizedParams.toString();
1487
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/idps?${stringifiedParams}` : `${getProxyPath()}/idps`;
1488
+ };
1489
+ /**
1490
+ * Creates or revises a connection document. If the slug does not already
1491
+ exist, a new connection is created. If a connection with that slug already
1492
+ exists, a revision is created.
1493
+
1494
+ A revision gets a new `revision_id` and does not modify the connection
1495
+ `id`, so identity links that reference the connection keep resolving while
1496
+ releases and auth attempts stay pinned to the revision they captured.
1497
+
1498
+ Identity fields are fixed for the life of the connection and a revision
1499
+ that changes one is rejected: `protocol`, `subject_claim`, and the
1500
+ endpoints that name the authority (`issuer` for OIDC, `token_endpoint`
1501
+ and `userinfo_endpoint` for OAuth 2.0). Their values decide which provider
1502
+ account a stored subject belongs to, so changing one would silently
1503
+ repoint existing identities at a different provider.
1504
+
1505
+ `subject_claim` is optional for OIDC and required for OAuth 2.0. For an
1506
+ OIDC connection, `sub` is used as the default value. If a revision updates
1507
+ `subject_claim` to a different value than the one set during creation, the
1508
+ request is rejected.
1509
+
1510
+ The document is validated against the `idp-connection.json` schema before
1511
+ anything is stored.
1512
+
1513
+ * @summary Create or revise an identity provider connection
1514
+ */
1515
+ const createIdp = async (createIdpBody, params, options) => {
1516
+ return customFetch(getCreateIdpUrl(params), {
1517
+ ...options,
1518
+ method: "POST",
1519
+ headers: {
1520
+ "Content-Type": "application/json",
1521
+ ...options?.headers
1522
+ },
1523
+ body: JSON.stringify(createIdpBody)
1524
+ });
1525
+ };
1526
+ const getQueryIdpsUrl = (params) => {
1527
+ const normalizedParams = new URLSearchParams();
1528
+ Object.entries(params || {}).forEach(([key, value]) => {
1529
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1530
+ });
1531
+ const stringifiedParams = normalizedParams.toString();
1532
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/query?${stringifiedParams}` : `${getProxyPath()}/idps/query`;
1533
+ };
1534
+ /**
1535
+ * Returns the identity provider connections of a project, paginated with a
1536
+ cursor. One row per connection, carrying its newest revision.
1537
+
1538
+ * @summary Query identity provider connections
1539
+ */
1540
+ const queryIdps = async (queryIdpsBody, params, options) => {
1541
+ return customFetch(getQueryIdpsUrl(params), {
1542
+ ...options,
1543
+ method: "POST",
1544
+ headers: {
1545
+ "Content-Type": "application/json",
1546
+ ...options?.headers
1547
+ },
1548
+ body: JSON.stringify(queryIdpsBody)
1549
+ });
1550
+ };
1551
+ const getGetIdpByIdUrl = (id, params) => {
1552
+ const normalizedParams = new URLSearchParams();
1553
+ Object.entries(params || {}).forEach(([key, value]) => {
1554
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1555
+ });
1556
+ const stringifiedParams = normalizedParams.toString();
1557
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/${id}?${stringifiedParams}` : `${getProxyPath()}/idps/${id}`;
1558
+ };
1559
+ /**
1560
+ * Reads a connection by its id, at its newest revision.
1561
+ `GET /idps/{id}/revisions` lists every revision of the connection.
1562
+
1563
+ The lookup is scoped to the project in `project_id`.
1564
+
1565
+ * @summary Get an identity provider connection by id
1566
+ */
1567
+ const getIdpById = async (id, params, options) => {
1568
+ return customFetch(getGetIdpByIdUrl(id, params), {
1569
+ ...options,
1570
+ method: "GET"
1571
+ });
1572
+ };
1573
+ const getListIdpRevisionsUrl = (id, params) => {
1574
+ const normalizedParams = new URLSearchParams();
1575
+ Object.entries(params || {}).forEach(([key, value]) => {
1576
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1577
+ });
1578
+ const stringifiedParams = normalizedParams.toString();
1579
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/${id}/revisions?${stringifiedParams}` : `${getProxyPath()}/idps/${id}/revisions`;
1580
+ };
1581
+ /**
1582
+ * Returns every revision of one connection, newest first, paginated with a
1583
+ cursor. The order is fixed, so there is no `sorting`.
1584
+
1585
+ The lookup is scoped to the project in `project_id`.
1586
+
1587
+ * @summary List the revisions of an identity provider connection
1588
+ */
1589
+ const listIdpRevisions = async (id, params, options) => {
1590
+ return customFetch(getListIdpRevisionsUrl(id, params), {
1591
+ ...options,
1592
+ method: "GET"
1593
+ });
1594
+ };
1595
+ const getGetIdpRevisionByIdUrl = (revisionId, params) => {
1596
+ const normalizedParams = new URLSearchParams();
1597
+ Object.entries(params || {}).forEach(([key, value]) => {
1598
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1599
+ });
1600
+ const stringifiedParams = normalizedParams.toString();
1601
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/revisions/${revisionId}?${stringifiedParams}` : `${getProxyPath()}/idps/revisions/${revisionId}`;
1602
+ };
1603
+ /**
1604
+ * Reads one revision of a connection by its `revision_id`, the value an auth
1605
+ attempt or a release pins.
1606
+
1607
+ The lookup is scoped to the project in `project_id`.
1608
+
1609
+ * @summary Get one revision of an identity provider connection
1610
+ */
1611
+ const getIdpRevisionById = async (revisionId, params, options) => {
1612
+ return customFetch(getGetIdpRevisionByIdUrl(revisionId, params), {
1613
+ ...options,
1614
+ method: "GET"
1615
+ });
1616
+ };
1420
1617
  const getCreateReleaseUrl = (params) => {
1421
1618
  const normalizedParams = new URLSearchParams();
1422
1619
  Object.entries(params || {}).forEach(([key, value]) => {
@@ -1516,10 +1713,23 @@ const getCreateGrantUrl = (params) => {
1516
1713
  /**
1517
1714
  * Bind a user or team to `project.viewer`, `project.editor`, or
1518
1715
  `project.admin` on the project identified by the `project-id` header.
1519
- IDs are `asgn_<opaque>`. Owning-team (`project.team`) grants are not
1520
- created here — claim owns that path. An unrevoked grant with the same
1521
- principal and relation occupies the unique key even after `expires_at`;
1522
- DELETE it before re-creating.
1716
+ Name the principal with `user` (`user_id` or `identifier`) or `team`
1717
+ (`team_id` or `name`). IDs are `asgn_<opaque>`. Owning-team
1718
+ (`project.team`) grants are not created here — claim owns that path. An
1719
+ unrevoked grant with the same principal and relation occupies the unique
1720
+ key even after `expires_at`; DELETE it before re-creating.
1721
+ Create does not accept `expand`. The `user_id` and team locators
1722
+ return 201, whose `user` / `team` carry only `user_id` / `team_id`,
1723
+ and still 404 / 409 when the principal is missing or the tuple
1724
+ already exists. Creating by `user.identifier` answers 202 with no
1725
+ body on every outcome. Granting the session caller's own user is
1726
+ `grant.invalid` on either user locator. Read the grant back for
1727
+ identifier and display.
1728
+
1729
+ Accepts either a project secret (`oauth2`) or a user-bound Console
1730
+ session cookie (`nextgenSession`). Session callers are authorized as
1731
+ the human against the target project (home may differ). CSRF/Origin
1732
+ for cookie mutations is a follow-up (#1140).
1523
1733
 
1524
1734
  * @summary Create grant
1525
1735
  */
@@ -1549,10 +1759,16 @@ viewer, editor, or admin), including expired grants so a client can
1549
1759
  DELETE before re-granting. Project-secret setup (`sk_proj`) and
1550
1760
  owning-team (`relation=team`) rows are not returned. Grants are not in
1551
1761
  `resource_scope_index`; project scope is required on the query (same as
1552
- get). Requires `project.read`. `expand: ["principal"]` additionally
1553
- requires `user.read` and `team.read` (documented on the expand enum;
1554
- those scopes cannot be ANDed onto this security block because they are
1555
- body-conditional).
1762
+ get). Requires `project.read`. `expand: ["principal"]` adds envelope
1763
+ fields on `user` / `team` and additionally requires `user.read` and
1764
+ `team.read` for project secrets (documented on the expand enum; those
1765
+ scopes cannot be ANDed onto this security block because they are
1766
+ body-conditional). A user-bound Console session that already passed
1767
+ the project Check may expand without those scopes.
1768
+
1769
+ Accepts either a project secret (`oauth2`) or a user-bound Console
1770
+ session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
1771
+ is a follow-up (#1140).
1556
1772
 
1557
1773
  * @summary Query grants
1558
1774
  */
@@ -1584,6 +1800,14 @@ still ignores expired grants. Grants are not registered in
1584
1800
  `resource_scope_index`; project scope is required on the query (same as
1585
1801
  events). Misses, revoked rows, project-secret setup (`sk_proj`),
1586
1802
  owning-team (`relation=team`) rows, and cross-project ids return 404.
1803
+ `expand=principal` adds envelope fields on `user` or `team` and requires
1804
+ `user.read` and `team.read` in addition to `project.read` for project
1805
+ secrets. A user-bound Console session that already passed the project
1806
+ Check may expand without those scopes.
1807
+
1808
+ Accepts either a project secret (`oauth2`) or a user-bound Console
1809
+ session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
1810
+ is a follow-up (#1140).
1587
1811
 
1588
1812
  * @summary Get grant
1589
1813
  */
@@ -1607,6 +1831,10 @@ Already-revoked, missing, project-secret setup, and owning-team grants
1607
1831
  return 404. The row is not un-revoked. Expired grants can still be
1608
1832
  revoked so the unique binding can be reused.
1609
1833
 
1834
+ Accepts either a project secret (`oauth2`) or a user-bound Console
1835
+ session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
1836
+ is a follow-up (#1140).
1837
+
1610
1838
  * @summary Revoke grant
1611
1839
  */
1612
1840
  const deleteGrant = async (id, params, options) => {
@@ -1673,6 +1901,122 @@ const getEvent = async (id, params, options) => {
1673
1901
  method: "GET"
1674
1902
  });
1675
1903
  };
1904
+ const getGetVariablesUrl = (params) => {
1905
+ const normalizedParams = new URLSearchParams();
1906
+ Object.entries(params || {}).forEach(([key, value]) => {
1907
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1908
+ });
1909
+ const stringifiedParams = normalizedParams.toString();
1910
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/variables?${stringifiedParams}` : `${getProxyPath()}/variables`;
1911
+ };
1912
+ /**
1913
+ * Returns the variables entered at the owner this request addresses, keyed by
1914
+ name — one environment of the project with `environment_name`, the project
1915
+ level itself without it.
1916
+
1917
+ Owners are separate, not a ladder: an environment does not inherit the
1918
+ project's variables and the project does not see its environments'. Reading
1919
+ everything a project holds therefore means reading each owner in turn.
1920
+
1921
+ Secret values are not returned. A secret appears as `{"secret": true}`,
1922
+ which says a value is held without disclosing it.
1923
+
1924
+ * @summary Get variables
1925
+ */
1926
+ const getVariables = async (params, options) => {
1927
+ return customFetch(getGetVariablesUrl(params), {
1928
+ ...options,
1929
+ method: "GET"
1930
+ });
1931
+ };
1932
+ const getUpdateVariablesUrl = (params) => {
1933
+ const normalizedParams = new URLSearchParams();
1934
+ Object.entries(params || {}).forEach(([key, value]) => {
1935
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1936
+ });
1937
+ const stringifiedParams = normalizedParams.toString();
1938
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/variables?${stringifiedParams}` : `${getProxyPath()}/variables`;
1939
+ };
1940
+ /**
1941
+ * Enters, replaces and removes variables at the owner this request
1942
+ addresses.
1943
+
1944
+ Every name in the body is applied at exactly that owner — the project, or
1945
+ the environment named by `environment_name` — and reaches no other. Names
1946
+ not in the body are untouched.
1947
+
1948
+ A bare scalar enters a non-secret value. `{"value": …, "secret": true}`
1949
+ stores the value encrypted under the project's active `secret` key, after
1950
+ which it can be referenced but not read back. `null` removes the name from
1951
+ this owner (RFC 7386), which is how several variables are removed in one
1952
+ request; removing a name this owner does not hold is a no-op rather than an
1953
+ error.
1954
+
1955
+ The body is applied whole or not at all, so a rejected request leaves the
1956
+ owner exactly as it was. Writing the same name and owner twice replaces the
1957
+ value rather than duplicating it, which makes a retry safe.
1958
+
1959
+ * @summary Update variables
1960
+ */
1961
+ const updateVariables = async (updateVariablesBody, params, options) => {
1962
+ return customFetch(getUpdateVariablesUrl(params), {
1963
+ ...options,
1964
+ method: "PATCH",
1965
+ headers: {
1966
+ "Content-Type": "application/json",
1967
+ ...options?.headers
1968
+ },
1969
+ body: JSON.stringify(updateVariablesBody)
1970
+ });
1971
+ };
1972
+ const getGetVariableUrl = (variableName, params) => {
1973
+ const normalizedParams = new URLSearchParams();
1974
+ Object.entries(params || {}).forEach(([key, value]) => {
1975
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
1976
+ });
1977
+ const stringifiedParams = normalizedParams.toString();
1978
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/variables/${variableName}?${stringifiedParams}` : `${getProxyPath()}/variables/${variableName}`;
1979
+ };
1980
+ /**
1981
+ * Reads one variable by name from the owner this request addresses — one
1982
+ environment of the project with `environment_name`, the project level
1983
+ itself without it.
1984
+
1985
+ A name that owner has not entered answers `var.not_found`, even when
1986
+ another owner of the same project holds it: nothing is inherited. A secret
1987
+ is found but not disclosed: the response is `{"secret": true}`.
1988
+
1989
+ * @summary Get a variable
1990
+ */
1991
+ const getVariable = async (variableName, params, options) => {
1992
+ return customFetch(getGetVariableUrl(variableName, params), {
1993
+ ...options,
1994
+ method: "GET"
1995
+ });
1996
+ };
1997
+ const getDeleteVariableUrl = (variableName, params) => {
1998
+ const normalizedParams = new URLSearchParams();
1999
+ Object.entries(params || {}).forEach(([key, value]) => {
2000
+ if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
2001
+ });
2002
+ const stringifiedParams = normalizedParams.toString();
2003
+ return stringifiedParams.length > 0 ? `${getProxyPath()}/variables/${variableName}?${stringifiedParams}` : `${getProxyPath()}/variables/${variableName}`;
2004
+ };
2005
+ /**
2006
+ * Removes the variable this owner entered under this name.
2007
+
2008
+ A variable is deletable only by the owner that entered it. Deleting a name
2009
+ another owner of the same project holds answers `var.not_found` and leaves
2010
+ that owner's value standing.
2011
+
2012
+ * @summary Delete a variable
2013
+ */
2014
+ const deleteVariable = async (variableName, params, options) => {
2015
+ return customFetch(getDeleteVariableUrl(variableName, params), {
2016
+ ...options,
2017
+ method: "DELETE"
2018
+ });
2019
+ };
1676
2020
  //#endregion
1677
2021
  //#region ../api/dist/runtime/api-factory.mjs
1678
2022
  /**
@@ -1716,7 +2060,7 @@ function createZitadelClient(opts) {
1716
2060
  } });
1717
2061
  }
1718
2062
  //#endregion
1719
- //#region ../config/dist/defaults-DHEYFHlz.mjs
2063
+ //#region ../config/dist/defaults-DV6hY2KT.mjs
1720
2064
  var default_human_user_default = {
1721
2065
  title: "DefaultHumanUserSchema",
1722
2066
  $schema: "https://json-schema.org/draft/2020-12/schema",
@@ -2698,4 +3042,4 @@ Object.defineProperty(exports, "startLocalZitadel", {
2698
3042
  }
2699
3043
  });
2700
3044
 
2701
- //# sourceMappingURL=src-pZyQN7qD.cjs.map
3045
+ //# sourceMappingURL=src-CFX_ayWr.cjs.map