@crowi/api-contract 2.0.0-alpha.15 → 2.0.0-alpha.17

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.
@@ -794,15 +794,13 @@ interface paths {
794
794
  path?: never;
795
795
  cookie?: never;
796
796
  };
797
- /** Top-level navigation that redirects the browser to the named provider */
797
+ /** Top-level navigation that redirects the browser to the named provider (public sign-in ONLY) */
798
798
  get: {
799
799
  parameters: {
800
800
  query: {
801
801
  continue: string;
802
802
  handoff_jwk: string;
803
803
  handoff_proof: string;
804
- link?: "1";
805
- link_grant?: string;
806
804
  };
807
805
  header?: never;
808
806
  path: {
@@ -819,7 +817,7 @@ interface paths {
819
817
  };
820
818
  content?: never;
821
819
  };
822
- /** @description Malformed continue / sender proof, or an invalid/expired/mismatched link grant */
820
+ /** @description Malformed continue / sender proof, OR a raw `link` query key is present (any value) — the retired link-via-GET flow is gone entirely; a raw `link` key is always rejected rather than silently downgraded to public sign-in. */
823
821
  400: {
824
822
  headers: {
825
823
  [name: string]: unknown;
@@ -834,36 +832,6 @@ interface paths {
834
832
  };
835
833
  };
836
834
  };
837
- /** @description link=1 without a web-session JWT — never downgraded to the public sign-in start */
838
- 401: {
839
- headers: {
840
- [name: string]: unknown;
841
- };
842
- content: {
843
- "application/json": {
844
- error: {
845
- code: components["schemas"]["ErrorCode"];
846
- message: string;
847
- details?: unknown;
848
- };
849
- };
850
- };
851
- };
852
- /** @description link=1 with a non-web credential (PAT / OAuth access token) */
853
- 403: {
854
- headers: {
855
- [name: string]: unknown;
856
- };
857
- content: {
858
- "application/json": {
859
- error: {
860
- code: components["schemas"]["ErrorCode"];
861
- message: string;
862
- details?: unknown;
863
- };
864
- };
865
- };
866
- };
867
835
  /** @description Unknown, unconfigured, or credential-kind provider */
868
836
  404: {
869
837
  headers: {
@@ -928,7 +896,7 @@ interface paths {
928
896
  };
929
897
  requestBody?: never;
930
898
  responses: {
931
- /** @description Redirect to the trusted web login/complete page on success, or back to the trusted web /login on failure */
899
+ /** @description Ordinary sign-in: redirect to the trusted web login/complete page on success, or back to the trusted web /login on failure. Link flow (query `state` in the reserved crowilnk_ namespace): success redirects to `/me?provider=<name>&link_completion=<code>` (provider + completion code ONLY); failure redirects to `/me?provider=<name>&link=link_failed` (provider + the generic marker ONLY — never a completion code, never accountLabel, never the underlying reason). */
932
900
  302: {
933
901
  headers: {
934
902
  [name: string]: unknown;
@@ -1161,7 +1129,7 @@ interface paths {
1161
1129
  patch?: never;
1162
1130
  trace?: never;
1163
1131
  };
1164
- "/auth/providers/{name}/link-grants": {
1132
+ "/auth/providers/{name}/link-start": {
1165
1133
  parameters: {
1166
1134
  query?: never;
1167
1135
  header?: never;
@@ -1170,7 +1138,7 @@ interface paths {
1170
1138
  };
1171
1139
  get?: never;
1172
1140
  put?: never;
1173
- /** Mint a short-lived, opaque grant that authorizes ONE link start for the current web session */
1141
+ /** Mint an IdP authorization URL + flow-specific state cookie for the current web session (stage 1 of 3) */
1174
1142
  post: {
1175
1143
  parameters: {
1176
1144
  query?: never;
@@ -1180,26 +1148,36 @@ interface paths {
1180
1148
  };
1181
1149
  cookie?: never;
1182
1150
  };
1183
- requestBody?: {
1184
- content: {
1185
- "application/json": {
1186
- handoffChallenge: string;
1187
- };
1188
- };
1189
- };
1151
+ requestBody?: never;
1190
1152
  responses: {
1191
- /** @description Opaque single-use grant id */
1153
+ /** @description Authorization URL to navigate the browser to. Sets a flow-specific, 300s state cookie. */
1192
1154
  200: {
1193
1155
  headers: {
1194
1156
  [name: string]: unknown;
1195
1157
  };
1196
1158
  content: {
1197
1159
  "application/json": {
1198
- linkGrant: string;
1160
+ /** Format: uri */
1161
+ authorizationUrl: string;
1199
1162
  };
1200
1163
  };
1201
1164
  };
1202
- /** @description Authentication required */
1165
+ /** @description The signed link-state cookie value would exceed its per-cookie byte limit, or the aggregate Cookie-header admission budget cannot be satisfied even after pruning — no Set-Cookie or authorizationUrl is returned. */
1166
+ 400: {
1167
+ headers: {
1168
+ [name: string]: unknown;
1169
+ };
1170
+ content: {
1171
+ "application/json": {
1172
+ error: {
1173
+ code: components["schemas"]["ErrorCode"];
1174
+ message: string;
1175
+ details?: unknown;
1176
+ };
1177
+ };
1178
+ };
1179
+ };
1180
+ /** @description Authentication required (credential missing/invalid — resolved by middleware before this route's own validation) */
1203
1181
  401: {
1204
1182
  headers: {
1205
1183
  [name: string]: unknown;
@@ -1216,7 +1194,7 @@ interface paths {
1216
1194
  };
1217
1195
  };
1218
1196
  };
1219
- /** @description Non-web credential (PAT / OAuth access token) */
1197
+ /** @description Non-web credential (PAT / OAuth access token) — linking is a session-level account change */
1220
1198
  403: {
1221
1199
  headers: {
1222
1200
  [name: string]: unknown;
@@ -1246,7 +1224,7 @@ interface paths {
1246
1224
  };
1247
1225
  };
1248
1226
  };
1249
- /** @description Internal server error */
1227
+ /** @description Internal server error (e.g. a declared multi-instance topology with no reachable Redis) */
1250
1228
  500: {
1251
1229
  headers: {
1252
1230
  [name: string]: unknown;
@@ -1270,36 +1248,60 @@ interface paths {
1270
1248
  patch?: never;
1271
1249
  trace?: never;
1272
1250
  };
1273
- "/auth/providers/{name}/identity": {
1251
+ "/auth/providers/{name}/link-completions/{code}": {
1274
1252
  parameters: {
1275
1253
  query?: never;
1276
1254
  header?: never;
1277
1255
  path?: never;
1278
1256
  cookie?: never;
1279
1257
  };
1280
- get?: never;
1281
- put?: never;
1282
- post?: never;
1283
- /** Disconnect the current user's identity for this provider */
1284
- delete: {
1258
+ /** Read a pending link completion's confirmation details (stage 3a — non-destructive) */
1259
+ get: {
1285
1260
  parameters: {
1286
1261
  query?: never;
1287
1262
  header?: never;
1288
1263
  path: {
1289
1264
  name: string;
1265
+ code: string;
1290
1266
  };
1291
1267
  cookie?: never;
1292
1268
  };
1293
1269
  requestBody?: never;
1294
1270
  responses: {
1295
- /** @description Identity removed */
1296
- 204: {
1271
+ /** @description Pending, unconsumed completion bound to the caller — provider label fallback + optional display-only accountLabel */
1272
+ 200: {
1297
1273
  headers: {
1298
1274
  [name: string]: unknown;
1299
1275
  };
1300
- content?: never;
1276
+ content: {
1277
+ "application/json": {
1278
+ provider: string;
1279
+ accountLabel?: string;
1280
+ };
1281
+ };
1301
1282
  };
1302
- /** @description Authentication required */
1283
+ /** @description Authenticated but `{code}` fails the 43-character base64url shape (VALIDATION_ERROR) */
1284
+ 400: {
1285
+ headers: {
1286
+ [name: string]: unknown;
1287
+ };
1288
+ content: {
1289
+ "application/json": {
1290
+ error: {
1291
+ /** @enum {string} */
1292
+ code: "VALIDATION_ERROR";
1293
+ message: string;
1294
+ details?: {
1295
+ fieldErrors: {
1296
+ [key: string]: string[];
1297
+ };
1298
+ formErrors: string[];
1299
+ };
1300
+ };
1301
+ };
1302
+ };
1303
+ };
1304
+ /** @description Authentication required — resolved by middleware before this route's own `{code}` shape validation, so an unauthenticated + malformed code is still 401, never 400 */
1303
1305
  401: {
1304
1306
  headers: {
1305
1307
  [name: string]: unknown;
@@ -1331,7 +1333,7 @@ interface paths {
1331
1333
  };
1332
1334
  };
1333
1335
  };
1334
- /** @description No identity linked for this provider */
1336
+ /** @description Never-issued, expired, retention-expired, or bound to a different user/provider/authVersion — all collapse to the same generic NOT_FOUND (no result-unknown code exists) */
1335
1337
  404: {
1336
1338
  headers: {
1337
1339
  [name: string]: unknown;
@@ -1346,7 +1348,7 @@ interface paths {
1346
1348
  };
1347
1349
  };
1348
1350
  };
1349
- /** @description Refused: password auth is disabled instance-wide, or this user has no password set */
1351
+ /** @description The caller's own completion was already consumed */
1350
1352
  409: {
1351
1353
  headers: {
1352
1354
  [name: string]: unknown;
@@ -1355,7 +1357,7 @@ interface paths {
1355
1357
  "application/json": {
1356
1358
  error: {
1357
1359
  /** @enum {string} */
1358
- code: "FEDERATED_UNLINK_DISABLED" | "PASSWORD_REQUIRED";
1360
+ code: "LINK_COMPLETION_CONSUMED";
1359
1361
  message: string;
1360
1362
  };
1361
1363
  };
@@ -1379,62 +1381,55 @@ interface paths {
1379
1381
  };
1380
1382
  };
1381
1383
  };
1382
- options?: never;
1383
- head?: never;
1384
- patch?: never;
1385
- trace?: never;
1386
- };
1387
- "/auth/federated-registration/{token}": {
1388
- parameters: {
1389
- query?: never;
1390
- header?: never;
1391
- path?: never;
1392
- cookie?: never;
1393
- };
1394
- /** Read-only snapshot (email/provider/providerLabel) for a pending federated registration */
1395
- get: {
1384
+ put?: never;
1385
+ /** Atomically consume a link completion code and insert the identity (stage 3b — terminal) */
1386
+ post: {
1396
1387
  parameters: {
1397
1388
  query?: never;
1398
1389
  header?: never;
1399
1390
  path: {
1400
- token: string;
1391
+ name: string;
1392
+ code: string;
1401
1393
  };
1402
1394
  cookie?: never;
1403
1395
  };
1404
1396
  requestBody?: never;
1405
1397
  responses: {
1406
- /** @description Pending registration snapshot */
1398
+ /** @description Linked (fresh winner OR an already-consumed replay that resolves to the same owner) — the same body either way */
1407
1399
  200: {
1408
1400
  headers: {
1409
1401
  [name: string]: unknown;
1410
1402
  };
1411
1403
  content: {
1412
1404
  "application/json": {
1413
- /** Format: email */
1414
- email: string;
1415
- provider: string;
1416
- providerLabel: string;
1417
- approvalPending: boolean;
1405
+ /** @enum {string} */
1406
+ result: "linked";
1418
1407
  };
1419
1408
  };
1420
1409
  };
1421
- /** @description Grant is unknown, expired, or cancelled */
1422
- 404: {
1410
+ /** @description Authenticated but `{code}` fails the 43-character base64url shape (VALIDATION_ERROR) */
1411
+ 400: {
1423
1412
  headers: {
1424
1413
  [name: string]: unknown;
1425
1414
  };
1426
1415
  content: {
1427
1416
  "application/json": {
1428
1417
  error: {
1429
- code: components["schemas"]["ErrorCode"];
1418
+ /** @enum {string} */
1419
+ code: "VALIDATION_ERROR";
1430
1420
  message: string;
1431
- details?: unknown;
1421
+ details?: {
1422
+ fieldErrors: {
1423
+ [key: string]: string[];
1424
+ };
1425
+ formErrors: string[];
1426
+ };
1432
1427
  };
1433
1428
  };
1434
1429
  };
1435
1430
  };
1436
- /** @description Internal server error */
1437
- 500: {
1431
+ /** @description Authentication required resolved by middleware before this route's own `{code}` shape validation, so an unauthenticated + malformed code is still 401, never 400 */
1432
+ 401: {
1438
1433
  headers: {
1439
1434
  [name: string]: unknown;
1440
1435
  };
@@ -1442,52 +1437,16 @@ interface paths {
1442
1437
  "application/json": {
1443
1438
  error: {
1444
1439
  /** @enum {string} */
1445
- code: "INTERNAL_ERROR";
1440
+ code: "AUTHENTICATION_REQUIRED";
1446
1441
  /** @enum {string} */
1447
- message: "Internal server error";
1442
+ message: "Authentication is required";
1443
+ redirectTo?: string;
1448
1444
  };
1449
1445
  };
1450
1446
  };
1451
1447
  };
1452
- };
1453
- };
1454
- put?: never;
1455
- /** Submit the chosen username; provisions the User (JIT) and activates or queues approval */
1456
- post: {
1457
- parameters: {
1458
- query?: never;
1459
- header?: never;
1460
- path: {
1461
- token: string;
1462
- };
1463
- cookie?: never;
1464
- };
1465
- requestBody?: {
1466
- content: {
1467
- "application/json": {
1468
- username: string;
1469
- };
1470
- };
1471
- };
1472
- responses: {
1473
- /** @description Open: account is active — a Phase 1 handoff code, redeemed via POST /auth/handoff. Restricted: awaiting admin approval. */
1474
- 200: {
1475
- headers: {
1476
- [name: string]: unknown;
1477
- };
1478
- content: {
1479
- "application/json": {
1480
- /** @enum {string} */
1481
- status: "active";
1482
- code: string;
1483
- } | {
1484
- /** @enum {string} */
1485
- status: "approval_required";
1486
- };
1487
- };
1488
- };
1489
- /** @description Username fails the shared username contract */
1490
- 400: {
1448
+ /** @description Non-web credential (PAT / OAuth access token) */
1449
+ 403: {
1491
1450
  headers: {
1492
1451
  [name: string]: unknown;
1493
1452
  };
@@ -1501,7 +1460,7 @@ interface paths {
1501
1460
  };
1502
1461
  };
1503
1462
  };
1504
- /** @description Grant is unknown, expired, or cancelled */
1463
+ /** @description Never-issued, expired, retention-expired, or bound to a different user/provider — all collapse to the same generic NOT_FOUND */
1505
1464
  404: {
1506
1465
  headers: {
1507
1466
  [name: string]: unknown;
@@ -1516,7 +1475,7 @@ interface paths {
1516
1475
  };
1517
1476
  };
1518
1477
  };
1519
- /** @description Username/email already taken, or the identity is already linked to a different user */
1478
+ /** @description FEDERATED_IDENTITY_IN_USE (provider account owned by someone else, or this user already has a different account of this provider), FEDERATED_LINK_AUTH_STATE_CHANGED (fresh User re-read found the session inactive or authVersion changed since link-start), or FEDERATED_LINK_NOT_LINKED (an already-consumed replay whose original insert has not landed) — no other conflict code exists. */
1520
1479
  409: {
1521
1480
  headers: {
1522
1481
  [name: string]: unknown;
@@ -1524,9 +1483,9 @@ interface paths {
1524
1483
  content: {
1525
1484
  "application/json": {
1526
1485
  error: {
1527
- code: components["schemas"]["ErrorCode"];
1486
+ /** @enum {string} */
1487
+ code: "FEDERATED_IDENTITY_IN_USE" | "FEDERATED_LINK_AUTH_STATE_CHANGED" | "FEDERATED_LINK_NOT_LINKED";
1528
1488
  message: string;
1529
- details?: unknown;
1530
1489
  };
1531
1490
  };
1532
1491
  };
@@ -1555,7 +1514,7 @@ interface paths {
1555
1514
  patch?: never;
1556
1515
  trace?: never;
1557
1516
  };
1558
- "/auth/federated-registration/{token}/logout": {
1517
+ "/auth/providers/{name}/identity": {
1559
1518
  parameters: {
1560
1519
  query?: never;
1561
1520
  header?: never;
@@ -1564,27 +1523,28 @@ interface paths {
1564
1523
  };
1565
1524
  get?: never;
1566
1525
  put?: never;
1567
- /** Cancel a pending federated registration and invalidate the grant */
1568
- post: {
1526
+ post?: never;
1527
+ /** Disconnect the current user's identity for this provider */
1528
+ delete: {
1569
1529
  parameters: {
1570
1530
  query?: never;
1571
1531
  header?: never;
1572
1532
  path: {
1573
- token: string;
1533
+ name: string;
1574
1534
  };
1575
1535
  cookie?: never;
1576
1536
  };
1577
1537
  requestBody?: never;
1578
1538
  responses: {
1579
- /** @description Grant cancelled (or was already inactive) — idempotent */
1539
+ /** @description Identity removed */
1580
1540
  204: {
1581
1541
  headers: {
1582
1542
  [name: string]: unknown;
1583
1543
  };
1584
1544
  content?: never;
1585
1545
  };
1586
- /** @description Internal server error */
1587
- 500: {
1546
+ /** @description Authentication required */
1547
+ 401: {
1588
1548
  headers: {
1589
1549
  [name: string]: unknown;
1590
1550
  };
@@ -1592,54 +1552,31 @@ interface paths {
1592
1552
  "application/json": {
1593
1553
  error: {
1594
1554
  /** @enum {string} */
1595
- code: "INTERNAL_ERROR";
1555
+ code: "AUTHENTICATION_REQUIRED";
1596
1556
  /** @enum {string} */
1597
- message: "Internal server error";
1557
+ message: "Authentication is required";
1558
+ redirectTo?: string;
1598
1559
  };
1599
1560
  };
1600
1561
  };
1601
1562
  };
1602
- };
1603
- };
1604
- delete?: never;
1605
- options?: never;
1606
- head?: never;
1607
- patch?: never;
1608
- trace?: never;
1609
- };
1610
- "/invite/accept": {
1611
- parameters: {
1612
- query?: never;
1613
- header?: never;
1614
- path?: never;
1615
- cookie?: never;
1616
- };
1617
- /** Preview an invite (returns the invited email) for the acceptance page */
1618
- get: {
1619
- parameters: {
1620
- query: {
1621
- token: string;
1622
- };
1623
- header?: never;
1624
- path?: never;
1625
- cookie?: never;
1626
- };
1627
- requestBody?: never;
1628
- responses: {
1629
- /** @description Invite is valid */
1630
- 200: {
1563
+ /** @description Non-web credential (PAT / OAuth access token) */
1564
+ 403: {
1631
1565
  headers: {
1632
1566
  [name: string]: unknown;
1633
1567
  };
1634
1568
  content: {
1635
1569
  "application/json": {
1636
- /** Format: email */
1637
- email: string;
1570
+ error: {
1571
+ code: components["schemas"]["ErrorCode"];
1572
+ message: string;
1573
+ details?: unknown;
1574
+ };
1638
1575
  };
1639
1576
  };
1640
1577
  };
1641
- /** @description Invite token is invalid or expired */
1642
- 401: {
1578
+ /** @description No identity linked for this provider */
1579
+ 404: {
1643
1580
  headers: {
1644
1581
  [name: string]: unknown;
1645
1582
  };
@@ -1653,7 +1590,7 @@ interface paths {
1653
1590
  };
1654
1591
  };
1655
1592
  };
1656
- /** @description Invite already accepted */
1593
+ /** @description Refused: password auth is disabled instance-wide, or this user has no password set */
1657
1594
  409: {
1658
1595
  headers: {
1659
1596
  [name: string]: unknown;
@@ -1661,9 +1598,9 @@ interface paths {
1661
1598
  content: {
1662
1599
  "application/json": {
1663
1600
  error: {
1664
- code: components["schemas"]["ErrorCode"];
1601
+ /** @enum {string} */
1602
+ code: "FEDERATED_UNLINK_DISABLED" | "PASSWORD_REQUIRED";
1665
1603
  message: string;
1666
- details?: unknown;
1667
1604
  };
1668
1605
  };
1669
1606
  };
@@ -1686,50 +1623,47 @@ interface paths {
1686
1623
  };
1687
1624
  };
1688
1625
  };
1689
- put?: never;
1690
- /** Accept an invite: set credentials, activate the account, sign in */
1691
- post: {
1692
- parameters: {
1626
+ options?: never;
1627
+ head?: never;
1628
+ patch?: never;
1629
+ trace?: never;
1630
+ };
1631
+ "/auth/federated-registration/{token}": {
1632
+ parameters: {
1633
+ query?: never;
1634
+ header?: never;
1635
+ path?: never;
1636
+ cookie?: never;
1637
+ };
1638
+ /** Read-only snapshot (email/provider/providerLabel) for a pending federated registration */
1639
+ get: {
1640
+ parameters: {
1693
1641
  query?: never;
1694
1642
  header?: never;
1695
- path?: never;
1696
- cookie?: never;
1697
- };
1698
- requestBody?: {
1699
- content: {
1700
- "application/json": {
1701
- token: string;
1702
- username: string;
1703
- name: string;
1704
- password: string;
1705
- };
1643
+ path: {
1644
+ token: string;
1706
1645
  };
1646
+ cookie?: never;
1707
1647
  };
1648
+ requestBody?: never;
1708
1649
  responses: {
1709
- /** @description Invite accepted; account activated and signed in */
1650
+ /** @description Pending registration snapshot */
1710
1651
  200: {
1711
1652
  headers: {
1712
1653
  [name: string]: unknown;
1713
1654
  };
1714
1655
  content: {
1715
1656
  "application/json": {
1716
- accessToken: string;
1717
- refreshToken: string;
1718
- expiresIn: number;
1719
- user: {
1720
- id: string;
1721
- username: string;
1722
- /** Format: email */
1723
- email: string;
1724
- name: string;
1725
- image?: string;
1726
- admin?: boolean;
1727
- };
1657
+ /** Format: email */
1658
+ email: string;
1659
+ provider: string;
1660
+ providerLabel: string;
1661
+ approvalPending: boolean;
1728
1662
  };
1729
1663
  };
1730
1664
  };
1731
- /** @description Validation failed */
1732
- 400: {
1665
+ /** @description Grant is unknown, expired, or cancelled */
1666
+ 404: {
1733
1667
  headers: {
1734
1668
  [name: string]: unknown;
1735
1669
  };
@@ -1743,8 +1677,61 @@ interface paths {
1743
1677
  };
1744
1678
  };
1745
1679
  };
1746
- /** @description Invite token is invalid or expired */
1747
- 401: {
1680
+ /** @description Internal server error */
1681
+ 500: {
1682
+ headers: {
1683
+ [name: string]: unknown;
1684
+ };
1685
+ content: {
1686
+ "application/json": {
1687
+ error: {
1688
+ /** @enum {string} */
1689
+ code: "INTERNAL_ERROR";
1690
+ /** @enum {string} */
1691
+ message: "Internal server error";
1692
+ };
1693
+ };
1694
+ };
1695
+ };
1696
+ };
1697
+ };
1698
+ put?: never;
1699
+ /** Submit the chosen username; provisions the User (JIT) and activates or queues approval */
1700
+ post: {
1701
+ parameters: {
1702
+ query?: never;
1703
+ header?: never;
1704
+ path: {
1705
+ token: string;
1706
+ };
1707
+ cookie?: never;
1708
+ };
1709
+ requestBody?: {
1710
+ content: {
1711
+ "application/json": {
1712
+ username: string;
1713
+ };
1714
+ };
1715
+ };
1716
+ responses: {
1717
+ /** @description Open: account is active — a Phase 1 handoff code, redeemed via POST /auth/handoff. Restricted: awaiting admin approval. */
1718
+ 200: {
1719
+ headers: {
1720
+ [name: string]: unknown;
1721
+ };
1722
+ content: {
1723
+ "application/json": {
1724
+ /** @enum {string} */
1725
+ status: "active";
1726
+ code: string;
1727
+ } | {
1728
+ /** @enum {string} */
1729
+ status: "approval_required";
1730
+ };
1731
+ };
1732
+ };
1733
+ /** @description Username fails the shared username contract */
1734
+ 400: {
1748
1735
  headers: {
1749
1736
  [name: string]: unknown;
1750
1737
  };
@@ -1758,7 +1745,7 @@ interface paths {
1758
1745
  };
1759
1746
  };
1760
1747
  };
1761
- /** @description Invited user no longer exists */
1748
+ /** @description Grant is unknown, expired, or cancelled */
1762
1749
  404: {
1763
1750
  headers: {
1764
1751
  [name: string]: unknown;
@@ -1773,7 +1760,7 @@ interface paths {
1773
1760
  };
1774
1761
  };
1775
1762
  };
1776
- /** @description Invite already accepted, or username already taken */
1763
+ /** @description Username/email already taken, or the identity is already linked to a different user */
1777
1764
  409: {
1778
1765
  headers: {
1779
1766
  [name: string]: unknown;
@@ -1812,50 +1799,36 @@ interface paths {
1812
1799
  patch?: never;
1813
1800
  trace?: never;
1814
1801
  };
1815
- "/me": {
1802
+ "/auth/federated-registration/{token}/logout": {
1816
1803
  parameters: {
1817
1804
  query?: never;
1818
1805
  header?: never;
1819
1806
  path?: never;
1820
1807
  cookie?: never;
1821
1808
  };
1822
- /** Get current user profile */
1823
- get: {
1809
+ get?: never;
1810
+ put?: never;
1811
+ /** Cancel a pending federated registration and invalidate the grant */
1812
+ post: {
1824
1813
  parameters: {
1825
1814
  query?: never;
1826
1815
  header?: never;
1827
- path?: never;
1816
+ path: {
1817
+ token: string;
1818
+ };
1828
1819
  cookie?: never;
1829
1820
  };
1830
1821
  requestBody?: never;
1831
1822
  responses: {
1832
- /** @description Current user profile */
1833
- 200: {
1823
+ /** @description Grant cancelled (or was already inactive) — idempotent */
1824
+ 204: {
1834
1825
  headers: {
1835
1826
  [name: string]: unknown;
1836
1827
  };
1837
- content: {
1838
- "application/json": {
1839
- id: string;
1840
- username: string;
1841
- name: string;
1842
- /** Format: email */
1843
- email: string;
1844
- /** @enum {string} */
1845
- lang: "en" | "ja";
1846
- /** @enum {string} */
1847
- theme: "system" | "light" | "dark";
1848
- image: string | null;
1849
- introduction?: string;
1850
- hasPassword: boolean;
1851
- createdAt: string;
1852
- federated: boolean;
1853
- emailChangePending?: boolean;
1854
- };
1855
- };
1828
+ content?: never;
1856
1829
  };
1857
- /** @description Authentication required */
1858
- 401: {
1830
+ /** @description Internal server error */
1831
+ 500: {
1859
1832
  headers: {
1860
1833
  [name: string]: unknown;
1861
1834
  };
@@ -1863,80 +1836,84 @@ interface paths {
1863
1836
  "application/json": {
1864
1837
  error: {
1865
1838
  /** @enum {string} */
1866
- code: "AUTHENTICATION_REQUIRED";
1839
+ code: "INTERNAL_ERROR";
1867
1840
  /** @enum {string} */
1868
- message: "Authentication is required";
1869
- redirectTo?: string;
1841
+ message: "Internal server error";
1870
1842
  };
1871
1843
  };
1872
1844
  };
1873
1845
  };
1874
1846
  };
1875
1847
  };
1876
- /** Update profile */
1877
- put: {
1848
+ delete?: never;
1849
+ options?: never;
1850
+ head?: never;
1851
+ patch?: never;
1852
+ trace?: never;
1853
+ };
1854
+ "/invite/accept": {
1855
+ parameters: {
1856
+ query?: never;
1857
+ header?: never;
1858
+ path?: never;
1859
+ cookie?: never;
1860
+ };
1861
+ /** Preview an invite (returns the invited email) for the acceptance page */
1862
+ get: {
1878
1863
  parameters: {
1879
- query?: never;
1864
+ query: {
1865
+ token: string;
1866
+ };
1880
1867
  header?: never;
1881
1868
  path?: never;
1882
1869
  cookie?: never;
1883
1870
  };
1884
- requestBody?: {
1885
- content: {
1886
- "application/json": {
1887
- userForm: {
1888
- name: string;
1871
+ requestBody?: never;
1872
+ responses: {
1873
+ /** @description Invite is valid */
1874
+ 200: {
1875
+ headers: {
1876
+ [name: string]: unknown;
1877
+ };
1878
+ content: {
1879
+ "application/json": {
1889
1880
  /** Format: email */
1890
1881
  email: string;
1891
- /** @enum {string} */
1892
- lang: "en" | "ja";
1893
1882
  };
1894
1883
  };
1895
1884
  };
1896
- };
1897
- responses: {
1898
- /** @description Updated profile */
1899
- 200: {
1885
+ /** @description Invite token is invalid or expired */
1886
+ 401: {
1900
1887
  headers: {
1901
1888
  [name: string]: unknown;
1902
1889
  };
1903
1890
  content: {
1904
1891
  "application/json": {
1905
- id: string;
1906
- username: string;
1907
- name: string;
1908
- /** Format: email */
1909
- email: string;
1910
- /** @enum {string} */
1911
- lang: "en" | "ja";
1912
- /** @enum {string} */
1913
- theme: "system" | "light" | "dark";
1914
- image: string | null;
1915
- introduction?: string;
1916
- hasPassword: boolean;
1917
- createdAt: string;
1918
- federated: boolean;
1919
- emailChangePending?: boolean;
1892
+ error: {
1893
+ code: components["schemas"]["ErrorCode"];
1894
+ message: string;
1895
+ details?: unknown;
1896
+ };
1920
1897
  };
1921
1898
  };
1922
1899
  };
1923
- /** @description Profile update failed */
1924
- 400: {
1900
+ /** @description Invite already accepted */
1901
+ 409: {
1925
1902
  headers: {
1926
1903
  [name: string]: unknown;
1927
1904
  };
1928
1905
  content: {
1929
1906
  "application/json": {
1930
- /** @enum {string} */
1931
- status: "error";
1932
- code?: string;
1933
- message?: string;
1934
- errors?: string[];
1907
+ error: {
1908
+ code: components["schemas"]["ErrorCode"];
1909
+ message: string;
1910
+ details?: unknown;
1911
+ };
1935
1912
  };
1936
1913
  };
1937
1914
  };
1938
- /** @description Authentication required */
1939
- 401: {
1915
+ /** @description Internal server error */
1916
+ 500: {
1940
1917
  headers: {
1941
1918
  [name: string]: unknown;
1942
1919
  };
@@ -1944,38 +1921,18 @@ interface paths {
1944
1921
  "application/json": {
1945
1922
  error: {
1946
1923
  /** @enum {string} */
1947
- code: "AUTHENTICATION_REQUIRED";
1924
+ code: "INTERNAL_ERROR";
1948
1925
  /** @enum {string} */
1949
- message: "Authentication is required";
1950
- redirectTo?: string;
1926
+ message: "Internal server error";
1951
1927
  };
1952
1928
  };
1953
1929
  };
1954
1930
  };
1955
1931
  };
1956
1932
  };
1957
- post?: never;
1958
- delete?: never;
1959
- options?: never;
1960
- head?: never;
1961
- patch?: never;
1962
- trace?: never;
1963
- };
1964
- "/me/theme": {
1965
- parameters: {
1966
- query?: never;
1967
- header?: never;
1968
- path?: never;
1969
- cookie?: never;
1970
- };
1971
- get?: never;
1972
1933
  put?: never;
1973
- post?: never;
1974
- delete?: never;
1975
- options?: never;
1976
- head?: never;
1977
- /** Update preferred UI theme */
1978
- patch: {
1934
+ /** Accept an invite: set credentials, activate the account, sign in */
1935
+ post: {
1979
1936
  parameters: {
1980
1937
  query?: never;
1981
1938
  header?: never;
@@ -1985,43 +1942,98 @@ interface paths {
1985
1942
  requestBody?: {
1986
1943
  content: {
1987
1944
  "application/json": {
1988
- /** @enum {string} */
1989
- theme: "system" | "light" | "dark";
1945
+ token: string;
1946
+ username: string;
1947
+ name: string;
1948
+ password: string;
1990
1949
  };
1991
1950
  };
1992
1951
  };
1993
1952
  responses: {
1994
- /** @description Theme updated */
1953
+ /** @description Invite accepted; account activated and signed in */
1995
1954
  200: {
1996
1955
  headers: {
1997
1956
  [name: string]: unknown;
1998
1957
  };
1999
1958
  content: {
2000
1959
  "application/json": {
2001
- /** @enum {string} */
2002
- status: "ok";
2003
- /** @enum {string} */
2004
- theme: "system" | "light" | "dark";
1960
+ accessToken: string;
1961
+ refreshToken: string;
1962
+ expiresIn: number;
1963
+ user: {
1964
+ id: string;
1965
+ username: string;
1966
+ /** Format: email */
1967
+ email: string;
1968
+ name: string;
1969
+ image?: string;
1970
+ admin?: boolean;
1971
+ };
2005
1972
  };
2006
1973
  };
2007
1974
  };
2008
- /** @description Theme update failed */
1975
+ /** @description Validation failed */
2009
1976
  400: {
2010
1977
  headers: {
2011
1978
  [name: string]: unknown;
2012
1979
  };
2013
1980
  content: {
2014
1981
  "application/json": {
2015
- /** @enum {string} */
2016
- status: "error";
2017
- code?: string;
2018
- message?: string;
2019
- errors?: string[];
1982
+ error: {
1983
+ code: components["schemas"]["ErrorCode"];
1984
+ message: string;
1985
+ details?: unknown;
1986
+ };
2020
1987
  };
2021
1988
  };
2022
1989
  };
2023
- /** @description Authentication required */
1990
+ /** @description Invite token is invalid or expired */
2024
1991
  401: {
1992
+ headers: {
1993
+ [name: string]: unknown;
1994
+ };
1995
+ content: {
1996
+ "application/json": {
1997
+ error: {
1998
+ code: components["schemas"]["ErrorCode"];
1999
+ message: string;
2000
+ details?: unknown;
2001
+ };
2002
+ };
2003
+ };
2004
+ };
2005
+ /** @description Invited user no longer exists */
2006
+ 404: {
2007
+ headers: {
2008
+ [name: string]: unknown;
2009
+ };
2010
+ content: {
2011
+ "application/json": {
2012
+ error: {
2013
+ code: components["schemas"]["ErrorCode"];
2014
+ message: string;
2015
+ details?: unknown;
2016
+ };
2017
+ };
2018
+ };
2019
+ };
2020
+ /** @description Invite already accepted, or username already taken */
2021
+ 409: {
2022
+ headers: {
2023
+ [name: string]: unknown;
2024
+ };
2025
+ content: {
2026
+ "application/json": {
2027
+ error: {
2028
+ code: components["schemas"]["ErrorCode"];
2029
+ message: string;
2030
+ details?: unknown;
2031
+ };
2032
+ };
2033
+ };
2034
+ };
2035
+ /** @description Internal server error */
2036
+ 500: {
2025
2037
  headers: {
2026
2038
  [name: string]: unknown;
2027
2039
  };
@@ -2029,69 +2041,60 @@ interface paths {
2029
2041
  "application/json": {
2030
2042
  error: {
2031
2043
  /** @enum {string} */
2032
- code: "AUTHENTICATION_REQUIRED";
2044
+ code: "INTERNAL_ERROR";
2033
2045
  /** @enum {string} */
2034
- message: "Authentication is required";
2035
- redirectTo?: string;
2046
+ message: "Internal server error";
2036
2047
  };
2037
2048
  };
2038
2049
  };
2039
2050
  };
2040
2051
  };
2041
2052
  };
2053
+ delete?: never;
2054
+ options?: never;
2055
+ head?: never;
2056
+ patch?: never;
2042
2057
  trace?: never;
2043
2058
  };
2044
- "/me/picture": {
2059
+ "/me": {
2045
2060
  parameters: {
2046
2061
  query?: never;
2047
2062
  header?: never;
2048
2063
  path?: never;
2049
2064
  cookie?: never;
2050
2065
  };
2051
- get?: never;
2052
- put?: never;
2053
- /** Upload profile picture */
2054
- post: {
2066
+ /** Get current user profile */
2067
+ get: {
2055
2068
  parameters: {
2056
2069
  query?: never;
2057
2070
  header?: never;
2058
2071
  path?: never;
2059
2072
  cookie?: never;
2060
2073
  };
2061
- requestBody?: {
2062
- content: {
2063
- "multipart/form-data": {
2064
- /** @description Profile picture file */
2065
- file?: unknown;
2066
- };
2067
- };
2068
- };
2074
+ requestBody?: never;
2069
2075
  responses: {
2070
- /** @description Picture uploaded */
2076
+ /** @description Current user profile */
2071
2077
  200: {
2072
2078
  headers: {
2073
2079
  [name: string]: unknown;
2074
2080
  };
2075
2081
  content: {
2076
2082
  "application/json": {
2077
- status: boolean;
2078
- url?: string;
2079
- message?: string;
2080
- };
2081
- };
2082
- };
2083
- /** @description Upload failed */
2084
- 400: {
2085
- headers: {
2086
- [name: string]: unknown;
2087
- };
2088
- content: {
2089
- "application/json": {
2083
+ id: string;
2084
+ username: string;
2085
+ name: string;
2086
+ /** Format: email */
2087
+ email: string;
2090
2088
  /** @enum {string} */
2091
- status: "error";
2092
- code?: string;
2093
- message?: string;
2094
- errors?: string[];
2089
+ lang: "en" | "ja";
2090
+ /** @enum {string} */
2091
+ theme: "system" | "light" | "dark";
2092
+ image: string | null;
2093
+ introduction?: string;
2094
+ hasPassword: boolean;
2095
+ createdAt: string;
2096
+ federated: boolean;
2097
+ emailChangePending?: boolean;
2095
2098
  };
2096
2099
  };
2097
2100
  };
@@ -2114,30 +2117,54 @@ interface paths {
2114
2117
  };
2115
2118
  };
2116
2119
  };
2117
- /** Delete profile picture */
2118
- delete: {
2120
+ /** Update profile */
2121
+ put: {
2119
2122
  parameters: {
2120
2123
  query?: never;
2121
2124
  header?: never;
2122
2125
  path?: never;
2123
2126
  cookie?: never;
2124
2127
  };
2125
- requestBody?: never;
2128
+ requestBody?: {
2129
+ content: {
2130
+ "application/json": {
2131
+ userForm: {
2132
+ name: string;
2133
+ /** Format: email */
2134
+ email: string;
2135
+ /** @enum {string} */
2136
+ lang: "en" | "ja";
2137
+ };
2138
+ };
2139
+ };
2140
+ };
2126
2141
  responses: {
2127
- /** @description Picture deleted */
2142
+ /** @description Updated profile */
2128
2143
  200: {
2129
2144
  headers: {
2130
2145
  [name: string]: unknown;
2131
2146
  };
2132
2147
  content: {
2133
2148
  "application/json": {
2149
+ id: string;
2150
+ username: string;
2151
+ name: string;
2152
+ /** Format: email */
2153
+ email: string;
2134
2154
  /** @enum {string} */
2135
- status: "ok";
2136
- message?: string;
2155
+ lang: "en" | "ja";
2156
+ /** @enum {string} */
2157
+ theme: "system" | "light" | "dark";
2158
+ image: string | null;
2159
+ introduction?: string;
2160
+ hasPassword: boolean;
2161
+ createdAt: string;
2162
+ federated: boolean;
2163
+ emailChangePending?: boolean;
2137
2164
  };
2138
2165
  };
2139
2166
  };
2140
- /** @description Delete failed */
2167
+ /** @description Profile update failed */
2141
2168
  400: {
2142
2169
  headers: {
2143
2170
  [name: string]: unknown;
@@ -2171,12 +2198,14 @@ interface paths {
2171
2198
  };
2172
2199
  };
2173
2200
  };
2201
+ post?: never;
2202
+ delete?: never;
2174
2203
  options?: never;
2175
2204
  head?: never;
2176
2205
  patch?: never;
2177
2206
  trace?: never;
2178
2207
  };
2179
- "/me/password": {
2208
+ "/me/theme": {
2180
2209
  parameters: {
2181
2210
  query?: never;
2182
2211
  header?: never;
@@ -2184,8 +2213,13 @@ interface paths {
2184
2213
  cookie?: never;
2185
2214
  };
2186
2215
  get?: never;
2187
- /** Update password */
2188
- put: {
2216
+ put?: never;
2217
+ post?: never;
2218
+ delete?: never;
2219
+ options?: never;
2220
+ head?: never;
2221
+ /** Update preferred UI theme */
2222
+ patch: {
2189
2223
  parameters: {
2190
2224
  query?: never;
2191
2225
  header?: never;
@@ -2195,14 +2229,13 @@ interface paths {
2195
2229
  requestBody?: {
2196
2230
  content: {
2197
2231
  "application/json": {
2198
- oldPassword?: string;
2199
- newPassword: string;
2200
- newPasswordConfirm: string;
2232
+ /** @enum {string} */
2233
+ theme: "system" | "light" | "dark";
2201
2234
  };
2202
2235
  };
2203
2236
  };
2204
2237
  responses: {
2205
- /** @description Password updated; earlier sessions revoked and a fresh token pair issued */
2238
+ /** @description Theme updated */
2206
2239
  200: {
2207
2240
  headers: {
2208
2241
  [name: string]: unknown;
@@ -2211,14 +2244,12 @@ interface paths {
2211
2244
  "application/json": {
2212
2245
  /** @enum {string} */
2213
2246
  status: "ok";
2214
- message: string;
2215
- accessToken: string;
2216
- refreshToken: string;
2217
- expiresIn: number;
2247
+ /** @enum {string} */
2248
+ theme: "system" | "light" | "dark";
2218
2249
  };
2219
2250
  };
2220
2251
  };
2221
- /** @description Password update failed */
2252
+ /** @description Theme update failed */
2222
2253
  400: {
2223
2254
  headers: {
2224
2255
  [name: string]: unknown;
@@ -2227,7 +2258,8 @@ interface paths {
2227
2258
  "application/json": {
2228
2259
  /** @enum {string} */
2229
2260
  status: "error";
2230
- message: string;
2261
+ code?: string;
2262
+ message?: string;
2231
2263
  errors?: string[];
2232
2264
  };
2233
2265
  };
@@ -2251,46 +2283,258 @@ interface paths {
2251
2283
  };
2252
2284
  };
2253
2285
  };
2254
- post?: never;
2255
- delete?: never;
2256
- options?: never;
2257
- head?: never;
2258
- patch?: never;
2259
2286
  trace?: never;
2260
2287
  };
2261
- "/me/recently-viewed-pages": {
2288
+ "/me/picture": {
2262
2289
  parameters: {
2263
2290
  query?: never;
2264
2291
  header?: never;
2265
2292
  path?: never;
2266
2293
  cookie?: never;
2267
2294
  };
2268
- /** Get the current user's recently-viewed pages */
2269
- get: {
2295
+ get?: never;
2296
+ put?: never;
2297
+ /** Upload profile picture */
2298
+ post: {
2270
2299
  parameters: {
2271
2300
  query?: never;
2272
2301
  header?: never;
2273
2302
  path?: never;
2274
2303
  cookie?: never;
2275
2304
  };
2276
- requestBody?: never;
2305
+ requestBody?: {
2306
+ content: {
2307
+ "multipart/form-data": {
2308
+ /** @description Profile picture file */
2309
+ file?: unknown;
2310
+ };
2311
+ };
2312
+ };
2277
2313
  responses: {
2278
- /** @description Recently-viewed pages list (up to 5) */
2314
+ /** @description Picture uploaded */
2279
2315
  200: {
2280
2316
  headers: {
2281
2317
  [name: string]: unknown;
2282
2318
  };
2283
2319
  content: {
2284
2320
  "application/json": {
2285
- pages: {
2286
- _id: string;
2287
- path: string;
2288
- revision?: string | {
2289
- _id: string;
2290
- path: string;
2291
- body: string;
2292
- /** @default markdown */
2293
- format: string;
2321
+ status: boolean;
2322
+ url?: string;
2323
+ message?: string;
2324
+ };
2325
+ };
2326
+ };
2327
+ /** @description Upload failed */
2328
+ 400: {
2329
+ headers: {
2330
+ [name: string]: unknown;
2331
+ };
2332
+ content: {
2333
+ "application/json": {
2334
+ /** @enum {string} */
2335
+ status: "error";
2336
+ code?: string;
2337
+ message?: string;
2338
+ errors?: string[];
2339
+ };
2340
+ };
2341
+ };
2342
+ /** @description Authentication required */
2343
+ 401: {
2344
+ headers: {
2345
+ [name: string]: unknown;
2346
+ };
2347
+ content: {
2348
+ "application/json": {
2349
+ error: {
2350
+ /** @enum {string} */
2351
+ code: "AUTHENTICATION_REQUIRED";
2352
+ /** @enum {string} */
2353
+ message: "Authentication is required";
2354
+ redirectTo?: string;
2355
+ };
2356
+ };
2357
+ };
2358
+ };
2359
+ };
2360
+ };
2361
+ /** Delete profile picture */
2362
+ delete: {
2363
+ parameters: {
2364
+ query?: never;
2365
+ header?: never;
2366
+ path?: never;
2367
+ cookie?: never;
2368
+ };
2369
+ requestBody?: never;
2370
+ responses: {
2371
+ /** @description Picture deleted */
2372
+ 200: {
2373
+ headers: {
2374
+ [name: string]: unknown;
2375
+ };
2376
+ content: {
2377
+ "application/json": {
2378
+ /** @enum {string} */
2379
+ status: "ok";
2380
+ message?: string;
2381
+ };
2382
+ };
2383
+ };
2384
+ /** @description Delete failed */
2385
+ 400: {
2386
+ headers: {
2387
+ [name: string]: unknown;
2388
+ };
2389
+ content: {
2390
+ "application/json": {
2391
+ /** @enum {string} */
2392
+ status: "error";
2393
+ code?: string;
2394
+ message?: string;
2395
+ errors?: string[];
2396
+ };
2397
+ };
2398
+ };
2399
+ /** @description Authentication required */
2400
+ 401: {
2401
+ headers: {
2402
+ [name: string]: unknown;
2403
+ };
2404
+ content: {
2405
+ "application/json": {
2406
+ error: {
2407
+ /** @enum {string} */
2408
+ code: "AUTHENTICATION_REQUIRED";
2409
+ /** @enum {string} */
2410
+ message: "Authentication is required";
2411
+ redirectTo?: string;
2412
+ };
2413
+ };
2414
+ };
2415
+ };
2416
+ };
2417
+ };
2418
+ options?: never;
2419
+ head?: never;
2420
+ patch?: never;
2421
+ trace?: never;
2422
+ };
2423
+ "/me/password": {
2424
+ parameters: {
2425
+ query?: never;
2426
+ header?: never;
2427
+ path?: never;
2428
+ cookie?: never;
2429
+ };
2430
+ get?: never;
2431
+ /** Update password */
2432
+ put: {
2433
+ parameters: {
2434
+ query?: never;
2435
+ header?: never;
2436
+ path?: never;
2437
+ cookie?: never;
2438
+ };
2439
+ requestBody?: {
2440
+ content: {
2441
+ "application/json": {
2442
+ oldPassword?: string;
2443
+ newPassword: string;
2444
+ newPasswordConfirm: string;
2445
+ };
2446
+ };
2447
+ };
2448
+ responses: {
2449
+ /** @description Password updated; earlier sessions revoked and a fresh token pair issued */
2450
+ 200: {
2451
+ headers: {
2452
+ [name: string]: unknown;
2453
+ };
2454
+ content: {
2455
+ "application/json": {
2456
+ /** @enum {string} */
2457
+ status: "ok";
2458
+ message: string;
2459
+ accessToken: string;
2460
+ refreshToken: string;
2461
+ expiresIn: number;
2462
+ };
2463
+ };
2464
+ };
2465
+ /** @description Password update failed */
2466
+ 400: {
2467
+ headers: {
2468
+ [name: string]: unknown;
2469
+ };
2470
+ content: {
2471
+ "application/json": {
2472
+ /** @enum {string} */
2473
+ status: "error";
2474
+ message: string;
2475
+ errors?: string[];
2476
+ };
2477
+ };
2478
+ };
2479
+ /** @description Authentication required */
2480
+ 401: {
2481
+ headers: {
2482
+ [name: string]: unknown;
2483
+ };
2484
+ content: {
2485
+ "application/json": {
2486
+ error: {
2487
+ /** @enum {string} */
2488
+ code: "AUTHENTICATION_REQUIRED";
2489
+ /** @enum {string} */
2490
+ message: "Authentication is required";
2491
+ redirectTo?: string;
2492
+ };
2493
+ };
2494
+ };
2495
+ };
2496
+ };
2497
+ };
2498
+ post?: never;
2499
+ delete?: never;
2500
+ options?: never;
2501
+ head?: never;
2502
+ patch?: never;
2503
+ trace?: never;
2504
+ };
2505
+ "/me/recently-viewed-pages": {
2506
+ parameters: {
2507
+ query?: never;
2508
+ header?: never;
2509
+ path?: never;
2510
+ cookie?: never;
2511
+ };
2512
+ /** Get the current user's recently-viewed pages */
2513
+ get: {
2514
+ parameters: {
2515
+ query?: never;
2516
+ header?: never;
2517
+ path?: never;
2518
+ cookie?: never;
2519
+ };
2520
+ requestBody?: never;
2521
+ responses: {
2522
+ /** @description Recently-viewed pages list (up to 5) */
2523
+ 200: {
2524
+ headers: {
2525
+ [name: string]: unknown;
2526
+ };
2527
+ content: {
2528
+ "application/json": {
2529
+ pages: {
2530
+ _id: string;
2531
+ path: string;
2532
+ revision?: string | {
2533
+ _id: string;
2534
+ path: string;
2535
+ body: string;
2536
+ /** @default markdown */
2537
+ format: string;
2294
2538
  author?: {
2295
2539
  _id: string;
2296
2540
  id?: string;
@@ -2738,58 +2982,281 @@ interface paths {
2738
2982
  patch?: never;
2739
2983
  trace?: never;
2740
2984
  };
2741
- "/oauth/authorize": {
2985
+ "/me/oauth-sessions": {
2742
2986
  parameters: {
2743
2987
  query?: never;
2744
2988
  header?: never;
2745
2989
  path?: never;
2746
2990
  cookie?: never;
2747
2991
  };
2748
- get?: never;
2749
- put?: never;
2750
- /** Issue an authorization code for the consenting web user (PKCE) */
2751
- post: {
2992
+ /** List the current user's active OAuth sessions (refresh-token rotation-chain tips) */
2993
+ get: {
2752
2994
  parameters: {
2753
2995
  query?: never;
2754
2996
  header?: never;
2755
2997
  path?: never;
2756
2998
  cookie?: never;
2757
2999
  };
2758
- requestBody?: {
2759
- content: {
2760
- "application/json": {
2761
- client_id: string;
2762
- redirect_uri: string;
2763
- scope: string;
2764
- code_challenge: string;
2765
- /** @enum {string} */
2766
- code_challenge_method: "S256";
2767
- state?: string;
2768
- };
2769
- };
2770
- };
3000
+ requestBody?: never;
2771
3001
  responses: {
2772
- /** @description Authorization code issued; `redirectUri` carries `code` + `state` */
3002
+ /** @description Active OAuth session list (no secrets) */
2773
3003
  200: {
2774
3004
  headers: {
2775
3005
  [name: string]: unknown;
2776
3006
  };
2777
3007
  content: {
2778
3008
  "application/json": {
2779
- redirectUri: string;
3009
+ oauthSessions: {
3010
+ id: string;
3011
+ clientId: string;
3012
+ clientName: string;
3013
+ scopes: string[];
3014
+ /** Format: date-time */
3015
+ authorizedAt: string;
3016
+ /** Format: date-time */
3017
+ lastRefreshedAt: string;
3018
+ /** Format: date-time */
3019
+ expiresAt: string;
3020
+ }[];
2780
3021
  };
2781
3022
  };
2782
3023
  };
2783
- /** @description Invalid request / scope / client (RFC 6749 §4.1.2.1) */
2784
- 400: {
3024
+ /** @description Authentication required */
3025
+ 401: {
2785
3026
  headers: {
2786
3027
  [name: string]: unknown;
2787
3028
  };
2788
3029
  content: {
2789
3030
  "application/json": {
2790
- /** @enum {string} */
2791
- error: "invalid_request" | "invalid_client" | "invalid_grant" | "unauthorized_client" | "unsupported_grant_type" | "invalid_scope" | "access_denied" | "authorization_pending" | "slow_down" | "expired_token";
2792
- error_description?: string;
3031
+ error: {
3032
+ /** @enum {string} */
3033
+ code: "AUTHENTICATION_REQUIRED";
3034
+ /** @enum {string} */
3035
+ message: "Authentication is required";
3036
+ redirectTo?: string;
3037
+ };
3038
+ };
3039
+ };
3040
+ };
3041
+ /** @description OAuth sessions can only be managed from a web session, or the account is not active */
3042
+ 403: {
3043
+ headers: {
3044
+ [name: string]: unknown;
3045
+ };
3046
+ content: {
3047
+ "application/json": {
3048
+ error: {
3049
+ /** @enum {string} */
3050
+ code: "FORBIDDEN";
3051
+ message: string;
3052
+ };
3053
+ } | {
3054
+ error: {
3055
+ /** @enum {string} */
3056
+ code: "USER_REGISTERED" | "USER_SUSPENDED" | "USER_INVITED";
3057
+ message: string;
3058
+ redirectTo: string;
3059
+ };
3060
+ };
3061
+ };
3062
+ };
3063
+ /** @description Internal server error */
3064
+ 500: {
3065
+ headers: {
3066
+ [name: string]: unknown;
3067
+ };
3068
+ content: {
3069
+ "application/json": {
3070
+ error: {
3071
+ /** @enum {string} */
3072
+ code: "INTERNAL_ERROR";
3073
+ /** @enum {string} */
3074
+ message: "Internal server error";
3075
+ };
3076
+ };
3077
+ };
3078
+ };
3079
+ };
3080
+ };
3081
+ put?: never;
3082
+ post?: never;
3083
+ delete?: never;
3084
+ options?: never;
3085
+ head?: never;
3086
+ patch?: never;
3087
+ trace?: never;
3088
+ };
3089
+ "/me/oauth-sessions/{id}": {
3090
+ parameters: {
3091
+ query?: never;
3092
+ header?: never;
3093
+ path?: never;
3094
+ cookie?: never;
3095
+ };
3096
+ get?: never;
3097
+ put?: never;
3098
+ post?: never;
3099
+ /** Revoke an OAuth session (the rotation-chain component reachable from this tip) */
3100
+ delete: {
3101
+ parameters: {
3102
+ query?: never;
3103
+ header?: never;
3104
+ path: {
3105
+ id: string;
3106
+ };
3107
+ cookie?: never;
3108
+ };
3109
+ requestBody?: never;
3110
+ responses: {
3111
+ /** @description Session revoked */
3112
+ 200: {
3113
+ headers: {
3114
+ [name: string]: unknown;
3115
+ };
3116
+ content: {
3117
+ "application/json": {
3118
+ id: string;
3119
+ clientId: string;
3120
+ clientName: string;
3121
+ scopes: string[];
3122
+ /** Format: date-time */
3123
+ authorizedAt: string;
3124
+ /** Format: date-time */
3125
+ lastRefreshedAt: string;
3126
+ /** Format: date-time */
3127
+ expiresAt: string;
3128
+ };
3129
+ };
3130
+ };
3131
+ /** @description Authentication required */
3132
+ 401: {
3133
+ headers: {
3134
+ [name: string]: unknown;
3135
+ };
3136
+ content: {
3137
+ "application/json": {
3138
+ error: {
3139
+ /** @enum {string} */
3140
+ code: "AUTHENTICATION_REQUIRED";
3141
+ /** @enum {string} */
3142
+ message: "Authentication is required";
3143
+ redirectTo?: string;
3144
+ };
3145
+ };
3146
+ };
3147
+ };
3148
+ /** @description OAuth sessions can only be managed from a web session, or the account is not active */
3149
+ 403: {
3150
+ headers: {
3151
+ [name: string]: unknown;
3152
+ };
3153
+ content: {
3154
+ "application/json": {
3155
+ error: {
3156
+ /** @enum {string} */
3157
+ code: "FORBIDDEN";
3158
+ message: string;
3159
+ };
3160
+ } | {
3161
+ error: {
3162
+ /** @enum {string} */
3163
+ code: "USER_REGISTERED" | "USER_SUSPENDED" | "USER_INVITED";
3164
+ message: string;
3165
+ redirectTo: string;
3166
+ };
3167
+ };
3168
+ };
3169
+ };
3170
+ /** @description No such session belonging to the current user */
3171
+ 404: {
3172
+ headers: {
3173
+ [name: string]: unknown;
3174
+ };
3175
+ content: {
3176
+ "application/json": {
3177
+ error: {
3178
+ /** @enum {string} */
3179
+ code: "NOT_FOUND";
3180
+ message: string;
3181
+ };
3182
+ };
3183
+ };
3184
+ };
3185
+ /** @description Internal server error */
3186
+ 500: {
3187
+ headers: {
3188
+ [name: string]: unknown;
3189
+ };
3190
+ content: {
3191
+ "application/json": {
3192
+ error: {
3193
+ /** @enum {string} */
3194
+ code: "INTERNAL_ERROR";
3195
+ /** @enum {string} */
3196
+ message: "Internal server error";
3197
+ };
3198
+ };
3199
+ };
3200
+ };
3201
+ };
3202
+ };
3203
+ options?: never;
3204
+ head?: never;
3205
+ patch?: never;
3206
+ trace?: never;
3207
+ };
3208
+ "/oauth/authorize": {
3209
+ parameters: {
3210
+ query?: never;
3211
+ header?: never;
3212
+ path?: never;
3213
+ cookie?: never;
3214
+ };
3215
+ get?: never;
3216
+ put?: never;
3217
+ /** Issue an authorization code for the consenting web user (PKCE) */
3218
+ post: {
3219
+ parameters: {
3220
+ query?: never;
3221
+ header?: never;
3222
+ path?: never;
3223
+ cookie?: never;
3224
+ };
3225
+ requestBody?: {
3226
+ content: {
3227
+ "application/json": {
3228
+ client_id: string;
3229
+ redirect_uri: string;
3230
+ scope: string;
3231
+ code_challenge: string;
3232
+ /** @enum {string} */
3233
+ code_challenge_method: "S256";
3234
+ state?: string;
3235
+ };
3236
+ };
3237
+ };
3238
+ responses: {
3239
+ /** @description Authorization code issued; `redirectUri` carries `code` + `state` */
3240
+ 200: {
3241
+ headers: {
3242
+ [name: string]: unknown;
3243
+ };
3244
+ content: {
3245
+ "application/json": {
3246
+ redirectUri: string;
3247
+ };
3248
+ };
3249
+ };
3250
+ /** @description Invalid request / scope / client (RFC 6749 §4.1.2.1) */
3251
+ 400: {
3252
+ headers: {
3253
+ [name: string]: unknown;
3254
+ };
3255
+ content: {
3256
+ "application/json": {
3257
+ /** @enum {string} */
3258
+ error: "invalid_request" | "invalid_client" | "invalid_grant" | "unauthorized_client" | "unsupported_grant_type" | "invalid_scope" | "access_denied" | "authorization_pending" | "slow_down" | "expired_token";
3259
+ error_description?: string;
2793
3260
  };
2794
3261
  };
2795
3262
  };
@@ -5929,66 +6396,187 @@ interface paths {
5929
6396
  patch?: never;
5930
6397
  trace?: never;
5931
6398
  };
5932
- "/pages": {
6399
+ "/pages/{pageId}/history": {
5933
6400
  parameters: {
5934
6401
  query?: never;
5935
6402
  header?: never;
5936
6403
  path?: never;
5937
6404
  cookie?: never;
5938
6405
  };
5939
- /** Get page data by path or page_id */
6406
+ /** A page's content revisions and metadata events as one timeline, newest first */
5940
6407
  get: {
5941
6408
  parameters: {
5942
6409
  query?: {
5943
- path?: string;
5944
- page_id?: string;
5945
- revision_id?: string;
6410
+ cursor?: string;
6411
+ limit?: number;
5946
6412
  };
5947
6413
  header?: never;
5948
- path?: never;
6414
+ path: {
6415
+ pageId: string;
6416
+ };
5949
6417
  cookie?: never;
5950
6418
  };
5951
6419
  requestBody?: never;
5952
6420
  responses: {
5953
- /** @description The requested page with populated revision. `revision.renderedAst` shape is content-negotiated via the `X-Crowi-Ast-Version` request header (RFC-0023): requests declaring `X-Crowi-Ast-Version: 1` receive the typed `{astVersion, root}` envelope; all other requests receive the stored bare mdast Root verbatim. The response varies on this header (`Vary: X-Crowi-Ast-Version`). */
6421
+ /** @description One page of the timeline, plus a cursor when more remains */
5954
6422
  200: {
6423
+ headers: {
6424
+ [name: string]: unknown;
6425
+ };
6426
+ content: {
6427
+ "application/json": components["schemas"]["PageHistoryResponse"];
6428
+ };
6429
+ };
6430
+ /** @description Malformed page id, cursor, or query */
6431
+ 400: {
5955
6432
  headers: {
5956
6433
  [name: string]: unknown;
5957
6434
  };
5958
6435
  content: {
5959
6436
  "application/json": {
5960
- page: {
5961
- _id: string;
5962
- path: string;
5963
- revision: {
5964
- _id: string;
5965
- path: string;
5966
- body: string;
5967
- /** @default markdown */
5968
- format: string;
5969
- author?: {
5970
- _id: string;
5971
- id?: string;
5972
- username: string;
5973
- name: string;
5974
- /** Format: email */
5975
- email: string;
5976
- image?: string | null;
5977
- createdAt: string;
5978
- } | null;
5979
- createdAt: string;
5980
- meta?: {
5981
- toc?: {
5982
- level: number;
5983
- text: string;
5984
- anchorId: string;
5985
- }[];
5986
- wikiLinks?: {
5987
- raw: string;
5988
- target: string;
5989
- displayText?: string;
5990
- }[];
5991
- mentions?: {
6437
+ error: {
6438
+ code: string;
6439
+ message: string;
6440
+ };
6441
+ };
6442
+ };
6443
+ };
6444
+ /** @description Authentication required */
6445
+ 401: {
6446
+ headers: {
6447
+ [name: string]: unknown;
6448
+ };
6449
+ content: {
6450
+ "application/json": {
6451
+ error: {
6452
+ /** @enum {string} */
6453
+ code: "AUTHENTICATION_REQUIRED";
6454
+ /** @enum {string} */
6455
+ message: "Authentication is required";
6456
+ redirectTo?: string;
6457
+ };
6458
+ };
6459
+ };
6460
+ };
6461
+ /** @description The access token does not grant pages:read */
6462
+ 403: {
6463
+ headers: {
6464
+ [name: string]: unknown;
6465
+ };
6466
+ content: {
6467
+ "application/json": {
6468
+ error: {
6469
+ /** @enum {string} */
6470
+ code: "INSUFFICIENT_SCOPE";
6471
+ message: string;
6472
+ details?: {
6473
+ requiredScope: string;
6474
+ };
6475
+ };
6476
+ };
6477
+ };
6478
+ };
6479
+ /** @description Page not found (also covers grant-denied) */
6480
+ 404: {
6481
+ headers: {
6482
+ [name: string]: unknown;
6483
+ };
6484
+ content: {
6485
+ "application/json": {
6486
+ error: {
6487
+ /** @enum {string} */
6488
+ code: "PAGE_NOT_FOUND";
6489
+ /** @enum {string} */
6490
+ message: "Page not found";
6491
+ };
6492
+ };
6493
+ };
6494
+ };
6495
+ /** @description The timeline could not be read — includes the page identifier so an operator can run the repair */
6496
+ 500: {
6497
+ headers: {
6498
+ [name: string]: unknown;
6499
+ };
6500
+ content: {
6501
+ "application/json": {
6502
+ error: {
6503
+ code: string;
6504
+ message: string;
6505
+ pageId: string;
6506
+ };
6507
+ };
6508
+ };
6509
+ };
6510
+ };
6511
+ };
6512
+ put?: never;
6513
+ post?: never;
6514
+ delete?: never;
6515
+ options?: never;
6516
+ head?: never;
6517
+ patch?: never;
6518
+ trace?: never;
6519
+ };
6520
+ "/pages": {
6521
+ parameters: {
6522
+ query?: never;
6523
+ header?: never;
6524
+ path?: never;
6525
+ cookie?: never;
6526
+ };
6527
+ /** Get page data by path or page_id */
6528
+ get: {
6529
+ parameters: {
6530
+ query?: {
6531
+ path?: string;
6532
+ page_id?: string;
6533
+ revision_id?: string;
6534
+ };
6535
+ header?: never;
6536
+ path?: never;
6537
+ cookie?: never;
6538
+ };
6539
+ requestBody?: never;
6540
+ responses: {
6541
+ /** @description The requested page with populated revision. `revision.renderedAst` shape is content-negotiated via the `X-Crowi-Ast-Version` request header (RFC-0023): requests declaring `X-Crowi-Ast-Version: 1` receive the typed `{astVersion, root}` envelope; all other requests receive the stored bare mdast Root verbatim. The response varies on this header (`Vary: X-Crowi-Ast-Version`). */
6542
+ 200: {
6543
+ headers: {
6544
+ [name: string]: unknown;
6545
+ };
6546
+ content: {
6547
+ "application/json": {
6548
+ page: {
6549
+ _id: string;
6550
+ path: string;
6551
+ revision: {
6552
+ _id: string;
6553
+ path: string;
6554
+ body: string;
6555
+ /** @default markdown */
6556
+ format: string;
6557
+ author?: {
6558
+ _id: string;
6559
+ id?: string;
6560
+ username: string;
6561
+ name: string;
6562
+ /** Format: email */
6563
+ email: string;
6564
+ image?: string | null;
6565
+ createdAt: string;
6566
+ } | null;
6567
+ createdAt: string;
6568
+ meta?: {
6569
+ toc?: {
6570
+ level: number;
6571
+ text: string;
6572
+ anchorId: string;
6573
+ }[];
6574
+ wikiLinks?: {
6575
+ raw: string;
6576
+ target: string;
6577
+ displayText?: string;
6578
+ }[];
6579
+ mentions?: {
5992
6580
  username: string;
5993
6581
  }[];
5994
6582
  codeBlockLanguages?: string[];
@@ -6503,7 +7091,9 @@ interface paths {
6503
7091
  delete: {
6504
7092
  parameters: {
6505
7093
  query?: never;
6506
- header?: never;
7094
+ header?: {
7095
+ "idempotency-key"?: string;
7096
+ };
6507
7097
  path?: never;
6508
7098
  cookie?: never;
6509
7099
  };
@@ -6633,7 +7223,7 @@ interface paths {
6633
7223
  };
6634
7224
  };
6635
7225
  };
6636
- /** @description PAGE_DELETE_FAILED */
7226
+ /** @description PAGE_DELETE_FAILED / IDEMPOTENCY_KEY_REQUIRED / PAGE_TRANSITION_INCOMPLETE */
6637
7227
  400: {
6638
7228
  headers: {
6639
7229
  [name: string]: unknown;
@@ -6644,6 +7234,18 @@ interface paths {
6644
7234
  code: string;
6645
7235
  message: string;
6646
7236
  };
7237
+ } | {
7238
+ error: {
7239
+ /** @enum {string} */
7240
+ code: "IDEMPOTENCY_KEY_REQUIRED";
7241
+ message: string;
7242
+ };
7243
+ } | {
7244
+ error: {
7245
+ /** @enum {string} */
7246
+ code: "PAGE_TRANSITION_INCOMPLETE";
7247
+ message: string;
7248
+ };
6647
7249
  };
6648
7250
  };
6649
7251
  };
@@ -6680,7 +7282,7 @@ interface paths {
6680
7282
  };
6681
7283
  };
6682
7284
  };
6683
- /** @description Stale revision_id */
7285
+ /** @description Stale revision_id / IDEMPOTENCY_KEY_CONFLICT / PAGE_TRANSITION_IN_PROGRESS */
6684
7286
  409: {
6685
7287
  headers: {
6686
7288
  [name: string]: unknown;
@@ -6692,6 +7294,18 @@ interface paths {
6692
7294
  code: "PAGE_REVISION_ERROR";
6693
7295
  message: string;
6694
7296
  };
7297
+ } | {
7298
+ error: {
7299
+ /** @enum {string} */
7300
+ code: "IDEMPOTENCY_KEY_CONFLICT";
7301
+ message: string;
7302
+ };
7303
+ } | {
7304
+ error: {
7305
+ /** @enum {string} */
7306
+ code: "PAGE_TRANSITION_IN_PROGRESS";
7307
+ message: string;
7308
+ };
6695
7309
  };
6696
7310
  };
6697
7311
  };
@@ -8378,7 +8992,9 @@ interface paths {
8378
8992
  post: {
8379
8993
  parameters: {
8380
8994
  query?: never;
8381
- header?: never;
8995
+ header?: {
8996
+ "idempotency-key"?: string;
8997
+ };
8382
8998
  path?: never;
8383
8999
  cookie?: never;
8384
9000
  };
@@ -8506,7 +9122,7 @@ interface paths {
8506
9122
  };
8507
9123
  };
8508
9124
  };
8509
- /** @description PAGE_REVERT_FAILED */
9125
+ /** @description PAGE_REVERT_FAILED / IDEMPOTENCY_KEY_REQUIRED / PAGE_TRANSITION_INCOMPLETE */
8510
9126
  400: {
8511
9127
  headers: {
8512
9128
  [name: string]: unknown;
@@ -8517,6 +9133,18 @@ interface paths {
8517
9133
  code: string;
8518
9134
  message: string;
8519
9135
  };
9136
+ } | {
9137
+ error: {
9138
+ /** @enum {string} */
9139
+ code: "IDEMPOTENCY_KEY_REQUIRED";
9140
+ message: string;
9141
+ };
9142
+ } | {
9143
+ error: {
9144
+ /** @enum {string} */
9145
+ code: "PAGE_TRANSITION_INCOMPLETE";
9146
+ message: string;
9147
+ };
8520
9148
  };
8521
9149
  };
8522
9150
  };
@@ -8553,6 +9181,27 @@ interface paths {
8553
9181
  };
8554
9182
  };
8555
9183
  };
9184
+ /** @description IDEMPOTENCY_KEY_CONFLICT / PAGE_TRANSITION_IN_PROGRESS */
9185
+ 409: {
9186
+ headers: {
9187
+ [name: string]: unknown;
9188
+ };
9189
+ content: {
9190
+ "application/json": {
9191
+ error: {
9192
+ /** @enum {string} */
9193
+ code: "IDEMPOTENCY_KEY_CONFLICT";
9194
+ message: string;
9195
+ };
9196
+ } | {
9197
+ error: {
9198
+ /** @enum {string} */
9199
+ code: "PAGE_TRANSITION_IN_PROGRESS";
9200
+ message: string;
9201
+ };
9202
+ };
9203
+ };
9204
+ };
8556
9205
  };
8557
9206
  };
8558
9207
  delete?: never;
@@ -8771,7 +9420,9 @@ interface paths {
8771
9420
  post: {
8772
9421
  parameters: {
8773
9422
  query?: never;
8774
- header?: never;
9423
+ header?: {
9424
+ "idempotency-key"?: string;
9425
+ };
8775
9426
  path?: never;
8776
9427
  cookie?: never;
8777
9428
  };
@@ -8904,7 +9555,7 @@ interface paths {
8904
9555
  };
8905
9556
  };
8906
9557
  };
8907
- /** @description PAGE_INVALID_NAME / PAGE_EXISTS / PAGE_RENAME_FAILED / PAGE_RENAME_TREE_FAILED */
9558
+ /** @description PAGE_INVALID_NAME / PAGE_EXISTS / PAGE_RENAME_FAILED / PAGE_RENAME_TREE_FAILED / IDEMPOTENCY_KEY_REQUIRED / PAGE_TRANSITION_INCOMPLETE */
8908
9559
  400: {
8909
9560
  headers: {
8910
9561
  [name: string]: unknown;
@@ -8926,6 +9577,18 @@ interface paths {
8926
9577
  }[];
8927
9578
  partial?: boolean;
8928
9579
  };
9580
+ } | {
9581
+ error: {
9582
+ /** @enum {string} */
9583
+ code: "IDEMPOTENCY_KEY_REQUIRED";
9584
+ message: string;
9585
+ };
9586
+ } | {
9587
+ error: {
9588
+ /** @enum {string} */
9589
+ code: "PAGE_TRANSITION_INCOMPLETE";
9590
+ message: string;
9591
+ };
8929
9592
  };
8930
9593
  };
8931
9594
  };
@@ -8962,7 +9625,7 @@ interface paths {
8962
9625
  };
8963
9626
  };
8964
9627
  };
8965
- /** @description Stale revision_id */
9628
+ /** @description Stale revision_id / IDEMPOTENCY_KEY_CONFLICT / PAGE_TRANSITION_IN_PROGRESS */
8966
9629
  409: {
8967
9630
  headers: {
8968
9631
  [name: string]: unknown;
@@ -8974,6 +9637,18 @@ interface paths {
8974
9637
  code: "PAGE_REVISION_ERROR";
8975
9638
  message: string;
8976
9639
  };
9640
+ } | {
9641
+ error: {
9642
+ /** @enum {string} */
9643
+ code: "IDEMPOTENCY_KEY_CONFLICT";
9644
+ message: string;
9645
+ };
9646
+ } | {
9647
+ error: {
9648
+ /** @enum {string} */
9649
+ code: "PAGE_TRANSITION_IN_PROGRESS";
9650
+ message: string;
9651
+ };
8977
9652
  };
8978
9653
  };
8979
9654
  };
@@ -8998,7 +9673,9 @@ interface paths {
8998
9673
  post: {
8999
9674
  parameters: {
9000
9675
  query?: never;
9001
- header?: never;
9676
+ header?: {
9677
+ "idempotency-key"?: string;
9678
+ };
9002
9679
  path?: never;
9003
9680
  cookie?: never;
9004
9681
  };
@@ -9023,7 +9700,7 @@ interface paths {
9023
9700
  };
9024
9701
  };
9025
9702
  };
9026
- /** @description PAGE_INVALID_NAME / PAGE_RENAME_TREE_FAILED (collisions, nothing to move, or partial failure) */
9703
+ /** @description PAGE_INVALID_NAME / PAGE_RENAME_TREE_FAILED / IDEMPOTENCY_KEY_REQUIRED */
9027
9704
  400: {
9028
9705
  headers: {
9029
9706
  [name: string]: unknown;
@@ -9045,6 +9722,12 @@ interface paths {
9045
9722
  }[];
9046
9723
  partial?: boolean;
9047
9724
  };
9725
+ } | {
9726
+ error: {
9727
+ /** @enum {string} */
9728
+ code: "IDEMPOTENCY_KEY_REQUIRED";
9729
+ message: string;
9730
+ };
9048
9731
  };
9049
9732
  };
9050
9733
  };
@@ -9065,6 +9748,21 @@ interface paths {
9065
9748
  };
9066
9749
  };
9067
9750
  };
9751
+ /** @description IDEMPOTENCY_KEY_CONFLICT */
9752
+ 409: {
9753
+ headers: {
9754
+ [name: string]: unknown;
9755
+ };
9756
+ content: {
9757
+ "application/json": {
9758
+ error: {
9759
+ /** @enum {string} */
9760
+ code: "IDEMPOTENCY_KEY_CONFLICT";
9761
+ message: string;
9762
+ };
9763
+ };
9764
+ };
9765
+ };
9068
9766
  };
9069
9767
  };
9070
9768
  delete?: never;
@@ -10653,7 +11351,518 @@ interface paths {
10653
11351
  patch?: never;
10654
11352
  trace?: never;
10655
11353
  };
10656
- "/attachments/{id}": {
11354
+ "/attachments/{id}": {
11355
+ parameters: {
11356
+ query?: never;
11357
+ header?: never;
11358
+ path?: never;
11359
+ cookie?: never;
11360
+ };
11361
+ get?: never;
11362
+ put?: never;
11363
+ post?: never;
11364
+ /** Remove an attachment */
11365
+ delete: {
11366
+ parameters: {
11367
+ query?: never;
11368
+ header?: never;
11369
+ path: {
11370
+ /** @description Attachment id (24-char hex ObjectId) */
11371
+ id: string;
11372
+ };
11373
+ cookie?: never;
11374
+ };
11375
+ requestBody?: never;
11376
+ responses: {
11377
+ /** @description Attachment removed */
11378
+ 200: {
11379
+ headers: {
11380
+ [name: string]: unknown;
11381
+ };
11382
+ content: {
11383
+ "application/json": {
11384
+ /** @enum {boolean} */
11385
+ success: true;
11386
+ };
11387
+ };
11388
+ };
11389
+ /** @description Invalid attachment id */
11390
+ 400: {
11391
+ headers: {
11392
+ [name: string]: unknown;
11393
+ };
11394
+ content: {
11395
+ "application/json": {
11396
+ error: {
11397
+ /** @enum {string} */
11398
+ code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
11399
+ message: string;
11400
+ };
11401
+ };
11402
+ };
11403
+ };
11404
+ /** @description Authentication required */
11405
+ 401: {
11406
+ headers: {
11407
+ [name: string]: unknown;
11408
+ };
11409
+ content: {
11410
+ "application/json": {
11411
+ error: {
11412
+ /** @enum {string} */
11413
+ code: "AUTHENTICATION_REQUIRED";
11414
+ /** @enum {string} */
11415
+ message: "Authentication is required";
11416
+ redirectTo?: string;
11417
+ };
11418
+ };
11419
+ };
11420
+ };
11421
+ /** @description Forbidden (kept for legacy parity; current policy only requires view-grant) */
11422
+ 403: {
11423
+ headers: {
11424
+ [name: string]: unknown;
11425
+ };
11426
+ content: {
11427
+ "application/json": {
11428
+ error: {
11429
+ /** @enum {string} */
11430
+ code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
11431
+ message: string;
11432
+ };
11433
+ };
11434
+ };
11435
+ };
11436
+ /** @description Attachment not found / page not granted */
11437
+ 404: {
11438
+ headers: {
11439
+ [name: string]: unknown;
11440
+ };
11441
+ content: {
11442
+ "application/json": {
11443
+ error: {
11444
+ /** @enum {string} */
11445
+ code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
11446
+ message: string;
11447
+ };
11448
+ };
11449
+ };
11450
+ };
11451
+ /** @description Internal server error */
11452
+ 500: {
11453
+ headers: {
11454
+ [name: string]: unknown;
11455
+ };
11456
+ content: {
11457
+ "application/json": {
11458
+ error: {
11459
+ /** @enum {string} */
11460
+ code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
11461
+ message: string;
11462
+ };
11463
+ };
11464
+ };
11465
+ };
11466
+ };
11467
+ };
11468
+ options?: never;
11469
+ head?: never;
11470
+ patch?: never;
11471
+ trace?: never;
11472
+ };
11473
+ "/attachments/upload-policy": {
11474
+ parameters: {
11475
+ query?: never;
11476
+ header?: never;
11477
+ path?: never;
11478
+ cookie?: never;
11479
+ };
11480
+ /** Get the server upload policy (allowed MIME types, extension hints, size limits) */
11481
+ get: {
11482
+ parameters: {
11483
+ query?: never;
11484
+ header?: never;
11485
+ path?: never;
11486
+ cookie?: never;
11487
+ };
11488
+ requestBody?: never;
11489
+ responses: {
11490
+ /** @description Current upload policy, derived from server-side constants (never a value maintained separately) */
11491
+ 200: {
11492
+ headers: {
11493
+ [name: string]: unknown;
11494
+ };
11495
+ content: {
11496
+ "application/json": {
11497
+ allowedMimeTypes: string[];
11498
+ extensionHints: {
11499
+ [key: string]: string;
11500
+ };
11501
+ maxBytes: {
11502
+ attachment: number;
11503
+ };
11504
+ profilePicture: {
11505
+ allowedMimeTypes: string[];
11506
+ maxBytes: number;
11507
+ };
11508
+ };
11509
+ };
11510
+ };
11511
+ /** @description Authentication required */
11512
+ 401: {
11513
+ headers: {
11514
+ [name: string]: unknown;
11515
+ };
11516
+ content: {
11517
+ "application/json": {
11518
+ error: {
11519
+ /** @enum {string} */
11520
+ code: "AUTHENTICATION_REQUIRED";
11521
+ /** @enum {string} */
11522
+ message: "Authentication is required";
11523
+ redirectTo?: string;
11524
+ };
11525
+ };
11526
+ };
11527
+ };
11528
+ };
11529
+ };
11530
+ put?: never;
11531
+ post?: never;
11532
+ delete?: never;
11533
+ options?: never;
11534
+ head?: never;
11535
+ patch?: never;
11536
+ trace?: never;
11537
+ };
11538
+ "/search": {
11539
+ parameters: {
11540
+ query?: never;
11541
+ header?: never;
11542
+ path?: never;
11543
+ cookie?: never;
11544
+ };
11545
+ /** Full-text search over pages */
11546
+ get: {
11547
+ parameters: {
11548
+ query: {
11549
+ q: string;
11550
+ tree?: string;
11551
+ type?: "portal" | "public" | "user";
11552
+ page?: number;
11553
+ limit?: number;
11554
+ };
11555
+ header?: never;
11556
+ path?: never;
11557
+ cookie?: never;
11558
+ };
11559
+ requestBody?: never;
11560
+ responses: {
11561
+ /** @description Ranked search hits joined with page + bookmark count metadata */
11562
+ 200: {
11563
+ headers: {
11564
+ [name: string]: unknown;
11565
+ };
11566
+ content: {
11567
+ "application/json": {
11568
+ meta: {
11569
+ took?: number;
11570
+ total: number;
11571
+ results: number;
11572
+ };
11573
+ data: {
11574
+ pageId: string;
11575
+ path: string;
11576
+ score?: number;
11577
+ snippet?: string;
11578
+ bookmarkCount: number;
11579
+ page: {
11580
+ _id: string;
11581
+ path: string;
11582
+ revision?: string | {
11583
+ _id: string;
11584
+ path: string;
11585
+ body: string;
11586
+ /** @default markdown */
11587
+ format: string;
11588
+ author?: {
11589
+ _id: string;
11590
+ id?: string;
11591
+ username: string;
11592
+ name: string;
11593
+ /** Format: email */
11594
+ email: string;
11595
+ image?: string | null;
11596
+ createdAt: string;
11597
+ } | null;
11598
+ createdAt: string;
11599
+ meta?: {
11600
+ toc?: {
11601
+ level: number;
11602
+ text: string;
11603
+ anchorId: string;
11604
+ }[];
11605
+ wikiLinks?: {
11606
+ raw: string;
11607
+ target: string;
11608
+ displayText?: string;
11609
+ }[];
11610
+ mentions?: {
11611
+ username: string;
11612
+ }[];
11613
+ codeBlockLanguages?: string[];
11614
+ rawSpaceLinks?: string[];
11615
+ };
11616
+ renderedAst?: components["schemas"]["RenderedAstEnvelope"] | components["schemas"]["LegacyRenderedAstRoot"];
11617
+ renderedAstArtifactKey?: string;
11618
+ rendererVersion?: string;
11619
+ parentRevisionId?: string | null;
11620
+ /** @enum {string} */
11621
+ type?: "snapshot" | "incremental";
11622
+ savedBy?: string | {
11623
+ _id: string;
11624
+ id?: string;
11625
+ username: string;
11626
+ name: string;
11627
+ /** Format: email */
11628
+ email: string;
11629
+ image?: string | null;
11630
+ createdAt: string;
11631
+ } | null;
11632
+ contributors?: (string | {
11633
+ _id: string;
11634
+ id?: string;
11635
+ username: string;
11636
+ name: string;
11637
+ /** Format: email */
11638
+ email: string;
11639
+ image?: string | null;
11640
+ createdAt: string;
11641
+ })[];
11642
+ message?: string;
11643
+ /** @enum {string} */
11644
+ editVia?: "web" | "oauth" | "pat";
11645
+ };
11646
+ redirectTo?: string | null;
11647
+ /** @enum {string|null} */
11648
+ status?: "wip" | "published" | "deleted" | "deprecated" | "draft" | null;
11649
+ grant?: number;
11650
+ grantedUsers?: string[];
11651
+ creator?: string | {
11652
+ _id: string;
11653
+ id?: string;
11654
+ username: string;
11655
+ name: string;
11656
+ /** Format: email */
11657
+ email: string;
11658
+ image?: string | null;
11659
+ createdAt: string;
11660
+ } | null;
11661
+ lastUpdateUser?: string | {
11662
+ _id: string;
11663
+ id?: string;
11664
+ username: string;
11665
+ name: string;
11666
+ /** Format: email */
11667
+ email: string;
11668
+ image?: string | null;
11669
+ createdAt: string;
11670
+ } | null;
11671
+ liker?: string[];
11672
+ /** @default 0 */
11673
+ commentCount: number;
11674
+ extended?: {
11675
+ [key: string]: unknown;
11676
+ };
11677
+ createdAt: string;
11678
+ updatedAt?: string;
11679
+ currentRevision?: string | null;
11680
+ yjsCheckpointAt?: string | null;
11681
+ latestRevision?: string;
11682
+ likerCount?: number;
11683
+ seenUsersCount?: number;
11684
+ };
11685
+ }[];
11686
+ };
11687
+ };
11688
+ };
11689
+ /** @description Validation error (e.g. empty `q`, invalid `type` enum) */
11690
+ 400: {
11691
+ headers: {
11692
+ [name: string]: unknown;
11693
+ };
11694
+ content: {
11695
+ "application/json": {
11696
+ error: {
11697
+ /** @enum {string} */
11698
+ code: "VALIDATION_ERROR";
11699
+ message: string;
11700
+ details?: {
11701
+ fieldErrors: {
11702
+ [key: string]: string[];
11703
+ };
11704
+ formErrors: string[];
11705
+ };
11706
+ };
11707
+ };
11708
+ };
11709
+ };
11710
+ /** @description Authentication required */
11711
+ 401: {
11712
+ headers: {
11713
+ [name: string]: unknown;
11714
+ };
11715
+ content: {
11716
+ "application/json": {
11717
+ error: {
11718
+ /** @enum {string} */
11719
+ code: "AUTHENTICATION_REQUIRED";
11720
+ /** @enum {string} */
11721
+ message: "Authentication is required";
11722
+ redirectTo?: string;
11723
+ };
11724
+ };
11725
+ };
11726
+ };
11727
+ /** @description Search driver raised an unexpected error */
11728
+ 500: {
11729
+ headers: {
11730
+ [name: string]: unknown;
11731
+ };
11732
+ content: {
11733
+ "application/json": {
11734
+ error: {
11735
+ /** @enum {string} */
11736
+ code: "INTERNAL_ERROR";
11737
+ /** @enum {string} */
11738
+ message: "Internal server error";
11739
+ };
11740
+ };
11741
+ };
11742
+ };
11743
+ /** @description No search driver registered (install `@crowi/plugin-search-*`) */
11744
+ 503: {
11745
+ headers: {
11746
+ [name: string]: unknown;
11747
+ };
11748
+ content: {
11749
+ "application/json": {
11750
+ error: {
11751
+ /** @enum {string} */
11752
+ code: "SERVICE_UNAVAILABLE";
11753
+ feature: string;
11754
+ message: string;
11755
+ };
11756
+ };
11757
+ };
11758
+ };
11759
+ };
11760
+ };
11761
+ put?: never;
11762
+ post?: never;
11763
+ delete?: never;
11764
+ options?: never;
11765
+ head?: never;
11766
+ patch?: never;
11767
+ trace?: never;
11768
+ };
11769
+ "/admin/crypto/status": {
11770
+ parameters: {
11771
+ query?: never;
11772
+ header?: never;
11773
+ path?: never;
11774
+ cookie?: never;
11775
+ };
11776
+ /** Report which sensitive Config values are still plaintext */
11777
+ get: {
11778
+ parameters: {
11779
+ query?: never;
11780
+ header?: never;
11781
+ path?: never;
11782
+ cookie?: never;
11783
+ };
11784
+ requestBody?: never;
11785
+ responses: {
11786
+ /** @description Per-(ns, key) status for every sensitive Config row */
11787
+ 200: {
11788
+ headers: {
11789
+ [name: string]: unknown;
11790
+ };
11791
+ content: {
11792
+ "application/json": {
11793
+ encryptionConfigured: boolean;
11794
+ unencryptedCount: number;
11795
+ encryptedCount: number;
11796
+ entries: {
11797
+ ns: string;
11798
+ key: string;
11799
+ present: boolean;
11800
+ encrypted: boolean;
11801
+ }[];
11802
+ };
11803
+ };
11804
+ };
11805
+ /** @description Authentication required */
11806
+ 401: {
11807
+ headers: {
11808
+ [name: string]: unknown;
11809
+ };
11810
+ content: {
11811
+ "application/json": {
11812
+ error: {
11813
+ /** @enum {string} */
11814
+ code: "AUTHENTICATION_REQUIRED";
11815
+ /** @enum {string} */
11816
+ message: "Authentication is required";
11817
+ redirectTo?: string;
11818
+ };
11819
+ };
11820
+ };
11821
+ };
11822
+ /** @description Admin permission required */
11823
+ 403: {
11824
+ headers: {
11825
+ [name: string]: unknown;
11826
+ };
11827
+ content: {
11828
+ "application/json": {
11829
+ error: {
11830
+ /** @enum {string} */
11831
+ code: "ADMIN_REQUIRED";
11832
+ /** @enum {string} */
11833
+ message: "Admin permission required";
11834
+ redirectTo?: string;
11835
+ };
11836
+ };
11837
+ };
11838
+ };
11839
+ /** @description Internal server error */
11840
+ 500: {
11841
+ headers: {
11842
+ [name: string]: unknown;
11843
+ };
11844
+ content: {
11845
+ "application/json": {
11846
+ error: {
11847
+ /** @enum {string} */
11848
+ code: "INTERNAL_ERROR";
11849
+ /** @enum {string} */
11850
+ message: "Internal server error";
11851
+ };
11852
+ };
11853
+ };
11854
+ };
11855
+ };
11856
+ };
11857
+ put?: never;
11858
+ post?: never;
11859
+ delete?: never;
11860
+ options?: never;
11861
+ head?: never;
11862
+ patch?: never;
11863
+ trace?: never;
11864
+ };
11865
+ "/admin/crypto/reencrypt": {
10657
11866
  parameters: {
10658
11867
  query?: never;
10659
11868
  header?: never;
@@ -10662,44 +11871,26 @@ interface paths {
10662
11871
  };
10663
11872
  get?: never;
10664
11873
  put?: never;
10665
- post?: never;
10666
- /** Remove an attachment */
10667
- delete: {
11874
+ /** Re-encrypt every plaintext sensitive Config value with the current key */
11875
+ post: {
10668
11876
  parameters: {
10669
11877
  query?: never;
10670
11878
  header?: never;
10671
- path: {
10672
- /** @description Attachment id (24-char hex ObjectId) */
10673
- id: string;
10674
- };
11879
+ path?: never;
10675
11880
  cookie?: never;
10676
11881
  };
10677
11882
  requestBody?: never;
10678
11883
  responses: {
10679
- /** @description Attachment removed */
11884
+ /** @description Migration completed (counts reported) */
10680
11885
  200: {
10681
11886
  headers: {
10682
11887
  [name: string]: unknown;
10683
11888
  };
10684
11889
  content: {
10685
11890
  "application/json": {
10686
- /** @enum {boolean} */
10687
- success: true;
10688
- };
10689
- };
10690
- };
10691
- /** @description Invalid attachment id */
10692
- 400: {
10693
- headers: {
10694
- [name: string]: unknown;
10695
- };
10696
- content: {
10697
- "application/json": {
10698
- error: {
10699
- /** @enum {string} */
10700
- code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
10701
- message: string;
10702
- };
11891
+ rewritten: number;
11892
+ alreadyEncrypted: number;
11893
+ missing: number;
10703
11894
  };
10704
11895
  };
10705
11896
  };
@@ -10720,7 +11911,7 @@ interface paths {
10720
11911
  };
10721
11912
  };
10722
11913
  };
10723
- /** @description Forbidden (kept for legacy parity; current policy only requires view-grant) */
11914
+ /** @description Admin permission required */
10724
11915
  403: {
10725
11916
  headers: {
10726
11917
  [name: string]: unknown;
@@ -10729,23 +11920,10 @@ interface paths {
10729
11920
  "application/json": {
10730
11921
  error: {
10731
11922
  /** @enum {string} */
10732
- code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
10733
- message: string;
10734
- };
10735
- };
10736
- };
10737
- };
10738
- /** @description Attachment not found / page not granted */
10739
- 404: {
10740
- headers: {
10741
- [name: string]: unknown;
10742
- };
10743
- content: {
10744
- "application/json": {
10745
- error: {
11923
+ code: "ADMIN_REQUIRED";
10746
11924
  /** @enum {string} */
10747
- code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
10748
- message: string;
11925
+ message: "Admin permission required";
11926
+ redirectTo?: string;
10749
11927
  };
10750
11928
  };
10751
11929
  };
@@ -10759,59 +11937,15 @@ interface paths {
10759
11937
  "application/json": {
10760
11938
  error: {
10761
11939
  /** @enum {string} */
10762
- code: "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "FILE_MISSING" | "FILE_TOO_LARGE" | "DISALLOWED_MIME" | "INVALID_ATTACHMENT_ID" | "ATTACHMENT_NOT_FOUND" | "FORBIDDEN_FOR_DELETE" | "UPLOAD_FAILED" | "REMOVE_FAILED";
10763
- message: string;
10764
- };
10765
- };
10766
- };
10767
- };
10768
- };
10769
- };
10770
- options?: never;
10771
- head?: never;
10772
- patch?: never;
10773
- trace?: never;
10774
- };
10775
- "/attachments/upload-policy": {
10776
- parameters: {
10777
- query?: never;
10778
- header?: never;
10779
- path?: never;
10780
- cookie?: never;
10781
- };
10782
- /** Get the server upload policy (allowed MIME types, extension hints, size limits) */
10783
- get: {
10784
- parameters: {
10785
- query?: never;
10786
- header?: never;
10787
- path?: never;
10788
- cookie?: never;
10789
- };
10790
- requestBody?: never;
10791
- responses: {
10792
- /** @description Current upload policy, derived from server-side constants (never a value maintained separately) */
10793
- 200: {
10794
- headers: {
10795
- [name: string]: unknown;
10796
- };
10797
- content: {
10798
- "application/json": {
10799
- allowedMimeTypes: string[];
10800
- extensionHints: {
10801
- [key: string]: string;
10802
- };
10803
- maxBytes: {
10804
- attachment: number;
10805
- };
10806
- profilePicture: {
10807
- allowedMimeTypes: string[];
10808
- maxBytes: number;
11940
+ code: "INTERNAL_ERROR";
11941
+ /** @enum {string} */
11942
+ message: "Internal server error";
10809
11943
  };
10810
11944
  };
10811
11945
  };
10812
11946
  };
10813
- /** @description Authentication required */
10814
- 401: {
11947
+ /** @description CROWI_ENCRYPTION_KEY is not configured on the server */
11948
+ 503: {
10815
11949
  headers: {
10816
11950
  [name: string]: unknown;
10817
11951
  };
@@ -10819,39 +11953,32 @@ interface paths {
10819
11953
  "application/json": {
10820
11954
  error: {
10821
11955
  /** @enum {string} */
10822
- code: "AUTHENTICATION_REQUIRED";
10823
- /** @enum {string} */
10824
- message: "Authentication is required";
10825
- redirectTo?: string;
11956
+ code: "ENCRYPTION_NOT_CONFIGURED";
11957
+ message: string;
10826
11958
  };
10827
11959
  };
10828
11960
  };
10829
11961
  };
10830
11962
  };
10831
11963
  };
10832
- put?: never;
10833
- post?: never;
10834
11964
  delete?: never;
10835
11965
  options?: never;
10836
11966
  head?: never;
10837
11967
  patch?: never;
10838
11968
  trace?: never;
10839
11969
  };
10840
- "/search": {
11970
+ "/admin/page-deletions": {
10841
11971
  parameters: {
10842
11972
  query?: never;
10843
11973
  header?: never;
10844
11974
  path?: never;
10845
11975
  cookie?: never;
10846
11976
  };
10847
- /** Full-text search over pages */
11977
+ /** List recent page deletion records or find them by deleted page id */
10848
11978
  get: {
10849
11979
  parameters: {
10850
- query: {
10851
- q: string;
10852
- tree?: string;
10853
- type?: "portal" | "public" | "user";
10854
- page?: number;
11980
+ query?: {
11981
+ pageId?: string;
10855
11982
  limit?: number;
10856
11983
  };
10857
11984
  header?: never;
@@ -10860,135 +11987,27 @@ interface paths {
10860
11987
  };
10861
11988
  requestBody?: never;
10862
11989
  responses: {
10863
- /** @description Ranked search hits joined with page + bookmark count metadata */
11990
+ /** @description Page deletion records */
10864
11991
  200: {
10865
11992
  headers: {
10866
11993
  [name: string]: unknown;
10867
11994
  };
10868
11995
  content: {
10869
11996
  "application/json": {
10870
- meta: {
10871
- took?: number;
10872
- total: number;
10873
- results: number;
10874
- };
10875
- data: {
11997
+ records: {
11998
+ _id: string;
10876
11999
  pageId: string;
10877
12000
  path: string;
10878
- score?: number;
10879
- snippet?: string;
10880
- bookmarkCount: number;
10881
- page: {
10882
- _id: string;
10883
- path: string;
10884
- revision?: string | {
10885
- _id: string;
10886
- path: string;
10887
- body: string;
10888
- /** @default markdown */
10889
- format: string;
10890
- author?: {
10891
- _id: string;
10892
- id?: string;
10893
- username: string;
10894
- name: string;
10895
- /** Format: email */
10896
- email: string;
10897
- image?: string | null;
10898
- createdAt: string;
10899
- } | null;
10900
- createdAt: string;
10901
- meta?: {
10902
- toc?: {
10903
- level: number;
10904
- text: string;
10905
- anchorId: string;
10906
- }[];
10907
- wikiLinks?: {
10908
- raw: string;
10909
- target: string;
10910
- displayText?: string;
10911
- }[];
10912
- mentions?: {
10913
- username: string;
10914
- }[];
10915
- codeBlockLanguages?: string[];
10916
- rawSpaceLinks?: string[];
10917
- };
10918
- renderedAst?: components["schemas"]["RenderedAstEnvelope"] | components["schemas"]["LegacyRenderedAstRoot"];
10919
- renderedAstArtifactKey?: string;
10920
- rendererVersion?: string;
10921
- parentRevisionId?: string | null;
10922
- /** @enum {string} */
10923
- type?: "snapshot" | "incremental";
10924
- savedBy?: string | {
10925
- _id: string;
10926
- id?: string;
10927
- username: string;
10928
- name: string;
10929
- /** Format: email */
10930
- email: string;
10931
- image?: string | null;
10932
- createdAt: string;
10933
- } | null;
10934
- contributors?: (string | {
10935
- _id: string;
10936
- id?: string;
10937
- username: string;
10938
- name: string;
10939
- /** Format: email */
10940
- email: string;
10941
- image?: string | null;
10942
- createdAt: string;
10943
- })[];
10944
- message?: string;
10945
- /** @enum {string} */
10946
- editVia?: "web" | "oauth" | "pat";
10947
- };
10948
- redirectTo?: string | null;
10949
- /** @enum {string|null} */
10950
- status?: "wip" | "published" | "deleted" | "deprecated" | "draft" | null;
10951
- grant?: number;
10952
- grantedUsers?: string[];
10953
- creator?: string | {
10954
- _id: string;
10955
- id?: string;
10956
- username: string;
10957
- name: string;
10958
- /** Format: email */
10959
- email: string;
10960
- image?: string | null;
10961
- createdAt: string;
10962
- } | null;
10963
- lastUpdateUser?: string | {
10964
- _id: string;
10965
- id?: string;
10966
- username: string;
10967
- name: string;
10968
- /** Format: email */
10969
- email: string;
10970
- image?: string | null;
10971
- createdAt: string;
10972
- } | null;
10973
- liker?: string[];
10974
- /** @default 0 */
10975
- commentCount: number;
10976
- extended?: {
10977
- [key: string]: unknown;
10978
- };
10979
- createdAt: string;
10980
- updatedAt?: string;
10981
- currentRevision?: string | null;
10982
- yjsCheckpointAt?: string | null;
10983
- latestRevision?: string;
10984
- likerCount?: number;
10985
- seenUsersCount?: number;
10986
- };
12001
+ actor: string | null;
12002
+ /** Format: date-time */
12003
+ deletedAt: string;
12004
+ /** @enum {string} */
12005
+ mode: "user_hard_delete";
10987
12006
  }[];
10988
12007
  };
10989
12008
  };
10990
12009
  };
10991
- /** @description Validation error (e.g. empty `q`, invalid `type` enum) */
12010
+ /** @description Invalid query */
10992
12011
  400: {
10993
12012
  headers: {
10994
12013
  [name: string]: unknown;
@@ -11026,8 +12045,8 @@ interface paths {
11026
12045
  };
11027
12046
  };
11028
12047
  };
11029
- /** @description Search driver raised an unexpected error */
11030
- 500: {
12048
+ /** @description Admin permission required */
12049
+ 403: {
11031
12050
  headers: {
11032
12051
  [name: string]: unknown;
11033
12052
  };
@@ -11035,15 +12054,16 @@ interface paths {
11035
12054
  "application/json": {
11036
12055
  error: {
11037
12056
  /** @enum {string} */
11038
- code: "INTERNAL_ERROR";
12057
+ code: "ADMIN_REQUIRED";
11039
12058
  /** @enum {string} */
11040
- message: "Internal server error";
12059
+ message: "Admin permission required";
12060
+ redirectTo?: string;
11041
12061
  };
11042
12062
  };
11043
12063
  };
11044
12064
  };
11045
- /** @description No search driver registered (install `@crowi/plugin-search-*`) */
11046
- 503: {
12065
+ /** @description Internal server error */
12066
+ 500: {
11047
12067
  headers: {
11048
12068
  [name: string]: unknown;
11049
12069
  };
@@ -11051,9 +12071,9 @@ interface paths {
11051
12071
  "application/json": {
11052
12072
  error: {
11053
12073
  /** @enum {string} */
11054
- code: "SERVICE_UNAVAILABLE";
11055
- feature: string;
11056
- message: string;
12074
+ code: "INTERNAL_ERROR";
12075
+ /** @enum {string} */
12076
+ message: "Internal server error";
11057
12077
  };
11058
12078
  };
11059
12079
  };
@@ -11062,45 +12082,53 @@ interface paths {
11062
12082
  };
11063
12083
  put?: never;
11064
12084
  post?: never;
11065
- delete?: never;
11066
- options?: never;
11067
- head?: never;
11068
- patch?: never;
11069
- trace?: never;
11070
- };
11071
- "/admin/crypto/status": {
11072
- parameters: {
11073
- query?: never;
11074
- header?: never;
11075
- path?: never;
11076
- cookie?: never;
11077
- };
11078
- /** Report which sensitive Config values are still plaintext */
11079
- get: {
12085
+ /** Erase one deletion record or every record for one exact path */
12086
+ delete: {
11080
12087
  parameters: {
11081
12088
  query?: never;
11082
12089
  header?: never;
11083
12090
  path?: never;
11084
12091
  cookie?: never;
11085
12092
  };
11086
- requestBody?: never;
12093
+ requestBody: {
12094
+ content: {
12095
+ "application/json": {
12096
+ recordId: string;
12097
+ } | {
12098
+ path: string;
12099
+ };
12100
+ };
12101
+ };
11087
12102
  responses: {
11088
- /** @description Per-(ns, key) status for every sensitive Config row */
12103
+ /** @description Number of erased records */
11089
12104
  200: {
11090
12105
  headers: {
11091
12106
  [name: string]: unknown;
11092
12107
  };
11093
12108
  content: {
11094
12109
  "application/json": {
11095
- encryptionConfigured: boolean;
11096
- unencryptedCount: number;
11097
- encryptedCount: number;
11098
- entries: {
11099
- ns: string;
11100
- key: string;
11101
- present: boolean;
11102
- encrypted: boolean;
11103
- }[];
12110
+ deletedCount: number;
12111
+ };
12112
+ };
12113
+ };
12114
+ /** @description A recordId or path selector is required */
12115
+ 400: {
12116
+ headers: {
12117
+ [name: string]: unknown;
12118
+ };
12119
+ content: {
12120
+ "application/json": {
12121
+ error: {
12122
+ /** @enum {string} */
12123
+ code: "VALIDATION_ERROR";
12124
+ message: string;
12125
+ details?: {
12126
+ fieldErrors: {
12127
+ [key: string]: string[];
12128
+ };
12129
+ formErrors: string[];
12130
+ };
12131
+ };
11104
12132
  };
11105
12133
  };
11106
12134
  };
@@ -11138,6 +12166,21 @@ interface paths {
11138
12166
  };
11139
12167
  };
11140
12168
  };
12169
+ /** @description No matching deletion record */
12170
+ 404: {
12171
+ headers: {
12172
+ [name: string]: unknown;
12173
+ };
12174
+ content: {
12175
+ "application/json": {
12176
+ error: {
12177
+ /** @enum {string} */
12178
+ code: "NOT_FOUND";
12179
+ message: string;
12180
+ };
12181
+ };
12182
+ };
12183
+ };
11141
12184
  /** @description Internal server error */
11142
12185
  500: {
11143
12186
  headers: {
@@ -11156,43 +12199,69 @@ interface paths {
11156
12199
  };
11157
12200
  };
11158
12201
  };
11159
- put?: never;
11160
- post?: never;
11161
- delete?: never;
11162
12202
  options?: never;
11163
12203
  head?: never;
11164
12204
  patch?: never;
11165
12205
  trace?: never;
11166
12206
  };
11167
- "/admin/crypto/reencrypt": {
12207
+ "/admin/page-deletions/by-path": {
11168
12208
  parameters: {
11169
12209
  query?: never;
11170
12210
  header?: never;
11171
12211
  path?: never;
11172
12212
  cookie?: never;
11173
12213
  };
11174
- get?: never;
11175
- put?: never;
11176
- /** Re-encrypt every plaintext sensitive Config value with the current key */
11177
- post: {
12214
+ /** List deletion records for one exact historical path */
12215
+ get: {
11178
12216
  parameters: {
11179
- query?: never;
12217
+ query: {
12218
+ path: string;
12219
+ limit?: number;
12220
+ };
11180
12221
  header?: never;
11181
12222
  path?: never;
11182
12223
  cookie?: never;
11183
12224
  };
11184
12225
  requestBody?: never;
11185
12226
  responses: {
11186
- /** @description Migration completed (counts reported) */
12227
+ /** @description Page deletion records for the path */
11187
12228
  200: {
11188
12229
  headers: {
11189
12230
  [name: string]: unknown;
11190
12231
  };
11191
12232
  content: {
11192
12233
  "application/json": {
11193
- rewritten: number;
11194
- alreadyEncrypted: number;
11195
- missing: number;
12234
+ records: {
12235
+ _id: string;
12236
+ pageId: string;
12237
+ path: string;
12238
+ actor: string | null;
12239
+ /** Format: date-time */
12240
+ deletedAt: string;
12241
+ /** @enum {string} */
12242
+ mode: "user_hard_delete";
12243
+ }[];
12244
+ };
12245
+ };
12246
+ };
12247
+ /** @description Invalid query */
12248
+ 400: {
12249
+ headers: {
12250
+ [name: string]: unknown;
12251
+ };
12252
+ content: {
12253
+ "application/json": {
12254
+ error: {
12255
+ /** @enum {string} */
12256
+ code: "VALIDATION_ERROR";
12257
+ message: string;
12258
+ details?: {
12259
+ fieldErrors: {
12260
+ [key: string]: string[];
12261
+ };
12262
+ formErrors: string[];
12263
+ };
12264
+ };
11196
12265
  };
11197
12266
  };
11198
12267
  };
@@ -11246,23 +12315,10 @@ interface paths {
11246
12315
  };
11247
12316
  };
11248
12317
  };
11249
- /** @description CROWI_ENCRYPTION_KEY is not configured on the server */
11250
- 503: {
11251
- headers: {
11252
- [name: string]: unknown;
11253
- };
11254
- content: {
11255
- "application/json": {
11256
- error: {
11257
- /** @enum {string} */
11258
- code: "ENCRYPTION_NOT_CONFIGURED";
11259
- message: string;
11260
- };
11261
- };
11262
- };
11263
- };
11264
12318
  };
11265
12319
  };
12320
+ put?: never;
12321
+ post?: never;
11266
12322
  delete?: never;
11267
12323
  options?: never;
11268
12324
  head?: never;
@@ -11424,6 +12480,22 @@ interface paths {
11424
12480
  };
11425
12481
  };
11426
12482
  };
12483
+ /** @description Internal server error */
12484
+ 500: {
12485
+ headers: {
12486
+ [name: string]: unknown;
12487
+ };
12488
+ content: {
12489
+ "application/json": {
12490
+ error: {
12491
+ /** @enum {string} */
12492
+ code: "INTERNAL_ERROR";
12493
+ /** @enum {string} */
12494
+ message: "Internal server error";
12495
+ };
12496
+ };
12497
+ };
12498
+ };
11427
12499
  };
11428
12500
  };
11429
12501
  post?: never;
@@ -11937,6 +13009,22 @@ interface paths {
11937
13009
  };
11938
13010
  };
11939
13011
  };
13012
+ /** @description Internal server error */
13013
+ 500: {
13014
+ headers: {
13015
+ [name: string]: unknown;
13016
+ };
13017
+ content: {
13018
+ "application/json": {
13019
+ error: {
13020
+ /** @enum {string} */
13021
+ code: "INTERNAL_ERROR";
13022
+ /** @enum {string} */
13023
+ message: "Internal server error";
13024
+ };
13025
+ };
13026
+ };
13027
+ };
11940
13028
  };
11941
13029
  };
11942
13030
  post?: never;
@@ -14362,11 +15450,12 @@ interface paths {
14362
15450
  values: {
14363
15451
  [key: string]: unknown;
14364
15452
  };
15453
+ confirmLinkedIdentities?: boolean;
14365
15454
  };
14366
15455
  };
14367
15456
  };
14368
15457
  responses: {
14369
- /** @description Save succeeded; hotReloaded flag indicates live apply */
15458
+ /** @description Save succeeded; hotReloaded flag indicates live apply. verificationResults (feature-plugin-config-live-verification) carries non-blocking connectivity/permission probe results for the changed plugin and its dependents, run after this save already persisted and reconfigured — empty on a no-op save or when no affected plugin declares verifyConfig, optional on the wire for rolling-deploy compat with an older api replica, and reflects only the instance that answered this request (never a cluster-wide aggregate). */
14370
15459
  200: {
14371
15460
  headers: {
14372
15461
  [name: string]: unknown;
@@ -14377,6 +15466,17 @@ interface paths {
14377
15466
  ok: true;
14378
15467
  hotReloaded: boolean;
14379
15468
  reconfigureFailed: boolean;
15469
+ verificationResults?: ({
15470
+ plugin: string;
15471
+ /** @enum {string} */
15472
+ status: "ok";
15473
+ } | {
15474
+ plugin: string;
15475
+ /** @enum {string} */
15476
+ status: "failed";
15477
+ /** @enum {string} */
15478
+ reason: "unreachable" | "auth-failed" | "resource-missing" | "write-denied" | "unknown";
15479
+ })[];
14380
15480
  };
14381
15481
  };
14382
15482
  };
@@ -14429,6 +15529,22 @@ interface paths {
14429
15529
  };
14430
15530
  };
14431
15531
  };
15532
+ /** @description The save rewrites a credential atomic group and users are linked through this plugin's auth driver(s); resubmit with confirmLinkedIdentities: true to proceed */
15533
+ 409: {
15534
+ headers: {
15535
+ [name: string]: unknown;
15536
+ };
15537
+ content: {
15538
+ "application/json": {
15539
+ error: {
15540
+ /** @enum {string} */
15541
+ code: "LINKED_IDENTITIES_EXIST";
15542
+ message: string;
15543
+ count: number;
15544
+ };
15545
+ };
15546
+ };
15547
+ };
14432
15548
  /** @description Plugin config failed plugin-defined validation */
14433
15549
  422: {
14434
15550
  headers: {
@@ -15234,7 +16350,7 @@ interface components {
15234
16350
  };
15235
16351
  };
15236
16352
  /** @enum {string} */
15237
- ErrorCode: "AUTHENTICATION_REQUIRED" | "ADMIN_REQUIRED" | "THIRD_PARTY_AUTH_REQUIRED" | "USER_REGISTERED" | "USER_SUSPENDED" | "USER_INVITED" | "USER_NOT_ACTIVE" | "EMAIL_NOT_CONFIRMED" | "INTERNAL_ERROR" | "VALIDATION_ERROR" | "INVALID_REQUEST" | "NOT_FOUND" | "CONFLICT" | "SERVICE_UNAVAILABLE" | "APPLICATION_NOT_INSTALLED" | "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "PAGE_NOT_GRANTED" | "PAGE_REVISION_ERROR" | "PAGE_TWIN_EXISTS" | "INVALID_GRANT" | "COMMENT_NOT_FOUND" | "NOTIFICATION_NOT_FOUND" | "USER_NOT_FOUND" | "USER_EXISTS" | "USERNAME_TAKEN" | "EMAIL_TAKEN" | "EMAIL_NOT_ALLOWED" | "INVALID_ACTIVATION_TOKEN" | "INVALID_INVITE_TOKEN" | "INVITE_ALREADY_ACCEPTED" | "INVALID_RESET_TOKEN" | "INVALID_EMAIL_CHANGE_TOKEN" | "INVALID_CREDENTIALS" | "REFRESH_TOKEN_REQUIRED" | "REGISTRATION_CLOSED" | "FEDERATED_HANDOFF_INVALID" | "FEDERATED_HANDOFF_CONSUMED" | "ENCRYPTION_NOT_CONFIGURED" | "MAIL_FROM_NOT_CONFIGURED" | "MAIL_TEST_FAILED" | "PLUGIN_NOT_FOUND" | "PLUGIN_CONFIG_VALIDATION_FAILED";
16353
+ ErrorCode: "AUTHENTICATION_REQUIRED" | "ADMIN_REQUIRED" | "THIRD_PARTY_AUTH_REQUIRED" | "USER_REGISTERED" | "USER_SUSPENDED" | "USER_INVITED" | "USER_NOT_ACTIVE" | "EMAIL_NOT_CONFIRMED" | "INTERNAL_ERROR" | "VALIDATION_ERROR" | "INVALID_REQUEST" | "NOT_FOUND" | "CONFLICT" | "SERVICE_UNAVAILABLE" | "APPLICATION_NOT_INSTALLED" | "INVALID_PAGE_ID" | "PAGE_NOT_FOUND" | "PAGE_NOT_GRANTED" | "PAGE_REVISION_ERROR" | "PAGE_TWIN_EXISTS" | "INVALID_GRANT" | "IDEMPOTENCY_KEY_REQUIRED" | "IDEMPOTENCY_KEY_CONFLICT" | "PAGE_TRANSITION_IN_PROGRESS" | "PAGE_TRANSITION_INCOMPLETE" | "COMMENT_NOT_FOUND" | "NOTIFICATION_NOT_FOUND" | "USER_NOT_FOUND" | "USER_EXISTS" | "USERNAME_TAKEN" | "EMAIL_TAKEN" | "EMAIL_NOT_ALLOWED" | "INVALID_ACTIVATION_TOKEN" | "INVALID_INVITE_TOKEN" | "INVITE_ALREADY_ACCEPTED" | "INVALID_RESET_TOKEN" | "INVALID_EMAIL_CHANGE_TOKEN" | "INVALID_CREDENTIALS" | "REFRESH_TOKEN_REQUIRED" | "REGISTRATION_CLOSED" | "FEDERATED_HANDOFF_INVALID" | "FEDERATED_HANDOFF_CONSUMED" | "FEDERATED_IDENTITY_IN_USE" | "FEDERATED_LINK_AUTH_STATE_CHANGED" | "FEDERATED_LINK_NOT_LINKED" | "LINK_COMPLETION_CONSUMED" | "ENCRYPTION_NOT_CONFIGURED" | "MAIL_FROM_NOT_CONFIGURED" | "MAIL_TEST_FAILED" | "PLUGIN_NOT_FOUND" | "PLUGIN_CONFIG_VALIDATION_FAILED" | "LINKED_IDENTITIES_EXIST";
15238
16354
  ApplicationNotInstalledError: {
15239
16355
  error: {
15240
16356
  /** @enum {string} */
@@ -15415,6 +16531,32 @@ interface components {
15415
16531
  /** @enum {string} */
15416
16532
  status: "approved" | "denied";
15417
16533
  };
16534
+ OAuthSession: {
16535
+ id: string;
16536
+ clientId: string;
16537
+ clientName: string;
16538
+ scopes: string[];
16539
+ /** Format: date-time */
16540
+ authorizedAt: string;
16541
+ /** Format: date-time */
16542
+ lastRefreshedAt: string;
16543
+ /** Format: date-time */
16544
+ expiresAt: string;
16545
+ };
16546
+ ListOAuthSessionsResponse: {
16547
+ oauthSessions: {
16548
+ id: string;
16549
+ clientId: string;
16550
+ clientName: string;
16551
+ scopes: string[];
16552
+ /** Format: date-time */
16553
+ authorizedAt: string;
16554
+ /** Format: date-time */
16555
+ lastRefreshedAt: string;
16556
+ /** Format: date-time */
16557
+ expiresAt: string;
16558
+ }[];
16559
+ };
15418
16560
  ClientInfoResponse: {
15419
16561
  clientId: string;
15420
16562
  name: string;
@@ -16974,12 +18116,24 @@ interface components {
16974
18116
  values: {
16975
18117
  [key: string]: unknown;
16976
18118
  };
18119
+ confirmLinkedIdentities?: boolean;
16977
18120
  };
16978
18121
  UpdatePluginConfigResponse: {
16979
18122
  /** @enum {boolean} */
16980
18123
  ok: true;
16981
18124
  hotReloaded: boolean;
16982
18125
  reconfigureFailed: boolean;
18126
+ verificationResults?: ({
18127
+ plugin: string;
18128
+ /** @enum {string} */
18129
+ status: "ok";
18130
+ } | {
18131
+ plugin: string;
18132
+ /** @enum {string} */
18133
+ status: "failed";
18134
+ /** @enum {string} */
18135
+ reason: "unreachable" | "auth-failed" | "resource-missing" | "write-denied" | "unknown";
18136
+ })[];
16983
18137
  };
16984
18138
  PluginNotFoundError: {
16985
18139
  error: {
@@ -17001,6 +18155,97 @@ interface components {
17001
18155
  };
17002
18156
  /** @enum {string} */
17003
18157
  Capability: "oauth" | "oauth:auth-code" | "oauth:device" | "oauth:pkce" | "pat" | "pages" | "comments" | "bookmarks" | "attachments" | "notifications" | "search" | "collab" | "collab:redis" | "link-card";
18158
+ PageHistoryResponse: {
18159
+ entries: components["schemas"]["PageHistoryEntry"][];
18160
+ nextCursor: string | null;
18161
+ tracking: components["schemas"]["PageHistoryTracking"];
18162
+ };
18163
+ PageHistoryEntry: components["schemas"]["PageHistoryContentRow"] | components["schemas"]["PageHistoryEventRow"];
18164
+ PageHistoryContentRow: {
18165
+ /** @example 66a1f2c3d4e5f60718293a4b */
18166
+ id: string;
18167
+ sequence: number | null;
18168
+ /** Format: date-time */
18169
+ occurredAt: string;
18170
+ actor: {
18171
+ _id: string;
18172
+ id?: string;
18173
+ username: string;
18174
+ name: string;
18175
+ /** Format: email */
18176
+ email: string;
18177
+ image?: string | null;
18178
+ createdAt: string;
18179
+ } | null;
18180
+ /**
18181
+ * @description discriminator enum property added by openapi-typescript
18182
+ * @enum {string}
18183
+ */
18184
+ type: "content_revision";
18185
+ revisionId: string;
18186
+ savedBy?: {
18187
+ _id: string;
18188
+ id?: string;
18189
+ username: string;
18190
+ name: string;
18191
+ /** Format: email */
18192
+ email: string;
18193
+ image?: string | null;
18194
+ createdAt: string;
18195
+ } | null;
18196
+ contributors?: {
18197
+ _id: string;
18198
+ id?: string;
18199
+ username: string;
18200
+ name: string;
18201
+ /** Format: email */
18202
+ email: string;
18203
+ image?: string | null;
18204
+ createdAt: string;
18205
+ }[];
18206
+ /** @enum {string} */
18207
+ editVia?: "web" | "oauth" | "pat";
18208
+ pending?: boolean;
18209
+ };
18210
+ PageHistoryEventRow: {
18211
+ /** @example 66a1f2c3d4e5f60718293a4b */
18212
+ id: string;
18213
+ sequence: number | null;
18214
+ /** Format: date-time */
18215
+ occurredAt: string;
18216
+ actor: {
18217
+ _id: string;
18218
+ id?: string;
18219
+ username: string;
18220
+ name: string;
18221
+ /** Format: email */
18222
+ email: string;
18223
+ image?: string | null;
18224
+ createdAt: string;
18225
+ } | null;
18226
+ /**
18227
+ * @description discriminator enum property added by openapi-typescript
18228
+ * @enum {string}
18229
+ */
18230
+ type: "page_event";
18231
+ /** @enum {string} */
18232
+ kind: "page_created" | "page_renamed" | "visibility_changed" | "page_trashed" | "page_restored" | "draft_published";
18233
+ payload: {
18234
+ [key: string]: unknown;
18235
+ };
18236
+ operationId: string | null;
18237
+ subtree?: boolean;
18238
+ pending?: boolean;
18239
+ };
18240
+ PageHistoryTracking: {
18241
+ /** @enum {string} */
18242
+ state: "ready";
18243
+ /** Format: date-time */
18244
+ trackingStartedAt: string;
18245
+ } | {
18246
+ /** @enum {string} */
18247
+ state: "untracked";
18248
+ };
17004
18249
  };
17005
18250
  responses: never;
17006
18251
  parameters: never;