@ornncompute/cli 1.0.112 → 1.0.114
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/package.json +1 -1
- package/src/catalog-shell.mjs +4 -1
- package/src/device-auth.mjs +31 -25
- package/src/machine-reference.mjs +2 -1
- package/src/registry-commands.mjs +12 -10
- package/src/session-commands.mjs +20 -15
- package/vendor/api-client/authorization.js +491 -0
- package/vendor/capabilities/cli.js +58 -39
package/package.json
CHANGED
package/src/catalog-shell.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCliSession } from "../vendor/api-client/authorization.js";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
2
3
|
|
|
3
4
|
import {
|
|
@@ -1009,7 +1010,9 @@ async function executeCapability(
|
|
|
1009
1010
|
}
|
|
1010
1011
|
if (capability.domain === "listings" && ownOrganizationId === undefined) {
|
|
1011
1012
|
// Verify listing owner IDs before the request, never after a committed mutation.
|
|
1012
|
-
const session = await
|
|
1013
|
+
const session = await getCliSession((path, init) =>
|
|
1014
|
+
customerCapabilityFetch(io, path, init, authSnapshot)
|
|
1015
|
+
);
|
|
1013
1016
|
ownOrganizationId = session.selectedOrganization?.id ?? null;
|
|
1014
1017
|
}
|
|
1015
1018
|
return customerCapabilityFetch(io, path, init, authSnapshot);
|
package/src/device-auth.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
startCliDeviceAuthorization,
|
|
3
|
+
pollCliDeviceAuthorization,
|
|
4
|
+
} from "../vendor/api-client/authorization.js";
|
|
1
5
|
import { spawn } from "node:child_process";
|
|
2
6
|
|
|
3
7
|
import { configuredAuthBaseUrl } from "./auth-store.mjs";
|
|
@@ -90,7 +94,7 @@ export async function openBrowser(url, { platform = process.platform, spawnImpl
|
|
|
90
94
|
|
|
91
95
|
export async function startDeviceFlow({ apiBaseUrl, authBaseUrl, fetchImpl = fetch } = {}) {
|
|
92
96
|
const requestBaseUrl = apiBaseUrl || authBaseUrl;
|
|
93
|
-
const data = await
|
|
97
|
+
const data = await startCliDeviceAuthorization(deviceRequest(fetchImpl, requestBaseUrl));
|
|
94
98
|
|
|
95
99
|
const deviceCode = pickString(data, "deviceCode", "device_code");
|
|
96
100
|
const userCode = pickString(data, "userCode", "user_code");
|
|
@@ -126,11 +130,10 @@ export async function pollDeviceFlow({
|
|
|
126
130
|
signal,
|
|
127
131
|
} = {}) {
|
|
128
132
|
const requestBaseUrl = apiBaseUrl || authBaseUrl;
|
|
129
|
-
return
|
|
130
|
-
fetchImpl,
|
|
131
|
-
`${requestBaseUrl}/v1/cli/device/poll`,
|
|
133
|
+
return pollCliDeviceAuthorization(
|
|
134
|
+
deviceRequest(fetchImpl, requestBaseUrl),
|
|
132
135
|
{ device_code: deviceCode },
|
|
133
|
-
|
|
136
|
+
signal
|
|
134
137
|
);
|
|
135
138
|
}
|
|
136
139
|
|
|
@@ -258,28 +261,31 @@ export async function waitForDeviceApproval({
|
|
|
258
261
|
}
|
|
259
262
|
}
|
|
260
263
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
const data = text ? parseJson(text, url) : {};
|
|
273
|
-
|
|
274
|
-
if (!response.ok) {
|
|
275
|
-
const detail = data.detail || data.error || response.statusText;
|
|
276
|
-
throw new DeviceAuthError(`Auth request failed: ${detail}`, {
|
|
277
|
-
detail: data,
|
|
278
|
-
status: response.status,
|
|
264
|
+
function deviceRequest(fetchImpl, baseUrl) {
|
|
265
|
+
return async (path, { body, method, signal } = {}) => {
|
|
266
|
+
const url = `${baseUrl}${path}`;
|
|
267
|
+
const response = await fetchImpl(url, {
|
|
268
|
+
body: JSON.stringify(body),
|
|
269
|
+
headers: {
|
|
270
|
+
Accept: "application/json",
|
|
271
|
+
"Content-Type": "application/json",
|
|
272
|
+
},
|
|
273
|
+
method,
|
|
274
|
+
...(signal ? { signal } : {}),
|
|
279
275
|
});
|
|
280
|
-
|
|
276
|
+
const text = await response.text();
|
|
277
|
+
const data = text ? parseJson(text, url) : {};
|
|
281
278
|
|
|
282
|
-
|
|
279
|
+
if (!response.ok) {
|
|
280
|
+
const detail = data.detail || data.error || response.statusText;
|
|
281
|
+
throw new DeviceAuthError(`Auth request failed: ${detail}`, {
|
|
282
|
+
detail: data,
|
|
283
|
+
status: response.status,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return data;
|
|
288
|
+
};
|
|
283
289
|
}
|
|
284
290
|
|
|
285
291
|
function parseJson(text, url) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCliSession } from "../vendor/api-client/authorization.js";
|
|
1
2
|
import { listAllReservations } from "../vendor/api-client/commerce.js";
|
|
2
3
|
import { gpuLabeler } from "./gpu-catalog.mjs";
|
|
3
4
|
|
|
@@ -114,7 +115,7 @@ function invalidGateway(interaction, message) {
|
|
|
114
115
|
export async function listActiveReservations(context, interaction) {
|
|
115
116
|
const session = context.cli?.session
|
|
116
117
|
? (await context.cli.session("context", {})).data
|
|
117
|
-
: await context.fetch
|
|
118
|
+
: await getCliSession(context.fetch);
|
|
118
119
|
const customerId = text((session.selectedOrganization ?? session.selected_organization)?.id);
|
|
119
120
|
if (!customerId) {
|
|
120
121
|
interaction.usage("Select an organization before choosing a reservation.", {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
listApiKeys,
|
|
3
|
+
createApiKey,
|
|
4
|
+
revokeApiKey,
|
|
5
|
+
getCliSession,
|
|
6
|
+
} from "../vendor/api-client/authorization.js";
|
|
1
7
|
import { spawn as spawnProcessDefault } from "node:child_process";
|
|
2
8
|
import os from "node:os";
|
|
3
9
|
|
|
@@ -18,7 +24,7 @@ async function login({
|
|
|
18
24
|
hostname = os.hostname(),
|
|
19
25
|
}) {
|
|
20
26
|
const registry = await fetch("/v1/orchestrator/registry");
|
|
21
|
-
const session = await fetch
|
|
27
|
+
const session = await getCliSession(fetch);
|
|
22
28
|
const organizationId = (session?.selectedOrganization ?? session?.selected_organization)?.id;
|
|
23
29
|
if (typeof organizationId !== "string" || !organizationId) {
|
|
24
30
|
interaction.usage("Join an organization before logging in to its registry.", {
|
|
@@ -26,25 +32,21 @@ async function login({
|
|
|
26
32
|
field: "organization",
|
|
27
33
|
});
|
|
28
34
|
}
|
|
29
|
-
const keysPath = `/v1/organizations/${encodeURIComponent(organizationId)}/api-keys`;
|
|
30
35
|
const name = `${KEY_NAME_PREFIX}${hostname}`.slice(0, 100);
|
|
31
36
|
|
|
32
|
-
const existing = await fetch
|
|
37
|
+
const existing = await listApiKeys(fetch, organizationId);
|
|
33
38
|
for (const key of existing?.api_keys ?? []) {
|
|
34
39
|
if (key?.name === name && typeof key.id === "string") {
|
|
35
|
-
await fetch
|
|
40
|
+
await revokeApiKey(fetch, organizationId, key.id);
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
|
-
const created = await fetch
|
|
39
|
-
method: "POST",
|
|
40
|
-
body: { name, access: "read_write" },
|
|
41
|
-
});
|
|
43
|
+
const created = await createApiKey(fetch, organizationId, { name, access: "read_write" });
|
|
42
44
|
|
|
43
45
|
let exit;
|
|
44
46
|
try {
|
|
45
47
|
exit = await dockerLogin(spawnProcess, registry.host, created.token);
|
|
46
48
|
} catch (error) {
|
|
47
|
-
await fetch
|
|
49
|
+
await revokeApiKey(fetch, organizationId, created.id);
|
|
48
50
|
const missing = error?.code === "ENOENT";
|
|
49
51
|
interaction.error(
|
|
50
52
|
missing
|
|
@@ -54,7 +56,7 @@ async function login({
|
|
|
54
56
|
);
|
|
55
57
|
}
|
|
56
58
|
if (exit.code !== 0) {
|
|
57
|
-
await fetch
|
|
59
|
+
await revokeApiKey(fetch, organizationId, created.id);
|
|
58
60
|
interaction.error(`docker login ${registry.host} failed; no key was kept.`, {
|
|
59
61
|
code: "docker_login_failed",
|
|
60
62
|
exitCode: 1,
|
package/src/session-commands.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCliSession, revokeCliSession } from "../vendor/api-client/authorization.js";
|
|
1
2
|
import { CliApiError, cliRequest, resolveApiBaseUrl } from "./api-client.mjs";
|
|
2
3
|
import {
|
|
3
4
|
bindAuthUser,
|
|
@@ -143,13 +144,15 @@ async function context({ env, fetchImpl, sessionSnapshot }) {
|
|
|
143
144
|
sessionSnapshot.current = localSession;
|
|
144
145
|
}
|
|
145
146
|
const data = sessionContext(
|
|
146
|
-
await
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
await getCliSession((endpoint, init) =>
|
|
148
|
+
cliRequest({
|
|
149
|
+
...init,
|
|
150
|
+
endpoint,
|
|
151
|
+
env,
|
|
152
|
+
fetchImpl,
|
|
153
|
+
session: localSession,
|
|
154
|
+
})
|
|
155
|
+
)
|
|
153
156
|
);
|
|
154
157
|
await bindAuthUser(data.user, {
|
|
155
158
|
env,
|
|
@@ -291,14 +294,16 @@ async function logout(runtime) {
|
|
|
291
294
|
try {
|
|
292
295
|
if (!revocationError && session?.accessToken) {
|
|
293
296
|
attempted = true;
|
|
294
|
-
await
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
297
|
+
await revokeCliSession((endpoint, init) =>
|
|
298
|
+
cliRequest({
|
|
299
|
+
...init,
|
|
300
|
+
endpoint,
|
|
301
|
+
env: runtime.env,
|
|
302
|
+
fetchImpl: runtime.fetchImpl,
|
|
303
|
+
raw: true,
|
|
304
|
+
session,
|
|
305
|
+
})
|
|
306
|
+
);
|
|
302
307
|
}
|
|
303
308
|
} catch (error) {
|
|
304
309
|
revocationError = error;
|
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
// ../../packages/api-client/dist/authorization/paths.js
|
|
2
|
+
var organizationPath = (id) => `/v1/organizations/${encodeURIComponent(id)}`;
|
|
3
|
+
var personPath = (id) => `/v1/people/${encodeURIComponent(id)}`;
|
|
4
|
+
function withQuery(path, values) {
|
|
5
|
+
const query = new URLSearchParams();
|
|
6
|
+
for (const [key, value] of Object.entries(values)) {
|
|
7
|
+
if (value !== void 0 && value !== null && value !== "")
|
|
8
|
+
query.set(key, Array.isArray(value) ? value.join(",") : String(value));
|
|
9
|
+
}
|
|
10
|
+
return query.size ? `${path}?${query}` : path;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// ../../packages/api-client/dist/authorization/organizations.js
|
|
14
|
+
function listOrganizations(request, query = {}, signal) {
|
|
15
|
+
return request(withQuery("/v1/organizations", query), { method: "GET", signal });
|
|
16
|
+
}
|
|
17
|
+
async function listSupplierOrganizations(request, signal) {
|
|
18
|
+
const rows = [];
|
|
19
|
+
for (let offset = 0; offset < 5e4; offset += 1e3) {
|
|
20
|
+
const page = await listOrganizations(request, { role: "supplier", limit: 1e3, offset, sort: "created_at", direction: "asc" }, signal);
|
|
21
|
+
if (!Array.isArray(page))
|
|
22
|
+
throw new Error("Invalid supplier directory response.");
|
|
23
|
+
rows.push(...page);
|
|
24
|
+
if (page.length < 1e3)
|
|
25
|
+
return rows;
|
|
26
|
+
}
|
|
27
|
+
throw new Error("The supplier directory is too large to load completely.");
|
|
28
|
+
}
|
|
29
|
+
async function listOrganizationsByIds(request, ids, signal) {
|
|
30
|
+
const unique = [
|
|
31
|
+
...new Set(ids.map((id) => id?.trim()).filter((id) => Boolean(id)))
|
|
32
|
+
];
|
|
33
|
+
const chunks = [];
|
|
34
|
+
for (let start = 0; start < unique.length; start += 100)
|
|
35
|
+
chunks.push(unique.slice(start, start + 100));
|
|
36
|
+
const pages = await Promise.all(chunks.map(async (chunk, index) => {
|
|
37
|
+
if (index > 0)
|
|
38
|
+
await new Promise((resolve) => setTimeout(resolve, Math.random() * 40));
|
|
39
|
+
return listOrganizations(request, { ids: chunk, limit: chunk.length }, signal);
|
|
40
|
+
}));
|
|
41
|
+
return pages.flat();
|
|
42
|
+
}
|
|
43
|
+
function countOrganizations(request, query = {}, signal) {
|
|
44
|
+
return request(withQuery("/v1/staff/v1/organizations/count", query), {
|
|
45
|
+
method: "GET",
|
|
46
|
+
signal
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function getOrganization(request, id, signal) {
|
|
50
|
+
return request(organizationPath(id), { method: "GET", signal });
|
|
51
|
+
}
|
|
52
|
+
function listOrganizationsForUser(request, query, signal) {
|
|
53
|
+
return request(withQuery("/v1/organizations/by-user", query), {
|
|
54
|
+
method: "GET",
|
|
55
|
+
signal
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function createOrganization(request, body, signal) {
|
|
59
|
+
return request("/v1/organizations", { method: "POST", body, signal });
|
|
60
|
+
}
|
|
61
|
+
function updateOrganization(request, id, body) {
|
|
62
|
+
return request(organizationPath(id), { method: "PATCH", body });
|
|
63
|
+
}
|
|
64
|
+
function listOrganizationMembers(request, id, signal) {
|
|
65
|
+
return request(`${organizationPath(id)}/members`, { method: "GET", signal });
|
|
66
|
+
}
|
|
67
|
+
function getOrganizationMembership(request, id, email) {
|
|
68
|
+
return request(`${organizationPath(id)}/members/${encodeURIComponent(email)}`, {
|
|
69
|
+
method: "GET"
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function removeOrganizationMember(request, id, email) {
|
|
73
|
+
return request(`${organizationPath(id)}/members/${encodeURIComponent(email)}`, {
|
|
74
|
+
method: "DELETE"
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ../../packages/api-client/dist/authorization/account.js
|
|
79
|
+
function getUserProfile(request, id, signal) {
|
|
80
|
+
return request(`${personPath(id)}/profile`, {
|
|
81
|
+
method: "GET",
|
|
82
|
+
signal
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function updateUserProfile(request, id, body) {
|
|
86
|
+
return request(`${personPath(id)}/profile`, {
|
|
87
|
+
method: "PATCH",
|
|
88
|
+
body
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function getUserPreferences(request, id, signal) {
|
|
92
|
+
return request(`${personPath(id)}/preferences`, {
|
|
93
|
+
method: "GET",
|
|
94
|
+
signal
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function updateUserPreferences(request, id, body) {
|
|
98
|
+
return request(`${personPath(id)}/preferences`, {
|
|
99
|
+
method: "PATCH",
|
|
100
|
+
body
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function getNotificationPreferences(request, id, signal) {
|
|
104
|
+
return request(`${organizationPath(id)}/notification-preferences`, {
|
|
105
|
+
method: "GET",
|
|
106
|
+
signal
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function updateNotificationPreferences(request, id, body) {
|
|
110
|
+
return request(`${organizationPath(id)}/notification-preferences`, {
|
|
111
|
+
method: "PATCH",
|
|
112
|
+
body
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function listApiKeys(request, id, signal) {
|
|
116
|
+
return request(`${organizationPath(id)}/api-keys`, {
|
|
117
|
+
method: "GET",
|
|
118
|
+
signal
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function createApiKey(request, id, body) {
|
|
122
|
+
return request(`${organizationPath(id)}/api-keys`, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
body
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function revokeApiKey(request, id, keyId) {
|
|
128
|
+
return request(`${organizationPath(id)}/api-keys/${encodeURIComponent(keyId)}`, {
|
|
129
|
+
method: "DELETE"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function listAvailabilityAlerts(request, id, signal) {
|
|
133
|
+
return request(`${personPath(id)}/availability-alerts`, { method: "GET", signal });
|
|
134
|
+
}
|
|
135
|
+
function setAvailabilityAlert(request, id, alert) {
|
|
136
|
+
return request(`${personPath(id)}/availability-alerts/${encodeURIComponent(alert.gpu_slug)}/${encodeURIComponent(alert.sale_type)}`, { method: "PUT", body: { enabled: alert.enabled } });
|
|
137
|
+
}
|
|
138
|
+
var personAvatarPath = (id) => `${personPath(id)}/avatar`;
|
|
139
|
+
var organizationAvatarPath = (id) => `${organizationPath(id)}/avatar`;
|
|
140
|
+
function getPersonAvatar(fetcher, id) {
|
|
141
|
+
return fetcher(personAvatarPath(id), { method: "GET" });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ../../packages/api-client/dist/authorization/invites.js
|
|
145
|
+
var invitePath = (id) => `/v1/invites/${encodeURIComponent(id)}`;
|
|
146
|
+
function listInvites(request, organizationId, signal) {
|
|
147
|
+
return request(withQuery("/v1/invites", { organization_id: organizationId }), {
|
|
148
|
+
method: "GET",
|
|
149
|
+
signal
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function getInvite(request, id) {
|
|
153
|
+
return request(invitePath(id), { method: "GET" });
|
|
154
|
+
}
|
|
155
|
+
function createInvite(request, body) {
|
|
156
|
+
return request("/v1/invites", { method: "POST", body });
|
|
157
|
+
}
|
|
158
|
+
function revokeInvite(request, organizationId, id) {
|
|
159
|
+
return request(withQuery(invitePath(id), { organization_id: organizationId }), {
|
|
160
|
+
method: "DELETE"
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function acceptInvite(request, id, body = {}) {
|
|
164
|
+
return request(`${invitePath(id)}/accept`, { method: "POST", body });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ../../packages/api-client/dist/authorization/ssh-keys.js
|
|
168
|
+
function listSshKeys(request, id, query = {}, signal) {
|
|
169
|
+
return request(withQuery(`${organizationPath(id)}/ssh-keys`, query), {
|
|
170
|
+
method: "GET",
|
|
171
|
+
signal
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async function listAllSshKeys(request, id, signal) {
|
|
175
|
+
const ssh_keys = [];
|
|
176
|
+
const seen = /* @__PURE__ */ new Set();
|
|
177
|
+
let cursor = null;
|
|
178
|
+
let has_revoked = false;
|
|
179
|
+
do {
|
|
180
|
+
const page = await listSshKeys(request, id, { status: "all", limit: 500, cursor }, signal);
|
|
181
|
+
ssh_keys.push(...page.ssh_keys);
|
|
182
|
+
has_revoked ||= page.has_revoked === true;
|
|
183
|
+
cursor = page.next_cursor ?? null;
|
|
184
|
+
if (cursor && seen.has(cursor))
|
|
185
|
+
throw new Error("SSH key pagination did not advance.");
|
|
186
|
+
if (cursor)
|
|
187
|
+
seen.add(cursor);
|
|
188
|
+
} while (cursor);
|
|
189
|
+
return { ssh_keys, next_cursor: null, has_revoked };
|
|
190
|
+
}
|
|
191
|
+
function createSshKey(request, id, body, query = {}) {
|
|
192
|
+
return request(withQuery(`${organizationPath(id)}/ssh-keys`, query), {
|
|
193
|
+
method: "POST",
|
|
194
|
+
body
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
function revokeSshKey(request, id, keyId, query = {}) {
|
|
198
|
+
return request(withQuery(`${organizationPath(id)}/ssh-keys/${encodeURIComponent(keyId)}`, query), { method: "DELETE" });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ../../packages/api-client/dist/authorization/staff.js
|
|
202
|
+
var staffOrganizationPath = (id) => `/v1/staff/organizations/${encodeURIComponent(id)}`;
|
|
203
|
+
function searchStaffPeople(request, query, signal) {
|
|
204
|
+
return request(withQuery("/v1/staff/people", query), { method: "GET", signal });
|
|
205
|
+
}
|
|
206
|
+
function searchStaffOrganizations(request, query, signal) {
|
|
207
|
+
return request(withQuery("/v1/staff/organizations", query), {
|
|
208
|
+
method: "GET",
|
|
209
|
+
signal
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function getStaffOrganization(request, id, signal) {
|
|
213
|
+
return request(staffOrganizationPath(id), {
|
|
214
|
+
method: "GET",
|
|
215
|
+
signal
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function createStaffOrganization(request, body) {
|
|
219
|
+
return request("/v1/staff/organizations", {
|
|
220
|
+
method: "POST",
|
|
221
|
+
body
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function listStaffOrganizationMembers(request, id, signal) {
|
|
225
|
+
return request(`${staffOrganizationPath(id)}/members`, { method: "GET", signal });
|
|
226
|
+
}
|
|
227
|
+
function addStaffOrganizationMember(request, id, body) {
|
|
228
|
+
return request(`${staffOrganizationPath(id)}/members`, {
|
|
229
|
+
method: "POST",
|
|
230
|
+
body
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function removeStaffOrganizationMember(request, id, email) {
|
|
234
|
+
return request(`${staffOrganizationPath(id)}/members/${encodeURIComponent(email)}`, {
|
|
235
|
+
method: "DELETE"
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
function listStaffOrganizationInvites(request, id, signal) {
|
|
239
|
+
return request(`${staffOrganizationPath(id)}/invites`, { method: "GET", signal });
|
|
240
|
+
}
|
|
241
|
+
function revokeStaffOrganizationInvite(request, id, inviteId) {
|
|
242
|
+
return request(`${staffOrganizationPath(id)}/invites/${encodeURIComponent(inviteId)}`, {
|
|
243
|
+
method: "DELETE"
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
function createStaffInvite(request, body) {
|
|
247
|
+
return request("/v1/staff/invites", { method: "POST", body });
|
|
248
|
+
}
|
|
249
|
+
function updateOrganizationApproval(request, id, body) {
|
|
250
|
+
return request(`${organizationPath(id)}/approval`, { method: "POST", body });
|
|
251
|
+
}
|
|
252
|
+
function cancelOrganizationFollowUp(request, id) {
|
|
253
|
+
return request(`${organizationPath(id)}/follow-up/cancel`, {
|
|
254
|
+
method: "POST",
|
|
255
|
+
body: {}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function listSupplierApplications(request, query = {}, signal) {
|
|
259
|
+
return request(withQuery("/v1/supplier-applications", query), {
|
|
260
|
+
method: "GET",
|
|
261
|
+
signal
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function updateSupplierApplication(request, id, body) {
|
|
265
|
+
return request(`/v1/supplier-applications/${encodeURIComponent(id)}`, {
|
|
266
|
+
method: "PATCH",
|
|
267
|
+
body
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function approveSupplierApplicationFromSlack(fetcher, id, actorEmail) {
|
|
271
|
+
return fetcher(`/v1/staff/v1/supplier-applications/${encodeURIComponent(id)}`, {
|
|
272
|
+
method: "PATCH",
|
|
273
|
+
headers: { "Content-Type": "application/json" },
|
|
274
|
+
body: JSON.stringify({ approve_pending: true, actor_email: actorEmail })
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ../../packages/api-client/dist/authorization/onboarding.js
|
|
279
|
+
function submitOnboardingIntake(fetcher, body) {
|
|
280
|
+
return fetcher("/v1/onboarding/intake", {
|
|
281
|
+
method: "POST",
|
|
282
|
+
headers: { "Content-Type": "application/json" },
|
|
283
|
+
body: JSON.stringify(body)
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function listOnboardingSlots(fetcher, id, query) {
|
|
287
|
+
return fetcher(withQuery(`${organizationPath(id)}/onboarding-booking/slots`, query), {
|
|
288
|
+
method: "GET"
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
function bookOnboardingCall(fetcher, id, body) {
|
|
292
|
+
return fetcher(`${organizationPath(id)}/onboarding-booking`, {
|
|
293
|
+
method: "POST",
|
|
294
|
+
headers: { "Content-Type": "application/json" },
|
|
295
|
+
body: JSON.stringify(body)
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
function cancelOnboardingCall(fetcher, id) {
|
|
299
|
+
return fetcher(`${organizationPath(id)}/onboarding-booking`, { method: "DELETE" });
|
|
300
|
+
}
|
|
301
|
+
function createSupplierApplication(fetcher, body, query = {}) {
|
|
302
|
+
return fetcher(withQuery("/v1/supplier-applications", query), {
|
|
303
|
+
method: "POST",
|
|
304
|
+
headers: { "Content-Type": "application/json" },
|
|
305
|
+
body: JSON.stringify(body)
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// ../../packages/api-client/dist/authorization/sessions.js
|
|
310
|
+
var browserSessionPath = "/v1/auth/session";
|
|
311
|
+
var signInPath = "/v1/auth/sign-in";
|
|
312
|
+
var inviteRedeemPath = "/v1/auth/invites/redeem";
|
|
313
|
+
var unsubscribePath = "/v1/auth/unsubscribe";
|
|
314
|
+
var post = (body, signal) => ({
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: { "Content-Type": "application/json" },
|
|
317
|
+
body: JSON.stringify(body),
|
|
318
|
+
...signal ? { signal } : {}
|
|
319
|
+
});
|
|
320
|
+
function getBrowserSession(fetcher, query = {}, options = {}) {
|
|
321
|
+
return fetcher(withQuery(browserSessionPath, query), { ...options, method: "GET" });
|
|
322
|
+
}
|
|
323
|
+
function signOutBrowserSession(fetcher, next) {
|
|
324
|
+
return fetcher(withQuery("/v1/auth/sign-out", { next }), post({}));
|
|
325
|
+
}
|
|
326
|
+
function changeEmail(fetcher, body) {
|
|
327
|
+
return fetcher("/v1/auth/change-email", post(body));
|
|
328
|
+
}
|
|
329
|
+
function authorizeStaff(fetcher, body, signal) {
|
|
330
|
+
return fetcher("/v1/authorize", post(body, signal));
|
|
331
|
+
}
|
|
332
|
+
function createSlackSession(fetcher, body, signal) {
|
|
333
|
+
return fetcher("/v1/slack/session", post(body, signal));
|
|
334
|
+
}
|
|
335
|
+
function startCliDeviceAuthorization(request) {
|
|
336
|
+
return request("/v1/cli/device/start", {
|
|
337
|
+
method: "POST",
|
|
338
|
+
body: {}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function pollCliDeviceAuthorization(request, body, signal) {
|
|
342
|
+
return request("/v1/cli/device/poll", { method: "POST", body, signal });
|
|
343
|
+
}
|
|
344
|
+
function approveCliDeviceAuthorization(fetcher, body) {
|
|
345
|
+
return fetcher("/v1/cli/device/approve", post(body));
|
|
346
|
+
}
|
|
347
|
+
function getCliSession(request) {
|
|
348
|
+
return request("/v1/cli/session", { method: "GET" });
|
|
349
|
+
}
|
|
350
|
+
function revokeCliSession(request) {
|
|
351
|
+
return request("/v1/cli/session", { method: "DELETE" });
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// ../../packages/api-client/dist/authorization/mcp.js
|
|
355
|
+
function getMcpApplication(fetcher, clientId) {
|
|
356
|
+
return fetcher(`/v1/mcp/applications/${encodeURIComponent(clientId)}`, { method: "GET" });
|
|
357
|
+
}
|
|
358
|
+
function listMcpConnections(fetcher, userId) {
|
|
359
|
+
return fetcher(withQuery("/v1/mcp/connections", { user_id: userId }), { method: "GET" });
|
|
360
|
+
}
|
|
361
|
+
function revokeMcpConnection(fetcher, userId, clientId) {
|
|
362
|
+
return fetcher(withQuery(`/v1/mcp/connections/${encodeURIComponent(clientId)}`, { user_id: userId }), { method: "DELETE" });
|
|
363
|
+
}
|
|
364
|
+
function resolveMcpSession(fetcher, token) {
|
|
365
|
+
return fetcher("/v1/mcp/session", {
|
|
366
|
+
method: "POST",
|
|
367
|
+
headers: { "Content-Type": "application/json" },
|
|
368
|
+
body: JSON.stringify({ token })
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
function authorizeMcp(fetcher, body, signal) {
|
|
372
|
+
return fetcher("/v1/auth/mcp/authorize", {
|
|
373
|
+
method: "POST",
|
|
374
|
+
headers: { "Content-Type": "application/json" },
|
|
375
|
+
body: JSON.stringify(body),
|
|
376
|
+
signal
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
function consentMcp(fetcher, body, signal) {
|
|
380
|
+
return fetcher("/v1/auth/mcp/consent", {
|
|
381
|
+
method: "POST",
|
|
382
|
+
headers: { "Content-Type": "application/json" },
|
|
383
|
+
body: JSON.stringify(body),
|
|
384
|
+
signal
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ../../packages/api-client/dist/authorization/impersonation.js
|
|
389
|
+
function getActiveImpersonationGrant(fetcher, staffUserId) {
|
|
390
|
+
return fetcher(`/v1/impersonation/active/${encodeURIComponent(staffUserId)}`, { method: "GET" });
|
|
391
|
+
}
|
|
392
|
+
function deleteImpersonationGrant(fetcher, staffUserId) {
|
|
393
|
+
return fetcher(`/v1/impersonation/${encodeURIComponent(staffUserId)}`, { method: "DELETE" });
|
|
394
|
+
}
|
|
395
|
+
function listImpersonationCustomers(request, query = {}, signal) {
|
|
396
|
+
return request(withQuery("/v1/staff/impersonation/customers", query), {
|
|
397
|
+
method: "GET",
|
|
398
|
+
signal
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
function startStaffImpersonation(fetcher, body) {
|
|
402
|
+
return fetcher("/v1/staff/impersonation/start", {
|
|
403
|
+
method: "POST",
|
|
404
|
+
headers: { "Content-Type": "application/json" },
|
|
405
|
+
body: JSON.stringify(body)
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function stopStaffImpersonation(fetcher) {
|
|
409
|
+
return fetcher("/v1/staff/impersonation/stop", { method: "POST" });
|
|
410
|
+
}
|
|
411
|
+
export {
|
|
412
|
+
acceptInvite,
|
|
413
|
+
addStaffOrganizationMember,
|
|
414
|
+
approveCliDeviceAuthorization,
|
|
415
|
+
approveSupplierApplicationFromSlack,
|
|
416
|
+
authorizeMcp,
|
|
417
|
+
authorizeStaff,
|
|
418
|
+
bookOnboardingCall,
|
|
419
|
+
browserSessionPath,
|
|
420
|
+
cancelOnboardingCall,
|
|
421
|
+
cancelOrganizationFollowUp,
|
|
422
|
+
changeEmail,
|
|
423
|
+
consentMcp,
|
|
424
|
+
countOrganizations,
|
|
425
|
+
createApiKey,
|
|
426
|
+
createInvite,
|
|
427
|
+
createOrganization,
|
|
428
|
+
createSlackSession,
|
|
429
|
+
createSshKey,
|
|
430
|
+
createStaffInvite,
|
|
431
|
+
createStaffOrganization,
|
|
432
|
+
createSupplierApplication,
|
|
433
|
+
deleteImpersonationGrant,
|
|
434
|
+
getActiveImpersonationGrant,
|
|
435
|
+
getBrowserSession,
|
|
436
|
+
getCliSession,
|
|
437
|
+
getInvite,
|
|
438
|
+
getMcpApplication,
|
|
439
|
+
getNotificationPreferences,
|
|
440
|
+
getOrganization,
|
|
441
|
+
getOrganizationMembership,
|
|
442
|
+
getPersonAvatar,
|
|
443
|
+
getStaffOrganization,
|
|
444
|
+
getUserPreferences,
|
|
445
|
+
getUserProfile,
|
|
446
|
+
inviteRedeemPath,
|
|
447
|
+
listAllSshKeys,
|
|
448
|
+
listApiKeys,
|
|
449
|
+
listAvailabilityAlerts,
|
|
450
|
+
listImpersonationCustomers,
|
|
451
|
+
listInvites,
|
|
452
|
+
listMcpConnections,
|
|
453
|
+
listOnboardingSlots,
|
|
454
|
+
listOrganizationMembers,
|
|
455
|
+
listOrganizations,
|
|
456
|
+
listOrganizationsByIds,
|
|
457
|
+
listOrganizationsForUser,
|
|
458
|
+
listSshKeys,
|
|
459
|
+
listStaffOrganizationInvites,
|
|
460
|
+
listStaffOrganizationMembers,
|
|
461
|
+
listSupplierApplications,
|
|
462
|
+
listSupplierOrganizations,
|
|
463
|
+
organizationAvatarPath,
|
|
464
|
+
personAvatarPath,
|
|
465
|
+
pollCliDeviceAuthorization,
|
|
466
|
+
removeOrganizationMember,
|
|
467
|
+
removeStaffOrganizationMember,
|
|
468
|
+
resolveMcpSession,
|
|
469
|
+
revokeApiKey,
|
|
470
|
+
revokeCliSession,
|
|
471
|
+
revokeInvite,
|
|
472
|
+
revokeMcpConnection,
|
|
473
|
+
revokeSshKey,
|
|
474
|
+
revokeStaffOrganizationInvite,
|
|
475
|
+
searchStaffOrganizations,
|
|
476
|
+
searchStaffPeople,
|
|
477
|
+
setAvailabilityAlert,
|
|
478
|
+
signInPath,
|
|
479
|
+
signOutBrowserSession,
|
|
480
|
+
startCliDeviceAuthorization,
|
|
481
|
+
startStaffImpersonation,
|
|
482
|
+
stopStaffImpersonation,
|
|
483
|
+
submitOnboardingIntake,
|
|
484
|
+
unsubscribePath,
|
|
485
|
+
updateNotificationPreferences,
|
|
486
|
+
updateOrganization,
|
|
487
|
+
updateOrganizationApproval,
|
|
488
|
+
updateSupplierApplication,
|
|
489
|
+
updateUserPreferences,
|
|
490
|
+
updateUserProfile
|
|
491
|
+
};
|
|
@@ -236,25 +236,55 @@ function ensureFacility(request, body2) {
|
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
// ../../packages/
|
|
240
|
-
|
|
241
|
-
const
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
|
|
239
|
+
// ../../packages/api-client/dist/authorization/paths.js
|
|
240
|
+
function withQuery(path, values) {
|
|
241
|
+
const query2 = new URLSearchParams();
|
|
242
|
+
for (const [key, value] of Object.entries(values)) {
|
|
243
|
+
if (value !== void 0 && value !== null && value !== "")
|
|
244
|
+
query2.set(key, Array.isArray(value) ? value.join(",") : String(value));
|
|
245
|
+
}
|
|
246
|
+
return query2.size ? `${path}?${query2}` : path;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ../../packages/api-client/dist/authorization/organizations.js
|
|
250
|
+
function listOrganizations(request, query2 = {}, signal) {
|
|
251
|
+
return request(withQuery("/v1/organizations", query2), { method: "GET", signal });
|
|
252
|
+
}
|
|
253
|
+
async function listSupplierOrganizations(request, signal) {
|
|
248
254
|
const rows = [];
|
|
249
255
|
for (let offset = 0; offset < 5e4; offset += 1e3) {
|
|
250
|
-
const page2 = await
|
|
256
|
+
const page2 = await listOrganizations(request, { role: "supplier", limit: 1e3, offset, sort: "created_at", direction: "asc" }, signal);
|
|
257
|
+
if (!Array.isArray(page2))
|
|
258
|
+
throw new Error("Invalid supplier directory response.");
|
|
251
259
|
rows.push(...page2);
|
|
252
260
|
if (page2.length < 1e3)
|
|
253
261
|
return rows;
|
|
254
262
|
}
|
|
255
|
-
throw new Error("
|
|
263
|
+
throw new Error("The supplier directory is too large to load completely.");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ../../packages/api-client/dist/authorization/staff.js
|
|
267
|
+
function createStaffInvite(request, body2) {
|
|
268
|
+
return request("/v1/staff/invites", { method: "POST", body: body2 });
|
|
256
269
|
}
|
|
257
270
|
|
|
271
|
+
// ../../packages/api-client/dist/authorization/sessions.js
|
|
272
|
+
function getCliSession(request) {
|
|
273
|
+
return request("/v1/cli/session", { method: "GET" });
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ../../packages/capabilities/dist/supplier-directory.js
|
|
277
|
+
function listSupplierOrganizationPage(fetch, input) {
|
|
278
|
+
return listOrganizations(fetch, {
|
|
279
|
+
role: "supplier",
|
|
280
|
+
...input,
|
|
281
|
+
q: input.q?.trim() || void 0,
|
|
282
|
+
sort: "created_at",
|
|
283
|
+
direction: "asc"
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
var listSupplierOrganizations2 = listSupplierOrganizations;
|
|
287
|
+
|
|
258
288
|
// ../../packages/capabilities/dist/capabilities/fleet.js
|
|
259
289
|
import { z as z2 } from "zod";
|
|
260
290
|
function queryPath(path, params) {
|
|
@@ -311,7 +341,6 @@ var listSuppliersCapability = defineCapability({
|
|
|
311
341
|
roles: ["admin"],
|
|
312
342
|
description: "List supplier organizations (id, name). Resolve supplier names to organization_id with this before nodes.list or facilities.list. When next_offset is present, pass it back as offset for the next page.",
|
|
313
343
|
mutation: "read",
|
|
314
|
-
http: { method: "GET", path: "/v1/organizations" },
|
|
315
344
|
slack: {
|
|
316
345
|
parameters: {
|
|
317
346
|
type: "object",
|
|
@@ -328,7 +357,7 @@ var listSuppliersCapability = defineCapability({
|
|
|
328
357
|
const paged = parsed.limit !== void 0 || parsed.offset !== void 0 || parsed.q !== void 0;
|
|
329
358
|
const limit = parsed.limit ?? 25;
|
|
330
359
|
const offset = parsed.offset ?? 0;
|
|
331
|
-
const rows = paged ? await listSupplierOrganizationPage(ctx.fetch, { ...parsed, limit, offset }) : await
|
|
360
|
+
const rows = paged ? await listSupplierOrganizationPage(ctx.fetch, { ...parsed, limit, offset }) : await listSupplierOrganizations2(ctx.fetch);
|
|
332
361
|
return {
|
|
333
362
|
suppliers: rows.map((org) => ({ id: org.id, name: org.name })),
|
|
334
363
|
...paged && rows.length === limit ? { next_offset: offset + rows.length } : {}
|
|
@@ -997,19 +1026,6 @@ var usersListInput = z5.object({
|
|
|
997
1026
|
limit: directoryLimit,
|
|
998
1027
|
offset: directoryOffset
|
|
999
1028
|
});
|
|
1000
|
-
function directoryPath(input) {
|
|
1001
|
-
const params = [`limit=${input.limit}`, `offset=${input.offset}`, "sort=name", "direction=asc"];
|
|
1002
|
-
if (input.q)
|
|
1003
|
-
params.push(`q=${encodeURIComponent(input.q)}`);
|
|
1004
|
-
if (input.role)
|
|
1005
|
-
params.push(`role=${encodeURIComponent(input.role)}`);
|
|
1006
|
-
if (input.approved !== void 0) {
|
|
1007
|
-
params.push(`approved=${input.approved}`);
|
|
1008
|
-
}
|
|
1009
|
-
if (input.ids)
|
|
1010
|
-
params.push(`ids=${encodeURIComponent(input.ids.join(","))}`);
|
|
1011
|
-
return `/v1/organizations?${params.join("&")}`;
|
|
1012
|
-
}
|
|
1013
1029
|
function directoryMembers(organization) {
|
|
1014
1030
|
return organization.members ?? [];
|
|
1015
1031
|
}
|
|
@@ -1027,7 +1043,6 @@ var organizationListCapability = defineCapability({
|
|
|
1027
1043
|
roles: ["admin"],
|
|
1028
1044
|
description: "List organizations from the Authorization directory. Search by company name, contact/member name, or email; filter by role, approval, or UUIDs. When next_offset is present, pass it back as offset for the next page. Use the organization id as organizationId when recording downtime, and ask the user to choose if matches are ambiguous.",
|
|
1029
1045
|
mutation: "read",
|
|
1030
|
-
http: { method: "GET", path: "/v1/organizations" },
|
|
1031
1046
|
slack: {
|
|
1032
1047
|
parameters: {
|
|
1033
1048
|
type: "object",
|
|
@@ -1054,8 +1069,12 @@ var organizationListCapability = defineCapability({
|
|
|
1054
1069
|
const parsed = organizationListInput.parse(input);
|
|
1055
1070
|
const limit = parsed.limit;
|
|
1056
1071
|
const offset = parsed.offset ?? 0;
|
|
1057
|
-
const rows = await ctx.fetch
|
|
1058
|
-
|
|
1072
|
+
const rows = await listOrganizations(ctx.fetch, {
|
|
1073
|
+
...parsed,
|
|
1074
|
+
limit,
|
|
1075
|
+
offset,
|
|
1076
|
+
sort: "name",
|
|
1077
|
+
direction: "asc"
|
|
1059
1078
|
});
|
|
1060
1079
|
return {
|
|
1061
1080
|
organizations: rows.map((organization) => ({
|
|
@@ -1079,7 +1098,6 @@ var usersListCapability = defineCapability({
|
|
|
1079
1098
|
roles: ["admin"],
|
|
1080
1099
|
description: "List users who belong to an organization, from the Authorization directory. Search by person name, email, or company name; use organization_id to restrict results to one organization. When next_offset is present, pass it back as offset for the next page.",
|
|
1081
1100
|
mutation: "read",
|
|
1082
|
-
http: { method: "GET", path: "/v1/organizations" },
|
|
1083
1101
|
slack: {
|
|
1084
1102
|
parameters: {
|
|
1085
1103
|
type: "object",
|
|
@@ -1102,12 +1120,14 @@ var usersListCapability = defineCapability({
|
|
|
1102
1120
|
const parsed = usersListInput.parse(input);
|
|
1103
1121
|
const limit = parsed.limit;
|
|
1104
1122
|
const offset = parsed.offset ?? 0;
|
|
1105
|
-
const rows = await ctx.fetch
|
|
1123
|
+
const rows = await listOrganizations(ctx.fetch, {
|
|
1106
1124
|
limit,
|
|
1107
1125
|
offset,
|
|
1108
1126
|
q: parsed.q,
|
|
1109
|
-
ids: parsed.organization_id ? [parsed.organization_id] : void 0
|
|
1110
|
-
|
|
1127
|
+
ids: parsed.organization_id ? [parsed.organization_id] : void 0,
|
|
1128
|
+
sort: "name",
|
|
1129
|
+
direction: "asc"
|
|
1130
|
+
});
|
|
1111
1131
|
const q = parsed.q?.toLowerCase();
|
|
1112
1132
|
const users = rows.flatMap((organization) => {
|
|
1113
1133
|
const members = directoryMembers(organization);
|
|
@@ -5094,7 +5114,7 @@ var whoamiCapability = defineCapability({
|
|
|
5094
5114
|
mutation: "read",
|
|
5095
5115
|
http: { method: "GET", path: "/v1/cli/session" },
|
|
5096
5116
|
input: emptyInput3,
|
|
5097
|
-
execute: async (ctx) => ctx.fetch
|
|
5117
|
+
execute: async (ctx) => getCliSession(ctx.fetch)
|
|
5098
5118
|
});
|
|
5099
5119
|
var statusCapability = defineCapability({
|
|
5100
5120
|
id: "identity.status",
|
|
@@ -5349,7 +5369,7 @@ var createListingCapability = defineCapability({
|
|
|
5349
5369
|
const supplierQuery = (parsed.site_supplier ?? "").trim().toLowerCase();
|
|
5350
5370
|
const place = (parsed.site_nickname ?? parsed.site ?? "").trim();
|
|
5351
5371
|
if (!organizationId && supplierQuery) {
|
|
5352
|
-
const matches = (await
|
|
5372
|
+
const matches = (await listSupplierOrganizations2(ctx.fetch)).filter((org) => org.id.toLowerCase() === supplierQuery || org.name.toLowerCase() === supplierQuery);
|
|
5353
5373
|
if (matches.length !== 1) {
|
|
5354
5374
|
return { ok: false, error: matches.length ? "ambiguous_supplier" : "supplier_not_found" };
|
|
5355
5375
|
}
|
|
@@ -5493,7 +5513,6 @@ var organizationInviteCapability = defineCapability({
|
|
|
5493
5513
|
roles: ["admin"],
|
|
5494
5514
|
description: "Invite a person to an existing organization (emails by default; send_email=false returns a join link), or omit organization_id to create a signup link with organization_role=consumer or supplier. Resolve organization UUIDs first; ask if ambiguous. Executes immediately. Keep invitation links secret.",
|
|
5495
5515
|
mutation: "immediate",
|
|
5496
|
-
http: { method: "POST", path: "/v1/staff/invites" },
|
|
5497
5516
|
cli: {
|
|
5498
5517
|
command: ["admin", "organizations", "invite"],
|
|
5499
5518
|
vnext: {
|
|
@@ -5528,9 +5547,9 @@ var organizationInviteCapability = defineCapability({
|
|
|
5528
5547
|
input: organizationInviteInput,
|
|
5529
5548
|
execute: async (ctx, input) => {
|
|
5530
5549
|
const parsed = organizationInviteInput.parse(input);
|
|
5531
|
-
return ctx.fetch
|
|
5532
|
-
|
|
5533
|
-
|
|
5550
|
+
return createStaffInvite(ctx.fetch, {
|
|
5551
|
+
...parsed,
|
|
5552
|
+
send_email: parsed.send_email ?? parsed.organization_id !== void 0
|
|
5534
5553
|
});
|
|
5535
5554
|
}
|
|
5536
5555
|
});
|