@k9o/core 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +168 -17
- package/dist/{chunk-O2ZTV6YN.js → chunk-KC4EDMBF.js} +61 -3
- package/dist/chunk-KC4EDMBF.js.map +1 -0
- package/dist/{chunk-2NDFTHUB.js → chunk-UL53GNYM.js} +23 -5
- package/dist/chunk-UL53GNYM.js.map +1 -0
- package/dist/http.d.ts +2 -0
- package/dist/http.js +2 -1
- package/dist/index.d.ts +563 -517
- package/dist/index.js +170 -421
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/url-grammar.d.ts +32 -16
- package/dist/url-grammar.js +5 -1
- package/package.json +4 -4
- package/src/audit.ts +16 -26
- package/src/compute/llms.ts +55 -33
- package/src/functions.ts +60 -27
- package/src/http.ts +5 -1
- package/src/index.ts +16 -17
- package/src/me.ts +69 -85
- package/src/migrations.ts +61 -11
- package/src/org.ts +138 -140
- package/src/orgs.ts +16 -3
- package/src/policies.ts +63 -24
- package/src/projects.ts +58 -22
- package/src/realtime.ts +21 -200
- package/src/region.ts +83 -3
- package/src/storage-buckets.ts +17 -5
- package/src/studio/workflows.ts +8 -8
- package/src/types.ts +3 -3
- package/src/url-grammar.ts +52 -25
- package/dist/chunk-2NDFTHUB.js.map +0 -1
- package/dist/chunk-O2ZTV6YN.js.map +0 -1
- package/src/metadata.ts +0 -130
package/src/index.ts
CHANGED
|
@@ -50,7 +50,6 @@ export type {
|
|
|
50
50
|
StorageBucket, CreateBucketOptions, UpdateBucketOptions, StorageObject, UploadOptions, SignedUrlOptions,
|
|
51
51
|
SignedUrl, RemovedObject, DeletedBucket,
|
|
52
52
|
} from "./storage-buckets.ts";
|
|
53
|
-
import { makeMetadataNamespace } from "./metadata.ts";
|
|
54
53
|
import { makeMigrationsNamespace } from "./migrations.ts";
|
|
55
54
|
import { makeFunctionsNamespace } from "./functions.ts";
|
|
56
55
|
import { makePoliciesNamespace } from "./policies.ts";
|
|
@@ -83,6 +82,9 @@ export {
|
|
|
83
82
|
export {
|
|
84
83
|
validateBaseUrl,
|
|
85
84
|
resolveBaseUrl,
|
|
85
|
+
parseApiHost,
|
|
86
|
+
DEFAULT_BASE_URL,
|
|
87
|
+
type ApiHost,
|
|
86
88
|
validateSlug,
|
|
87
89
|
projectPath,
|
|
88
90
|
orgPath,
|
|
@@ -109,23 +111,21 @@ export type {
|
|
|
109
111
|
StorageLocation, StorageLocationProvider, StorageLocationCustodyMode, StorageLocationProviderParams,
|
|
110
112
|
CreateStorageLocationInput, UpdateStorageLocationInput, RetiredStorageLocation, StorageLocationTestResult,
|
|
111
113
|
} from "./storage-locations.ts";
|
|
112
|
-
export {
|
|
113
|
-
METADATA_OPERATORS,
|
|
114
|
-
type MetadataSlice, type MetadataOperator, type MetadataSurface,
|
|
115
|
-
type MetadataWhereClause, type MetadataQueryRecord, type MetadataQueryResult,
|
|
116
|
-
type MetadataQueryBuilder,
|
|
117
|
-
} from "./metadata.ts";
|
|
118
114
|
export type {
|
|
119
|
-
Migration, AppliedMigration,
|
|
115
|
+
Migration, AppliedMigration, AppliedMigrationRow, SkippedMigrationRow, ApplyMigrationsResult, ApplyPendingResult,
|
|
116
|
+
PendingMigration, PendingMigrationStatus, QueuedMigration,
|
|
120
117
|
Operation, ColumnSpec, IndexSpec, ColumnReferences,
|
|
121
118
|
MigrationPolicy, CollectionPolicy, StorageBucketPolicy, RelationshipSpec, ActionRule,
|
|
122
119
|
} from "./migrations.ts";
|
|
123
120
|
export type { FunctionRecord, DeployFunctionInput } from "./functions.ts";
|
|
124
|
-
export type {
|
|
121
|
+
export type {
|
|
122
|
+
PolicyBundle, PolicyDocument, PolicyPublishResult, PublishPolicyOptions, CreatePolicyInput, UpdatePolicyInput, ValidatePolicyResult,
|
|
123
|
+
} from "./policies.ts";
|
|
125
124
|
export type { AuditEvent, AuditQueryOpts } from "./audit.ts";
|
|
126
125
|
export type { Org } from "./orgs.ts";
|
|
127
126
|
export type {
|
|
128
127
|
OrgMember,
|
|
128
|
+
OrgInviteResult,
|
|
129
129
|
OrgGroup,
|
|
130
130
|
OrgRoleGrant,
|
|
131
131
|
OrgAuditEvent,
|
|
@@ -134,12 +134,16 @@ export type {
|
|
|
134
134
|
SmtpTestEmailResult,
|
|
135
135
|
OrgIdpProvider,
|
|
136
136
|
CreateOrgIdpInput,
|
|
137
|
+
UpdateOrgIdpInput,
|
|
138
|
+
OrgIdpProviderKind,
|
|
139
|
+
OrgDefaultLlm,
|
|
137
140
|
} from "./org.ts";
|
|
138
141
|
export type {
|
|
139
142
|
MyProfile,
|
|
140
143
|
MySession,
|
|
144
|
+
UpdateMyProfileInput,
|
|
141
145
|
MyApiToken,
|
|
142
|
-
|
|
146
|
+
CreateMyApiTokenInput,
|
|
143
147
|
} from "./me.ts";
|
|
144
148
|
export type { ExtensionSlug, Extension } from "./extensions-bridge.ts";
|
|
145
149
|
export type { GateClient } from "@k9o/gate";
|
|
@@ -188,6 +192,7 @@ export {
|
|
|
188
192
|
type LLMInvokeParams,
|
|
189
193
|
type LLMInvokeInput,
|
|
190
194
|
type LLMResponse,
|
|
195
|
+
type LLMUsage,
|
|
191
196
|
type LLMStreamChunk,
|
|
192
197
|
} from "./compute/llms.ts";
|
|
193
198
|
|
|
@@ -203,9 +208,7 @@ export {
|
|
|
203
208
|
type RealtimeFilter,
|
|
204
209
|
type RealtimeEvent,
|
|
205
210
|
type RealtimeSubscription,
|
|
206
|
-
type RealtimeTransportKind,
|
|
207
211
|
type SubscribeOptions,
|
|
208
|
-
type ReplayInput,
|
|
209
212
|
} from "./realtime.ts";
|
|
210
213
|
|
|
211
214
|
/**
|
|
@@ -222,9 +225,6 @@ export type K9oClient = {
|
|
|
222
225
|
* `client.kibo.vault.secrets` (credential pre-create): this namespace only registers a caller-supplied
|
|
223
226
|
* `credentialRef` string, never creates or resolves one. */
|
|
224
227
|
storage: ReturnType<typeof makeStorageNamespace>;
|
|
225
|
-
/** Cross-surface metadata query — `client.metadata.from(...).where(...).execute()`. Client-side
|
|
226
|
-
* only until the gateway's Inc-2 route lands; see `metadata.ts` for status. */
|
|
227
|
-
metadata: ReturnType<typeof makeMetadataNamespace>;
|
|
228
228
|
/** Migration lifecycle — `client.migrations.apply()` etc. */
|
|
229
229
|
migrations: ReturnType<typeof makeMigrationsNamespace>;
|
|
230
230
|
/** Function deploy + invoke — `client.functions.deploy()` etc. */
|
|
@@ -245,7 +245,7 @@ export type K9oClient = {
|
|
|
245
245
|
compute: ReturnType<typeof makeComputeNamespace>;
|
|
246
246
|
/** Platform AI primitives — `client.ai.embed({ model?, input })`. */
|
|
247
247
|
ai: ReturnType<typeof makeAiNamespace>;
|
|
248
|
-
/** Realtime subscriptions — `client.realtime.subscribe()`
|
|
248
|
+
/** Realtime subscriptions — `client.realtime.subscribe()` (SSE). */
|
|
249
249
|
realtime: ReturnType<typeof makeRealtimeNamespace>;
|
|
250
250
|
/** Gate (Identity-Aware Kernel) — composed from `@k9o/gate`. Available when projectSlug is bound on the client. */
|
|
251
251
|
readonly gate: GateClient;
|
|
@@ -278,7 +278,6 @@ export function createClient(options: CreateClientOptions): K9oClient {
|
|
|
278
278
|
from: makeFromFactory(config),
|
|
279
279
|
projects: makeProjectsNamespace(config),
|
|
280
280
|
storage: makeStorageNamespace(config),
|
|
281
|
-
metadata: makeMetadataNamespace(config),
|
|
282
281
|
migrations: makeMigrationsNamespace(config),
|
|
283
282
|
functions: makeFunctionsNamespace(config),
|
|
284
283
|
policies: makePoliciesNamespace(config),
|
package/src/me.ts
CHANGED
|
@@ -7,14 +7,10 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Wire mapping (gateway uses platform-plane / cross-org `/me/...` routes):
|
|
9
9
|
* - `client.me.profile.get/update` → GET/PATCH /me
|
|
10
|
-
* - `client.me.sessions.list
|
|
11
|
-
* - `client.me.
|
|
12
|
-
* - `client.me.
|
|
13
|
-
* - `client.me.
|
|
14
|
-
* - `client.me.dataExport.request` → POST /me/data-export (not available yet)
|
|
15
|
-
*
|
|
16
|
-
* Profile, sessions and MFA setup are served by the existing gateway routes
|
|
17
|
-
* `me.ts` + `mfa.ts`.
|
|
10
|
+
* - `client.me.sessions.list` → GET /me/sessions
|
|
11
|
+
* - `client.me.sessions.revoke` → POST /auth/sessions/<sessionId>/revoke
|
|
12
|
+
* - `client.me.sessions.revokeAll` → POST /me/sessions/revoke-all
|
|
13
|
+
* - `client.me.apiTokens.list/create/delete` → GET/POST/DELETE /me/api-tokens
|
|
18
14
|
*/
|
|
19
15
|
|
|
20
16
|
import { request, type HttpClientConfig } from "./http.ts";
|
|
@@ -22,48 +18,82 @@ import { orgPath } from "./url-grammar.ts";
|
|
|
22
18
|
import type { Envelope } from "./envelope.ts";
|
|
23
19
|
|
|
24
20
|
export type MyProfile = {
|
|
25
|
-
/** `
|
|
21
|
+
/** `usr_<base62>`. */
|
|
26
22
|
id: string;
|
|
27
23
|
email: string;
|
|
28
|
-
displayName: string
|
|
24
|
+
displayName: string;
|
|
25
|
+
mfaEnabled: boolean;
|
|
26
|
+
verifiedAt: string | null;
|
|
27
|
+
/** Set while the account is in its deletion grace period. */
|
|
28
|
+
deletedAt: string | null;
|
|
29
|
+
deletionRequestedAt: string | null;
|
|
30
|
+
deletionScheduledFor: string | null;
|
|
31
|
+
avatarUrl: string | null;
|
|
32
|
+
/** BCP 47 language tag, or `null` when unset. */
|
|
33
|
+
locale: string | null;
|
|
34
|
+
/** IANA time zone name, or `null` when unset. */
|
|
35
|
+
timezone: string | null;
|
|
29
36
|
/** ISO 8601. */
|
|
30
37
|
createdAt: string;
|
|
31
|
-
/**
|
|
32
|
-
|
|
38
|
+
/** ISO 8601. */
|
|
39
|
+
updatedAt: string;
|
|
33
40
|
};
|
|
34
41
|
|
|
35
42
|
export type MySession = {
|
|
36
43
|
/** `sess_<base62>`. */
|
|
37
44
|
id: string;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
userId: string;
|
|
46
|
+
/** Sign-in time. */
|
|
47
|
+
issuedAt: string;
|
|
48
|
+
expiresAt: string;
|
|
49
|
+
revokedAt: string | null;
|
|
50
|
+
mfaVerifiedAt: string | null;
|
|
42
51
|
userAgent: string | null;
|
|
43
52
|
ipAddress: string | null;
|
|
53
|
+
/** Always `null` for now. */
|
|
54
|
+
geoCountry: string | null;
|
|
44
55
|
/** Whether this session is the one issuing the current request. */
|
|
45
|
-
|
|
56
|
+
isCurrentSession: boolean;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Fields `profile.update` may change; `null` clears `locale` and `timezone`. */
|
|
60
|
+
export type UpdateMyProfileInput = {
|
|
61
|
+
displayName?: string | undefined;
|
|
62
|
+
/** BCP 47 language tag, for example `de-DE`. */
|
|
63
|
+
locale?: string | null | undefined;
|
|
64
|
+
/** IANA time zone name, for example `Europe/Berlin`. */
|
|
65
|
+
timezone?: string | null | undefined;
|
|
46
66
|
};
|
|
47
67
|
|
|
48
68
|
export type MyApiToken = {
|
|
49
|
-
/** `
|
|
69
|
+
/** `pat_<base62>`. */
|
|
50
70
|
id: string;
|
|
51
|
-
|
|
71
|
+
userId: string;
|
|
72
|
+
orgId: string;
|
|
73
|
+
label: string;
|
|
74
|
+
scopeManifest: CreateMyApiTokenInput["scopeManifest"];
|
|
75
|
+
ttlSeconds: number;
|
|
52
76
|
/** ISO 8601. */
|
|
53
77
|
createdAt: string;
|
|
54
|
-
/** ISO 8601
|
|
55
|
-
expiresAt: string
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
/** ISO 8601. */
|
|
79
|
+
expiresAt: string;
|
|
80
|
+
lastUsedAt: string | null;
|
|
81
|
+
revokedReason: string | null;
|
|
82
|
+
status: "active" | "revoked" | "expired";
|
|
59
83
|
};
|
|
60
84
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
/** Body of POST /me/api-tokens. Each `scopeManifest` field narrows the token; `null` or absent leaves it unrestricted. */
|
|
86
|
+
export type CreateMyApiTokenInput = {
|
|
87
|
+
label: string;
|
|
88
|
+
scopeManifest: {
|
|
89
|
+
operations?: ReadonlyArray<"read" | "write" | "admin"> | null | undefined;
|
|
90
|
+
projects?: ReadonlyArray<string> | null | undefined;
|
|
91
|
+
resourceClasses?: ReadonlyArray<string> | null | undefined;
|
|
92
|
+
collections?: Record<string, unknown> | null | undefined;
|
|
93
|
+
cidrs?: ReadonlyArray<string> | null | undefined;
|
|
94
|
+
};
|
|
95
|
+
/** Token lifetime in seconds (60 to 31536000). */
|
|
96
|
+
ttlSeconds?: number | undefined;
|
|
67
97
|
};
|
|
68
98
|
|
|
69
99
|
export function makeMeNamespace(config: HttpClientConfig) {
|
|
@@ -74,8 +104,8 @@ export function makeMeNamespace(config: HttpClientConfig) {
|
|
|
74
104
|
return request(config, { method: "GET", path: orgPath("me") });
|
|
75
105
|
},
|
|
76
106
|
|
|
77
|
-
/** PATCH /me — update mutable profile fields (displayName). */
|
|
78
|
-
async update(patch:
|
|
107
|
+
/** PATCH /me — update mutable profile fields (displayName, locale, timezone). */
|
|
108
|
+
async update(patch: UpdateMyProfileInput): Promise<Envelope<MyProfile>> {
|
|
79
109
|
return request(config, { method: "PATCH", path: orgPath("me"), body: patch });
|
|
80
110
|
},
|
|
81
111
|
},
|
|
@@ -86,76 +116,30 @@ export function makeMeNamespace(config: HttpClientConfig) {
|
|
|
86
116
|
return request(config, { method: "GET", path: orgPath("me/sessions") });
|
|
87
117
|
},
|
|
88
118
|
|
|
89
|
-
/**
|
|
119
|
+
/** POST /auth/sessions/<sessionId>/revoke — revoke a specific session. */
|
|
90
120
|
async revoke(sessionId: string): Promise<Envelope<{ revoked: boolean }>> {
|
|
91
|
-
return request(config, { method: "
|
|
121
|
+
return request(config, { method: "POST", path: orgPath(`auth/sessions/${encodeURIComponent(sessionId)}/revoke`) });
|
|
92
122
|
},
|
|
93
123
|
|
|
94
|
-
/**
|
|
124
|
+
/** POST /me/sessions/revoke-all — revoke all of the operator's sessions except the current one. */
|
|
95
125
|
async revokeAll(): Promise<Envelope<{ revoked: number }>> {
|
|
96
|
-
return request(config, { method: "
|
|
126
|
+
return request(config, { method: "POST", path: orgPath("me/sessions/revoke-all") });
|
|
97
127
|
},
|
|
98
128
|
},
|
|
99
129
|
|
|
100
|
-
/**
|
|
101
|
-
* API tokens for personal scripting. The gateway endpoints are not available yet,
|
|
102
|
-
* so these methods return K9O_NOT_FOUND until they ship.
|
|
103
|
-
*/
|
|
130
|
+
/** Personal access tokens for scripting. */
|
|
104
131
|
apiTokens: {
|
|
105
132
|
async list(): Promise<Envelope<ReadonlyArray<MyApiToken>>> {
|
|
106
133
|
return request(config, { method: "GET", path: orgPath("me/api-tokens") });
|
|
107
134
|
},
|
|
108
135
|
|
|
109
|
-
async create(input:
|
|
136
|
+
async create(input: CreateMyApiTokenInput): Promise<Envelope<MyApiToken & { plaintext: string }>> {
|
|
110
137
|
return request(config, { method: "POST", path: orgPath("me/api-tokens"), body: input });
|
|
111
138
|
},
|
|
112
139
|
|
|
113
|
-
async delete(tokenId: string): Promise<Envelope<
|
|
140
|
+
async delete(tokenId: string): Promise<Envelope<MyApiToken>> {
|
|
114
141
|
return request(config, { method: "DELETE", path: orgPath(`me/api-tokens/${encodeURIComponent(tokenId)}`) });
|
|
115
142
|
},
|
|
116
143
|
},
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Notifications — operator-targeted (account-level events). Forward-
|
|
120
|
-
* cycle substrate; methods route correctly when gateway ships.
|
|
121
|
-
*/
|
|
122
|
-
notifications: {
|
|
123
|
-
async list(opts?: { unreadOnly?: boolean | undefined; limit?: number | undefined; cursor?: string | undefined }): Promise<Envelope<ReadonlyArray<MyNotification>>> {
|
|
124
|
-
return request(config, { method: "GET", path: orgPath("me/notifications"), query: opts });
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
async markRead(notificationId: string): Promise<Envelope<MyNotification>> {
|
|
128
|
-
return request(config, { method: "PATCH", path: orgPath(`me/notifications/${encodeURIComponent(notificationId)}`), body: { read: true } });
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
async markAllRead(): Promise<Envelope<{ marked: number }>> {
|
|
132
|
-
return request(config, { method: "PATCH", path: orgPath("me/notifications"), body: { read: true } });
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Operator-self audit log — actions performed BY this operator across
|
|
138
|
-
* orgs. Distinct from `client.audit` (project-plane) and
|
|
139
|
-
* `client.org.auditLog` (org-plane).
|
|
140
|
-
*/
|
|
141
|
-
auditLog: {
|
|
142
|
-
async query(opts?: { since?: string | undefined; until?: string | undefined; type?: string | undefined; limit?: number | undefined; cursor?: string | undefined }): Promise<Envelope<ReadonlyArray<{ id: string; type: string; occurredAt: string; payload: Record<string, unknown> }>>> {
|
|
143
|
-
return request(config, { method: "GET", path: orgPath("me/audit-log"), query: opts });
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Personal data export per GDPR-style requests. Returns a job id
|
|
149
|
-
* the operator polls for completion.
|
|
150
|
-
*/
|
|
151
|
-
dataExport: {
|
|
152
|
-
async request(input?: { format?: "json" | "csv" }): Promise<Envelope<{ jobId: string; status: "queued" | "in-progress" | "ready" }>> {
|
|
153
|
-
return request(config, { method: "POST", path: orgPath("me/data-export"), body: input ?? {} });
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
async status(jobId: string): Promise<Envelope<{ jobId: string; status: "queued" | "in-progress" | "ready" | "failed"; downloadUrl: string | null }>> {
|
|
157
|
-
return request(config, { method: "GET", path: orgPath(`me/data-export/${encodeURIComponent(jobId)}`) });
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
144
|
};
|
|
161
145
|
}
|
package/src/migrations.ts
CHANGED
|
@@ -152,25 +152,74 @@ export type Migration = {
|
|
|
152
152
|
};
|
|
153
153
|
|
|
154
154
|
/**
|
|
155
|
-
* Applied-migration record returned by `list` + `get`.
|
|
155
|
+
* Applied-migration record returned by `list` + `get`. `get` also carries `opPayload`
|
|
156
|
+
* (the migration body as submitted, or `null` for old migrations).
|
|
156
157
|
*/
|
|
157
158
|
export type AppliedMigration = {
|
|
158
159
|
version: number;
|
|
159
160
|
slug: string;
|
|
160
161
|
checksum: string;
|
|
161
162
|
appliedAt: string;
|
|
163
|
+
noPolicy: boolean;
|
|
164
|
+
affectedCollections: ReadonlyArray<string>;
|
|
165
|
+
opPayload?: unknown;
|
|
162
166
|
};
|
|
163
167
|
|
|
168
|
+
/** A migration that `apply` or `applyPending` just applied. Carries no `appliedAt`. */
|
|
169
|
+
export type AppliedMigrationRow = {
|
|
170
|
+
version: number;
|
|
171
|
+
slug: string;
|
|
172
|
+
checksum: string;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/** A migration `apply` left alone, e.g. `already_applied`. */
|
|
176
|
+
export type SkippedMigrationRow = {
|
|
177
|
+
version: number;
|
|
178
|
+
slug: string;
|
|
179
|
+
reason: string;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
/** Result of `apply`. */
|
|
183
|
+
export type ApplyMigrationsResult = {
|
|
184
|
+
applied: ReadonlyArray<AppliedMigrationRow>;
|
|
185
|
+
skipped: ReadonlyArray<SkippedMigrationRow>;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/** Result of `applyPending`: `pendingId` is the queued row that was applied. */
|
|
189
|
+
export type ApplyPendingResult = ApplyMigrationsResult & {
|
|
190
|
+
pendingId: string;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export type PendingMigrationStatus = "queued" | "pending_approval" | "applied" | "rejected" | "cancelled";
|
|
194
|
+
|
|
164
195
|
/**
|
|
165
196
|
* Pending migration record returned by `listPending`.
|
|
166
197
|
*/
|
|
167
198
|
export type PendingMigration = {
|
|
168
|
-
|
|
199
|
+
id: string;
|
|
169
200
|
version: number;
|
|
170
201
|
slug: string;
|
|
171
202
|
checksum: string;
|
|
172
|
-
|
|
173
|
-
|
|
203
|
+
status: PendingMigrationStatus;
|
|
204
|
+
affectedCollections: ReadonlyArray<string>;
|
|
205
|
+
/** Approval that gates a `pending_approval` row, else `null`. */
|
|
206
|
+
approvalId: string | null;
|
|
207
|
+
queuedAt: string;
|
|
208
|
+
queuedBy: string;
|
|
209
|
+
decidedAt: string | null;
|
|
210
|
+
decidedBy: string | null;
|
|
211
|
+
decisionReason: string | null;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/** One row of the `queue` answer. */
|
|
215
|
+
export type QueuedMigration = {
|
|
216
|
+
/** The pending id to pass to `applyPending`, `rejectPending` or `deletePending`. */
|
|
217
|
+
id: string;
|
|
218
|
+
version: number;
|
|
219
|
+
slug: string;
|
|
220
|
+
status: "queued" | "pending_approval";
|
|
221
|
+
approvalId: string | null;
|
|
222
|
+
affectedCollections: ReadonlyArray<string>;
|
|
174
223
|
};
|
|
175
224
|
|
|
176
225
|
function requireProjectSlug(config: HttpClientConfig): string {
|
|
@@ -183,7 +232,7 @@ function requireProjectSlug(config: HttpClientConfig): string {
|
|
|
183
232
|
export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
184
233
|
return {
|
|
185
234
|
/** Apply migrations immediately (PROJECT_ADMIN minimum). */
|
|
186
|
-
async apply(input: { migrations: ReadonlyArray<Migration> }): Promise<Envelope<
|
|
235
|
+
async apply(input: { migrations: ReadonlyArray<Migration> }): Promise<Envelope<ApplyMigrationsResult>> {
|
|
187
236
|
const slug = requireProjectSlug(config);
|
|
188
237
|
return request(config, {
|
|
189
238
|
method: "POST",
|
|
@@ -211,7 +260,7 @@ export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
|
211
260
|
},
|
|
212
261
|
|
|
213
262
|
/** Queue migrations for maker-checker approval. */
|
|
214
|
-
async queue(input: { migrations: ReadonlyArray<Migration> }): Promise<Envelope<
|
|
263
|
+
async queue(input: { migrations: ReadonlyArray<Migration> }): Promise<Envelope<ReadonlyArray<QueuedMigration>>> {
|
|
215
264
|
const slug = requireProjectSlug(config);
|
|
216
265
|
return request(config, {
|
|
217
266
|
method: "POST",
|
|
@@ -220,12 +269,13 @@ export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
|
220
269
|
});
|
|
221
270
|
},
|
|
222
271
|
|
|
223
|
-
/** List pending
|
|
224
|
-
async listPending(): Promise<Envelope<ReadonlyArray<PendingMigration>>> {
|
|
272
|
+
/** List pending migrations: `queued` ones by default, or those with the given `status`. */
|
|
273
|
+
async listPending(opts?: { status?: PendingMigrationStatus | undefined }): Promise<Envelope<ReadonlyArray<PendingMigration>>> {
|
|
225
274
|
const slug = requireProjectSlug(config);
|
|
226
275
|
return request(config, {
|
|
227
276
|
method: "GET",
|
|
228
277
|
path: projectPath(slug, "migrations/pending"),
|
|
278
|
+
query: opts,
|
|
229
279
|
});
|
|
230
280
|
},
|
|
231
281
|
|
|
@@ -235,7 +285,7 @@ export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
|
235
285
|
* migration awaiting a distinct-admin's review, is refused here and
|
|
236
286
|
* needs its own approval flow, not this call).
|
|
237
287
|
*/
|
|
238
|
-
async applyPending(pendingId: string): Promise<Envelope<
|
|
288
|
+
async applyPending(pendingId: string): Promise<Envelope<ApplyPendingResult>> {
|
|
239
289
|
const slug = requireProjectSlug(config);
|
|
240
290
|
return request(config, {
|
|
241
291
|
method: "POST",
|
|
@@ -244,7 +294,7 @@ export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
|
244
294
|
},
|
|
245
295
|
|
|
246
296
|
/** Reject a pending migration (transitions to rejected; does not apply). */
|
|
247
|
-
async rejectPending(pendingId: string, input?: { reason?: string }): Promise<Envelope<{
|
|
297
|
+
async rejectPending(pendingId: string, input?: { reason?: string }): Promise<Envelope<{ pendingId: string; status: "rejected" }>> {
|
|
248
298
|
const slug = requireProjectSlug(config);
|
|
249
299
|
return request(config, {
|
|
250
300
|
method: "POST",
|
|
@@ -254,7 +304,7 @@ export function makeMigrationsNamespace(config: HttpClientConfig) {
|
|
|
254
304
|
},
|
|
255
305
|
|
|
256
306
|
/** Delete a pending migration from the queue. */
|
|
257
|
-
async deletePending(pendingId: string): Promise<Envelope<{
|
|
307
|
+
async deletePending(pendingId: string): Promise<Envelope<{ pendingId: string; status: "cancelled" }>> {
|
|
258
308
|
const slug = requireProjectSlug(config);
|
|
259
309
|
return request(config, {
|
|
260
310
|
method: "DELETE",
|