@meshagent/meshagent 0.44.13 → 0.45.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 +5 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/meshagent-client.d.ts +390 -372
- package/dist/browser/meshagent-client.js +841 -1040
- package/dist/browser/oauth-scopes.d.ts +1 -1
- package/dist/browser/oauth-scopes.js +64 -14
- package/dist/browser/participant-token.d.ts +68 -20
- package/dist/browser/participant-token.js +232 -61
- package/dist/browser/room-client.d.ts +4 -8
- package/dist/browser/room-client.js +4 -10
- package/dist/browser/services-client.d.ts +11 -0
- package/dist/browser/services-client.js +17 -0
- package/dist/browser/sqlite-client.d.ts +326 -0
- package/dist/browser/sqlite-client.js +630 -0
- package/dist/browser/toolkit-config.d.ts +7 -1
- package/dist/browser/toolkit-config.js +41 -22
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/meshagent-client.d.ts +390 -372
- package/dist/esm/meshagent-client.js +841 -1038
- package/dist/esm/oauth-scopes.d.ts +1 -1
- package/dist/esm/oauth-scopes.js +64 -14
- package/dist/esm/participant-token.d.ts +68 -20
- package/dist/esm/participant-token.js +228 -59
- package/dist/esm/room-client.d.ts +4 -8
- package/dist/esm/room-client.js +4 -10
- package/dist/esm/services-client.d.ts +11 -0
- package/dist/esm/services-client.js +17 -0
- package/dist/esm/sqlite-client.d.ts +326 -0
- package/dist/esm/sqlite-client.js +625 -0
- package/dist/esm/toolkit-config.d.ts +7 -1
- package/dist/esm/toolkit-config.js +41 -22
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +1 -1
- package/dist/node/meshagent-client.d.ts +390 -372
- package/dist/node/meshagent-client.js +841 -1040
- package/dist/node/oauth-scopes.d.ts +1 -1
- package/dist/node/oauth-scopes.js +64 -14
- package/dist/node/participant-token.d.ts +68 -20
- package/dist/node/participant-token.js +232 -61
- package/dist/node/room-client.d.ts +4 -8
- package/dist/node/room-client.js +4 -10
- package/dist/node/services-client.d.ts +11 -0
- package/dist/node/services-client.js +17 -0
- package/dist/node/sqlite-client.d.ts +326 -0
- package/dist/node/sqlite-client.js +630 -0
- package/dist/node/toolkit-config.d.ts +7 -1
- package/dist/node/toolkit-config.js +41 -22
- package/package.json +1 -1
- package/dist/browser/secrets-client.d.ts +0 -112
- package/dist/browser/secrets-client.js +0 -300
- package/dist/esm/secrets-client.d.ts +0 -112
- package/dist/esm/secrets-client.js +0 -296
- package/dist/node/secrets-client.d.ts +0 -112
- package/dist/node/secrets-client.js +0 -300
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { meshagentBaseUrl } from "./helpers.js";
|
|
2
2
|
import { ForbiddenException, RoomException } from "./requirement.js";
|
|
3
|
-
import { ApiScope } from "./participant-token.js";
|
|
4
|
-
import { decoder, encoder } from "./utils.js";
|
|
5
3
|
export class RoomSession {
|
|
6
4
|
constructor({ id, roomId, roomName, createdAt, isActive, participants, kind = "room", agentId, agentName, }) {
|
|
7
5
|
this.id = id;
|
|
@@ -27,226 +25,75 @@ export class RoomSession {
|
|
|
27
25
|
};
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
|
-
function
|
|
31
|
-
if (Array.isArray(value)) {
|
|
32
|
-
return value.map((item) => cloneJsonValue(item));
|
|
33
|
-
}
|
|
34
|
-
if (value != null && typeof value === "object") {
|
|
35
|
-
const result = {};
|
|
36
|
-
for (const [key, item] of Object.entries(value)) {
|
|
37
|
-
result[key] = cloneJsonValue(item);
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
return value;
|
|
42
|
-
}
|
|
43
|
-
function formatTemplateString(value, values) {
|
|
44
|
-
return value.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (token, key) => values[key] ?? token);
|
|
45
|
-
}
|
|
46
|
-
function formatJsonValue(value, values) {
|
|
28
|
+
function applyTemplateValues(value, values) {
|
|
47
29
|
if (typeof value === "string") {
|
|
48
|
-
return
|
|
30
|
+
return Object.entries(values).reduce((current, [key, replacement]) => current.split(`{${key}}`).join(replacement), value);
|
|
49
31
|
}
|
|
50
32
|
if (Array.isArray(value)) {
|
|
51
|
-
return value.map((item) =>
|
|
33
|
+
return value.map((item) => applyTemplateValues(item, values));
|
|
52
34
|
}
|
|
53
|
-
if (value
|
|
35
|
+
if (value !== null && typeof value === "object") {
|
|
54
36
|
const result = {};
|
|
55
|
-
for (const [key,
|
|
56
|
-
result[key] =
|
|
37
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
38
|
+
result[key] = applyTemplateValues(entry, values);
|
|
57
39
|
}
|
|
58
40
|
return result;
|
|
59
41
|
}
|
|
60
42
|
return value;
|
|
61
43
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
function normalizeFileMount(value) {
|
|
101
|
-
return {
|
|
102
|
-
path: stringValue(value.path) ?? "",
|
|
103
|
-
...(stringValue(value.subpath) !== undefined ? { subpath: stringValue(value.subpath) } : {}),
|
|
104
|
-
read_only: booleanValue(value.read_only) ?? true,
|
|
105
|
-
text: stringValue(value.text) ?? "",
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
function normalizeEmptyDirMount(value) {
|
|
109
|
-
return {
|
|
110
|
-
path: stringValue(value.path) ?? "",
|
|
111
|
-
read_only: booleanValue(value.read_only) ?? false,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
function normalizeConfigMount(value) {
|
|
115
|
-
return {
|
|
116
|
-
path: stringValue(value.path) ?? "/var/run/meshagent",
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function normalizeContainerMountSpec(value) {
|
|
120
|
-
const source = objectOrUndefined(value) ?? {};
|
|
121
|
-
const room = objectArray(source.room)?.map(normalizeRoomMount);
|
|
122
|
-
const project = objectArray(source.project)?.map(normalizeProjectMount);
|
|
123
|
-
const images = objectArray(source.images)?.map(normalizeImageMount);
|
|
124
|
-
const files = objectArray(source.files)?.map(normalizeFileMount);
|
|
125
|
-
const emptyDirs = objectArray(source.empty_dirs)?.map(normalizeEmptyDirMount);
|
|
126
|
-
const configs = objectArray(source.configs)?.map(normalizeConfigMount);
|
|
127
|
-
return {
|
|
128
|
-
...(room !== undefined ? { room } : {}),
|
|
129
|
-
...(project !== undefined ? { project } : {}),
|
|
130
|
-
...(images !== undefined ? { images } : {}),
|
|
131
|
-
...(files !== undefined ? { files } : {}),
|
|
132
|
-
...(emptyDirs !== undefined ? { empty_dirs: emptyDirs } : {}),
|
|
133
|
-
...(configs !== undefined ? { configs } : {}),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
function normalizeAgentSpec(agent, values) {
|
|
137
|
-
const formatted = formatJsonValue(agent, values);
|
|
138
|
-
const spec = cloneJsonValue(formatted);
|
|
139
|
-
if (spec.email != null && spec.email.public == null) {
|
|
140
|
-
spec.email = { ...spec.email, public: false };
|
|
141
|
-
}
|
|
142
|
-
if (spec.channels?.email) {
|
|
143
|
-
spec.channels = {
|
|
144
|
-
...spec.channels,
|
|
145
|
-
email: spec.channels.email.map((channel) => ({
|
|
146
|
-
...channel,
|
|
147
|
-
private: channel.private ?? false,
|
|
148
|
-
})),
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (spec.channels?.messaging) {
|
|
152
|
-
spec.channels = {
|
|
153
|
-
...spec.channels,
|
|
154
|
-
messaging: spec.channels.messaging.map((channel) => ({
|
|
155
|
-
...channel,
|
|
156
|
-
protocol: channel.protocol ?? "meshagent.agent-message.v1",
|
|
157
|
-
})),
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
return spec;
|
|
161
|
-
}
|
|
162
|
-
export function normalizeServiceSpec(service) {
|
|
163
|
-
const normalized = cloneJsonValue(service);
|
|
164
|
-
if (normalized.container?.storage != null) {
|
|
165
|
-
normalized.container = {
|
|
166
|
-
...normalized.container,
|
|
167
|
-
storage: normalizeContainerMountSpec(normalized.container.storage),
|
|
44
|
+
function normalizeServiceSpec(service) {
|
|
45
|
+
const storage = service.container?.storage;
|
|
46
|
+
const agents = service.agents?.map((agent) => ({
|
|
47
|
+
...agent,
|
|
48
|
+
email: agent.email == null
|
|
49
|
+
? agent.email
|
|
50
|
+
: {
|
|
51
|
+
...agent.email,
|
|
52
|
+
public: agent.email.public ?? false,
|
|
53
|
+
},
|
|
54
|
+
channels: agent.channels == null
|
|
55
|
+
? agent.channels
|
|
56
|
+
: {
|
|
57
|
+
...agent.channels,
|
|
58
|
+
messaging: agent.channels.messaging?.map((channel) => ({
|
|
59
|
+
...channel,
|
|
60
|
+
protocol: channel.protocol ?? "meshagent.agent-message.v1",
|
|
61
|
+
})),
|
|
62
|
+
},
|
|
63
|
+
}));
|
|
64
|
+
const container = service.container == null
|
|
65
|
+
? service.container
|
|
66
|
+
: {
|
|
67
|
+
...service.container,
|
|
68
|
+
storage: storage == null
|
|
69
|
+
? storage
|
|
70
|
+
: {
|
|
71
|
+
...storage,
|
|
72
|
+
configs: storage.configs?.map((config) => ({
|
|
73
|
+
...config,
|
|
74
|
+
path: config.path ?? "/var/run/meshagent",
|
|
75
|
+
})),
|
|
76
|
+
files: storage.files?.map((file) => ({
|
|
77
|
+
...file,
|
|
78
|
+
read_only: file.read_only ?? true,
|
|
79
|
+
})),
|
|
80
|
+
},
|
|
168
81
|
};
|
|
169
|
-
}
|
|
170
|
-
return normalized;
|
|
82
|
+
return { ...service, agents, container };
|
|
171
83
|
}
|
|
172
84
|
export class ServiceTemplateSpec {
|
|
173
|
-
constructor(
|
|
174
|
-
this.
|
|
175
|
-
this.kind = kind;
|
|
176
|
-
this.variables = variables;
|
|
177
|
-
this.metadata = metadata;
|
|
178
|
-
this.ports = ports;
|
|
179
|
-
this.container = container;
|
|
180
|
-
this.external = external;
|
|
181
|
-
this.agents = agents;
|
|
85
|
+
constructor(template) {
|
|
86
|
+
this.template = template;
|
|
182
87
|
}
|
|
183
88
|
static fromJson(json) {
|
|
184
|
-
|
|
185
|
-
if (metadata === undefined || typeof metadata.name !== "string") {
|
|
186
|
-
throw new RoomException("Invalid service template payload: missing metadata.name");
|
|
187
|
-
}
|
|
188
|
-
return new ServiceTemplateSpec({
|
|
189
|
-
version: stringValue(json.version) ?? "v1",
|
|
190
|
-
kind: stringValue(json.kind) ?? "ServiceTemplate",
|
|
191
|
-
variables: objectArray(json.variables),
|
|
192
|
-
metadata: cloneJsonValue(metadata),
|
|
193
|
-
ports: (objectArray(json.ports) ?? []),
|
|
194
|
-
container: objectOrUndefined(json.container),
|
|
195
|
-
external: objectOrUndefined(json.external),
|
|
196
|
-
agents: objectArray(json.agents) ?? [],
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
toJson() {
|
|
200
|
-
return {
|
|
201
|
-
version: this.version,
|
|
202
|
-
kind: this.kind,
|
|
203
|
-
...(this.variables != null ? { variables: cloneJsonValue(this.variables) } : {}),
|
|
204
|
-
metadata: cloneJsonValue(this.metadata),
|
|
205
|
-
...(this.ports.length > 0 ? { ports: cloneJsonValue(this.ports) } : {}),
|
|
206
|
-
...(this.container != null ? { container: cloneJsonValue(this.container) } : {}),
|
|
207
|
-
...(this.external != null ? { external: cloneJsonValue(this.external) } : {}),
|
|
208
|
-
...(this.agents.length > 0 ? { agents: cloneJsonValue(this.agents) } : {}),
|
|
209
|
-
};
|
|
89
|
+
return new ServiceTemplateSpec(json);
|
|
210
90
|
}
|
|
211
91
|
toServiceSpec({ values = {} } = {}) {
|
|
212
|
-
const
|
|
213
|
-
|
|
92
|
+
const templated = applyTemplateValues(this.template, values);
|
|
93
|
+
return normalizeServiceSpec({
|
|
94
|
+
...templated,
|
|
214
95
|
kind: "Service",
|
|
215
|
-
|
|
216
|
-
agents: this.agents.map((agent) => normalizeAgentSpec(agent, values)),
|
|
217
|
-
ports: cloneJsonValue(this.ports),
|
|
218
|
-
};
|
|
219
|
-
if (this.container != null) {
|
|
220
|
-
const formattedContainer = formatJsonValue(this.container, values);
|
|
221
|
-
const image = stringValue(formattedContainer.image);
|
|
222
|
-
if (image === undefined || image.length === 0) {
|
|
223
|
-
throw new RoomException("ServiceTemplateSpec.image is required to build a ServiceSpec");
|
|
224
|
-
}
|
|
225
|
-
service.container = {
|
|
226
|
-
...(booleanValue(formattedContainer.private) !== undefined ? { private: booleanValue(formattedContainer.private) } : {}),
|
|
227
|
-
...(stringValue(formattedContainer.command) !== undefined ? { command: stringValue(formattedContainer.command) } : {}),
|
|
228
|
-
...(stringValue(formattedContainer.working_dir) !== undefined ? { working_dir: stringValue(formattedContainer.working_dir) } : {}),
|
|
229
|
-
image,
|
|
230
|
-
...(Array.isArray(formattedContainer.environment)
|
|
231
|
-
? { environment: formattedContainer.environment }
|
|
232
|
-
: {}),
|
|
233
|
-
...(objectOrUndefined(formattedContainer.storage) !== undefined
|
|
234
|
-
? { storage: normalizeContainerMountSpec(formattedContainer.storage) }
|
|
235
|
-
: {}),
|
|
236
|
-
...(booleanValue(formattedContainer.on_demand) !== undefined ? { on_demand: booleanValue(formattedContainer.on_demand) } : {}),
|
|
237
|
-
...(booleanValue(formattedContainer.writable_root_fs) !== undefined
|
|
238
|
-
? { writable_root_fs: booleanValue(formattedContainer.writable_root_fs) }
|
|
239
|
-
: {}),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
if (this.external != null) {
|
|
243
|
-
const formattedExternal = formatJsonValue(this.external, values);
|
|
244
|
-
const url = stringValue(formattedExternal.url);
|
|
245
|
-
if (url !== undefined) {
|
|
246
|
-
service.external = { url };
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return normalizeServiceSpec(service);
|
|
96
|
+
});
|
|
250
97
|
}
|
|
251
98
|
}
|
|
252
99
|
function pruneUndefinedValues(value) {
|
|
@@ -271,28 +118,62 @@ function pruneUndefinedValues(value) {
|
|
|
271
118
|
}
|
|
272
119
|
return value;
|
|
273
120
|
}
|
|
274
|
-
function
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
.filter((item) => item !== undefined);
|
|
121
|
+
function validateServiceSpec(service) {
|
|
122
|
+
const container = service.container;
|
|
123
|
+
if (container == null) {
|
|
124
|
+
return;
|
|
279
125
|
}
|
|
280
|
-
if (
|
|
281
|
-
|
|
126
|
+
if (typeof container.run_as === "string") {
|
|
127
|
+
throw new Error("container.run_as must be an object with an email field");
|
|
282
128
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
129
|
+
const environment = container.environment ?? [];
|
|
130
|
+
const hasSecretEnvironment = environment.some((entry) => entry.secret != null);
|
|
131
|
+
if (hasSecretEnvironment && container.run_as == null) {
|
|
132
|
+
throw new Error("container.run_as is required when using SecretValue");
|
|
133
|
+
}
|
|
134
|
+
for (const entry of environment) {
|
|
135
|
+
const secret = entry.secret;
|
|
136
|
+
if (secret == null) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const unsupportedFields = Object.keys(secret).filter((key) => key !== "id");
|
|
140
|
+
if (unsupportedFields.length > 0) {
|
|
141
|
+
throw new Error(`unsupported SecretValue fields: ${unsupportedFields.join(", ")}`);
|
|
290
142
|
}
|
|
291
|
-
return result;
|
|
292
143
|
}
|
|
293
|
-
|
|
144
|
+
const pullSecret = container.pull_secret;
|
|
145
|
+
if (pullSecret != null) {
|
|
146
|
+
const unsupportedFields = Object.keys(pullSecret).filter((key) => key !== "id");
|
|
147
|
+
if (unsupportedFields.length > 0) {
|
|
148
|
+
throw new Error(`unsupported SecretValue fields: ${unsupportedFields.join(", ")}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const defaultServiceRunAsScopes = ["secrets:proxy"];
|
|
153
|
+
function normalizeServiceRunAs(runAs) {
|
|
154
|
+
if (runAs == null) {
|
|
155
|
+
return runAs;
|
|
156
|
+
}
|
|
157
|
+
const email = runAs.email.trim().toLowerCase();
|
|
158
|
+
if (email.length === 0) {
|
|
159
|
+
throw new Error("container.run_as.email is required");
|
|
160
|
+
}
|
|
161
|
+
const scopes = runAs.scopes == null ? defaultServiceRunAsScopes : runAs.scopes;
|
|
162
|
+
const normalizedScopes = [];
|
|
163
|
+
for (const scope of scopes) {
|
|
164
|
+
const normalized = scope.trim();
|
|
165
|
+
if (normalized.length === 0 || normalizedScopes.includes(normalized)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
normalizedScopes.push(normalized);
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
email,
|
|
172
|
+
scopes: normalizedScopes.length === 0 ? [...defaultServiceRunAsScopes] : normalizedScopes,
|
|
173
|
+
};
|
|
294
174
|
}
|
|
295
175
|
function serializeServiceSpec(service) {
|
|
176
|
+
validateServiceSpec(service);
|
|
296
177
|
const agents = service.agents?.map((agent) => ({
|
|
297
178
|
...agent,
|
|
298
179
|
channels: agent.channels == null
|
|
@@ -305,8 +186,15 @@ function serializeServiceSpec(service) {
|
|
|
305
186
|
})),
|
|
306
187
|
},
|
|
307
188
|
}));
|
|
189
|
+
const container = service.container == null
|
|
190
|
+
? service.container
|
|
191
|
+
: {
|
|
192
|
+
...service.container,
|
|
193
|
+
run_as: normalizeServiceRunAs(service.container.run_as),
|
|
194
|
+
};
|
|
308
195
|
return pruneUndefinedValues({
|
|
309
196
|
...service,
|
|
197
|
+
container,
|
|
310
198
|
agents,
|
|
311
199
|
});
|
|
312
200
|
}
|
|
@@ -315,45 +203,6 @@ function serializeCreateServiceSpec(service) {
|
|
|
315
203
|
delete payload.id;
|
|
316
204
|
return payload;
|
|
317
205
|
}
|
|
318
|
-
export class ManagedAgentGrant {
|
|
319
|
-
constructor({ admin = false } = {}) {
|
|
320
|
-
this.admin = admin;
|
|
321
|
-
}
|
|
322
|
-
static fromJson(json) {
|
|
323
|
-
return new ManagedAgentGrant({ admin: json["admin"] === true });
|
|
324
|
-
}
|
|
325
|
-
toJson() {
|
|
326
|
-
return { admin: this.admin };
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
const globalScope = globalThis;
|
|
330
|
-
function bytesToBase64(bytes) {
|
|
331
|
-
if (globalScope.Buffer) {
|
|
332
|
-
return globalScope.Buffer.from(bytes).toString("base64");
|
|
333
|
-
}
|
|
334
|
-
if (!globalScope.btoa) {
|
|
335
|
-
throw new Error("base64 encoding is not available in this runtime");
|
|
336
|
-
}
|
|
337
|
-
let binary = "";
|
|
338
|
-
for (const byte of bytes) {
|
|
339
|
-
binary += String.fromCharCode(byte);
|
|
340
|
-
}
|
|
341
|
-
return globalScope.btoa(binary);
|
|
342
|
-
}
|
|
343
|
-
function base64ToBytes(base64) {
|
|
344
|
-
if (globalScope.Buffer) {
|
|
345
|
-
return Uint8Array.from(globalScope.Buffer.from(base64, "base64"));
|
|
346
|
-
}
|
|
347
|
-
if (!globalScope.atob) {
|
|
348
|
-
throw new Error("base64 decoding is not available in this runtime");
|
|
349
|
-
}
|
|
350
|
-
const binary = globalScope.atob(base64);
|
|
351
|
-
const bytes = new Uint8Array(binary.length);
|
|
352
|
-
for (let index = 0; index < binary.length; index += 1) {
|
|
353
|
-
bytes[index] = binary.charCodeAt(index);
|
|
354
|
-
}
|
|
355
|
-
return bytes;
|
|
356
|
-
}
|
|
357
206
|
function toFetchBody(body) {
|
|
358
207
|
if (body == null) {
|
|
359
208
|
return undefined;
|
|
@@ -365,11 +214,16 @@ function toFetchBody(body) {
|
|
|
365
214
|
copy.set(body);
|
|
366
215
|
return copy.buffer;
|
|
367
216
|
}
|
|
368
|
-
function
|
|
369
|
-
|
|
370
|
-
|
|
217
|
+
function bytesToBase64(value) {
|
|
218
|
+
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
219
|
+
if (typeof Buffer !== "undefined") {
|
|
220
|
+
return Buffer.from(bytes).toString("base64");
|
|
371
221
|
}
|
|
372
|
-
|
|
222
|
+
let binary = "";
|
|
223
|
+
for (const byte of bytes) {
|
|
224
|
+
binary += String.fromCharCode(byte);
|
|
225
|
+
}
|
|
226
|
+
return btoa(binary);
|
|
373
227
|
}
|
|
374
228
|
export class Meshagent {
|
|
375
229
|
constructor({ baseUrl, token } = {}) {
|
|
@@ -428,11 +282,10 @@ export class Meshagent {
|
|
|
428
282
|
catch {
|
|
429
283
|
message = "<unable to read body>";
|
|
430
284
|
}
|
|
431
|
-
const errorMessage = `Failed to ${action}. Status code: ${response.status}, body: ${message}`;
|
|
432
285
|
if (response.status === 403) {
|
|
433
|
-
throw new ForbiddenException(
|
|
286
|
+
throw new ForbiddenException(`Failed to ${action}. Status code: ${response.status}, body: ${message}`);
|
|
434
287
|
}
|
|
435
|
-
throw new RoomException(
|
|
288
|
+
throw new RoomException(`Failed to ${action}. Status code: ${response.status}, body: ${message}`);
|
|
436
289
|
}
|
|
437
290
|
switch (responseType) {
|
|
438
291
|
case "json":
|
|
@@ -449,22 +302,46 @@ export class Meshagent {
|
|
|
449
302
|
return undefined;
|
|
450
303
|
}
|
|
451
304
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
305
|
+
secretPayload(input) {
|
|
306
|
+
const payload = {};
|
|
307
|
+
if (input.projectId !== undefined)
|
|
308
|
+
payload.project_id = input.projectId;
|
|
309
|
+
if (input.name !== undefined)
|
|
310
|
+
payload.name = input.name;
|
|
311
|
+
if (input.type !== undefined)
|
|
312
|
+
payload.type = input.type;
|
|
313
|
+
if (input.httpOnly !== undefined)
|
|
314
|
+
payload.http_only = input.httpOnly;
|
|
315
|
+
if (input.metadata !== undefined)
|
|
316
|
+
payload.metadata = input.metadata;
|
|
317
|
+
if (input.annotations !== undefined)
|
|
318
|
+
payload.annotations = input.annotations;
|
|
319
|
+
return payload;
|
|
320
|
+
}
|
|
321
|
+
secretSearchPayload(input) {
|
|
322
|
+
const payload = {
|
|
323
|
+
page_size: input.pageSize ?? 100,
|
|
324
|
+
};
|
|
325
|
+
if (input.filter !== undefined)
|
|
326
|
+
payload.filter = input.filter;
|
|
327
|
+
if (input.name !== undefined)
|
|
328
|
+
payload.name = input.name;
|
|
329
|
+
if (input.type !== undefined)
|
|
330
|
+
payload.type = input.type;
|
|
331
|
+
if (input.httpOnly !== undefined)
|
|
332
|
+
payload.http_only = input.httpOnly;
|
|
333
|
+
if (input.metadata !== undefined)
|
|
334
|
+
payload.metadata = input.metadata;
|
|
335
|
+
if (input.annotations !== undefined)
|
|
336
|
+
payload.annotations = input.annotations;
|
|
337
|
+
if (input.continuationToken !== undefined)
|
|
338
|
+
payload.continuation_token = input.continuationToken;
|
|
339
|
+
return payload;
|
|
340
|
+
}
|
|
341
|
+
secretVersionPayload(input) {
|
|
464
342
|
return {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
settings: (settings && typeof settings === "object") ? settings : {},
|
|
343
|
+
value_base64: bytesToBase64(input.value),
|
|
344
|
+
set_current: input.setCurrent ?? true,
|
|
468
345
|
};
|
|
469
346
|
}
|
|
470
347
|
parseRoomSession(data) {
|
|
@@ -494,34 +371,33 @@ export class Meshagent {
|
|
|
494
371
|
createdAt: new Date(created),
|
|
495
372
|
isActive: isActiveValue,
|
|
496
373
|
participants: participants && typeof participants === "object" ? participants : undefined,
|
|
497
|
-
kind: typeof kind === "string" ? kind :
|
|
374
|
+
kind: typeof kind === "string" ? kind : undefined,
|
|
498
375
|
agentId: typeof agentId === "string" ? agentId : typeof agentIdRaw === "string" ? agentIdRaw : undefined,
|
|
499
376
|
agentName: typeof agentName === "string" ? agentName : typeof agentNameRaw === "string" ? agentNameRaw : undefined,
|
|
500
377
|
});
|
|
501
378
|
}
|
|
502
|
-
|
|
379
|
+
parseRoom(data) {
|
|
503
380
|
if (!data || typeof data !== "object") {
|
|
504
|
-
throw new RoomException("Invalid
|
|
381
|
+
throw new RoomException("Invalid room payload");
|
|
505
382
|
}
|
|
506
|
-
const { id, name,
|
|
383
|
+
const { id, name, metadata, annotations } = data;
|
|
507
384
|
if (typeof id !== "string" || typeof name !== "string") {
|
|
508
|
-
throw new RoomException("Invalid
|
|
385
|
+
throw new RoomException("Invalid room payload: missing id or name");
|
|
509
386
|
}
|
|
510
387
|
return {
|
|
511
388
|
id,
|
|
512
389
|
name,
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
: {},
|
|
390
|
+
metadata: metadata && typeof metadata === "object" ? metadata : {},
|
|
391
|
+
annotations: annotations && typeof annotations === "object" ? annotations : {},
|
|
516
392
|
};
|
|
517
393
|
}
|
|
518
|
-
|
|
394
|
+
parseGroup(data) {
|
|
519
395
|
if (!data || typeof data !== "object") {
|
|
520
|
-
throw new RoomException("Invalid
|
|
396
|
+
throw new RoomException("Invalid group payload");
|
|
521
397
|
}
|
|
522
398
|
const { id, name, metadata, annotations } = data;
|
|
523
399
|
if (typeof id !== "string" || typeof name !== "string") {
|
|
524
|
-
throw new RoomException("Invalid
|
|
400
|
+
throw new RoomException("Invalid group payload: missing id or name");
|
|
525
401
|
}
|
|
526
402
|
return {
|
|
527
403
|
id,
|
|
@@ -681,53 +557,170 @@ export class Meshagent {
|
|
|
681
557
|
createdAt: new Date(createdAtValue),
|
|
682
558
|
};
|
|
683
559
|
}
|
|
684
|
-
|
|
685
|
-
if (!
|
|
686
|
-
throw new RoomException("Invalid
|
|
687
|
-
}
|
|
688
|
-
const roomData = data.room;
|
|
689
|
-
const room = this.parseRoom(roomData);
|
|
690
|
-
const userId = data.user_id ?? data.userId;
|
|
691
|
-
if (typeof userId !== "string") {
|
|
692
|
-
throw new RoomException("Invalid room grant payload: missing user_id");
|
|
560
|
+
parseAccessResource(resource) {
|
|
561
|
+
if (!resource || typeof resource !== "object" || typeof resource.type !== "string" || typeof resource.id !== "string") {
|
|
562
|
+
throw new RoomException("Invalid access resource payload");
|
|
693
563
|
}
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
564
|
+
return {
|
|
565
|
+
type: resource.type,
|
|
566
|
+
id: resource.id,
|
|
567
|
+
name: typeof resource.name === "string" ? resource.name : null,
|
|
568
|
+
metadata: resource.metadata && typeof resource.metadata === "object" ? resource.metadata : {},
|
|
569
|
+
annotations: resource.annotations && typeof resource.annotations === "object" ? resource.annotations : {},
|
|
570
|
+
};
|
|
697
571
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
throw new RoomException("Invalid room grant count payload: missing room");
|
|
702
|
-
}
|
|
703
|
-
const room = this.parseRoom(roomData);
|
|
704
|
-
const count = data.count;
|
|
705
|
-
if (typeof count !== "number") {
|
|
706
|
-
throw new RoomException("Invalid room grant count payload: missing count");
|
|
572
|
+
parseAccessSubject(subject) {
|
|
573
|
+
if (!subject || typeof subject !== "object" || typeof subject.type !== "string" || typeof subject.id !== "string") {
|
|
574
|
+
throw new RoomException("Invalid access subject payload");
|
|
707
575
|
}
|
|
708
|
-
return {
|
|
576
|
+
return {
|
|
577
|
+
type: subject.type,
|
|
578
|
+
id: subject.id,
|
|
579
|
+
name: typeof subject.name === "string" ? subject.name : null,
|
|
580
|
+
firstName: typeof subject.first_name === "string" ? subject.first_name : null,
|
|
581
|
+
lastName: typeof subject.last_name === "string" ? subject.last_name : null,
|
|
582
|
+
email: typeof subject.email === "string" ? subject.email : null,
|
|
583
|
+
objectType: typeof subject.object_type === "string" ? subject.object_type : null,
|
|
584
|
+
relation: typeof subject.relation === "string" ? subject.relation : null,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
serializeAccessSubject(subject) {
|
|
588
|
+
return {
|
|
589
|
+
type: subject.type,
|
|
590
|
+
id: subject.id,
|
|
591
|
+
...(subject.name !== undefined ? { name: subject.name } : {}),
|
|
592
|
+
...(subject.firstName !== undefined ? { first_name: subject.firstName } : {}),
|
|
593
|
+
...(subject.lastName !== undefined ? { last_name: subject.lastName } : {}),
|
|
594
|
+
...(subject.email !== undefined ? { email: subject.email } : {}),
|
|
595
|
+
...(subject.objectType !== undefined ? { object_type: subject.objectType } : {}),
|
|
596
|
+
...(subject.relation !== undefined ? { relation: subject.relation } : {}),
|
|
597
|
+
};
|
|
709
598
|
}
|
|
710
|
-
|
|
599
|
+
serializeAccessResource(resource) {
|
|
600
|
+
return {
|
|
601
|
+
type: resource.type,
|
|
602
|
+
id: resource.id,
|
|
603
|
+
...(resource.name !== undefined ? { name: resource.name } : {}),
|
|
604
|
+
...(resource.metadata !== undefined ? { metadata: resource.metadata } : {}),
|
|
605
|
+
...(resource.annotations !== undefined ? { annotations: resource.annotations } : {}),
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
parseProjectMember(data) {
|
|
711
609
|
if (!data || typeof data !== "object") {
|
|
712
|
-
throw new RoomException("Invalid
|
|
713
|
-
}
|
|
714
|
-
const
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
610
|
+
throw new RoomException("Invalid project member payload");
|
|
611
|
+
}
|
|
612
|
+
const user = data.user && typeof data.user === "object" ? data.user : data;
|
|
613
|
+
const directRoles = Array.isArray(data.direct_roles)
|
|
614
|
+
? data.direct_roles.filter((item) => item === "member" ||
|
|
615
|
+
item === "admin" ||
|
|
616
|
+
item === "developer" ||
|
|
617
|
+
item === "room_creator" ||
|
|
618
|
+
item === "agent_creator" ||
|
|
619
|
+
item === "mailbox_creator" ||
|
|
620
|
+
item === "route_creator" ||
|
|
621
|
+
item === "scheduled_task_creator" ||
|
|
622
|
+
item === "llm_proxy_user" ||
|
|
623
|
+
item === "usage_reporter" ||
|
|
624
|
+
item === "billing_manager" ||
|
|
625
|
+
item === "group_manager")
|
|
626
|
+
: [];
|
|
627
|
+
const id = typeof user.id === "string" ? user.id : "";
|
|
628
|
+
const email = typeof user.email === "string" ? user.email : "";
|
|
629
|
+
return {
|
|
630
|
+
id,
|
|
631
|
+
email,
|
|
632
|
+
firstName: typeof user.first_name === "string" ? user.first_name : null,
|
|
633
|
+
lastName: typeof user.last_name === "string" ? user.last_name : null,
|
|
634
|
+
directRoles,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
parseGroupMember(data) {
|
|
638
|
+
if (!data || typeof data !== "object") {
|
|
639
|
+
throw new RoomException("Invalid group member payload");
|
|
721
640
|
}
|
|
722
|
-
|
|
723
|
-
|
|
641
|
+
const directRoles = Array.isArray(data.direct_roles)
|
|
642
|
+
? data.direct_roles.filter((item) => item === "member" || item === "manager")
|
|
643
|
+
: [];
|
|
644
|
+
return {
|
|
645
|
+
subject: this.parseAccessSubject(data.subject),
|
|
646
|
+
directRoles,
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
parseProjectRoomGrant(data) {
|
|
650
|
+
if (!data || typeof data !== "object") {
|
|
651
|
+
throw new RoomException("Invalid room grant payload");
|
|
724
652
|
}
|
|
653
|
+
const parsedResource = this.parseAccessResource(data.resource);
|
|
654
|
+
const parsedSubject = this.parseAccessSubject(data.subject);
|
|
655
|
+
const parsedDirectRoles = Array.isArray(data.direct_roles)
|
|
656
|
+
? data.direct_roles.filter((item) => item === "member" ||
|
|
657
|
+
item === "viewer" ||
|
|
658
|
+
item === "operator" ||
|
|
659
|
+
item === "developer" ||
|
|
660
|
+
item === "admin" ||
|
|
661
|
+
item === "room_creator" ||
|
|
662
|
+
item === "room_inventory" ||
|
|
663
|
+
item === "room_manager" ||
|
|
664
|
+
item === "session_inventory" ||
|
|
665
|
+
item === "agent_creator" ||
|
|
666
|
+
item === "agent_inventory" ||
|
|
667
|
+
item === "agent_manager" ||
|
|
668
|
+
item === "repository_creator" ||
|
|
669
|
+
item === "repository_inventory" ||
|
|
670
|
+
item === "repository_manager" ||
|
|
671
|
+
item === "feed_creator" ||
|
|
672
|
+
item === "feed_inventory" ||
|
|
673
|
+
item === "feed_manager" ||
|
|
674
|
+
item === "oauth_client_creator" ||
|
|
675
|
+
item === "oauth_client_inventory" ||
|
|
676
|
+
item === "oauth_client_manager" ||
|
|
677
|
+
item === "api_key_creator" ||
|
|
678
|
+
item === "api_key_inventory" ||
|
|
679
|
+
item === "api_key_manager" ||
|
|
680
|
+
item === "service_creator" ||
|
|
681
|
+
item === "service_inventory" ||
|
|
682
|
+
item === "service_manager" ||
|
|
683
|
+
item === "service_account_creator" ||
|
|
684
|
+
item === "service_account_inventory" ||
|
|
685
|
+
item === "service_account_manager" ||
|
|
686
|
+
item === "participant_token_creator" ||
|
|
687
|
+
item === "mailbox_creator" ||
|
|
688
|
+
item === "mailbox_inventory" ||
|
|
689
|
+
item === "mailbox_manager" ||
|
|
690
|
+
item === "route_creator" ||
|
|
691
|
+
item === "route_inventory" ||
|
|
692
|
+
item === "route_manager" ||
|
|
693
|
+
item === "scheduled_task_creator" ||
|
|
694
|
+
item === "scheduled_task_inventory" ||
|
|
695
|
+
item === "scheduled_task_manager" ||
|
|
696
|
+
item === "feed_subscription_creator" ||
|
|
697
|
+
item === "feed_subscription_inventory" ||
|
|
698
|
+
item === "feed_subscription_manager" ||
|
|
699
|
+
item === "llm_logger_creator" ||
|
|
700
|
+
item === "llm_logger_inventory" ||
|
|
701
|
+
item === "llm_logger_manager" ||
|
|
702
|
+
item === "llm_proxy_user" ||
|
|
703
|
+
item === "usage_reporter" ||
|
|
704
|
+
item === "billing_manager" ||
|
|
705
|
+
item === "group_manager" ||
|
|
706
|
+
item === "reader" ||
|
|
707
|
+
item === "subscriber" ||
|
|
708
|
+
item === "publisher" ||
|
|
709
|
+
item === "manager" ||
|
|
710
|
+
item === "list")
|
|
711
|
+
: [];
|
|
712
|
+
const room = {
|
|
713
|
+
id: parsedResource.id,
|
|
714
|
+
name: parsedResource.name ?? parsedResource.id,
|
|
715
|
+
metadata: parsedResource.metadata ?? {},
|
|
716
|
+
annotations: parsedResource.annotations ?? {},
|
|
717
|
+
};
|
|
725
718
|
return {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
719
|
+
resource: parsedResource,
|
|
720
|
+
subject: parsedSubject,
|
|
721
|
+
directRoles: parsedDirectRoles,
|
|
722
|
+
room,
|
|
723
|
+
userId: parsedSubject.id,
|
|
731
724
|
};
|
|
732
725
|
}
|
|
733
726
|
parseBalance(data) {
|
|
@@ -776,196 +769,13 @@ export class Meshagent {
|
|
|
776
769
|
createdAt: new Date(createdValue),
|
|
777
770
|
};
|
|
778
771
|
}
|
|
779
|
-
parseSecret(data) {
|
|
780
|
-
if (!data || typeof data !== "object") {
|
|
781
|
-
throw new RoomException("Invalid secret payload");
|
|
782
|
-
}
|
|
783
|
-
const type = data.type;
|
|
784
|
-
if (type === "docker") {
|
|
785
|
-
const server = data.server;
|
|
786
|
-
const username = data.username;
|
|
787
|
-
const password = data.password;
|
|
788
|
-
if (typeof server !== "string" || typeof username !== "string" || typeof password !== "string") {
|
|
789
|
-
throw new RoomException("Invalid docker secret payload");
|
|
790
|
-
}
|
|
791
|
-
return {
|
|
792
|
-
id: typeof data.id === "string" ? data.id : undefined,
|
|
793
|
-
name: data.name,
|
|
794
|
-
type: "docker",
|
|
795
|
-
server,
|
|
796
|
-
username,
|
|
797
|
-
password,
|
|
798
|
-
email: typeof data.email === "string" ? data.email : undefined,
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
if (type === "keys") {
|
|
802
|
-
const record = data.data;
|
|
803
|
-
if (!record || typeof record !== "object") {
|
|
804
|
-
throw new RoomException("Invalid keys secret payload");
|
|
805
|
-
}
|
|
806
|
-
return {
|
|
807
|
-
id: typeof data.id === "string" ? data.id : undefined,
|
|
808
|
-
name: data.name,
|
|
809
|
-
type: "keys",
|
|
810
|
-
data: record,
|
|
811
|
-
};
|
|
812
|
-
}
|
|
813
|
-
throw new RoomException(`Unknown secret type: ${type}`);
|
|
814
|
-
}
|
|
815
|
-
parseManagedSecretInfo(data) {
|
|
816
|
-
if (!data || typeof data !== "object") {
|
|
817
|
-
throw new RoomException("Invalid managed secret payload");
|
|
818
|
-
}
|
|
819
|
-
const { id, type, name, delegated_to: delegatedToRaw, delegatedTo } = data;
|
|
820
|
-
if (typeof id !== "string" || typeof type !== "string" || typeof name !== "string") {
|
|
821
|
-
throw new RoomException("Invalid managed secret payload: missing id, type, or name");
|
|
822
|
-
}
|
|
823
|
-
const delegatedToValue = typeof delegatedTo === "string"
|
|
824
|
-
? delegatedTo
|
|
825
|
-
: typeof delegatedToRaw === "string"
|
|
826
|
-
? delegatedToRaw
|
|
827
|
-
: null;
|
|
828
|
-
return {
|
|
829
|
-
id,
|
|
830
|
-
type,
|
|
831
|
-
name,
|
|
832
|
-
delegatedTo: delegatedToValue,
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
parseManagedSecret(data) {
|
|
836
|
-
const secret = this.parseManagedSecretInfo(data);
|
|
837
|
-
const dataBase64 = data.data_base64 ?? data.dataBase64;
|
|
838
|
-
if (typeof dataBase64 !== "string") {
|
|
839
|
-
throw new RoomException("Invalid managed secret payload: missing data_base64");
|
|
840
|
-
}
|
|
841
|
-
return {
|
|
842
|
-
...secret,
|
|
843
|
-
dataBase64,
|
|
844
|
-
data: base64ToBytes(dataBase64),
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
parseSecretPayload(secret, rawData) {
|
|
848
|
-
let payload;
|
|
849
|
-
try {
|
|
850
|
-
payload = JSON.parse(decoder.decode(rawData));
|
|
851
|
-
}
|
|
852
|
-
catch {
|
|
853
|
-
throw new RoomException(`Invalid secret payload for ${secret.id}`);
|
|
854
|
-
}
|
|
855
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
856
|
-
throw new RoomException(`Invalid secret payload for ${secret.id}`);
|
|
857
|
-
}
|
|
858
|
-
if (secret.type === "docker") {
|
|
859
|
-
const { server, username, password, email } = payload;
|
|
860
|
-
if (typeof server !== "string" || typeof username !== "string" || typeof password !== "string") {
|
|
861
|
-
throw new RoomException(`Invalid secret payload for ${secret.id}`);
|
|
862
|
-
}
|
|
863
|
-
return {
|
|
864
|
-
id: secret.id,
|
|
865
|
-
name: secret.name,
|
|
866
|
-
type: "docker",
|
|
867
|
-
server,
|
|
868
|
-
username,
|
|
869
|
-
password,
|
|
870
|
-
email: typeof email === "string" ? email : "none@example.com",
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
const entries = Object.entries(payload);
|
|
874
|
-
if (entries.some(([, value]) => typeof value !== "string")) {
|
|
875
|
-
throw new RoomException(`Invalid secret payload for ${secret.id}`);
|
|
876
|
-
}
|
|
877
|
-
return {
|
|
878
|
-
id: secret.id,
|
|
879
|
-
name: secret.name,
|
|
880
|
-
type: "keys",
|
|
881
|
-
data: Object.fromEntries(entries),
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
toSecretPayload(secret) {
|
|
885
|
-
if (secret.type === "docker") {
|
|
886
|
-
return {
|
|
887
|
-
name: secret.name,
|
|
888
|
-
type: secret.type,
|
|
889
|
-
data: {
|
|
890
|
-
server: secret.server,
|
|
891
|
-
username: secret.username,
|
|
892
|
-
password: secret.password,
|
|
893
|
-
email: secret.email ?? "none@example.com",
|
|
894
|
-
},
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
return {
|
|
898
|
-
name: secret.name,
|
|
899
|
-
type: secret.type,
|
|
900
|
-
data: { ...secret.data },
|
|
901
|
-
};
|
|
902
|
-
}
|
|
903
|
-
parseConnectorRef(data) {
|
|
904
|
-
if (data == null) {
|
|
905
|
-
return null;
|
|
906
|
-
}
|
|
907
|
-
if (typeof data !== "object") {
|
|
908
|
-
throw new RoomException("Invalid connector payload");
|
|
909
|
-
}
|
|
910
|
-
const { openai_connector_id: openaiConnectorIdRaw, openaiConnectorId, server_url: serverUrlRaw, serverUrl, client_secret_id: clientSecretIdRaw, clientSecretId, } = data;
|
|
911
|
-
return {
|
|
912
|
-
openaiConnectorId: typeof openaiConnectorId === "string"
|
|
913
|
-
? openaiConnectorId
|
|
914
|
-
: typeof openaiConnectorIdRaw === "string"
|
|
915
|
-
? openaiConnectorIdRaw
|
|
916
|
-
: null,
|
|
917
|
-
serverUrl: typeof serverUrl === "string"
|
|
918
|
-
? serverUrl
|
|
919
|
-
: typeof serverUrlRaw === "string"
|
|
920
|
-
? serverUrlRaw
|
|
921
|
-
: null,
|
|
922
|
-
clientSecretId: typeof clientSecretId === "string"
|
|
923
|
-
? clientSecretId
|
|
924
|
-
: typeof clientSecretIdRaw === "string"
|
|
925
|
-
? clientSecretIdRaw
|
|
926
|
-
: null,
|
|
927
|
-
};
|
|
928
|
-
}
|
|
929
|
-
serializeConnectorRef(connector) {
|
|
930
|
-
if (connector == null) {
|
|
931
|
-
return null;
|
|
932
|
-
}
|
|
933
|
-
const payload = {};
|
|
934
|
-
if (connector.openaiConnectorId) {
|
|
935
|
-
payload.openai_connector_id = connector.openaiConnectorId;
|
|
936
|
-
}
|
|
937
|
-
if (connector.serverUrl) {
|
|
938
|
-
payload.server_url = connector.serverUrl;
|
|
939
|
-
}
|
|
940
|
-
if (connector.clientSecretId) {
|
|
941
|
-
payload.client_secret_id = connector.clientSecretId;
|
|
942
|
-
}
|
|
943
|
-
return payload;
|
|
944
|
-
}
|
|
945
|
-
parseExternalOAuthClientRegistration(data) {
|
|
946
|
-
if (!data || typeof data !== "object") {
|
|
947
|
-
throw new RoomException("Invalid external oauth registration payload");
|
|
948
|
-
}
|
|
949
|
-
const { id, delegated_to: delegatedToRaw, delegatedTo, connector, oauth, client_id: clientIdRaw, clientId, client_secret: clientSecretRaw, clientSecret, } = data;
|
|
950
|
-
const delegatedToValue = typeof delegatedTo === "string" ? delegatedTo : delegatedToRaw;
|
|
951
|
-
const clientIdValue = typeof clientId === "string" ? clientId : clientIdRaw;
|
|
952
|
-
const clientSecretValue = typeof clientSecret === "string" ? clientSecret : clientSecretRaw;
|
|
953
|
-
if (typeof id !== "string" || typeof delegatedToValue !== "string" || typeof clientIdValue !== "string") {
|
|
954
|
-
throw new RoomException("Invalid external oauth registration payload: missing fields");
|
|
955
|
-
}
|
|
956
|
-
return {
|
|
957
|
-
id,
|
|
958
|
-
delegatedTo: delegatedToValue,
|
|
959
|
-
connector: this.parseConnectorRef(connector),
|
|
960
|
-
oauth: oauth && typeof oauth === "object" ? oauth : null,
|
|
961
|
-
clientId: clientIdValue,
|
|
962
|
-
clientSecret: typeof clientSecretValue === "string" ? clientSecretValue : null,
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
772
|
parseOAuthClient(data) {
|
|
966
773
|
if (!data || typeof data !== "object") {
|
|
967
774
|
throw new RoomException("Invalid OAuth client payload");
|
|
968
775
|
}
|
|
776
|
+
if ("client" in data && data.client && typeof data.client === "object") {
|
|
777
|
+
data = data.client;
|
|
778
|
+
}
|
|
969
779
|
const { client_id: clientIdRaw, clientId, client_secret: clientSecretRaw, clientSecret, grant_types: grantTypesRaw, grantTypes, response_types: responseTypesRaw, responseTypes, redirect_uris: redirectUrisRaw, redirectUris, scope, project_id: projectIdRaw, projectId, metadata } = data;
|
|
970
780
|
const clientIdValue = typeof clientId === "string" ? clientId : clientIdRaw;
|
|
971
781
|
const clientSecretValue = typeof clientSecret === "string" ? clientSecret : clientSecretRaw;
|
|
@@ -991,6 +801,7 @@ export class Meshagent {
|
|
|
991
801
|
scope,
|
|
992
802
|
projectId: projectIdValue,
|
|
993
803
|
metadata: metadata && typeof metadata === "object" ? metadata : {},
|
|
804
|
+
official: Boolean(data.official),
|
|
994
805
|
};
|
|
995
806
|
}
|
|
996
807
|
parseRoomConnectionInfo(data) {
|
|
@@ -1031,45 +842,6 @@ export class Meshagent {
|
|
|
1031
842
|
responseType: "arrayBuffer",
|
|
1032
843
|
});
|
|
1033
844
|
}
|
|
1034
|
-
async getProjectRole(projectId) {
|
|
1035
|
-
const payload = await this.request(`/accounts/projects/${projectId}/role`, {
|
|
1036
|
-
action: "fetch project role",
|
|
1037
|
-
});
|
|
1038
|
-
const role = payload?.role;
|
|
1039
|
-
if (role !== "member" && role !== "admin" && role !== "developer") {
|
|
1040
|
-
throw new RoomException("Invalid role payload");
|
|
1041
|
-
}
|
|
1042
|
-
return role;
|
|
1043
|
-
}
|
|
1044
|
-
async createShare(projectId, settings) {
|
|
1045
|
-
return await this.request(`/accounts/projects/${projectId}/shares`, {
|
|
1046
|
-
method: "POST",
|
|
1047
|
-
json: { settings: settings ?? {} },
|
|
1048
|
-
action: "create share",
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
|
-
async deleteShare(projectId, shareId) {
|
|
1052
|
-
await this.request(`/accounts/projects/${projectId}/shares/${shareId}`, {
|
|
1053
|
-
method: "DELETE",
|
|
1054
|
-
action: "delete share",
|
|
1055
|
-
responseType: "void",
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
|
-
async updateShare(projectId, shareId, settings) {
|
|
1059
|
-
await this.request(`/accounts/projects/${projectId}/shares/${shareId}`, {
|
|
1060
|
-
method: "PUT",
|
|
1061
|
-
json: { settings: settings ?? {} },
|
|
1062
|
-
action: "update share",
|
|
1063
|
-
responseType: "void",
|
|
1064
|
-
});
|
|
1065
|
-
}
|
|
1066
|
-
async listShares(projectId) {
|
|
1067
|
-
const data = await this.request(`/accounts/projects/${projectId}/shares`, {
|
|
1068
|
-
action: "list shares",
|
|
1069
|
-
});
|
|
1070
|
-
const shares = Array.isArray(data?.shares) ? data.shares : [];
|
|
1071
|
-
return shares.map((item) => this.parseRoomShare(item));
|
|
1072
|
-
}
|
|
1073
845
|
async createProject(name, settings) {
|
|
1074
846
|
return await this.request(`/accounts/projects`, {
|
|
1075
847
|
method: "POST",
|
|
@@ -1078,39 +850,15 @@ export class Meshagent {
|
|
|
1078
850
|
});
|
|
1079
851
|
}
|
|
1080
852
|
async addUserToProject(projectId, userId, options = {}) {
|
|
1081
|
-
const {
|
|
853
|
+
const { roles = ["member"], email, inviteRedirectUrl } = options;
|
|
1082
854
|
return await this.request(`/accounts/projects/${projectId}/users`, {
|
|
1083
855
|
method: "POST",
|
|
1084
856
|
json: {
|
|
1085
857
|
project_id: projectId,
|
|
1086
858
|
user_id: userId,
|
|
1087
|
-
|
|
1088
|
-
...(
|
|
1089
|
-
...(
|
|
1090
|
-
? { can_create_rooms: canCreateRooms }
|
|
1091
|
-
: {}),
|
|
1092
|
-
...(inviteRedirectUrl !== undefined
|
|
1093
|
-
? { invite_redirect_url: inviteRedirectUrl }
|
|
1094
|
-
: {}),
|
|
1095
|
-
},
|
|
1096
|
-
action: "add user to project",
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
async addUserToProjectByEmail(projectId, email, options = {}) {
|
|
1100
|
-
const { isAdmin, isDeveloper, canCreateRooms, inviteRedirectUrl } = options;
|
|
1101
|
-
return await this.request(`/accounts/projects/${projectId}/users`, {
|
|
1102
|
-
method: "POST",
|
|
1103
|
-
json: {
|
|
1104
|
-
project_id: projectId,
|
|
1105
|
-
email,
|
|
1106
|
-
...(isAdmin !== undefined ? { is_admin: isAdmin } : {}),
|
|
1107
|
-
...(isDeveloper !== undefined ? { is_developer: isDeveloper } : {}),
|
|
1108
|
-
...(canCreateRooms !== undefined
|
|
1109
|
-
? { can_create_rooms: canCreateRooms }
|
|
1110
|
-
: {}),
|
|
1111
|
-
...(inviteRedirectUrl !== undefined
|
|
1112
|
-
? { invite_redirect_url: inviteRedirectUrl }
|
|
1113
|
-
: {}),
|
|
859
|
+
roles,
|
|
860
|
+
...(email !== undefined ? { email } : {}),
|
|
861
|
+
...(inviteRedirectUrl !== undefined ? { invite_redirect_url: inviteRedirectUrl } : {}),
|
|
1114
862
|
},
|
|
1115
863
|
action: "add user to project",
|
|
1116
864
|
});
|
|
@@ -1128,79 +876,281 @@ export class Meshagent {
|
|
|
1128
876
|
action: "update project settings",
|
|
1129
877
|
});
|
|
1130
878
|
}
|
|
879
|
+
async updateUserInProject(projectId, userId, roles) {
|
|
880
|
+
return await this.request(`/accounts/projects/${projectId}/users/${userId}`, {
|
|
881
|
+
method: "PUT",
|
|
882
|
+
json: { roles },
|
|
883
|
+
action: "update project user",
|
|
884
|
+
});
|
|
885
|
+
}
|
|
1131
886
|
async getUsersInProjectPage(projectId, options = {}) {
|
|
1132
|
-
const {
|
|
887
|
+
const { pageSize = 100, continuationToken, filter, email } = options;
|
|
1133
888
|
const data = await this.request(`/accounts/projects/${projectId}/users`, {
|
|
1134
|
-
query: {
|
|
889
|
+
query: { page_size: pageSize, continuation_token: continuationToken, filter, email },
|
|
1135
890
|
action: "fetch project users",
|
|
1136
891
|
});
|
|
1137
|
-
const users = Array.isArray(data?.users) ? data.users : [];
|
|
1138
|
-
return { users
|
|
1139
|
-
}
|
|
1140
|
-
async getUsersInProject(projectId) {
|
|
1141
|
-
const page = await this.getUsersInProjectPage(projectId);
|
|
1142
|
-
return
|
|
892
|
+
const users = Array.isArray(data?.users) ? data.users : [];
|
|
893
|
+
return { users: users.map((user) => this.parseProjectMember(user)), continuationToken: data?.continuation_token ?? null };
|
|
894
|
+
}
|
|
895
|
+
async getUsersInProject(projectId) {
|
|
896
|
+
const page = await this.getUsersInProjectPage(projectId);
|
|
897
|
+
return page.users;
|
|
898
|
+
}
|
|
899
|
+
async getUserProfile(userId) {
|
|
900
|
+
return await this.request(`/accounts/profiles/${userId}`, {
|
|
901
|
+
action: "fetch user profile",
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
async updateUserProfile(userId, firstName, lastName) {
|
|
905
|
+
return await this.request(`/accounts/profiles/${userId}`, {
|
|
906
|
+
method: "PUT",
|
|
907
|
+
json: { first_name: firstName, last_name: lastName },
|
|
908
|
+
action: "update user profile",
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
async listProjects() {
|
|
912
|
+
return await this.request(`/accounts/projects`, {
|
|
913
|
+
action: "list projects",
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
async getProject(projectId) {
|
|
917
|
+
return await this.request(`/accounts/projects/${projectId}`, {
|
|
918
|
+
action: "get project",
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
async getProjectByKey(projectKey) {
|
|
922
|
+
return await this.request(`/accounts/projects/by-key/${encodeURIComponent(projectKey)}`, {
|
|
923
|
+
action: "get project by key",
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
async listServiceAccounts(projectId, options = {}) {
|
|
927
|
+
const params = new URLSearchParams();
|
|
928
|
+
if (options.pageSize !== undefined)
|
|
929
|
+
params.set("page_size", String(options.pageSize));
|
|
930
|
+
if (options.continuationToken !== undefined)
|
|
931
|
+
params.set("continuation_token", options.continuationToken);
|
|
932
|
+
if (options.filter !== undefined)
|
|
933
|
+
params.set("filter", options.filter);
|
|
934
|
+
if (options.view !== undefined)
|
|
935
|
+
params.set("view", options.view);
|
|
936
|
+
const query = params.toString();
|
|
937
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts${query ? `?${query}` : ""}`, {
|
|
938
|
+
action: "list service accounts",
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
async createServiceAccount(projectId, name, options = {}) {
|
|
942
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts`, {
|
|
943
|
+
method: "POST",
|
|
944
|
+
json: { name, ...options },
|
|
945
|
+
action: "create service account",
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
async mintParticipantToken(projectId, options) {
|
|
949
|
+
const json = options.grants !== undefined
|
|
950
|
+
? { name: options.name, grants: options.grants }
|
|
951
|
+
: {
|
|
952
|
+
name: options.name,
|
|
953
|
+
room_name: options.roomName,
|
|
954
|
+
role: options.role,
|
|
955
|
+
api: options.api,
|
|
956
|
+
};
|
|
957
|
+
const data = await this.request(`/accounts/projects/${projectId}/participant-tokens`, {
|
|
958
|
+
method: "POST",
|
|
959
|
+
json,
|
|
960
|
+
action: "mint participant token",
|
|
961
|
+
});
|
|
962
|
+
if (typeof data?.token !== "string" || data.token.trim() === "") {
|
|
963
|
+
throw new Error("Invalid participant token mint response");
|
|
964
|
+
}
|
|
965
|
+
return data.token;
|
|
966
|
+
}
|
|
967
|
+
async createApiKey(projectId, serviceAccountId, name, description) {
|
|
968
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/api-keys`, {
|
|
969
|
+
method: "POST",
|
|
970
|
+
json: { name, description },
|
|
971
|
+
action: "create api key",
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
async deleteApiKey(projectId, serviceAccountId, id) {
|
|
975
|
+
await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/api-keys/${id}`, {
|
|
976
|
+
method: "DELETE",
|
|
977
|
+
action: "delete api key",
|
|
978
|
+
responseType: "void",
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
async revokeApiKeysByMsid(projectId, serviceAccountId, msid) {
|
|
982
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/api-keys:revoke`, {
|
|
983
|
+
method: "POST",
|
|
984
|
+
json: { msid },
|
|
985
|
+
action: "revoke api keys",
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
async listApiKeys(projectId, serviceAccountId) {
|
|
989
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/api-keys`, {
|
|
990
|
+
action: "list api keys",
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
async createUserSecret(input) {
|
|
994
|
+
return await this.request(`/accounts/users/me/secrets`, {
|
|
995
|
+
method: "POST",
|
|
996
|
+
json: this.secretPayload(input),
|
|
997
|
+
action: "create user secret",
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
async listUserSecrets(options = {}) {
|
|
1001
|
+
return await this.request(`/accounts/users/me/secrets`, {
|
|
1002
|
+
query: {
|
|
1003
|
+
page_size: options.pageSize ?? 100,
|
|
1004
|
+
continuation_token: options.continuationToken,
|
|
1005
|
+
filter: options.filter,
|
|
1006
|
+
},
|
|
1007
|
+
action: "list user secrets",
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
async searchUserSecrets(input = {}) {
|
|
1011
|
+
return await this.request(`/accounts/users/me/secrets:search`, {
|
|
1012
|
+
method: "POST",
|
|
1013
|
+
json: this.secretSearchPayload(input),
|
|
1014
|
+
action: "search user secrets",
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
async getUserSecret(secretId, options = {}) {
|
|
1018
|
+
return await this.request(`/accounts/users/me/secrets/${secretId}`, {
|
|
1019
|
+
query: {
|
|
1020
|
+
include_value: options.includeValue ? "true" : undefined,
|
|
1021
|
+
},
|
|
1022
|
+
action: "get user secret",
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
async updateUserSecret(secretId, input) {
|
|
1026
|
+
return await this.request(`/accounts/users/me/secrets/${secretId}`, {
|
|
1027
|
+
method: "PATCH",
|
|
1028
|
+
json: this.secretPayload(input),
|
|
1029
|
+
action: "update user secret",
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
async deleteUserSecret(secretId) {
|
|
1033
|
+
await this.request(`/accounts/users/me/secrets/${secretId}`, {
|
|
1034
|
+
method: "DELETE",
|
|
1035
|
+
action: "delete user secret",
|
|
1036
|
+
responseType: "void",
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
async listUserSecretVersions(secretId) {
|
|
1040
|
+
const page = await this.request(`/accounts/users/me/secrets/${secretId}/versions`, {
|
|
1041
|
+
action: "list user secret versions",
|
|
1042
|
+
});
|
|
1043
|
+
return page.versions;
|
|
1044
|
+
}
|
|
1045
|
+
async createUserSecretVersion(secretId, input) {
|
|
1046
|
+
return await this.request(`/accounts/users/me/secrets/${secretId}/versions`, {
|
|
1047
|
+
method: "POST",
|
|
1048
|
+
json: this.secretVersionPayload(input),
|
|
1049
|
+
action: "create user secret version",
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
async listUserSecretProxyAccess(secretId, options = {}) {
|
|
1053
|
+
return await this.request(`/accounts/users/me/secrets/${secretId}/access`, {
|
|
1054
|
+
query: {
|
|
1055
|
+
page_size: options.pageSize ?? 100,
|
|
1056
|
+
continuation_token: options.continuationToken,
|
|
1057
|
+
},
|
|
1058
|
+
action: "list user secret proxy access",
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
async grantUserSecretProxyAccess(secretId, serviceAccountId) {
|
|
1062
|
+
await this.request(`/accounts/users/me/secrets/${secretId}/access:grant-proxy`, {
|
|
1063
|
+
method: "POST",
|
|
1064
|
+
json: { subject: { type: "service_account", id: serviceAccountId } },
|
|
1065
|
+
action: "grant user secret proxy access",
|
|
1066
|
+
responseType: "void",
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
async revokeUserSecretProxyAccess(secretId, serviceAccountId) {
|
|
1070
|
+
await this.request(`/accounts/users/me/secrets/${secretId}/access:revoke-proxy`, {
|
|
1071
|
+
method: "POST",
|
|
1072
|
+
json: { subject: { type: "service_account", id: serviceAccountId } },
|
|
1073
|
+
action: "revoke user secret proxy access",
|
|
1074
|
+
responseType: "void",
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
async createServiceAccountSecret(projectId, serviceAccountId, input) {
|
|
1078
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets`, {
|
|
1079
|
+
method: "POST",
|
|
1080
|
+
json: this.secretPayload(input),
|
|
1081
|
+
action: "create service account secret",
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
async listServiceAccountSecrets(projectId, serviceAccountId, options = {}) {
|
|
1085
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets`, {
|
|
1086
|
+
query: {
|
|
1087
|
+
page_size: options.pageSize ?? 100,
|
|
1088
|
+
continuation_token: options.continuationToken,
|
|
1089
|
+
filter: options.filter,
|
|
1090
|
+
},
|
|
1091
|
+
action: "list service account secrets",
|
|
1092
|
+
});
|
|
1143
1093
|
}
|
|
1144
|
-
async
|
|
1145
|
-
return await this.request(`/accounts/
|
|
1146
|
-
|
|
1094
|
+
async searchServiceAccountSecrets(projectId, serviceAccountId, input = {}) {
|
|
1095
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets:search`, {
|
|
1096
|
+
method: "POST",
|
|
1097
|
+
json: this.secretSearchPayload(input),
|
|
1098
|
+
action: "search service account secrets",
|
|
1147
1099
|
});
|
|
1148
1100
|
}
|
|
1149
|
-
async
|
|
1150
|
-
return await this.request(`/accounts/
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1101
|
+
async getServiceAccountSecret(projectId, serviceAccountId, secretId, options = {}) {
|
|
1102
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets/${secretId}`, {
|
|
1103
|
+
query: {
|
|
1104
|
+
include_value: options.includeValue ? "true" : undefined,
|
|
1105
|
+
},
|
|
1106
|
+
action: "get service account secret",
|
|
1154
1107
|
});
|
|
1155
1108
|
}
|
|
1156
|
-
async
|
|
1157
|
-
return await this.request(`/accounts/projects`, {
|
|
1158
|
-
|
|
1109
|
+
async updateServiceAccountSecret(projectId, serviceAccountId, secretId, input) {
|
|
1110
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets/${secretId}`, {
|
|
1111
|
+
method: "PATCH",
|
|
1112
|
+
json: this.secretPayload(input),
|
|
1113
|
+
action: "update service account secret",
|
|
1159
1114
|
});
|
|
1160
1115
|
}
|
|
1161
|
-
async
|
|
1162
|
-
|
|
1163
|
-
|
|
1116
|
+
async deleteServiceAccountSecret(projectId, serviceAccountId, secretId) {
|
|
1117
|
+
await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets/${secretId}`, {
|
|
1118
|
+
method: "DELETE",
|
|
1119
|
+
action: "delete service account secret",
|
|
1120
|
+
responseType: "void",
|
|
1164
1121
|
});
|
|
1165
1122
|
}
|
|
1166
|
-
async
|
|
1167
|
-
|
|
1168
|
-
action: "
|
|
1123
|
+
async listServiceAccountSecretVersions(projectId, serviceAccountId, secretId) {
|
|
1124
|
+
const page = await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets/${secretId}/versions`, {
|
|
1125
|
+
action: "list service account secret versions",
|
|
1169
1126
|
});
|
|
1127
|
+
return page.versions;
|
|
1170
1128
|
}
|
|
1171
|
-
async
|
|
1172
|
-
|
|
1173
|
-
const permissionsJson = permissions == null
|
|
1174
|
-
? undefined
|
|
1175
|
-
: Object.fromEntries(Object.entries(permissions).map(([userId, grant]) => [userId, grant.toJson()]));
|
|
1176
|
-
const data = await this.request(`/accounts/projects/${this.encodePathComponent(projectId)}/agents`, {
|
|
1129
|
+
async createServiceAccountSecretVersion(projectId, serviceAccountId, secretId, input) {
|
|
1130
|
+
return await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/secrets/${secretId}/versions`, {
|
|
1177
1131
|
method: "POST",
|
|
1178
|
-
json:
|
|
1179
|
-
|
|
1180
|
-
if_not_exists: ifNotExists,
|
|
1181
|
-
...(permissionsJson !== undefined ? { permissions: permissionsJson } : {}),
|
|
1182
|
-
},
|
|
1183
|
-
action: "create agent",
|
|
1132
|
+
json: this.secretVersionPayload(input),
|
|
1133
|
+
action: "create service account secret version",
|
|
1184
1134
|
});
|
|
1185
|
-
return this.parseManagedAgent(data);
|
|
1186
1135
|
}
|
|
1187
|
-
async
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
json: { name, description },
|
|
1191
|
-
action: "create api key",
|
|
1136
|
+
async listServiceAccountPullSecrets(projectId, serviceAccountId) {
|
|
1137
|
+
const page = await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/pull-secrets`, {
|
|
1138
|
+
action: "list service account pull secrets",
|
|
1192
1139
|
});
|
|
1140
|
+
return page.secrets;
|
|
1193
1141
|
}
|
|
1194
|
-
async
|
|
1195
|
-
await this.request(`/accounts/projects/${projectId}/
|
|
1196
|
-
method: "
|
|
1197
|
-
action: "
|
|
1142
|
+
async addServiceAccountPullSecret(projectId, serviceAccountId, secretId) {
|
|
1143
|
+
await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/pull-secrets/${secretId}`, {
|
|
1144
|
+
method: "PUT",
|
|
1145
|
+
action: "add service account pull secret",
|
|
1198
1146
|
responseType: "void",
|
|
1199
1147
|
});
|
|
1200
1148
|
}
|
|
1201
|
-
async
|
|
1202
|
-
|
|
1203
|
-
|
|
1149
|
+
async removeServiceAccountPullSecret(projectId, serviceAccountId, secretId) {
|
|
1150
|
+
await this.request(`/accounts/projects/${projectId}/service-accounts/${serviceAccountId}/pull-secrets/${secretId}`, {
|
|
1151
|
+
method: "DELETE",
|
|
1152
|
+
action: "remove service account pull secret",
|
|
1153
|
+
responseType: "void",
|
|
1204
1154
|
});
|
|
1205
1155
|
}
|
|
1206
1156
|
async getPricing() {
|
|
@@ -1311,6 +1261,40 @@ export class Meshagent {
|
|
|
1311
1261
|
const sessions = Array.isArray(data?.sessions) ? data.sessions : [];
|
|
1312
1262
|
return sessions.map((item) => this.parseRoomSession(item));
|
|
1313
1263
|
}
|
|
1264
|
+
async listRecentRoomSessions(projectId, roomName, options = {}) {
|
|
1265
|
+
const params = new URLSearchParams();
|
|
1266
|
+
if (options.limit !== undefined) {
|
|
1267
|
+
params.set("limit", String(options.limit));
|
|
1268
|
+
}
|
|
1269
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
1270
|
+
const data = await this.request(`/accounts/projects/${projectId}/rooms/${encodeURIComponent(roomName)}/sessions${query}`, { action: "list recent room sessions" });
|
|
1271
|
+
const sessions = Array.isArray(data?.sessions) ? data.sessions : [];
|
|
1272
|
+
return sessions.map((item) => this.parseRoomSession(item));
|
|
1273
|
+
}
|
|
1274
|
+
async listRecentSingleAgentSessions(projectId, agentName, options = {}) {
|
|
1275
|
+
const params = new URLSearchParams();
|
|
1276
|
+
if (options.limit !== undefined) {
|
|
1277
|
+
params.set("limit", String(options.limit));
|
|
1278
|
+
}
|
|
1279
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
1280
|
+
const data = await this.request(`/accounts/projects/${projectId}/agents/${encodeURIComponent(agentName)}/sessions${query}`, { action: "list recent agent sessions" });
|
|
1281
|
+
const sessions = Array.isArray(data?.sessions) ? data.sessions : [];
|
|
1282
|
+
return sessions.map((item) => this.parseRoomSession(item));
|
|
1283
|
+
}
|
|
1284
|
+
async createAgent(params) {
|
|
1285
|
+
const body = {
|
|
1286
|
+
configuration: params.configuration,
|
|
1287
|
+
if_not_exists: params.ifNotExists ?? false,
|
|
1288
|
+
};
|
|
1289
|
+
if (params.permissions != null) {
|
|
1290
|
+
body.permissions = params.permissions;
|
|
1291
|
+
}
|
|
1292
|
+
return await this.request(`/accounts/projects/${params.projectId}/agents`, {
|
|
1293
|
+
method: "POST",
|
|
1294
|
+
json: body,
|
|
1295
|
+
action: "create agent",
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1314
1298
|
async listSessionEvents(projectId, sessionId) {
|
|
1315
1299
|
const data = await this.request(`/accounts/projects/${projectId}/sessions/${sessionId}/events`, {
|
|
1316
1300
|
action: "list session events",
|
|
@@ -1339,34 +1323,6 @@ export class Meshagent {
|
|
|
1339
1323
|
const metrics = data?.["metrics"];
|
|
1340
1324
|
return Array.isArray(metrics) ? metrics : [];
|
|
1341
1325
|
}
|
|
1342
|
-
async createWebhook(projectId, params) {
|
|
1343
|
-
const { name, url, events, description = "", action: webhookAction = "", payload = null } = params;
|
|
1344
|
-
return await this.request(`/accounts/projects/${projectId}/webhooks`, {
|
|
1345
|
-
method: "POST",
|
|
1346
|
-
json: { name, description, url, events, action: webhookAction, payload },
|
|
1347
|
-
action: "create webhook",
|
|
1348
|
-
});
|
|
1349
|
-
}
|
|
1350
|
-
async updateWebhook(projectId, webhookId, params) {
|
|
1351
|
-
const { name, url, events, description = "", action: webhookAction = null, payload = null } = params;
|
|
1352
|
-
return await this.request(`/accounts/projects/${projectId}/webhooks/${webhookId}`, {
|
|
1353
|
-
method: "PUT",
|
|
1354
|
-
json: { name, description, url, events, action: webhookAction, payload },
|
|
1355
|
-
action: "update webhook",
|
|
1356
|
-
});
|
|
1357
|
-
}
|
|
1358
|
-
async listWebhooks(projectId) {
|
|
1359
|
-
return await this.request(`/accounts/projects/${projectId}/webhooks`, {
|
|
1360
|
-
action: "list webhooks",
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
async deleteWebhook(projectId, webhookId) {
|
|
1364
|
-
await this.request(`/accounts/projects/${projectId}/webhooks/${webhookId}`, {
|
|
1365
|
-
method: "DELETE",
|
|
1366
|
-
action: "delete webhook",
|
|
1367
|
-
responseType: "void",
|
|
1368
|
-
});
|
|
1369
|
-
}
|
|
1370
1326
|
async createMailbox(params) {
|
|
1371
1327
|
const { projectId, address, room, queue, isPublic } = params;
|
|
1372
1328
|
await this.request(`/accounts/projects/${projectId}/mailboxes`, {
|
|
@@ -1399,18 +1355,24 @@ export class Meshagent {
|
|
|
1399
1355
|
return { address, room, roomId: room_id, queue };
|
|
1400
1356
|
}
|
|
1401
1357
|
async listMailboxesPage(projectId, options = {}) {
|
|
1402
|
-
const {
|
|
1358
|
+
const { pageSize = 100, continuationToken, filter } = options;
|
|
1403
1359
|
const data = await this.request(`/accounts/projects/${projectId}/mailboxes`, {
|
|
1404
|
-
query: {
|
|
1360
|
+
query: { page_size: pageSize, continuation_token: continuationToken, filter },
|
|
1405
1361
|
action: "list mailboxes",
|
|
1406
1362
|
});
|
|
1407
1363
|
const mailboxes = Array.isArray(data?.mailboxes) ? data.mailboxes : [];
|
|
1408
1364
|
const parsed = mailboxes.map((item) => this.parseMailbox(item));
|
|
1409
|
-
return { mailboxes: parsed, total: typeof data?.total === "number" ? data.total : parsed.length };
|
|
1365
|
+
return { mailboxes: parsed, total: typeof data?.total === "number" ? data.total : parsed.length, continuationToken: data.continuation_token ?? null };
|
|
1410
1366
|
}
|
|
1411
1367
|
async listMailboxes(projectId, options = {}) {
|
|
1412
|
-
const
|
|
1413
|
-
|
|
1368
|
+
const mailboxes = [];
|
|
1369
|
+
let continuationToken;
|
|
1370
|
+
do {
|
|
1371
|
+
const page = await this.listMailboxesPage(projectId, { ...options, continuationToken });
|
|
1372
|
+
mailboxes.push(...page.mailboxes);
|
|
1373
|
+
continuationToken = page.continuationToken ?? undefined;
|
|
1374
|
+
} while (continuationToken);
|
|
1375
|
+
return mailboxes;
|
|
1414
1376
|
}
|
|
1415
1377
|
async deleteMailbox(projectId, address) {
|
|
1416
1378
|
await this.request(`/accounts/projects/${projectId}/mailboxes/${address}`, {
|
|
@@ -1457,18 +1419,24 @@ export class Meshagent {
|
|
|
1457
1419
|
return this.parseFeed(data.feed);
|
|
1458
1420
|
}
|
|
1459
1421
|
async listFeedsPage(projectId, options = {}) {
|
|
1460
|
-
const {
|
|
1422
|
+
const { pageSize = 100, continuationToken, filter, view } = options;
|
|
1461
1423
|
const data = await this.request(`/accounts/projects/${projectId}/feeds`, {
|
|
1462
|
-
query: {
|
|
1424
|
+
query: { page_size: pageSize, continuation_token: continuationToken, filter, view },
|
|
1463
1425
|
action: "list feeds",
|
|
1464
1426
|
});
|
|
1465
1427
|
const feeds = Array.isArray(data?.feeds) ? data.feeds : [];
|
|
1466
1428
|
const parsed = feeds.map((item) => this.parseFeed(item));
|
|
1467
|
-
return { feeds: parsed, total: typeof data?.total === "number" ? data.total : parsed.length };
|
|
1429
|
+
return { feeds: parsed, total: typeof data?.total === "number" ? data.total : parsed.length, continuationToken: data.continuation_token ?? null };
|
|
1468
1430
|
}
|
|
1469
1431
|
async listFeeds(projectId, options = {}) {
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1432
|
+
const feeds = [];
|
|
1433
|
+
let continuationToken;
|
|
1434
|
+
do {
|
|
1435
|
+
const page = await this.listFeedsPage(projectId, { ...options, continuationToken });
|
|
1436
|
+
feeds.push(...page.feeds);
|
|
1437
|
+
continuationToken = page.continuationToken ?? undefined;
|
|
1438
|
+
} while (continuationToken);
|
|
1439
|
+
return feeds;
|
|
1472
1440
|
}
|
|
1473
1441
|
async listRoomFeedsPage(projectId, roomName, options = {}) {
|
|
1474
1442
|
const { count = 100, offset = 0, filter } = options;
|
|
@@ -1627,12 +1595,28 @@ export class Meshagent {
|
|
|
1627
1595
|
});
|
|
1628
1596
|
return this.parseProjectRepository(data);
|
|
1629
1597
|
}
|
|
1630
|
-
async
|
|
1598
|
+
async listRepositoriesPage(projectId, options = {}) {
|
|
1599
|
+
const { pageSize = 100, view, continuationToken } = options;
|
|
1631
1600
|
const data = await this.request(`/accounts/projects/${projectId}/repositories`, {
|
|
1601
|
+
query: { page_size: pageSize, view, continuation_token: continuationToken },
|
|
1632
1602
|
action: "list repositories",
|
|
1633
1603
|
});
|
|
1634
1604
|
const repositories = Array.isArray(data?.repositories) ? data.repositories : [];
|
|
1635
|
-
return
|
|
1605
|
+
return {
|
|
1606
|
+
repositories: repositories.map((item) => this.parseProjectRepository(item)),
|
|
1607
|
+
total: Number(data.total ?? repositories.length),
|
|
1608
|
+
continuationToken: data.continuation_token ?? null,
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
async listRepositories(projectId, options = {}) {
|
|
1612
|
+
const repositories = [];
|
|
1613
|
+
let continuationToken;
|
|
1614
|
+
do {
|
|
1615
|
+
const page = await this.listRepositoriesPage(projectId, { view: options.view, continuationToken });
|
|
1616
|
+
repositories.push(...page.repositories);
|
|
1617
|
+
continuationToken = page.continuationToken ?? undefined;
|
|
1618
|
+
} while (continuationToken);
|
|
1619
|
+
return repositories;
|
|
1636
1620
|
}
|
|
1637
1621
|
async deleteRepository(projectId, repositoryId) {
|
|
1638
1622
|
await this.request(`/accounts/projects/${projectId}/repositories/${repositoryId}`, {
|
|
@@ -1722,279 +1706,14 @@ export class Meshagent {
|
|
|
1722
1706
|
responseType: "void",
|
|
1723
1707
|
});
|
|
1724
1708
|
}
|
|
1725
|
-
async createProjectSecret(params) {
|
|
1726
|
-
const { projectId, name, type, data } = params;
|
|
1727
|
-
const payload = await this.request(`/accounts/projects/${projectId}/secrets`, {
|
|
1728
|
-
method: "POST",
|
|
1729
|
-
json: {
|
|
1730
|
-
name,
|
|
1731
|
-
type,
|
|
1732
|
-
data_base64: bytesToBase64(normalizeBinary(data)),
|
|
1733
|
-
},
|
|
1734
|
-
action: "create project secret",
|
|
1735
|
-
});
|
|
1736
|
-
if (!payload || typeof payload !== "object" || typeof payload.id !== "string") {
|
|
1737
|
-
throw new RoomException("Invalid create project secret response payload");
|
|
1738
|
-
}
|
|
1739
|
-
return payload.id;
|
|
1740
|
-
}
|
|
1741
|
-
async updateProjectSecret(params) {
|
|
1742
|
-
const { projectId, secretId, name, type, data } = params;
|
|
1743
|
-
await this.request(`/accounts/projects/${projectId}/secrets/${secretId}`, {
|
|
1744
|
-
method: "PUT",
|
|
1745
|
-
json: {
|
|
1746
|
-
name,
|
|
1747
|
-
type,
|
|
1748
|
-
data_base64: bytesToBase64(normalizeBinary(data)),
|
|
1749
|
-
},
|
|
1750
|
-
action: "update project secret",
|
|
1751
|
-
responseType: "void",
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
async getProjectSecret(projectId, secretId) {
|
|
1755
|
-
const data = await this.request(`/accounts/projects/${projectId}/secrets/${secretId}`, {
|
|
1756
|
-
action: "fetch project secret",
|
|
1757
|
-
});
|
|
1758
|
-
return this.parseManagedSecret(data);
|
|
1759
|
-
}
|
|
1760
|
-
async listProjectSecrets(projectId) {
|
|
1761
|
-
const data = await this.request(`/accounts/projects/${projectId}/secrets`, {
|
|
1762
|
-
action: "list project secrets",
|
|
1763
|
-
});
|
|
1764
|
-
const secrets = Array.isArray(data?.secrets) ? data.secrets : [];
|
|
1765
|
-
return secrets.map((item) => this.parseManagedSecretInfo(item));
|
|
1766
|
-
}
|
|
1767
|
-
async deleteProjectSecret(projectId, secretId) {
|
|
1768
|
-
await this.request(`/accounts/projects/${projectId}/secrets/${secretId}`, {
|
|
1769
|
-
method: "DELETE",
|
|
1770
|
-
action: "delete project secret",
|
|
1771
|
-
responseType: "void",
|
|
1772
|
-
});
|
|
1773
|
-
}
|
|
1774
|
-
async createRoomSecret(params) {
|
|
1775
|
-
const { projectId, roomName, data, secretId, name, type, delegatedTo, forIdentity } = params;
|
|
1776
|
-
const payload = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/secrets`, {
|
|
1777
|
-
method: "POST",
|
|
1778
|
-
json: {
|
|
1779
|
-
data_base64: bytesToBase64(normalizeBinary(data)),
|
|
1780
|
-
secret_id: secretId,
|
|
1781
|
-
name,
|
|
1782
|
-
type,
|
|
1783
|
-
delegated_to: delegatedTo,
|
|
1784
|
-
for_identity: forIdentity,
|
|
1785
|
-
},
|
|
1786
|
-
action: "create room secret",
|
|
1787
|
-
});
|
|
1788
|
-
if (!payload || typeof payload !== "object" || typeof payload.id !== "string") {
|
|
1789
|
-
throw new RoomException("Invalid create room secret response payload");
|
|
1790
|
-
}
|
|
1791
|
-
return payload.id;
|
|
1792
|
-
}
|
|
1793
|
-
async updateRoomSecret(params) {
|
|
1794
|
-
const { projectId, roomName, secretId, data, name, type, delegatedTo, forIdentity } = params;
|
|
1795
|
-
await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/secrets/${secretId}`, {
|
|
1796
|
-
method: "PUT",
|
|
1797
|
-
json: {
|
|
1798
|
-
data_base64: bytesToBase64(normalizeBinary(data)),
|
|
1799
|
-
name,
|
|
1800
|
-
type,
|
|
1801
|
-
delegated_to: delegatedTo,
|
|
1802
|
-
for_identity: forIdentity,
|
|
1803
|
-
},
|
|
1804
|
-
action: "update room secret",
|
|
1805
|
-
responseType: "void",
|
|
1806
|
-
});
|
|
1807
|
-
}
|
|
1808
|
-
async getRoomSecret(params) {
|
|
1809
|
-
const { projectId, roomName, secretId, delegatedTo, forIdentity } = params;
|
|
1810
|
-
const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/secrets/${secretId}`, {
|
|
1811
|
-
query: {
|
|
1812
|
-
delegated_to: delegatedTo,
|
|
1813
|
-
for_identity: forIdentity,
|
|
1814
|
-
},
|
|
1815
|
-
action: "fetch room secret",
|
|
1816
|
-
});
|
|
1817
|
-
return this.parseManagedSecret(data);
|
|
1818
|
-
}
|
|
1819
|
-
async listRoomSecrets(params) {
|
|
1820
|
-
const { projectId, roomName, forIdentity } = params;
|
|
1821
|
-
const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/secrets`, {
|
|
1822
|
-
query: {
|
|
1823
|
-
for_identity: forIdentity,
|
|
1824
|
-
},
|
|
1825
|
-
action: "list room secrets",
|
|
1826
|
-
});
|
|
1827
|
-
const secrets = Array.isArray(data?.secrets) ? data.secrets : [];
|
|
1828
|
-
return secrets.map((item) => this.parseManagedSecretInfo(item));
|
|
1829
|
-
}
|
|
1830
|
-
async deleteRoomSecret(params) {
|
|
1831
|
-
const { projectId, roomName, secretId, delegatedTo, forIdentity } = params;
|
|
1832
|
-
await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/secrets/${secretId}`, {
|
|
1833
|
-
method: "DELETE",
|
|
1834
|
-
query: {
|
|
1835
|
-
delegated_to: delegatedTo,
|
|
1836
|
-
for_identity: forIdentity,
|
|
1837
|
-
},
|
|
1838
|
-
action: "delete room secret",
|
|
1839
|
-
responseType: "void",
|
|
1840
|
-
});
|
|
1841
|
-
}
|
|
1842
|
-
async createSecret(projectId, secret) {
|
|
1843
|
-
await this.createProjectSecret({
|
|
1844
|
-
projectId,
|
|
1845
|
-
name: secret.name,
|
|
1846
|
-
type: secret.type,
|
|
1847
|
-
data: encoder.encode(JSON.stringify(this.toSecretPayload(secret).data)),
|
|
1848
|
-
});
|
|
1849
|
-
}
|
|
1850
|
-
async updateSecret(projectId, secret) {
|
|
1851
|
-
if (!secret.id) {
|
|
1852
|
-
throw new RoomException("Secret id is required to update a secret");
|
|
1853
|
-
}
|
|
1854
|
-
await this.updateProjectSecret({
|
|
1855
|
-
projectId,
|
|
1856
|
-
secretId: secret.id,
|
|
1857
|
-
name: secret.name,
|
|
1858
|
-
type: secret.type,
|
|
1859
|
-
data: encoder.encode(JSON.stringify(this.toSecretPayload(secret).data)),
|
|
1860
|
-
});
|
|
1861
|
-
}
|
|
1862
|
-
async deleteSecret(projectId, secretId) {
|
|
1863
|
-
await this.deleteProjectSecret(projectId, secretId);
|
|
1864
|
-
}
|
|
1865
|
-
async listSecrets(projectId) {
|
|
1866
|
-
const secretInfos = await this.listProjectSecrets(projectId);
|
|
1867
|
-
const secrets = await Promise.all(secretInfos.map(async (secretInfo) => {
|
|
1868
|
-
const secret = await this.getProjectSecret(projectId, secretInfo.id);
|
|
1869
|
-
return this.parseSecretPayload(secret, secret.data);
|
|
1870
|
-
}));
|
|
1871
|
-
return secrets;
|
|
1872
|
-
}
|
|
1873
|
-
async createProjectExternalOAuthRegistration(params) {
|
|
1874
|
-
const { projectId, oauth, clientId, clientSecret, delegatedTo, connector } = params;
|
|
1875
|
-
const payload = await this.request(`/accounts/projects/${projectId}/external-oauth`, {
|
|
1876
|
-
method: "POST",
|
|
1877
|
-
json: {
|
|
1878
|
-
oauth,
|
|
1879
|
-
client_id: clientId,
|
|
1880
|
-
client_secret: clientSecret,
|
|
1881
|
-
delegated_to: delegatedTo,
|
|
1882
|
-
connector: this.serializeConnectorRef(connector),
|
|
1883
|
-
},
|
|
1884
|
-
action: "create project external oauth registration",
|
|
1885
|
-
});
|
|
1886
|
-
if (!payload || typeof payload !== "object" || typeof payload.id !== "string") {
|
|
1887
|
-
throw new RoomException("Invalid create project external oauth registration response payload");
|
|
1888
|
-
}
|
|
1889
|
-
return payload.id;
|
|
1890
|
-
}
|
|
1891
|
-
async updateProjectExternalOAuthRegistration(params) {
|
|
1892
|
-
const { projectId, registrationId, oauth, clientId, clientSecret, delegatedTo, connector } = params;
|
|
1893
|
-
await this.request(`/accounts/projects/${projectId}/external-oauth/${registrationId}`, {
|
|
1894
|
-
method: "PUT",
|
|
1895
|
-
json: {
|
|
1896
|
-
oauth,
|
|
1897
|
-
client_id: clientId,
|
|
1898
|
-
client_secret: clientSecret,
|
|
1899
|
-
delegated_to: delegatedTo,
|
|
1900
|
-
connector: this.serializeConnectorRef(connector),
|
|
1901
|
-
},
|
|
1902
|
-
action: "update project external oauth registration",
|
|
1903
|
-
responseType: "void",
|
|
1904
|
-
});
|
|
1905
|
-
}
|
|
1906
|
-
async listProjectExternalOAuthRegistrations(params) {
|
|
1907
|
-
const { projectId, delegatedTo } = params;
|
|
1908
|
-
const data = await this.request(`/accounts/projects/${projectId}/external-oauth`, {
|
|
1909
|
-
query: {
|
|
1910
|
-
delegated_to: delegatedTo,
|
|
1911
|
-
},
|
|
1912
|
-
action: "list project external oauth registrations",
|
|
1913
|
-
});
|
|
1914
|
-
const registrations = Array.isArray(data?.registrations) ? data.registrations : [];
|
|
1915
|
-
return registrations.map((item) => this.parseExternalOAuthClientRegistration(item));
|
|
1916
|
-
}
|
|
1917
|
-
async deleteProjectExternalOAuthRegistration(params) {
|
|
1918
|
-
const { projectId, registrationId, delegatedTo } = params;
|
|
1919
|
-
await this.request(`/accounts/projects/${projectId}/external-oauth/${registrationId}`, {
|
|
1920
|
-
method: "DELETE",
|
|
1921
|
-
query: {
|
|
1922
|
-
delegated_to: delegatedTo,
|
|
1923
|
-
},
|
|
1924
|
-
action: "delete project external oauth registration",
|
|
1925
|
-
responseType: "void",
|
|
1926
|
-
});
|
|
1927
|
-
}
|
|
1928
|
-
async createRoomExternalOAuthRegistration(params) {
|
|
1929
|
-
const { projectId, roomName, oauth, clientId, clientSecret, delegatedTo, connector } = params;
|
|
1930
|
-
const payload = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/external-oauth`, {
|
|
1931
|
-
method: "POST",
|
|
1932
|
-
json: {
|
|
1933
|
-
oauth,
|
|
1934
|
-
client_id: clientId,
|
|
1935
|
-
client_secret: clientSecret,
|
|
1936
|
-
delegated_to: delegatedTo,
|
|
1937
|
-
connector: this.serializeConnectorRef(connector),
|
|
1938
|
-
},
|
|
1939
|
-
action: "create room external oauth registration",
|
|
1940
|
-
});
|
|
1941
|
-
if (!payload || typeof payload !== "object" || typeof payload.id !== "string") {
|
|
1942
|
-
throw new RoomException("Invalid create room external oauth registration response payload");
|
|
1943
|
-
}
|
|
1944
|
-
return payload.id;
|
|
1945
|
-
}
|
|
1946
|
-
async updateRoomExternalOAuthRegistration(params) {
|
|
1947
|
-
const { projectId, roomName, registrationId, oauth, clientId, clientSecret, delegatedTo, connector } = params;
|
|
1948
|
-
await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/external-oauth/${registrationId}`, {
|
|
1949
|
-
method: "PUT",
|
|
1950
|
-
json: {
|
|
1951
|
-
oauth,
|
|
1952
|
-
client_id: clientId,
|
|
1953
|
-
client_secret: clientSecret,
|
|
1954
|
-
delegated_to: delegatedTo,
|
|
1955
|
-
connector: this.serializeConnectorRef(connector),
|
|
1956
|
-
},
|
|
1957
|
-
action: "update room external oauth registration",
|
|
1958
|
-
responseType: "void",
|
|
1959
|
-
});
|
|
1960
|
-
}
|
|
1961
|
-
async listRoomExternalOAuthRegistrations(params) {
|
|
1962
|
-
const { projectId, roomName, delegatedTo } = params;
|
|
1963
|
-
const data = await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/external-oauth`, {
|
|
1964
|
-
query: {
|
|
1965
|
-
delegated_to: delegatedTo,
|
|
1966
|
-
},
|
|
1967
|
-
action: "list room external oauth registrations",
|
|
1968
|
-
});
|
|
1969
|
-
const registrations = Array.isArray(data?.registrations) ? data.registrations : [];
|
|
1970
|
-
return registrations.map((item) => this.parseExternalOAuthClientRegistration(item));
|
|
1971
|
-
}
|
|
1972
|
-
async deleteRoomExternalOAuthRegistration(params) {
|
|
1973
|
-
const { projectId, roomName, registrationId, delegatedTo } = params;
|
|
1974
|
-
await this.request(`/accounts/projects/${projectId}/rooms/${roomName}/external-oauth/${registrationId}`, {
|
|
1975
|
-
method: "DELETE",
|
|
1976
|
-
query: {
|
|
1977
|
-
delegated_to: delegatedTo,
|
|
1978
|
-
},
|
|
1979
|
-
action: "delete room external oauth registration",
|
|
1980
|
-
responseType: "void",
|
|
1981
|
-
});
|
|
1982
|
-
}
|
|
1983
1709
|
async createRoom(params) {
|
|
1984
|
-
const { projectId, name, ifNotExists = false, metadata, annotations
|
|
1710
|
+
const { projectId, name, ifNotExists = false, metadata, annotations } = params;
|
|
1985
1711
|
const payload = {
|
|
1986
1712
|
name,
|
|
1987
1713
|
if_not_exists: Boolean(ifNotExists),
|
|
1988
1714
|
metadata,
|
|
1989
1715
|
annotations,
|
|
1990
1716
|
};
|
|
1991
|
-
if (permissions) {
|
|
1992
|
-
const serialized = {};
|
|
1993
|
-
for (const [key, value] of Object.entries(permissions)) {
|
|
1994
|
-
serialized[key] = value instanceof ApiScope ? value.toJSON() : value;
|
|
1995
|
-
}
|
|
1996
|
-
payload["permissions"] = serialized;
|
|
1997
|
-
}
|
|
1998
1717
|
const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
|
|
1999
1718
|
method: "POST",
|
|
2000
1719
|
json: payload,
|
|
@@ -2030,78 +1749,103 @@ export class Meshagent {
|
|
|
2030
1749
|
responseType: "void",
|
|
2031
1750
|
});
|
|
2032
1751
|
}
|
|
2033
|
-
async
|
|
2034
|
-
const
|
|
1752
|
+
async createGroup(params) {
|
|
1753
|
+
const { projectId, name, metadata, annotations } = params;
|
|
1754
|
+
const data = await this.request(`/accounts/projects/${projectId}/groups`, {
|
|
2035
1755
|
method: "POST",
|
|
2036
|
-
json: {},
|
|
2037
|
-
action: "
|
|
1756
|
+
json: { name, metadata, annotations },
|
|
1757
|
+
action: "create group",
|
|
2038
1758
|
});
|
|
2039
|
-
return this.
|
|
1759
|
+
return this.parseGroup(data);
|
|
2040
1760
|
}
|
|
2041
|
-
async
|
|
2042
|
-
const
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
1761
|
+
async getGroup(projectId, groupId) {
|
|
1762
|
+
const data = await this.request(`/accounts/projects/${projectId}/groups/${groupId}`, {
|
|
1763
|
+
action: "fetch group",
|
|
1764
|
+
});
|
|
1765
|
+
return this.parseGroup(data);
|
|
1766
|
+
}
|
|
1767
|
+
async updateGroup(projectId, groupId, name, options = {}) {
|
|
1768
|
+
const payload = { name };
|
|
1769
|
+
if (options.metadata !== undefined) {
|
|
1770
|
+
payload["metadata"] = options.metadata;
|
|
1771
|
+
}
|
|
1772
|
+
if (options.annotations !== undefined) {
|
|
1773
|
+
payload["annotations"] = options.annotations;
|
|
1774
|
+
}
|
|
1775
|
+
await this.request(`/accounts/projects/${projectId}/groups/${groupId}`, {
|
|
1776
|
+
method: "PUT",
|
|
1777
|
+
json: payload,
|
|
1778
|
+
action: "update group",
|
|
2051
1779
|
responseType: "void",
|
|
2052
1780
|
});
|
|
2053
1781
|
}
|
|
2054
|
-
async
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
json: {
|
|
2059
|
-
room_id: roomId,
|
|
2060
|
-
email,
|
|
2061
|
-
permissions: permissions.toJSON(),
|
|
2062
|
-
...(inviteRedirectUrl !== undefined
|
|
2063
|
-
? { invite_redirect_url: inviteRedirectUrl }
|
|
2064
|
-
: {}),
|
|
2065
|
-
},
|
|
2066
|
-
action: "create room grant",
|
|
1782
|
+
async deleteGroup(projectId, groupId) {
|
|
1783
|
+
await this.request(`/accounts/projects/${projectId}/groups/${groupId}`, {
|
|
1784
|
+
method: "DELETE",
|
|
1785
|
+
action: "delete group",
|
|
2067
1786
|
responseType: "void",
|
|
2068
1787
|
});
|
|
2069
1788
|
}
|
|
2070
|
-
async
|
|
2071
|
-
const
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
room_id: roomId,
|
|
2077
|
-
user_id: userId,
|
|
2078
|
-
permissions: permissions.toJSON(),
|
|
1789
|
+
async listGroupsPage(projectId, options = {}) {
|
|
1790
|
+
const data = await this.request(`/accounts/projects/${projectId}/groups`, {
|
|
1791
|
+
query: {
|
|
1792
|
+
page_size: options.pageSize ?? 50,
|
|
1793
|
+
continuation_token: options.continuationToken,
|
|
1794
|
+
filter: options.filter,
|
|
2079
1795
|
},
|
|
2080
|
-
action: "
|
|
1796
|
+
action: "list groups",
|
|
1797
|
+
});
|
|
1798
|
+
const groups = Array.isArray(data?.groups) ? data.groups : [];
|
|
1799
|
+
return {
|
|
1800
|
+
groups: groups.map((item) => this.parseGroup(item)),
|
|
1801
|
+
continuationToken: data?.continuation_token ?? null,
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
async listGroups(projectId, options = {}) {
|
|
1805
|
+
const page = await this.listGroupsPage(projectId, options);
|
|
1806
|
+
return page.groups;
|
|
1807
|
+
}
|
|
1808
|
+
async setGroupMember(params) {
|
|
1809
|
+
const { projectId, groupId, subject, role = "member" } = params;
|
|
1810
|
+
await this.request(`/accounts/projects/${projectId}/groups/${groupId}/members`, {
|
|
1811
|
+
method: "POST",
|
|
1812
|
+
json: { subject, role },
|
|
1813
|
+
action: "set group member",
|
|
2081
1814
|
responseType: "void",
|
|
2082
1815
|
});
|
|
2083
1816
|
}
|
|
2084
|
-
async
|
|
2085
|
-
const
|
|
2086
|
-
|
|
2087
|
-
|
|
1817
|
+
async listGroupMembersPage(projectId, groupId, options = {}) {
|
|
1818
|
+
const data = await this.request(`/accounts/projects/${projectId}/groups/${groupId}/members`, {
|
|
1819
|
+
query: { page_size: options.pageSize ?? 50, continuation_token: options.continuationToken },
|
|
1820
|
+
action: "list group members",
|
|
1821
|
+
});
|
|
1822
|
+
const members = Array.isArray(data?.members) ? data.members : [];
|
|
1823
|
+
return { members: members.map((item) => this.parseGroupMember(item)), continuationToken: data?.continuation_token ?? null };
|
|
1824
|
+
}
|
|
1825
|
+
async listGroupMembers(projectId, groupId, options = {}) {
|
|
1826
|
+
const page = await this.listGroupMembersPage(projectId, groupId, options);
|
|
1827
|
+
return page.members;
|
|
1828
|
+
}
|
|
1829
|
+
async deleteGroupMember(params) {
|
|
1830
|
+
const { projectId, groupId, subjectType, subjectId } = params;
|
|
1831
|
+
await this.request(`/accounts/projects/${projectId}/groups/${groupId}/members/${subjectType}/${subjectId}`, {
|
|
2088
1832
|
method: "DELETE",
|
|
2089
|
-
action: "delete
|
|
1833
|
+
action: "delete group member",
|
|
2090
1834
|
responseType: "void",
|
|
2091
1835
|
});
|
|
2092
1836
|
}
|
|
2093
|
-
async
|
|
2094
|
-
const
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
action: "
|
|
1837
|
+
async connectRoom(projectId, room) {
|
|
1838
|
+
const data = await this.request(`/accounts/projects/${projectId}/rooms/${room}/connect`, {
|
|
1839
|
+
method: "POST",
|
|
1840
|
+
json: {},
|
|
1841
|
+
action: "connect room",
|
|
2098
1842
|
});
|
|
2099
|
-
return this.
|
|
1843
|
+
return this.parseRoomConnectionInfo(data);
|
|
2100
1844
|
}
|
|
2101
1845
|
async listRooms(projectId, options = {}) {
|
|
2102
|
-
const {
|
|
1846
|
+
const { pageSize = 50, continuationToken, filter, view } = options;
|
|
2103
1847
|
const data = await this.request(`/accounts/projects/${projectId}/rooms`, {
|
|
2104
|
-
query: {
|
|
1848
|
+
query: { page_size: pageSize, continuation_token: continuationToken, filter, view },
|
|
2105
1849
|
action: "list rooms",
|
|
2106
1850
|
});
|
|
2107
1851
|
const rooms = Array.isArray(data?.rooms) ? data.rooms : [];
|
|
@@ -2132,16 +1876,23 @@ export class Meshagent {
|
|
|
2132
1876
|
return this.parseRoute(data.route);
|
|
2133
1877
|
}
|
|
2134
1878
|
async listRoutesPage(projectId, options = {}) {
|
|
2135
|
-
const {
|
|
1879
|
+
const { pageSize = 100, continuationToken, filter } = options;
|
|
2136
1880
|
const data = await this.request(`/accounts/projects/${projectId}/routes`, {
|
|
2137
|
-
query: {
|
|
1881
|
+
query: { page_size: pageSize, continuation_token: continuationToken, filter },
|
|
2138
1882
|
action: "list routes",
|
|
2139
1883
|
});
|
|
2140
1884
|
const routes = Array.isArray(data.routes) ? data.routes.map((item) => this.parseRoute(item)) : [];
|
|
2141
|
-
return { routes, total: Number(data.total ?? routes.length) };
|
|
1885
|
+
return { routes, total: Number(data.total ?? routes.length), continuationToken: data.continuation_token ?? null };
|
|
2142
1886
|
}
|
|
2143
1887
|
async listRoutes(projectId, options = {}) {
|
|
2144
|
-
|
|
1888
|
+
const routes = [];
|
|
1889
|
+
let continuationToken;
|
|
1890
|
+
do {
|
|
1891
|
+
const page = await this.listRoutesPage(projectId, { ...options, continuationToken });
|
|
1892
|
+
routes.push(...page.routes);
|
|
1893
|
+
continuationToken = page.continuationToken ?? undefined;
|
|
1894
|
+
} while (continuationToken);
|
|
1895
|
+
return routes;
|
|
2145
1896
|
}
|
|
2146
1897
|
async listRoomRoutesPage(params) {
|
|
2147
1898
|
const { projectId, roomName, count = 100, offset = 0, filter } = params;
|
|
@@ -2177,63 +1928,115 @@ export class Meshagent {
|
|
|
2177
1928
|
responseType: "void",
|
|
2178
1929
|
});
|
|
2179
1930
|
}
|
|
2180
|
-
async
|
|
2181
|
-
const
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
1931
|
+
async testAccess(projectId, params) {
|
|
1932
|
+
const data = await this.request(`/accounts/projects/${projectId}/access:test`, {
|
|
1933
|
+
method: "POST",
|
|
1934
|
+
json: {
|
|
1935
|
+
subject: this.serializeAccessSubject(params.subject),
|
|
1936
|
+
resource: this.serializeAccessResource(params.resource),
|
|
1937
|
+
relation: params.relation,
|
|
1938
|
+
},
|
|
1939
|
+
action: "test access",
|
|
1940
|
+
});
|
|
1941
|
+
return {
|
|
1942
|
+
allowed: data?.allowed === true,
|
|
1943
|
+
resource: data?.resource && typeof data.resource === "object" ? this.parseAccessResource(data.resource) : undefined,
|
|
1944
|
+
subject: data?.subject && typeof data.subject === "object" ? this.parseAccessSubject(data.subject) : undefined,
|
|
1945
|
+
relation: typeof data?.relation === "string" ? data.relation : undefined,
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
async getEffectiveAccess(projectId, params) {
|
|
1949
|
+
const data = await this.request(`/accounts/projects/${projectId}/access:effective`, {
|
|
1950
|
+
method: "POST",
|
|
1951
|
+
json: {
|
|
1952
|
+
subject: this.serializeAccessSubject(params.subject),
|
|
1953
|
+
resource: this.serializeAccessResource(params.resource),
|
|
1954
|
+
...(params.relations ? { relations: params.relations } : {}),
|
|
1955
|
+
},
|
|
1956
|
+
action: "get effective access",
|
|
2185
1957
|
});
|
|
2186
|
-
|
|
2187
|
-
|
|
1958
|
+
return {
|
|
1959
|
+
resource: this.parseAccessResource(data?.resource),
|
|
1960
|
+
subject: this.parseAccessSubject(data?.subject),
|
|
1961
|
+
effectiveRoles: Array.isArray(data?.effective_roles) ? data.effective_roles.filter((item) => typeof item === "string") : [],
|
|
1962
|
+
capabilities: data?.capabilities && typeof data.capabilities === "object" ? data.capabilities : {},
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
async listAccessBindings(projectId, params) {
|
|
1966
|
+
const page = await this.listAccessBindingsPage(projectId, params);
|
|
1967
|
+
return page.accessGrants;
|
|
2188
1968
|
}
|
|
2189
|
-
async
|
|
2190
|
-
const
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
1969
|
+
async listAccessBindingsPage(projectId, params) {
|
|
1970
|
+
const data = await this.request(`/accounts/projects/${projectId}/access:bindings`, {
|
|
1971
|
+
method: "POST",
|
|
1972
|
+
json: {
|
|
1973
|
+
subject: this.serializeAccessSubject(params.subject),
|
|
1974
|
+
},
|
|
1975
|
+
action: "list access bindings",
|
|
2195
1976
|
});
|
|
2196
|
-
|
|
2197
|
-
|
|
1977
|
+
return {
|
|
1978
|
+
accessGrants: Array.isArray(data?.access_grants)
|
|
1979
|
+
? data.access_grants.map((item) => this.parseProjectRoomGrant(item))
|
|
1980
|
+
: [],
|
|
1981
|
+
};
|
|
2198
1982
|
}
|
|
2199
|
-
async
|
|
2200
|
-
|
|
2201
|
-
const
|
|
2202
|
-
|
|
2203
|
-
query: {
|
|
2204
|
-
action: "
|
|
1983
|
+
async getResourcePolicyPage(projectId, params) {
|
|
1984
|
+
this.validateResourcePolicyType(params.resourceType);
|
|
1985
|
+
const data = await this.request(`/accounts/projects/${projectId}/iam/${params.resourceType}/${params.resourceId}/policy`, {
|
|
1986
|
+
method: "GET",
|
|
1987
|
+
query: { page_size: params.pageSize ?? 50, continuation_token: params.continuationToken },
|
|
1988
|
+
action: "get resource policy",
|
|
2205
1989
|
});
|
|
2206
|
-
|
|
2207
|
-
|
|
1990
|
+
return {
|
|
1991
|
+
resource: this.parseAccessResource(data?.resource),
|
|
1992
|
+
accessGrants: Array.isArray(data?.access_grants)
|
|
1993
|
+
? data.access_grants.map((item) => this.parseProjectRoomGrant(item))
|
|
1994
|
+
: [],
|
|
1995
|
+
continuationToken: typeof data?.continuation_token === "string" ? data.continuation_token : null,
|
|
1996
|
+
};
|
|
2208
1997
|
}
|
|
2209
|
-
async
|
|
2210
|
-
const
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
1998
|
+
async getResourcePolicy(projectId, params) {
|
|
1999
|
+
const grants = [];
|
|
2000
|
+
let continuationToken = params.continuationToken;
|
|
2001
|
+
do {
|
|
2002
|
+
const page = await this.getResourcePolicyPage(projectId, { ...params, continuationToken });
|
|
2003
|
+
grants.push(...page.accessGrants);
|
|
2004
|
+
continuationToken = page.continuationToken ?? undefined;
|
|
2005
|
+
} while (continuationToken);
|
|
2006
|
+
return grants;
|
|
2007
|
+
}
|
|
2008
|
+
async grantResourcePolicy(projectId, params) {
|
|
2009
|
+
this.validateResourcePolicyType(params.resourceType);
|
|
2010
|
+
await this.request(`/accounts/projects/${projectId}/iam/${params.resourceType}/${params.resourceId}/policy:grant`, {
|
|
2011
|
+
method: "POST",
|
|
2012
|
+
json: {
|
|
2013
|
+
subject: this.serializeAccessSubject(params.subject),
|
|
2014
|
+
roles: params.roles,
|
|
2015
|
+
...(params.inviteRedirectUrl ? { invite_redirect_url: params.inviteRedirectUrl } : {}),
|
|
2016
|
+
},
|
|
2017
|
+
action: "grant resource policy",
|
|
2214
2018
|
});
|
|
2215
|
-
const rooms = Array.isArray(data?.rooms) ? data.rooms : [];
|
|
2216
|
-
return rooms.map((item) => this.parseProjectRoomGrantCount(item));
|
|
2217
2019
|
}
|
|
2218
|
-
async
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2020
|
+
async revokeResourcePolicy(projectId, params) {
|
|
2021
|
+
this.validateResourcePolicyType(params.resourceType);
|
|
2022
|
+
await this.request(`/accounts/projects/${projectId}/iam/${params.resourceType}/${params.resourceId}/policy:revoke`, {
|
|
2023
|
+
method: "POST",
|
|
2024
|
+
json: {
|
|
2025
|
+
subject: this.serializeAccessSubject(params.subject),
|
|
2026
|
+
},
|
|
2027
|
+
action: "revoke resource policy",
|
|
2223
2028
|
});
|
|
2224
|
-
const users = Array.isArray(data?.users) ? data.users : [];
|
|
2225
|
-
const parsed = users.map((item) => this.parseProjectUserGrantCount(item));
|
|
2226
|
-
return { users: parsed, total: typeof data?.total === "number" ? data.total : parsed.length };
|
|
2227
2029
|
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2030
|
+
validateResourcePolicyType(resourceType) {
|
|
2031
|
+
if (resourceType === "agent") {
|
|
2032
|
+
throw new Error("managed agent resource policies are not supported; use agent run_as instead");
|
|
2033
|
+
}
|
|
2231
2034
|
}
|
|
2232
2035
|
async createOAuthClient(projectId, params) {
|
|
2233
|
-
const { grantTypes, responseTypes, redirectUris, scope, metadata = {} } = params;
|
|
2036
|
+
const { grantTypes, responseTypes, redirectUris, scope, metadata = {}, official = false } = params;
|
|
2234
2037
|
const data = await this.request(`/accounts/projects/${projectId}/oauth/clients`, {
|
|
2235
2038
|
method: "POST",
|
|
2236
|
-
json: { grant_types: grantTypes, response_types: responseTypes, redirect_uris: redirectUris, scope, metadata },
|
|
2039
|
+
json: { grant_types: grantTypes, response_types: responseTypes, redirect_uris: redirectUris, scope, metadata, official },
|
|
2237
2040
|
action: "create oauth client",
|
|
2238
2041
|
});
|
|
2239
2042
|
return this.parseOAuthClient(data);
|