@runlot/api 0.1.0-rc.38 → 0.1.0-rc.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +356 -8
- package/dist/schema.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/schema.d.ts
CHANGED
|
@@ -1399,10 +1399,14 @@ export interface paths {
|
|
|
1399
1399
|
get: operations["listMembers"];
|
|
1400
1400
|
put?: never;
|
|
1401
1401
|
/**
|
|
1402
|
-
* 기존 사용자를 멤버로 넣는다 (
|
|
1403
|
-
* @description **초대가
|
|
1404
|
-
*
|
|
1405
|
-
*
|
|
1402
|
+
* 기존 사용자를 멤버로 넣는다 (운영·자동화용)
|
|
1403
|
+
* @description **초대가 아니다.** 사용자는 이미 한 번 로그인해 `users` 에 있어야 하고
|
|
1404
|
+
* (`provider`+`subject` 로 가리킨다), 없으면 404 `user_not_found`. 이미
|
|
1405
|
+
* 멤버면 409 `already_member` — 역할을 바꾸는 것은 PUT 이다.
|
|
1406
|
+
*
|
|
1407
|
+
* 사람을 부르는 표면은 이것이 아니라 `POST …/invites` 다
|
|
1408
|
+
* (docs/members.md): GitHub 의 `subject` 는 숫자 id 라 관리자가 알 수
|
|
1409
|
+
* 없는 값이고, 이 끝점은 그것을 이미 아는 자동화의 것이다.
|
|
1406
1410
|
*
|
|
1407
1411
|
* admin 이상. 감사 `member.add`.
|
|
1408
1412
|
*/
|
|
@@ -1413,6 +1417,133 @@ export interface paths {
|
|
|
1413
1417
|
patch?: never;
|
|
1414
1418
|
trace?: never;
|
|
1415
1419
|
};
|
|
1420
|
+
"/v1/orgs/{orgSlug}/invites": {
|
|
1421
|
+
parameters: {
|
|
1422
|
+
query?: never;
|
|
1423
|
+
header?: never;
|
|
1424
|
+
path: {
|
|
1425
|
+
orgSlug: components["parameters"]["OrgSlug"];
|
|
1426
|
+
};
|
|
1427
|
+
cookie?: never;
|
|
1428
|
+
};
|
|
1429
|
+
/**
|
|
1430
|
+
* 대기 중인 초대 (`runlot member invites`)
|
|
1431
|
+
* @description **admin 이상.** 멤버 목록은 member 이상이 보지만 초대 목록은 다르다 —
|
|
1432
|
+
* 아직 조직에 없는 사람들의 이메일이고, 그것은 명부가 아니라 관리 작업의
|
|
1433
|
+
* 상태다.
|
|
1434
|
+
*
|
|
1435
|
+
* 수락·폐기된 초대는 안 나온다 (이력의 자리는 감사 기록이다). 만료된
|
|
1436
|
+
* 초대는 나온다 — 거기서 관리자가 할 일이 재발송이다.
|
|
1437
|
+
*/
|
|
1438
|
+
get: operations["listInvites"];
|
|
1439
|
+
put?: never;
|
|
1440
|
+
/**
|
|
1441
|
+
* 이메일로 초대한다 (`runlot member invite`)
|
|
1442
|
+
* @description admin 이상. 메일은 즉시 나가지 않는다 — cp-core 의 발송 회차가 큐를
|
|
1443
|
+
* 훑는다 (`sentAt` 이 비어 있으면 아직 큐에 있다는 뜻이다).
|
|
1444
|
+
*
|
|
1445
|
+
* **같은 주소로 다시 부르면 재발송이다**: 새 초대가 아니라 같은 행이
|
|
1446
|
+
* 갱신되고 (토큰·만료가 새로 서고 역할이 바뀐다) 200 으로 답한다. 새
|
|
1447
|
+
* 초대는 201 이다.
|
|
1448
|
+
*
|
|
1449
|
+
* 이미 멤버인 주소는 409 `already_member`. 대기 중 초대가 너무 많으면
|
|
1450
|
+
* 409 `too_many_invites` — 요금제 한도가 아니라 발신 남용 방지다.
|
|
1451
|
+
*
|
|
1452
|
+
* 수명은 이레, 한 번 쓰면 끝, 언제든 폐기할 수 있다. 감사 `member.invite`.
|
|
1453
|
+
*/
|
|
1454
|
+
post: operations["createInvite"];
|
|
1455
|
+
delete?: never;
|
|
1456
|
+
options?: never;
|
|
1457
|
+
head?: never;
|
|
1458
|
+
patch?: never;
|
|
1459
|
+
trace?: never;
|
|
1460
|
+
};
|
|
1461
|
+
"/v1/orgs/{orgSlug}/invites/{inviteId}": {
|
|
1462
|
+
parameters: {
|
|
1463
|
+
query?: never;
|
|
1464
|
+
header?: never;
|
|
1465
|
+
path: {
|
|
1466
|
+
orgSlug: components["parameters"]["OrgSlug"];
|
|
1467
|
+
inviteId: string;
|
|
1468
|
+
};
|
|
1469
|
+
cookie?: never;
|
|
1470
|
+
};
|
|
1471
|
+
get?: never;
|
|
1472
|
+
put?: never;
|
|
1473
|
+
post?: never;
|
|
1474
|
+
/**
|
|
1475
|
+
* 초대를 취소한다 (`runlot member uninvite`)
|
|
1476
|
+
* @description admin 이상. 아직 안 나간 메일은 **안 나간다** — 폐기가 발송 큐도 비운다.
|
|
1477
|
+
* 이미 수락·폐기된 초대는 404. 감사 `member.uninvite`.
|
|
1478
|
+
*/
|
|
1479
|
+
delete: operations["revokeInvite"];
|
|
1480
|
+
options?: never;
|
|
1481
|
+
head?: never;
|
|
1482
|
+
patch?: never;
|
|
1483
|
+
trace?: never;
|
|
1484
|
+
};
|
|
1485
|
+
"/v1/invites/{token}": {
|
|
1486
|
+
parameters: {
|
|
1487
|
+
query?: never;
|
|
1488
|
+
header?: never;
|
|
1489
|
+
path: {
|
|
1490
|
+
token: string;
|
|
1491
|
+
};
|
|
1492
|
+
cookie?: never;
|
|
1493
|
+
};
|
|
1494
|
+
/**
|
|
1495
|
+
* 초대 미리보기 (인증 없음)
|
|
1496
|
+
* @description **인증이 없다.** 초대 링크를 받은 사람은 아직 로그인하지 않았고, 로그인
|
|
1497
|
+
* 하기 전에 이것이 무엇인지 알아야 한다. 토큰은 32 바이트 난수라 열거할
|
|
1498
|
+
* 수 없고, 그래서 여는 대가가 "우리가 메일을 보낸 사람이 조직 이름을
|
|
1499
|
+
* 본다" 로 끝난다.
|
|
1500
|
+
*
|
|
1501
|
+
* **상태는 오류가 아니라 값이다** (`state`). 만료된 초대에 404 를 주면
|
|
1502
|
+
* 화면이 "링크가 틀렸다" 와 "링크가 늙었다" 를 구분하지 못한다.
|
|
1503
|
+
*
|
|
1504
|
+
* 모르는 토큰은 404 — 오래전에 폐기된 토큰과 같은 답이다.
|
|
1505
|
+
*/
|
|
1506
|
+
get: operations["getInvite"];
|
|
1507
|
+
put?: never;
|
|
1508
|
+
post?: never;
|
|
1509
|
+
delete?: never;
|
|
1510
|
+
options?: never;
|
|
1511
|
+
head?: never;
|
|
1512
|
+
patch?: never;
|
|
1513
|
+
trace?: never;
|
|
1514
|
+
};
|
|
1515
|
+
"/v1/invites/{token}/accept": {
|
|
1516
|
+
parameters: {
|
|
1517
|
+
query?: never;
|
|
1518
|
+
header?: never;
|
|
1519
|
+
path: {
|
|
1520
|
+
token: string;
|
|
1521
|
+
};
|
|
1522
|
+
cookie?: never;
|
|
1523
|
+
};
|
|
1524
|
+
get?: never;
|
|
1525
|
+
put?: never;
|
|
1526
|
+
/**
|
|
1527
|
+
* 초대를 수락한다
|
|
1528
|
+
* @description 로그인이 필요하다. **로그인한 계정의 이메일이 초대한 주소와 같아야
|
|
1529
|
+
* 한다는 규칙은 없다** — GitHub 비공개 이메일로 로그인한 사람은
|
|
1530
|
+
* `users.email` 이 아예 없고, 그 규칙을 넣으면 그 사람은 어떤 조직에도
|
|
1531
|
+
* 들어올 수 없다. 대신 수명 이레 · 한 번 쓰면 끝 · 언제든 폐기이고,
|
|
1532
|
+
* 감사 기록에 초대한 주소와 수락한 계정이 **둘 다** 남는다.
|
|
1533
|
+
*
|
|
1534
|
+
* **이미 멤버면 역할이 안 바뀐다** (`alreadyMember: true`). 초대장 하나가
|
|
1535
|
+
* admin 을 강등하는 표면이 되면 그 강등은 마지막-admin 검사를 지나지
|
|
1536
|
+
* 않는다.
|
|
1537
|
+
*
|
|
1538
|
+
* 감사 `member.accept`.
|
|
1539
|
+
*/
|
|
1540
|
+
post: operations["acceptInvite"];
|
|
1541
|
+
delete?: never;
|
|
1542
|
+
options?: never;
|
|
1543
|
+
head?: never;
|
|
1544
|
+
patch?: never;
|
|
1545
|
+
trace?: never;
|
|
1546
|
+
};
|
|
1416
1547
|
"/v1/orgs/{orgSlug}/members/{userId}": {
|
|
1417
1548
|
parameters: {
|
|
1418
1549
|
query?: never;
|
|
@@ -1434,9 +1565,14 @@ export interface paths {
|
|
|
1434
1565
|
put: operations["setMemberRole"];
|
|
1435
1566
|
post?: never;
|
|
1436
1567
|
/**
|
|
1437
|
-
* 멤버를 뺀다 (`runlot
|
|
1438
|
-
* @description
|
|
1439
|
-
* `
|
|
1568
|
+
* 멤버를 뺀다 · 스스로 나간다 (`runlot member rm`, `runlot member leave`)
|
|
1569
|
+
* @description **남을 빼는 것은 admin 이상, 자기를 빼는 것은 누구나** 할 수 있다
|
|
1570
|
+
* (`userId` 가 자기 자신이면 탈퇴다). admin 만 뺄 수 있게 두면 viewer 로
|
|
1571
|
+
* 초대된 사람이 조직을 나갈 길이 아예 없다.
|
|
1572
|
+
*
|
|
1573
|
+
* 마지막 admin 은 뺄 수도 나갈 수도 없다 (409 `last_admin`). 감사는
|
|
1574
|
+
* 제거가 `member.remove`, 탈퇴가 `member.leave` — 같은 문장이지만 다른
|
|
1575
|
+
* 사건이라 이름이 갈린다.
|
|
1440
1576
|
*/
|
|
1441
1577
|
delete: operations["removeMember"];
|
|
1442
1578
|
options?: never;
|
|
@@ -2522,7 +2658,7 @@ export interface components {
|
|
|
2522
2658
|
* 읽을 문장은 대시보드와 메일 템플릿이 각각 만든다.
|
|
2523
2659
|
* @enum {string}
|
|
2524
2660
|
*/
|
|
2525
|
-
kind: "project_limit" | "db_near_cap" | "storage_near_quota" | "backup_failed" | "restore_done" | "dns_publish_stalled";
|
|
2661
|
+
kind: "project_limit" | "db_near_cap" | "storage_near_quota" | "backup_failed" | "restore_done" | "dns_publish_stalled" | "billing_past_due";
|
|
2526
2662
|
/** @description 프로젝트 관련 알림이면 해당 프로젝트 이름. 조직 알림(`project_limit`)에는 없다 */
|
|
2527
2663
|
projectName?: string;
|
|
2528
2664
|
/** @description 종류별 중복 제거 키. 같은 (kind, key)는 24시간에 하나만 생성된다 */
|
|
@@ -3026,6 +3162,53 @@ export interface components {
|
|
|
3026
3162
|
/** Format: date-time */
|
|
3027
3163
|
addedAt: string;
|
|
3028
3164
|
};
|
|
3165
|
+
/**
|
|
3166
|
+
* @description `expired` 는 시각 비교의 결과이지 열이 아니다 — 초대는 만료되었다고
|
|
3167
|
+
* 표시되지 않고, 만료 시각이 지났을 뿐이다.
|
|
3168
|
+
* @enum {string}
|
|
3169
|
+
*/
|
|
3170
|
+
InviteState: "pending" | "expired" | "accepted" | "revoked";
|
|
3171
|
+
/**
|
|
3172
|
+
* @description **토큰이 없다.** 평문 토큰은 메일에만 실리고, cp-public 은 그 열을 읽지도
|
|
3173
|
+
* 못한다 (마이그레이션 0043 의 열 단위 GRANT).
|
|
3174
|
+
*/
|
|
3175
|
+
Invite: {
|
|
3176
|
+
/** Format: uuid */
|
|
3177
|
+
inviteId: string;
|
|
3178
|
+
/** Format: email */
|
|
3179
|
+
email: string;
|
|
3180
|
+
role: components["schemas"]["Role"];
|
|
3181
|
+
state: components["schemas"]["InviteState"];
|
|
3182
|
+
/** @description 부른 사람의 이름 또는 이메일. */
|
|
3183
|
+
invitedBy?: string;
|
|
3184
|
+
/** Format: date-time */
|
|
3185
|
+
createdAt: string;
|
|
3186
|
+
/** Format: date-time */
|
|
3187
|
+
expiresAt: string;
|
|
3188
|
+
/**
|
|
3189
|
+
* Format: date-time
|
|
3190
|
+
* @description 비어 있으면 아직 발송 큐에 있다 (발송은 cp-core 의 회차다).
|
|
3191
|
+
*/
|
|
3192
|
+
sentAt?: string;
|
|
3193
|
+
/** @description 마지막 발송 실패 이유. 성공해도 남을 수 있다. */
|
|
3194
|
+
sendError?: string;
|
|
3195
|
+
};
|
|
3196
|
+
/** @description 토큰을 든 사람에게 보이는 초대 (인증 없이 답한다). */
|
|
3197
|
+
InviteView: {
|
|
3198
|
+
orgSlug: string;
|
|
3199
|
+
orgName: string;
|
|
3200
|
+
role: components["schemas"]["Role"];
|
|
3201
|
+
/**
|
|
3202
|
+
* Format: email
|
|
3203
|
+
* @description **초대를 보낸 주소**다. 수락하는 계정의 주소와 다를 수 있고, 화면은
|
|
3204
|
+
* 그 사실을 말해야 한다.
|
|
3205
|
+
*/
|
|
3206
|
+
email: string;
|
|
3207
|
+
invitedBy?: string;
|
|
3208
|
+
state: components["schemas"]["InviteState"];
|
|
3209
|
+
/** Format: date-time */
|
|
3210
|
+
expiresAt: string;
|
|
3211
|
+
};
|
|
3029
3212
|
/**
|
|
3030
3213
|
* @description 워커의 `env.<NAME>` 이 된다. `DB`·`ASSETS`(바인딩 `env.db`·`env.assets` 의 대문자 짝) 와 `RUNLOT_` 접두는 예약이다
|
|
3031
3214
|
* — 앞 둘은 이미 바인딩이고, 뒤는 노드가 프로세스 환경에 쓰는 이름
|
|
@@ -3230,6 +3413,8 @@ export interface components {
|
|
|
3230
3413
|
periodEnd?: string;
|
|
3231
3414
|
/** @description 결제 이력이 있어 포털을 열 수 있다 */
|
|
3232
3415
|
hasPortal: boolean;
|
|
3416
|
+
/** @description 지금 프로젝트 수. 무료로 내려간 뒤 한도를 넘긴 상태를 화면이 말한다 — 넘긴 것은 지우지 않고 새 생성만 막힌다 */
|
|
3417
|
+
projectCount: number;
|
|
3233
3418
|
limits: {
|
|
3234
3419
|
free: components["schemas"]["PlanLimits"];
|
|
3235
3420
|
pro: components["schemas"]["PlanLimits"];
|
|
@@ -5952,6 +6137,169 @@ export interface operations {
|
|
|
5952
6137
|
};
|
|
5953
6138
|
};
|
|
5954
6139
|
};
|
|
6140
|
+
listInvites: {
|
|
6141
|
+
parameters: {
|
|
6142
|
+
query?: never;
|
|
6143
|
+
header?: never;
|
|
6144
|
+
path: {
|
|
6145
|
+
orgSlug: components["parameters"]["OrgSlug"];
|
|
6146
|
+
};
|
|
6147
|
+
cookie?: never;
|
|
6148
|
+
};
|
|
6149
|
+
requestBody?: never;
|
|
6150
|
+
responses: {
|
|
6151
|
+
/** @description 초대 목록 */
|
|
6152
|
+
200: {
|
|
6153
|
+
headers: {
|
|
6154
|
+
[name: string]: unknown;
|
|
6155
|
+
};
|
|
6156
|
+
content: {
|
|
6157
|
+
"application/json": {
|
|
6158
|
+
invites: components["schemas"]["Invite"][];
|
|
6159
|
+
};
|
|
6160
|
+
};
|
|
6161
|
+
};
|
|
6162
|
+
403: components["responses"]["Forbidden"];
|
|
6163
|
+
404: components["responses"]["NotFound"];
|
|
6164
|
+
};
|
|
6165
|
+
};
|
|
6166
|
+
createInvite: {
|
|
6167
|
+
parameters: {
|
|
6168
|
+
query?: never;
|
|
6169
|
+
header?: never;
|
|
6170
|
+
path: {
|
|
6171
|
+
orgSlug: components["parameters"]["OrgSlug"];
|
|
6172
|
+
};
|
|
6173
|
+
cookie?: never;
|
|
6174
|
+
};
|
|
6175
|
+
requestBody: {
|
|
6176
|
+
content: {
|
|
6177
|
+
"application/json": {
|
|
6178
|
+
/** Format: email */
|
|
6179
|
+
email: string;
|
|
6180
|
+
/** @description 기본값 `member`. */
|
|
6181
|
+
role?: components["schemas"]["Role"];
|
|
6182
|
+
};
|
|
6183
|
+
};
|
|
6184
|
+
};
|
|
6185
|
+
responses: {
|
|
6186
|
+
/** @description 기존 초대를 다시 보냈다 */
|
|
6187
|
+
200: {
|
|
6188
|
+
headers: {
|
|
6189
|
+
[name: string]: unknown;
|
|
6190
|
+
};
|
|
6191
|
+
content: {
|
|
6192
|
+
"application/json": components["schemas"]["Invite"];
|
|
6193
|
+
};
|
|
6194
|
+
};
|
|
6195
|
+
/** @description 새 초대 */
|
|
6196
|
+
201: {
|
|
6197
|
+
headers: {
|
|
6198
|
+
[name: string]: unknown;
|
|
6199
|
+
};
|
|
6200
|
+
content: {
|
|
6201
|
+
"application/json": components["schemas"]["Invite"];
|
|
6202
|
+
};
|
|
6203
|
+
};
|
|
6204
|
+
400: components["responses"]["BadRequest"];
|
|
6205
|
+
403: components["responses"]["Forbidden"];
|
|
6206
|
+
404: components["responses"]["NotFound"];
|
|
6207
|
+
/** @description 이미 멤버다 (`already_member`) · 대기 초대가 너무 많다 (`too_many_invites`) */
|
|
6208
|
+
409: {
|
|
6209
|
+
headers: {
|
|
6210
|
+
[name: string]: unknown;
|
|
6211
|
+
};
|
|
6212
|
+
content: {
|
|
6213
|
+
"application/json": components["schemas"]["Error"];
|
|
6214
|
+
};
|
|
6215
|
+
};
|
|
6216
|
+
};
|
|
6217
|
+
};
|
|
6218
|
+
revokeInvite: {
|
|
6219
|
+
parameters: {
|
|
6220
|
+
query?: never;
|
|
6221
|
+
header?: never;
|
|
6222
|
+
path: {
|
|
6223
|
+
orgSlug: components["parameters"]["OrgSlug"];
|
|
6224
|
+
inviteId: string;
|
|
6225
|
+
};
|
|
6226
|
+
cookie?: never;
|
|
6227
|
+
};
|
|
6228
|
+
requestBody?: never;
|
|
6229
|
+
responses: {
|
|
6230
|
+
/** @description 취소했다 */
|
|
6231
|
+
204: {
|
|
6232
|
+
headers: {
|
|
6233
|
+
[name: string]: unknown;
|
|
6234
|
+
};
|
|
6235
|
+
content?: never;
|
|
6236
|
+
};
|
|
6237
|
+
403: components["responses"]["Forbidden"];
|
|
6238
|
+
404: components["responses"]["NotFound"];
|
|
6239
|
+
};
|
|
6240
|
+
};
|
|
6241
|
+
getInvite: {
|
|
6242
|
+
parameters: {
|
|
6243
|
+
query?: never;
|
|
6244
|
+
header?: never;
|
|
6245
|
+
path: {
|
|
6246
|
+
token: string;
|
|
6247
|
+
};
|
|
6248
|
+
cookie?: never;
|
|
6249
|
+
};
|
|
6250
|
+
requestBody?: never;
|
|
6251
|
+
responses: {
|
|
6252
|
+
/** @description 초대 */
|
|
6253
|
+
200: {
|
|
6254
|
+
headers: {
|
|
6255
|
+
[name: string]: unknown;
|
|
6256
|
+
};
|
|
6257
|
+
content: {
|
|
6258
|
+
"application/json": components["schemas"]["InviteView"];
|
|
6259
|
+
};
|
|
6260
|
+
};
|
|
6261
|
+
404: components["responses"]["NotFound"];
|
|
6262
|
+
};
|
|
6263
|
+
};
|
|
6264
|
+
acceptInvite: {
|
|
6265
|
+
parameters: {
|
|
6266
|
+
query?: never;
|
|
6267
|
+
header?: never;
|
|
6268
|
+
path: {
|
|
6269
|
+
token: string;
|
|
6270
|
+
};
|
|
6271
|
+
cookie?: never;
|
|
6272
|
+
};
|
|
6273
|
+
requestBody?: never;
|
|
6274
|
+
responses: {
|
|
6275
|
+
/** @description 수락했다 */
|
|
6276
|
+
200: {
|
|
6277
|
+
headers: {
|
|
6278
|
+
[name: string]: unknown;
|
|
6279
|
+
};
|
|
6280
|
+
content: {
|
|
6281
|
+
"application/json": {
|
|
6282
|
+
orgSlug: string;
|
|
6283
|
+
orgName?: string;
|
|
6284
|
+
role: components["schemas"]["Role"];
|
|
6285
|
+
alreadyMember: boolean;
|
|
6286
|
+
invitedEmail?: string;
|
|
6287
|
+
};
|
|
6288
|
+
};
|
|
6289
|
+
};
|
|
6290
|
+
401: components["responses"]["Unauthorized"];
|
|
6291
|
+
404: components["responses"]["NotFound"];
|
|
6292
|
+
/** @description 이미 수락됨 (`invite_used`) · 취소됨 (`invite_revoked`) · 만료됨 (`invite_expired`) */
|
|
6293
|
+
409: {
|
|
6294
|
+
headers: {
|
|
6295
|
+
[name: string]: unknown;
|
|
6296
|
+
};
|
|
6297
|
+
content: {
|
|
6298
|
+
"application/json": components["schemas"]["Error"];
|
|
6299
|
+
};
|
|
6300
|
+
};
|
|
6301
|
+
};
|
|
6302
|
+
};
|
|
5955
6303
|
setMemberRole: {
|
|
5956
6304
|
parameters: {
|
|
5957
6305
|
query?: never;
|