@foxnose/sdk 0.1.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/LICENSE +190 -0
- package/README.md +213 -0
- package/dist/index.cjs +1397 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +716 -0
- package/dist/index.d.ts +716 -0
- package/dist/index.js +1353 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1353 @@
|
|
|
1
|
+
// src/auth/anonymous.ts
|
|
2
|
+
var AnonymousAuth = class {
|
|
3
|
+
buildHeaders(_request) {
|
|
4
|
+
return {};
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// src/auth/jwt.ts
|
|
9
|
+
var StaticTokenProvider = class {
|
|
10
|
+
constructor(token) {
|
|
11
|
+
this.token = token;
|
|
12
|
+
}
|
|
13
|
+
getToken() {
|
|
14
|
+
return this.token;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var JWTAuth = class _JWTAuth {
|
|
18
|
+
provider;
|
|
19
|
+
scheme;
|
|
20
|
+
constructor(provider, options) {
|
|
21
|
+
this.provider = provider;
|
|
22
|
+
this.scheme = options?.scheme ?? "Bearer";
|
|
23
|
+
}
|
|
24
|
+
buildHeaders(_request) {
|
|
25
|
+
const token = this.provider.getToken();
|
|
26
|
+
if (!token) {
|
|
27
|
+
throw new Error("Token provider returned an empty token");
|
|
28
|
+
}
|
|
29
|
+
return { Authorization: `${this.scheme} ${token}` };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convenience constructor for scripts with manual token management.
|
|
33
|
+
*/
|
|
34
|
+
static fromStaticToken(token, options) {
|
|
35
|
+
return new _JWTAuth(new StaticTokenProvider(token), options);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/auth/secure.ts
|
|
40
|
+
import { createHash, createSign } from "crypto";
|
|
41
|
+
|
|
42
|
+
// src/errors.ts
|
|
43
|
+
var FoxnoseError = class extends Error {
|
|
44
|
+
constructor(message) {
|
|
45
|
+
super(message);
|
|
46
|
+
this.name = "FoxnoseError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var FoxnoseAPIError = class extends FoxnoseError {
|
|
50
|
+
statusCode;
|
|
51
|
+
errorCode;
|
|
52
|
+
detail;
|
|
53
|
+
responseHeaders;
|
|
54
|
+
responseBody;
|
|
55
|
+
constructor(options) {
|
|
56
|
+
const code = options.errorCode ? `, error_code=${options.errorCode}` : "";
|
|
57
|
+
super(`${options.message} (status=${options.statusCode}${code})`);
|
|
58
|
+
this.name = "FoxnoseAPIError";
|
|
59
|
+
this.statusCode = options.statusCode;
|
|
60
|
+
this.errorCode = options.errorCode;
|
|
61
|
+
this.detail = options.detail;
|
|
62
|
+
this.responseHeaders = options.responseHeaders;
|
|
63
|
+
this.responseBody = options.responseBody;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var FoxnoseAuthError = class extends FoxnoseError {
|
|
67
|
+
constructor(message) {
|
|
68
|
+
super(message);
|
|
69
|
+
this.name = "FoxnoseAuthError";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var FoxnoseTransportError = class extends FoxnoseError {
|
|
73
|
+
constructor(message) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.name = "FoxnoseTransportError";
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// src/auth/secure.ts
|
|
80
|
+
var SecureKeyAuth = class {
|
|
81
|
+
publicKey;
|
|
82
|
+
privateKeyPem;
|
|
83
|
+
clock;
|
|
84
|
+
constructor(publicKey, privateKey, options) {
|
|
85
|
+
if (!publicKey || !privateKey) {
|
|
86
|
+
throw new Error("publicKey and privateKey are required");
|
|
87
|
+
}
|
|
88
|
+
this.publicKey = publicKey;
|
|
89
|
+
this.clock = options?.clock ?? (() => /* @__PURE__ */ new Date());
|
|
90
|
+
try {
|
|
91
|
+
const derB64 = privateKey;
|
|
92
|
+
this.privateKeyPem = `-----BEGIN EC PRIVATE KEY-----
|
|
93
|
+
` + derB64.match(/.{1,64}/g).join("\n") + `
|
|
94
|
+
-----END EC PRIVATE KEY-----`;
|
|
95
|
+
} catch (err) {
|
|
96
|
+
throw new FoxnoseAuthError(`Failed to load private key: ${err}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
buildHeaders(request) {
|
|
100
|
+
const body = request.body ?? new Uint8Array(0);
|
|
101
|
+
const now = this.clock();
|
|
102
|
+
const timestamp = now.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
103
|
+
let path;
|
|
104
|
+
try {
|
|
105
|
+
const parsed = new URL(request.url);
|
|
106
|
+
path = parsed.pathname || "/";
|
|
107
|
+
if (parsed.search) {
|
|
108
|
+
path = `${path}${parsed.search}`;
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
path = request.path || "/";
|
|
112
|
+
}
|
|
113
|
+
const bodyHash = createHash("sha256").update(body).digest("hex");
|
|
114
|
+
const dataToSign = `${path}|${bodyHash}|${timestamp}`;
|
|
115
|
+
const signer = createSign("SHA256");
|
|
116
|
+
signer.update(dataToSign);
|
|
117
|
+
signer.end();
|
|
118
|
+
const signatureBuffer = signer.sign({
|
|
119
|
+
key: this.privateKeyPem,
|
|
120
|
+
dsaEncoding: "der"
|
|
121
|
+
});
|
|
122
|
+
const signatureB64 = signatureBuffer.toString("base64");
|
|
123
|
+
return {
|
|
124
|
+
Authorization: `Secure ${this.publicKey}:${signatureB64}`,
|
|
125
|
+
Date: timestamp
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/auth/simple.ts
|
|
131
|
+
var SimpleKeyAuth = class {
|
|
132
|
+
publicKey;
|
|
133
|
+
secretKey;
|
|
134
|
+
constructor(publicKey, secretKey) {
|
|
135
|
+
if (!publicKey || !secretKey) {
|
|
136
|
+
throw new Error("publicKey and secretKey are required");
|
|
137
|
+
}
|
|
138
|
+
this.publicKey = publicKey;
|
|
139
|
+
this.secretKey = secretKey;
|
|
140
|
+
}
|
|
141
|
+
buildHeaders(_request) {
|
|
142
|
+
return { Authorization: `Simple ${this.publicKey}:${this.secretKey}` };
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// src/config.ts
|
|
147
|
+
var DEFAULT_RETRY_CONFIG = {
|
|
148
|
+
attempts: 3,
|
|
149
|
+
backoffFactor: 0.5,
|
|
150
|
+
statusCodes: [408, 425, 429, 500, 502, 503, 504],
|
|
151
|
+
methods: ["GET", "HEAD", "OPTIONS", "PUT", "DELETE"]
|
|
152
|
+
};
|
|
153
|
+
var SDK_VERSION = "0.1.0";
|
|
154
|
+
var DEFAULT_USER_AGENT = `foxnose-sdk-js/${SDK_VERSION}`;
|
|
155
|
+
function createConfig(options) {
|
|
156
|
+
if (!options.baseUrl) {
|
|
157
|
+
throw new Error("baseUrl must be provided");
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
baseUrl: options.baseUrl.replace(/\/+$/, ""),
|
|
161
|
+
timeout: options.timeout ?? 3e4,
|
|
162
|
+
defaultHeaders: options.defaultHeaders,
|
|
163
|
+
userAgent: options.userAgent ?? DEFAULT_USER_AGENT
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/http.ts
|
|
168
|
+
var HttpTransport = class {
|
|
169
|
+
config;
|
|
170
|
+
auth;
|
|
171
|
+
retry;
|
|
172
|
+
constructor(options) {
|
|
173
|
+
this.config = options.config;
|
|
174
|
+
this.auth = options.auth ?? new AnonymousAuth();
|
|
175
|
+
this.retry = options.retryConfig ?? { ...DEFAULT_RETRY_CONFIG };
|
|
176
|
+
}
|
|
177
|
+
async request(method, path, options) {
|
|
178
|
+
const parseJson = options?.parseJson ?? true;
|
|
179
|
+
const response = await this.sendWithRetries(method, path, options);
|
|
180
|
+
return this.maybeDecodeResponse(response, parseJson);
|
|
181
|
+
}
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
183
|
+
close() {
|
|
184
|
+
}
|
|
185
|
+
buildUrl(path, params) {
|
|
186
|
+
const base = this.config.baseUrl + path;
|
|
187
|
+
if (!params || Object.keys(params).length === 0) {
|
|
188
|
+
return base;
|
|
189
|
+
}
|
|
190
|
+
const searchParams = new URLSearchParams();
|
|
191
|
+
for (const [key, value] of Object.entries(params)) {
|
|
192
|
+
if (value !== void 0 && value !== null) {
|
|
193
|
+
searchParams.append(key, String(value));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const qs = searchParams.toString();
|
|
197
|
+
return qs ? `${base}?${qs}` : base;
|
|
198
|
+
}
|
|
199
|
+
buildRequest(method, path, options) {
|
|
200
|
+
const headers = {};
|
|
201
|
+
if (this.config.defaultHeaders) {
|
|
202
|
+
Object.assign(headers, this.config.defaultHeaders);
|
|
203
|
+
}
|
|
204
|
+
headers["User-Agent"] = headers["User-Agent"] ?? this.config.userAgent;
|
|
205
|
+
if (options?.headers) {
|
|
206
|
+
Object.assign(headers, options.headers);
|
|
207
|
+
}
|
|
208
|
+
let body = new Uint8Array(0);
|
|
209
|
+
let bodyInit;
|
|
210
|
+
if (options?.jsonBody !== void 0) {
|
|
211
|
+
const jsonStr = JSON.stringify(options.jsonBody);
|
|
212
|
+
body = new TextEncoder().encode(jsonStr);
|
|
213
|
+
bodyInit = jsonStr;
|
|
214
|
+
headers["Content-Type"] = headers["Content-Type"] ?? "application/json";
|
|
215
|
+
} else if (options?.content) {
|
|
216
|
+
body = options.content;
|
|
217
|
+
bodyInit = options.content;
|
|
218
|
+
}
|
|
219
|
+
const url = this.buildUrl(path, options?.params);
|
|
220
|
+
const requestData = {
|
|
221
|
+
method: method.toUpperCase(),
|
|
222
|
+
url,
|
|
223
|
+
path: this.buildSigningPath(path, options?.params),
|
|
224
|
+
body
|
|
225
|
+
};
|
|
226
|
+
const authHeaders = this.auth.buildHeaders(requestData);
|
|
227
|
+
if (authHeaders) {
|
|
228
|
+
Object.assign(headers, authHeaders);
|
|
229
|
+
}
|
|
230
|
+
const init = {
|
|
231
|
+
method: method.toUpperCase(),
|
|
232
|
+
headers,
|
|
233
|
+
body: bodyInit
|
|
234
|
+
};
|
|
235
|
+
return { url, init, body };
|
|
236
|
+
}
|
|
237
|
+
buildSigningPath(path, params) {
|
|
238
|
+
if (!params || Object.keys(params).length === 0) {
|
|
239
|
+
return path;
|
|
240
|
+
}
|
|
241
|
+
const searchParams = new URLSearchParams();
|
|
242
|
+
for (const [key, value] of Object.entries(params)) {
|
|
243
|
+
if (value !== void 0 && value !== null) {
|
|
244
|
+
searchParams.append(key, String(value));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const qs = searchParams.toString();
|
|
248
|
+
return qs ? `${path}?${qs}` : path;
|
|
249
|
+
}
|
|
250
|
+
shouldRetry(method, statusCode) {
|
|
251
|
+
if (!this.retry.methods.includes(method.toUpperCase())) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
return this.retry.statusCodes.includes(statusCode);
|
|
255
|
+
}
|
|
256
|
+
computeDelay(attempt, retryAfter) {
|
|
257
|
+
if (retryAfter) {
|
|
258
|
+
const parsed = parseFloat(retryAfter);
|
|
259
|
+
if (!isNaN(parsed)) {
|
|
260
|
+
return parsed * 1e3;
|
|
261
|
+
}
|
|
262
|
+
return 0;
|
|
263
|
+
}
|
|
264
|
+
const base = this.retry.backoffFactor * Math.pow(2, Math.max(attempt - 1, 0)) * 1e3;
|
|
265
|
+
return base * (0.5 + Math.random() * 0.5);
|
|
266
|
+
}
|
|
267
|
+
async maybeDecodeResponse(response, parseJson) {
|
|
268
|
+
if (!parseJson) {
|
|
269
|
+
return response;
|
|
270
|
+
}
|
|
271
|
+
const text = await response.text();
|
|
272
|
+
if (!text) {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
try {
|
|
276
|
+
return JSON.parse(text);
|
|
277
|
+
} catch {
|
|
278
|
+
return text;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
async sendWithRetries(method, path, options) {
|
|
282
|
+
for (let attempt = 1; attempt <= this.retry.attempts; attempt++) {
|
|
283
|
+
const { url, init } = this.buildRequest(method, path, options);
|
|
284
|
+
const controller = new AbortController();
|
|
285
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
286
|
+
init.signal = controller.signal;
|
|
287
|
+
let response;
|
|
288
|
+
try {
|
|
289
|
+
response = await fetch(url, init);
|
|
290
|
+
} catch (err) {
|
|
291
|
+
clearTimeout(timeoutId);
|
|
292
|
+
const delay = this.handleTransportError(err, method, attempt);
|
|
293
|
+
if (delay > 0) {
|
|
294
|
+
await this.sleep(delay);
|
|
295
|
+
}
|
|
296
|
+
continue;
|
|
297
|
+
} finally {
|
|
298
|
+
clearTimeout(timeoutId);
|
|
299
|
+
}
|
|
300
|
+
if (response.status >= 400) {
|
|
301
|
+
if (this.shouldRetry(method, response.status) && attempt < this.retry.attempts) {
|
|
302
|
+
const delay = this.computeDelay(attempt, response.headers.get("Retry-After"));
|
|
303
|
+
if (delay > 0) {
|
|
304
|
+
await this.sleep(delay);
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
await this.raiseAPIError(response);
|
|
309
|
+
}
|
|
310
|
+
return response;
|
|
311
|
+
}
|
|
312
|
+
throw new FoxnoseTransportError("All retry attempts exhausted");
|
|
313
|
+
}
|
|
314
|
+
handleTransportError(err, method, attempt) {
|
|
315
|
+
const canRetry = this.retry.methods.includes(method.toUpperCase()) && attempt < this.retry.attempts;
|
|
316
|
+
if (!canRetry) {
|
|
317
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
318
|
+
throw new FoxnoseTransportError(message);
|
|
319
|
+
}
|
|
320
|
+
return this.computeDelay(attempt);
|
|
321
|
+
}
|
|
322
|
+
async raiseAPIError(response) {
|
|
323
|
+
let message = "";
|
|
324
|
+
let errorCode;
|
|
325
|
+
let detail;
|
|
326
|
+
let body;
|
|
327
|
+
try {
|
|
328
|
+
const text = await response.text();
|
|
329
|
+
message = text;
|
|
330
|
+
if (text) {
|
|
331
|
+
try {
|
|
332
|
+
const payload = JSON.parse(text);
|
|
333
|
+
message = payload.message ?? message;
|
|
334
|
+
errorCode = payload.error_code;
|
|
335
|
+
detail = payload.detail;
|
|
336
|
+
body = payload;
|
|
337
|
+
} catch {
|
|
338
|
+
body = text;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} catch {
|
|
342
|
+
}
|
|
343
|
+
const responseHeaders = {};
|
|
344
|
+
response.headers.forEach((value, key) => {
|
|
345
|
+
responseHeaders[key] = value;
|
|
346
|
+
});
|
|
347
|
+
throw new FoxnoseAPIError({
|
|
348
|
+
message: message || "API request failed",
|
|
349
|
+
statusCode: response.status,
|
|
350
|
+
errorCode,
|
|
351
|
+
detail,
|
|
352
|
+
responseHeaders,
|
|
353
|
+
responseBody: body
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
sleep(ms) {
|
|
357
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
// src/management/models.ts
|
|
362
|
+
function resolveKey(value) {
|
|
363
|
+
if (typeof value === "string") {
|
|
364
|
+
return value;
|
|
365
|
+
}
|
|
366
|
+
if (value && typeof value === "object" && "key" in value && typeof value.key === "string") {
|
|
367
|
+
return value.key;
|
|
368
|
+
}
|
|
369
|
+
throw new TypeError(
|
|
370
|
+
`Expected a string or an object with a 'key' attribute, got ${typeof value}`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// src/management/paths.ts
|
|
375
|
+
function managementPaths(environmentKey) {
|
|
376
|
+
return {
|
|
377
|
+
// Organization paths
|
|
378
|
+
orgRoot: (orgKey) => `/organizations/${orgKey}`,
|
|
379
|
+
projectsBase: (orgKey) => `/organizations/${orgKey}/projects`,
|
|
380
|
+
projectRoot: (orgKey, projectKey) => `/organizations/${orgKey}/projects/${projectKey}`,
|
|
381
|
+
environmentsBase: (orgKey, projectKey) => `/organizations/${orgKey}/projects/${projectKey}/environments`,
|
|
382
|
+
environmentRoot: (orgKey, projectKey, envKey) => `/organizations/${orgKey}/projects/${projectKey}/environments/${envKey}`,
|
|
383
|
+
// Folder paths
|
|
384
|
+
foldersTreeRoot: () => `/v1/${environmentKey}/folders/tree`,
|
|
385
|
+
foldersTreeItem: () => `/v1/${environmentKey}/folders/tree/folder`,
|
|
386
|
+
folderVersionsBase: (folderKey) => `/v1/${environmentKey}/folders/${folderKey}/model/versions`,
|
|
387
|
+
folderSchemaTree: (folderKey, versionKey) => `/v1/${environmentKey}/folders/${folderKey}/model/versions/${versionKey}/schema/tree`,
|
|
388
|
+
// Component paths
|
|
389
|
+
componentsRoot: () => `/v1/${environmentKey}/components`,
|
|
390
|
+
componentRoot: (componentKey) => `/v1/${environmentKey}/components/${componentKey}`,
|
|
391
|
+
componentVersionsBase: (componentKey) => `/v1/${environmentKey}/components/${componentKey}/model/versions`,
|
|
392
|
+
componentSchemaTree: (componentKey, versionKey) => `/v1/${environmentKey}/components/${componentKey}/model/versions/${versionKey}/schema/tree`,
|
|
393
|
+
// Resource paths
|
|
394
|
+
resourceBase: (folderKey) => `/v1/${environmentKey}/folders/${folderKey}/resources`,
|
|
395
|
+
revisionBase: (folderKey, resourceKey) => `/v1/${environmentKey}/folders/${folderKey}/resources/${resourceKey}/revisions`,
|
|
396
|
+
// Management API key paths
|
|
397
|
+
managementApiKeysRoot: () => `/v1/${environmentKey}/permissions/management-api/api-keys`,
|
|
398
|
+
managementApiKeyRoot: (apiKey) => `/v1/${environmentKey}/permissions/management-api/api-keys/${apiKey}`,
|
|
399
|
+
// Flux API key paths
|
|
400
|
+
fluxApiKeysRoot: () => `/v1/${environmentKey}/permissions/flux-api/api-keys`,
|
|
401
|
+
fluxApiKeyRoot: (apiKey) => `/v1/${environmentKey}/permissions/flux-api/api-keys/${apiKey}`,
|
|
402
|
+
// API management paths
|
|
403
|
+
apisRoot: () => `/v1/${environmentKey}/api`,
|
|
404
|
+
apiRoot: (apiKey) => `/v1/${environmentKey}/api/${apiKey}`,
|
|
405
|
+
apiFoldersRoot: (apiKey) => `/v1/${environmentKey}/api/${apiKey}/folders`,
|
|
406
|
+
// Management role paths
|
|
407
|
+
managementRolesRoot: () => `/v1/${environmentKey}/permissions/management-api/roles`,
|
|
408
|
+
managementRoleRoot: (roleKey) => `/v1/${environmentKey}/permissions/management-api/roles/${roleKey}`,
|
|
409
|
+
rolePermissionsRoot: (roleKey) => `/v1/${environmentKey}/permissions/management-api/roles/${roleKey}/permissions`,
|
|
410
|
+
rolePermissionsBatch: (roleKey) => `/v1/${environmentKey}/permissions/management-api/roles/${roleKey}/permissions/batch`,
|
|
411
|
+
rolePermissionObjectsRoot: (roleKey) => `/v1/${environmentKey}/permissions/management-api/roles/${roleKey}/permissions/objects`,
|
|
412
|
+
// Flux role paths
|
|
413
|
+
fluxRolesRoot: () => `/v1/${environmentKey}/permissions/flux-api/roles`,
|
|
414
|
+
fluxRoleRoot: (roleKey) => `/v1/${environmentKey}/permissions/flux-api/roles/${roleKey}`,
|
|
415
|
+
fluxRolePermissionsRoot: (roleKey) => `/v1/${environmentKey}/permissions/flux-api/roles/${roleKey}/permissions`,
|
|
416
|
+
fluxRolePermissionsBatch: (roleKey) => `/v1/${environmentKey}/permissions/flux-api/roles/${roleKey}/permissions/batch`,
|
|
417
|
+
fluxRolePermissionObjectsRoot: (roleKey) => `/v1/${environmentKey}/permissions/flux-api/roles/${roleKey}/permissions/objects`,
|
|
418
|
+
// Locale paths
|
|
419
|
+
localesRoot: () => `/v1/${environmentKey}/locales`,
|
|
420
|
+
localeRoot: (code) => `/v1/${environmentKey}/locales/${code}`
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/management/client.ts
|
|
425
|
+
var ManagementClient = class {
|
|
426
|
+
environmentKey;
|
|
427
|
+
transport;
|
|
428
|
+
paths;
|
|
429
|
+
constructor(options) {
|
|
430
|
+
if (!options.environmentKey) {
|
|
431
|
+
throw new Error("environmentKey must be provided");
|
|
432
|
+
}
|
|
433
|
+
this.environmentKey = options.environmentKey;
|
|
434
|
+
const config = createConfig({
|
|
435
|
+
baseUrl: options.baseUrl ?? "https://api.foxnose.net",
|
|
436
|
+
timeout: options.timeout,
|
|
437
|
+
defaultHeaders: options.defaultHeaders
|
|
438
|
+
});
|
|
439
|
+
this.transport = new HttpTransport({
|
|
440
|
+
config,
|
|
441
|
+
auth: options.auth,
|
|
442
|
+
retryConfig: options.retryConfig
|
|
443
|
+
});
|
|
444
|
+
this.paths = managementPaths(options.environmentKey);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Low-level escape hatch for calling arbitrary endpoints.
|
|
448
|
+
*/
|
|
449
|
+
async request(method, path, options) {
|
|
450
|
+
return this.transport.request(method, path, options);
|
|
451
|
+
}
|
|
452
|
+
close() {
|
|
453
|
+
this.transport.close();
|
|
454
|
+
}
|
|
455
|
+
// ------------------------------------------------------------------ //
|
|
456
|
+
// Organization operations
|
|
457
|
+
// ------------------------------------------------------------------ //
|
|
458
|
+
async listOrganizations() {
|
|
459
|
+
const payload = await this.request("GET", "/organizations/") ?? [];
|
|
460
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
461
|
+
}
|
|
462
|
+
async getOrganization(orgKey) {
|
|
463
|
+
const key = resolveKey(orgKey);
|
|
464
|
+
return this.request("GET", `${this.paths.orgRoot(key)}/`);
|
|
465
|
+
}
|
|
466
|
+
async updateOrganization(orgKey, payload) {
|
|
467
|
+
const key = resolveKey(orgKey);
|
|
468
|
+
return this.request("PUT", `${this.paths.orgRoot(key)}/`, { jsonBody: payload });
|
|
469
|
+
}
|
|
470
|
+
async listRegions() {
|
|
471
|
+
const payload = await this.request("GET", "/regions/") ?? [];
|
|
472
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
473
|
+
}
|
|
474
|
+
async getAvailablePlans() {
|
|
475
|
+
return this.request("GET", "/plans/");
|
|
476
|
+
}
|
|
477
|
+
async getOrganizationPlan(orgKey) {
|
|
478
|
+
const key = resolveKey(orgKey);
|
|
479
|
+
return this.request("GET", `${this.paths.orgRoot(key)}/plan/`);
|
|
480
|
+
}
|
|
481
|
+
async setOrganizationPlan(orgKey, planCode) {
|
|
482
|
+
const key = resolveKey(orgKey);
|
|
483
|
+
return this.request("POST", `${this.paths.orgRoot(key)}/plan/${planCode}/`);
|
|
484
|
+
}
|
|
485
|
+
async getOrganizationUsage(orgKey) {
|
|
486
|
+
const key = resolveKey(orgKey);
|
|
487
|
+
return this.request("GET", `${this.paths.orgRoot(key)}/usage/`);
|
|
488
|
+
}
|
|
489
|
+
// ------------------------------------------------------------------ //
|
|
490
|
+
// Management API key operations
|
|
491
|
+
// ------------------------------------------------------------------ //
|
|
492
|
+
async listManagementApiKeys(params) {
|
|
493
|
+
return this.request("GET", `${this.paths.managementApiKeysRoot()}/`, { params });
|
|
494
|
+
}
|
|
495
|
+
async createManagementApiKey(payload) {
|
|
496
|
+
return this.request("POST", `${this.paths.managementApiKeysRoot()}/`, {
|
|
497
|
+
jsonBody: payload
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
async getManagementApiKey(key) {
|
|
501
|
+
const k = resolveKey(key);
|
|
502
|
+
return this.request("GET", `${this.paths.managementApiKeyRoot(k)}/`);
|
|
503
|
+
}
|
|
504
|
+
async updateManagementApiKey(key, payload) {
|
|
505
|
+
const k = resolveKey(key);
|
|
506
|
+
return this.request("PUT", `${this.paths.managementApiKeyRoot(k)}/`, {
|
|
507
|
+
jsonBody: payload
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
async deleteManagementApiKey(key) {
|
|
511
|
+
const k = resolveKey(key);
|
|
512
|
+
await this.request("DELETE", `${this.paths.managementApiKeyRoot(k)}/`, {
|
|
513
|
+
parseJson: false
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
// ------------------------------------------------------------------ //
|
|
517
|
+
// Flux API key operations
|
|
518
|
+
// ------------------------------------------------------------------ //
|
|
519
|
+
async listFluxApiKeys(params) {
|
|
520
|
+
return this.request("GET", `${this.paths.fluxApiKeysRoot()}/`, { params });
|
|
521
|
+
}
|
|
522
|
+
async createFluxApiKey(payload) {
|
|
523
|
+
return this.request("POST", `${this.paths.fluxApiKeysRoot()}/`, { jsonBody: payload });
|
|
524
|
+
}
|
|
525
|
+
async getFluxApiKey(key) {
|
|
526
|
+
const k = resolveKey(key);
|
|
527
|
+
return this.request("GET", `${this.paths.fluxApiKeyRoot(k)}/`);
|
|
528
|
+
}
|
|
529
|
+
async updateFluxApiKey(key, payload) {
|
|
530
|
+
const k = resolveKey(key);
|
|
531
|
+
return this.request("PUT", `${this.paths.fluxApiKeyRoot(k)}/`, { jsonBody: payload });
|
|
532
|
+
}
|
|
533
|
+
async deleteFluxApiKey(key) {
|
|
534
|
+
const k = resolveKey(key);
|
|
535
|
+
await this.request("DELETE", `${this.paths.fluxApiKeyRoot(k)}/`, { parseJson: false });
|
|
536
|
+
}
|
|
537
|
+
// ------------------------------------------------------------------ //
|
|
538
|
+
// API management operations
|
|
539
|
+
// ------------------------------------------------------------------ //
|
|
540
|
+
async listApis(params) {
|
|
541
|
+
return this.request("GET", `${this.paths.apisRoot()}/`, { params });
|
|
542
|
+
}
|
|
543
|
+
async createApi(payload) {
|
|
544
|
+
return this.request("POST", `${this.paths.apisRoot()}/`, { jsonBody: payload });
|
|
545
|
+
}
|
|
546
|
+
async getApi(apiKey) {
|
|
547
|
+
const key = resolveKey(apiKey);
|
|
548
|
+
return this.request("GET", `${this.paths.apiRoot(key)}/`);
|
|
549
|
+
}
|
|
550
|
+
async updateApi(apiKey, payload) {
|
|
551
|
+
const key = resolveKey(apiKey);
|
|
552
|
+
return this.request("PUT", `${this.paths.apiRoot(key)}/`, { jsonBody: payload });
|
|
553
|
+
}
|
|
554
|
+
async deleteApi(apiKey) {
|
|
555
|
+
const key = resolveKey(apiKey);
|
|
556
|
+
await this.request("DELETE", `${this.paths.apiRoot(key)}/`, { parseJson: false });
|
|
557
|
+
}
|
|
558
|
+
// ------------------------------------------------------------------ //
|
|
559
|
+
// API Folder associations
|
|
560
|
+
// ------------------------------------------------------------------ //
|
|
561
|
+
async listApiFolders(apiKey, params) {
|
|
562
|
+
const key = resolveKey(apiKey);
|
|
563
|
+
return this.request("GET", `${this.paths.apiFoldersRoot(key)}/`, { params });
|
|
564
|
+
}
|
|
565
|
+
async addApiFolder(apiKey, folderKey, options) {
|
|
566
|
+
const aKey = resolveKey(apiKey);
|
|
567
|
+
const fKey = resolveKey(folderKey);
|
|
568
|
+
const body = { folder: fKey };
|
|
569
|
+
if (options?.allowedMethods) {
|
|
570
|
+
body.allowed_methods = options.allowedMethods;
|
|
571
|
+
}
|
|
572
|
+
return this.request("POST", `${this.paths.apiFoldersRoot(aKey)}/`, { jsonBody: body });
|
|
573
|
+
}
|
|
574
|
+
async getApiFolder(apiKey, folderKey) {
|
|
575
|
+
const aKey = resolveKey(apiKey);
|
|
576
|
+
const fKey = resolveKey(folderKey);
|
|
577
|
+
return this.request("GET", `${this.paths.apiFoldersRoot(aKey)}/${fKey}/`);
|
|
578
|
+
}
|
|
579
|
+
async updateApiFolder(apiKey, folderKey, options) {
|
|
580
|
+
const aKey = resolveKey(apiKey);
|
|
581
|
+
const fKey = resolveKey(folderKey);
|
|
582
|
+
const body = {};
|
|
583
|
+
if (options?.allowedMethods) {
|
|
584
|
+
body.allowed_methods = options.allowedMethods;
|
|
585
|
+
}
|
|
586
|
+
return this.request("PUT", `${this.paths.apiFoldersRoot(aKey)}/${fKey}/`, {
|
|
587
|
+
jsonBody: body
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
async removeApiFolder(apiKey, folderKey) {
|
|
591
|
+
const aKey = resolveKey(apiKey);
|
|
592
|
+
const fKey = resolveKey(folderKey);
|
|
593
|
+
await this.request("DELETE", `${this.paths.apiFoldersRoot(aKey)}/${fKey}/`, {
|
|
594
|
+
parseJson: false
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
// ------------------------------------------------------------------ //
|
|
598
|
+
// Management role operations
|
|
599
|
+
// ------------------------------------------------------------------ //
|
|
600
|
+
async listManagementRoles(params) {
|
|
601
|
+
return this.request("GET", `${this.paths.managementRolesRoot()}/`, { params });
|
|
602
|
+
}
|
|
603
|
+
async createManagementRole(payload) {
|
|
604
|
+
return this.request("POST", `${this.paths.managementRolesRoot()}/`, {
|
|
605
|
+
jsonBody: payload
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
async getManagementRole(roleKey) {
|
|
609
|
+
const key = resolveKey(roleKey);
|
|
610
|
+
return this.request("GET", `${this.paths.managementRoleRoot(key)}/`);
|
|
611
|
+
}
|
|
612
|
+
async updateManagementRole(roleKey, payload) {
|
|
613
|
+
const key = resolveKey(roleKey);
|
|
614
|
+
return this.request("PUT", `${this.paths.managementRoleRoot(key)}/`, {
|
|
615
|
+
jsonBody: payload
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
async deleteManagementRole(roleKey) {
|
|
619
|
+
const key = resolveKey(roleKey);
|
|
620
|
+
await this.request("DELETE", `${this.paths.managementRoleRoot(key)}/`, {
|
|
621
|
+
parseJson: false
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
// Management role permissions
|
|
625
|
+
async listManagementRolePermissions(roleKey) {
|
|
626
|
+
const key = resolveKey(roleKey);
|
|
627
|
+
const payload = await this.request("GET", `${this.paths.rolePermissionsRoot(key)}/`) ?? [];
|
|
628
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
629
|
+
}
|
|
630
|
+
async upsertManagementRolePermission(roleKey, payload) {
|
|
631
|
+
const key = resolveKey(roleKey);
|
|
632
|
+
return this.request("POST", `${this.paths.rolePermissionsRoot(key)}/`, {
|
|
633
|
+
jsonBody: payload
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
async deleteManagementRolePermission(roleKey, contentType) {
|
|
637
|
+
const key = resolveKey(roleKey);
|
|
638
|
+
await this.request("DELETE", `${this.paths.rolePermissionsRoot(key)}/`, {
|
|
639
|
+
params: { content_type: contentType },
|
|
640
|
+
parseJson: false
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
async replaceManagementRolePermissions(roleKey, permissions) {
|
|
644
|
+
const key = resolveKey(roleKey);
|
|
645
|
+
const payload = await this.request("POST", `${this.paths.rolePermissionsBatch(key)}/`, {
|
|
646
|
+
jsonBody: permissions
|
|
647
|
+
});
|
|
648
|
+
return Array.isArray(payload) ? payload : [];
|
|
649
|
+
}
|
|
650
|
+
// Management permission objects
|
|
651
|
+
async listManagementPermissionObjects(roleKey, contentType) {
|
|
652
|
+
const key = resolveKey(roleKey);
|
|
653
|
+
const payload = await this.request("GET", `${this.paths.rolePermissionObjectsRoot(key)}/`, {
|
|
654
|
+
params: { content_type: contentType }
|
|
655
|
+
}) ?? [];
|
|
656
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
657
|
+
}
|
|
658
|
+
async addManagementPermissionObject(roleKey, payload) {
|
|
659
|
+
const key = resolveKey(roleKey);
|
|
660
|
+
return this.request("POST", `${this.paths.rolePermissionObjectsRoot(key)}/`, {
|
|
661
|
+
jsonBody: payload
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
async deleteManagementPermissionObject(roleKey, payload) {
|
|
665
|
+
const key = resolveKey(roleKey);
|
|
666
|
+
await this.request("DELETE", `${this.paths.rolePermissionObjectsRoot(key)}/`, {
|
|
667
|
+
jsonBody: payload,
|
|
668
|
+
parseJson: false
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
// ------------------------------------------------------------------ //
|
|
672
|
+
// Flux role operations
|
|
673
|
+
// ------------------------------------------------------------------ //
|
|
674
|
+
async listFluxRoles(params) {
|
|
675
|
+
return this.request("GET", `${this.paths.fluxRolesRoot()}/`, { params });
|
|
676
|
+
}
|
|
677
|
+
async createFluxRole(payload) {
|
|
678
|
+
return this.request("POST", `${this.paths.fluxRolesRoot()}/`, { jsonBody: payload });
|
|
679
|
+
}
|
|
680
|
+
async getFluxRole(roleKey) {
|
|
681
|
+
const key = resolveKey(roleKey);
|
|
682
|
+
return this.request("GET", `${this.paths.fluxRoleRoot(key)}/`);
|
|
683
|
+
}
|
|
684
|
+
async updateFluxRole(roleKey, payload) {
|
|
685
|
+
const key = resolveKey(roleKey);
|
|
686
|
+
return this.request("PUT", `${this.paths.fluxRoleRoot(key)}/`, { jsonBody: payload });
|
|
687
|
+
}
|
|
688
|
+
async deleteFluxRole(roleKey) {
|
|
689
|
+
const key = resolveKey(roleKey);
|
|
690
|
+
await this.request("DELETE", `${this.paths.fluxRoleRoot(key)}/`, { parseJson: false });
|
|
691
|
+
}
|
|
692
|
+
// Flux role permissions
|
|
693
|
+
async listFluxRolePermissions(roleKey) {
|
|
694
|
+
const key = resolveKey(roleKey);
|
|
695
|
+
const payload = await this.request("GET", `${this.paths.fluxRolePermissionsRoot(key)}/`) ?? [];
|
|
696
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
697
|
+
}
|
|
698
|
+
async upsertFluxRolePermission(roleKey, payload) {
|
|
699
|
+
const key = resolveKey(roleKey);
|
|
700
|
+
return this.request("POST", `${this.paths.fluxRolePermissionsRoot(key)}/`, {
|
|
701
|
+
jsonBody: payload
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
async deleteFluxRolePermission(roleKey, contentType) {
|
|
705
|
+
const key = resolveKey(roleKey);
|
|
706
|
+
await this.request(
|
|
707
|
+
"DELETE",
|
|
708
|
+
`${this.paths.fluxRolePermissionsRoot(key)}/`,
|
|
709
|
+
{ params: { content_type: contentType }, parseJson: false }
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
async replaceFluxRolePermissions(roleKey, permissions) {
|
|
713
|
+
const key = resolveKey(roleKey);
|
|
714
|
+
const payload = await this.request("POST", `${this.paths.fluxRolePermissionsBatch(key)}/`, {
|
|
715
|
+
jsonBody: permissions
|
|
716
|
+
});
|
|
717
|
+
return Array.isArray(payload) ? payload : [];
|
|
718
|
+
}
|
|
719
|
+
// Flux permission objects
|
|
720
|
+
async listFluxPermissionObjects(roleKey, contentType) {
|
|
721
|
+
const key = resolveKey(roleKey);
|
|
722
|
+
const payload = await this.request("GET", `${this.paths.fluxRolePermissionObjectsRoot(key)}/`, {
|
|
723
|
+
params: { content_type: contentType }
|
|
724
|
+
}) ?? [];
|
|
725
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
726
|
+
}
|
|
727
|
+
async addFluxPermissionObject(roleKey, payload) {
|
|
728
|
+
const key = resolveKey(roleKey);
|
|
729
|
+
return this.request("POST", `${this.paths.fluxRolePermissionObjectsRoot(key)}/`, {
|
|
730
|
+
jsonBody: payload
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
async deleteFluxPermissionObject(roleKey, payload) {
|
|
734
|
+
const key = resolveKey(roleKey);
|
|
735
|
+
await this.request("DELETE", `${this.paths.fluxRolePermissionObjectsRoot(key)}/`, {
|
|
736
|
+
jsonBody: payload,
|
|
737
|
+
parseJson: false
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
// ------------------------------------------------------------------ //
|
|
741
|
+
// Folder operations
|
|
742
|
+
// ------------------------------------------------------------------ //
|
|
743
|
+
async listFolders(params) {
|
|
744
|
+
return this.request("GET", `${this.paths.foldersTreeRoot()}/`, { params });
|
|
745
|
+
}
|
|
746
|
+
async getFolder(folderKey) {
|
|
747
|
+
const key = resolveKey(folderKey);
|
|
748
|
+
return this.request("GET", `${this.paths.foldersTreeItem()}/`, {
|
|
749
|
+
params: { key }
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
async getFolderByPath(path) {
|
|
753
|
+
return this.request("GET", `${this.paths.foldersTreeItem()}/`, {
|
|
754
|
+
params: { path }
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
async listFolderTree(options) {
|
|
758
|
+
const params = {};
|
|
759
|
+
if (options?.key) params.key = options.key;
|
|
760
|
+
if (options?.mode) params.mode = options.mode;
|
|
761
|
+
return this.request("GET", `${this.paths.foldersTreeRoot()}/`, { params });
|
|
762
|
+
}
|
|
763
|
+
async createFolder(payload) {
|
|
764
|
+
return this.request("POST", `${this.paths.foldersTreeRoot()}/`, { jsonBody: payload });
|
|
765
|
+
}
|
|
766
|
+
async updateFolder(folderKey, payload) {
|
|
767
|
+
const key = resolveKey(folderKey);
|
|
768
|
+
return this.request("PUT", `${this.paths.foldersTreeItem()}/`, {
|
|
769
|
+
params: { key },
|
|
770
|
+
jsonBody: payload
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
async deleteFolder(folderKey) {
|
|
774
|
+
const key = resolveKey(folderKey);
|
|
775
|
+
await this.request("DELETE", `${this.paths.foldersTreeItem()}/`, {
|
|
776
|
+
params: { key },
|
|
777
|
+
parseJson: false
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
// ------------------------------------------------------------------ //
|
|
781
|
+
// Folder version operations
|
|
782
|
+
// ------------------------------------------------------------------ //
|
|
783
|
+
async listFolderVersions(folderKey, params) {
|
|
784
|
+
const key = resolveKey(folderKey);
|
|
785
|
+
return this.request("GET", `${this.paths.folderVersionsBase(key)}/`, { params });
|
|
786
|
+
}
|
|
787
|
+
async createFolderVersion(folderKey, payload, options) {
|
|
788
|
+
const key = resolveKey(folderKey);
|
|
789
|
+
const params = {};
|
|
790
|
+
if (options?.copyFrom) {
|
|
791
|
+
params.copy_from = resolveKey(options.copyFrom);
|
|
792
|
+
}
|
|
793
|
+
return this.request("POST", `${this.paths.folderVersionsBase(key)}/`, {
|
|
794
|
+
jsonBody: payload,
|
|
795
|
+
params: Object.keys(params).length > 0 ? params : void 0
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
async getFolderVersion(folderKey, versionKey, options) {
|
|
799
|
+
const fKey = resolveKey(folderKey);
|
|
800
|
+
const vKey = resolveKey(versionKey);
|
|
801
|
+
const params = {};
|
|
802
|
+
if (options?.includeSchema !== void 0) {
|
|
803
|
+
params.include_schema = options.includeSchema;
|
|
804
|
+
}
|
|
805
|
+
return this.request("GET", `${this.paths.folderVersionsBase(fKey)}/${vKey}/`, {
|
|
806
|
+
params: Object.keys(params).length > 0 ? params : void 0
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
async updateFolderVersion(folderKey, versionKey, payload) {
|
|
810
|
+
const fKey = resolveKey(folderKey);
|
|
811
|
+
const vKey = resolveKey(versionKey);
|
|
812
|
+
return this.request("PUT", `${this.paths.folderVersionsBase(fKey)}/${vKey}/`, {
|
|
813
|
+
jsonBody: payload
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
async deleteFolderVersion(folderKey, versionKey) {
|
|
817
|
+
const fKey = resolveKey(folderKey);
|
|
818
|
+
const vKey = resolveKey(versionKey);
|
|
819
|
+
await this.request("DELETE", `${this.paths.folderVersionsBase(fKey)}/${vKey}/`, {
|
|
820
|
+
parseJson: false
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
async publishFolderVersion(folderKey, versionKey) {
|
|
824
|
+
const fKey = resolveKey(folderKey);
|
|
825
|
+
const vKey = resolveKey(versionKey);
|
|
826
|
+
return this.request(
|
|
827
|
+
"POST",
|
|
828
|
+
`${this.paths.folderVersionsBase(fKey)}/${vKey}/publish/`
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
// ------------------------------------------------------------------ //
|
|
832
|
+
// Folder field operations
|
|
833
|
+
// ------------------------------------------------------------------ //
|
|
834
|
+
async listFolderFields(folderKey, versionKey, params) {
|
|
835
|
+
const fKey = resolveKey(folderKey);
|
|
836
|
+
const vKey = resolveKey(versionKey);
|
|
837
|
+
return this.request("GET", `${this.paths.folderSchemaTree(fKey, vKey)}/`, { params });
|
|
838
|
+
}
|
|
839
|
+
async createFolderField(folderKey, versionKey, payload) {
|
|
840
|
+
const fKey = resolveKey(folderKey);
|
|
841
|
+
const vKey = resolveKey(versionKey);
|
|
842
|
+
return this.request("POST", `${this.paths.folderSchemaTree(fKey, vKey)}/`, {
|
|
843
|
+
jsonBody: payload
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
async getFolderField(folderKey, versionKey, fieldPath) {
|
|
847
|
+
const fKey = resolveKey(folderKey);
|
|
848
|
+
const vKey = resolveKey(versionKey);
|
|
849
|
+
return this.request(
|
|
850
|
+
"GET",
|
|
851
|
+
`${this.paths.folderSchemaTree(fKey, vKey)}/field/`,
|
|
852
|
+
{ params: { path: fieldPath } }
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
async updateFolderField(folderKey, versionKey, fieldPath, payload) {
|
|
856
|
+
const fKey = resolveKey(folderKey);
|
|
857
|
+
const vKey = resolveKey(versionKey);
|
|
858
|
+
return this.request(
|
|
859
|
+
"PUT",
|
|
860
|
+
`${this.paths.folderSchemaTree(fKey, vKey)}/field/`,
|
|
861
|
+
{ params: { path: fieldPath }, jsonBody: payload }
|
|
862
|
+
);
|
|
863
|
+
}
|
|
864
|
+
async deleteFolderField(folderKey, versionKey, fieldPath) {
|
|
865
|
+
const fKey = resolveKey(folderKey);
|
|
866
|
+
const vKey = resolveKey(versionKey);
|
|
867
|
+
await this.request(
|
|
868
|
+
"DELETE",
|
|
869
|
+
`${this.paths.folderSchemaTree(fKey, vKey)}/field/`,
|
|
870
|
+
{ params: { path: fieldPath }, parseJson: false }
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
// ------------------------------------------------------------------ //
|
|
874
|
+
// Component operations
|
|
875
|
+
// ------------------------------------------------------------------ //
|
|
876
|
+
async listComponents(params) {
|
|
877
|
+
return this.request("GET", `${this.paths.componentsRoot()}/`, { params });
|
|
878
|
+
}
|
|
879
|
+
async getComponent(componentKey) {
|
|
880
|
+
const key = resolveKey(componentKey);
|
|
881
|
+
return this.request("GET", `${this.paths.componentRoot(key)}/`);
|
|
882
|
+
}
|
|
883
|
+
async createComponent(payload) {
|
|
884
|
+
return this.request("POST", `${this.paths.componentsRoot()}/`, { jsonBody: payload });
|
|
885
|
+
}
|
|
886
|
+
async updateComponent(componentKey, payload) {
|
|
887
|
+
const key = resolveKey(componentKey);
|
|
888
|
+
return this.request("PUT", `${this.paths.componentRoot(key)}/`, { jsonBody: payload });
|
|
889
|
+
}
|
|
890
|
+
async deleteComponent(componentKey) {
|
|
891
|
+
const key = resolveKey(componentKey);
|
|
892
|
+
await this.request("DELETE", `${this.paths.componentRoot(key)}/`, { parseJson: false });
|
|
893
|
+
}
|
|
894
|
+
// ------------------------------------------------------------------ //
|
|
895
|
+
// Component version operations
|
|
896
|
+
// ------------------------------------------------------------------ //
|
|
897
|
+
async listComponentVersions(componentKey, params) {
|
|
898
|
+
const key = resolveKey(componentKey);
|
|
899
|
+
return this.request("GET", `${this.paths.componentVersionsBase(key)}/`, { params });
|
|
900
|
+
}
|
|
901
|
+
async createComponentVersion(componentKey, payload, options) {
|
|
902
|
+
const key = resolveKey(componentKey);
|
|
903
|
+
const params = {};
|
|
904
|
+
if (options?.copyFrom) {
|
|
905
|
+
params.copy_from = resolveKey(options.copyFrom);
|
|
906
|
+
}
|
|
907
|
+
return this.request("POST", `${this.paths.componentVersionsBase(key)}/`, {
|
|
908
|
+
jsonBody: payload,
|
|
909
|
+
params: Object.keys(params).length > 0 ? params : void 0
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
async getComponentVersion(componentKey, versionKey, options) {
|
|
913
|
+
const cKey = resolveKey(componentKey);
|
|
914
|
+
const vKey = resolveKey(versionKey);
|
|
915
|
+
const params = {};
|
|
916
|
+
if (options?.includeSchema !== void 0) {
|
|
917
|
+
params.include_schema = options.includeSchema;
|
|
918
|
+
}
|
|
919
|
+
return this.request("GET", `${this.paths.componentVersionsBase(cKey)}/${vKey}/`, {
|
|
920
|
+
params: Object.keys(params).length > 0 ? params : void 0
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
async publishComponentVersion(componentKey, versionKey) {
|
|
924
|
+
const cKey = resolveKey(componentKey);
|
|
925
|
+
const vKey = resolveKey(versionKey);
|
|
926
|
+
return this.request(
|
|
927
|
+
"POST",
|
|
928
|
+
`${this.paths.componentVersionsBase(cKey)}/${vKey}/publish/`
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
async updateComponentVersion(componentKey, versionKey, payload) {
|
|
932
|
+
const cKey = resolveKey(componentKey);
|
|
933
|
+
const vKey = resolveKey(versionKey);
|
|
934
|
+
return this.request("PUT", `${this.paths.componentVersionsBase(cKey)}/${vKey}/`, {
|
|
935
|
+
jsonBody: payload
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
async deleteComponentVersion(componentKey, versionKey) {
|
|
939
|
+
const cKey = resolveKey(componentKey);
|
|
940
|
+
const vKey = resolveKey(versionKey);
|
|
941
|
+
await this.request("DELETE", `${this.paths.componentVersionsBase(cKey)}/${vKey}/`, {
|
|
942
|
+
parseJson: false
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
// ------------------------------------------------------------------ //
|
|
946
|
+
// Component field operations
|
|
947
|
+
// ------------------------------------------------------------------ //
|
|
948
|
+
async listComponentFields(componentKey, versionKey, params) {
|
|
949
|
+
const cKey = resolveKey(componentKey);
|
|
950
|
+
const vKey = resolveKey(versionKey);
|
|
951
|
+
return this.request("GET", `${this.paths.componentSchemaTree(cKey, vKey)}/`, { params });
|
|
952
|
+
}
|
|
953
|
+
async createComponentField(componentKey, versionKey, payload) {
|
|
954
|
+
const cKey = resolveKey(componentKey);
|
|
955
|
+
const vKey = resolveKey(versionKey);
|
|
956
|
+
return this.request("POST", `${this.paths.componentSchemaTree(cKey, vKey)}/`, {
|
|
957
|
+
jsonBody: payload
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
async getComponentField(componentKey, versionKey, fieldPath) {
|
|
961
|
+
const cKey = resolveKey(componentKey);
|
|
962
|
+
const vKey = resolveKey(versionKey);
|
|
963
|
+
return this.request(
|
|
964
|
+
"GET",
|
|
965
|
+
`${this.paths.componentSchemaTree(cKey, vKey)}/field/`,
|
|
966
|
+
{ params: { path: fieldPath } }
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
async updateComponentField(componentKey, versionKey, fieldPath, payload) {
|
|
970
|
+
const cKey = resolveKey(componentKey);
|
|
971
|
+
const vKey = resolveKey(versionKey);
|
|
972
|
+
return this.request(
|
|
973
|
+
"PUT",
|
|
974
|
+
`${this.paths.componentSchemaTree(cKey, vKey)}/field/`,
|
|
975
|
+
{ params: { path: fieldPath }, jsonBody: payload }
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
async deleteComponentField(componentKey, versionKey, fieldPath) {
|
|
979
|
+
const cKey = resolveKey(componentKey);
|
|
980
|
+
const vKey = resolveKey(versionKey);
|
|
981
|
+
await this.request(
|
|
982
|
+
"DELETE",
|
|
983
|
+
`${this.paths.componentSchemaTree(cKey, vKey)}/field/`,
|
|
984
|
+
{ params: { path: fieldPath }, parseJson: false }
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
// ------------------------------------------------------------------ //
|
|
988
|
+
// Resource operations
|
|
989
|
+
// ------------------------------------------------------------------ //
|
|
990
|
+
async listResources(folderKey, params) {
|
|
991
|
+
const key = resolveKey(folderKey);
|
|
992
|
+
return this.request("GET", `${this.paths.resourceBase(key)}/`, { params });
|
|
993
|
+
}
|
|
994
|
+
async getResource(folderKey, resourceKey) {
|
|
995
|
+
const fKey = resolveKey(folderKey);
|
|
996
|
+
const rKey = resolveKey(resourceKey);
|
|
997
|
+
return this.request("GET", `${this.paths.resourceBase(fKey)}/${rKey}/`);
|
|
998
|
+
}
|
|
999
|
+
async createResource(folderKey, payload, options) {
|
|
1000
|
+
const key = resolveKey(folderKey);
|
|
1001
|
+
const params = {};
|
|
1002
|
+
if (options?.component) {
|
|
1003
|
+
params.component = resolveKey(options.component);
|
|
1004
|
+
}
|
|
1005
|
+
const body = { ...payload };
|
|
1006
|
+
if (options?.externalId) {
|
|
1007
|
+
body.external_id = options.externalId;
|
|
1008
|
+
}
|
|
1009
|
+
return this.request("POST", `${this.paths.resourceBase(key)}/`, {
|
|
1010
|
+
params: Object.keys(params).length ? params : void 0,
|
|
1011
|
+
jsonBody: body
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
async upsertResource(folderKey, payload, options) {
|
|
1015
|
+
const key = resolveKey(folderKey);
|
|
1016
|
+
const params = { external_id: options.externalId };
|
|
1017
|
+
if (options.component) {
|
|
1018
|
+
params.component = resolveKey(options.component);
|
|
1019
|
+
}
|
|
1020
|
+
return this.request("PUT", `${this.paths.resourceBase(key)}/`, {
|
|
1021
|
+
params,
|
|
1022
|
+
jsonBody: payload
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
async batchUpsertResources(folderKey, items, options) {
|
|
1026
|
+
const fKey = resolveKey(folderKey);
|
|
1027
|
+
const maxConcurrency = options?.maxConcurrency ?? 5;
|
|
1028
|
+
if (maxConcurrency < 1) {
|
|
1029
|
+
throw new Error("maxConcurrency must be at least 1");
|
|
1030
|
+
}
|
|
1031
|
+
if (items.length === 0) {
|
|
1032
|
+
return { succeeded: [], failed: [] };
|
|
1033
|
+
}
|
|
1034
|
+
const failFast = options?.failFast ?? false;
|
|
1035
|
+
const onProgress = options?.onProgress;
|
|
1036
|
+
const succeeded = [];
|
|
1037
|
+
const failed = [];
|
|
1038
|
+
let completed = 0;
|
|
1039
|
+
const queue = [...items.entries()];
|
|
1040
|
+
const processItem = async (index, item) => {
|
|
1041
|
+
try {
|
|
1042
|
+
const params = { external_id: item.external_id };
|
|
1043
|
+
if (item.component) {
|
|
1044
|
+
params.component = item.component;
|
|
1045
|
+
}
|
|
1046
|
+
const result = await this.request(
|
|
1047
|
+
"PUT",
|
|
1048
|
+
`${this.paths.resourceBase(fKey)}/`,
|
|
1049
|
+
{ params, jsonBody: item.payload }
|
|
1050
|
+
);
|
|
1051
|
+
succeeded.push(result);
|
|
1052
|
+
} catch (err) {
|
|
1053
|
+
failed.push({
|
|
1054
|
+
index,
|
|
1055
|
+
external_id: item.external_id,
|
|
1056
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
1057
|
+
});
|
|
1058
|
+
if (failFast) {
|
|
1059
|
+
throw err;
|
|
1060
|
+
}
|
|
1061
|
+
} finally {
|
|
1062
|
+
completed++;
|
|
1063
|
+
onProgress?.(completed, items.length);
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
let i = 0;
|
|
1067
|
+
while (i < queue.length) {
|
|
1068
|
+
const batch = queue.slice(i, i + maxConcurrency);
|
|
1069
|
+
try {
|
|
1070
|
+
await Promise.all(batch.map(([index, item]) => processItem(index, item)));
|
|
1071
|
+
} catch (err) {
|
|
1072
|
+
if (failFast) throw err;
|
|
1073
|
+
}
|
|
1074
|
+
i += maxConcurrency;
|
|
1075
|
+
}
|
|
1076
|
+
return { succeeded, failed };
|
|
1077
|
+
}
|
|
1078
|
+
async updateResource(folderKey, resourceKey, payload) {
|
|
1079
|
+
const fKey = resolveKey(folderKey);
|
|
1080
|
+
const rKey = resolveKey(resourceKey);
|
|
1081
|
+
await this.request("PUT", `${this.paths.resourceBase(fKey)}/${rKey}/`, {
|
|
1082
|
+
jsonBody: payload,
|
|
1083
|
+
parseJson: false
|
|
1084
|
+
});
|
|
1085
|
+
return this.getResource(fKey, rKey);
|
|
1086
|
+
}
|
|
1087
|
+
async deleteResource(folderKey, resourceKey) {
|
|
1088
|
+
const fKey = resolveKey(folderKey);
|
|
1089
|
+
const rKey = resolveKey(resourceKey);
|
|
1090
|
+
await this.request("DELETE", `${this.paths.resourceBase(fKey)}/${rKey}/`, {
|
|
1091
|
+
parseJson: false
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
async getResourceData(folderKey, resourceKey) {
|
|
1095
|
+
const fKey = resolveKey(folderKey);
|
|
1096
|
+
const rKey = resolveKey(resourceKey);
|
|
1097
|
+
return this.request("GET", `${this.paths.resourceBase(fKey)}/${rKey}/data/`);
|
|
1098
|
+
}
|
|
1099
|
+
// ------------------------------------------------------------------ //
|
|
1100
|
+
// Revision operations
|
|
1101
|
+
// ------------------------------------------------------------------ //
|
|
1102
|
+
async listRevisions(folderKey, resourceKey, params) {
|
|
1103
|
+
const fKey = resolveKey(folderKey);
|
|
1104
|
+
const rKey = resolveKey(resourceKey);
|
|
1105
|
+
return this.request("GET", `${this.paths.revisionBase(fKey, rKey)}/`, { params });
|
|
1106
|
+
}
|
|
1107
|
+
async createRevision(folderKey, resourceKey, payload) {
|
|
1108
|
+
const fKey = resolveKey(folderKey);
|
|
1109
|
+
const rKey = resolveKey(resourceKey);
|
|
1110
|
+
return this.request("POST", `${this.paths.revisionBase(fKey, rKey)}/`, {
|
|
1111
|
+
jsonBody: payload
|
|
1112
|
+
});
|
|
1113
|
+
}
|
|
1114
|
+
async getRevision(folderKey, resourceKey, revisionKey) {
|
|
1115
|
+
const fKey = resolveKey(folderKey);
|
|
1116
|
+
const rKey = resolveKey(resourceKey);
|
|
1117
|
+
const rvKey = resolveKey(revisionKey);
|
|
1118
|
+
return this.request("GET", `${this.paths.revisionBase(fKey, rKey)}/${rvKey}/`);
|
|
1119
|
+
}
|
|
1120
|
+
async updateRevision(folderKey, resourceKey, revisionKey, payload) {
|
|
1121
|
+
const fKey = resolveKey(folderKey);
|
|
1122
|
+
const rKey = resolveKey(resourceKey);
|
|
1123
|
+
const rvKey = resolveKey(revisionKey);
|
|
1124
|
+
return this.request("PUT", `${this.paths.revisionBase(fKey, rKey)}/${rvKey}/`, {
|
|
1125
|
+
jsonBody: payload
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
async deleteRevision(folderKey, resourceKey, revisionKey) {
|
|
1129
|
+
const fKey = resolveKey(folderKey);
|
|
1130
|
+
const rKey = resolveKey(resourceKey);
|
|
1131
|
+
const rvKey = resolveKey(revisionKey);
|
|
1132
|
+
await this.request("DELETE", `${this.paths.revisionBase(fKey, rKey)}/${rvKey}/`, {
|
|
1133
|
+
parseJson: false
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
async publishRevision(folderKey, resourceKey, revisionKey, payload) {
|
|
1137
|
+
const fKey = resolveKey(folderKey);
|
|
1138
|
+
const rKey = resolveKey(resourceKey);
|
|
1139
|
+
const rvKey = resolveKey(revisionKey);
|
|
1140
|
+
return this.request(
|
|
1141
|
+
"POST",
|
|
1142
|
+
`${this.paths.revisionBase(fKey, rKey)}/${rvKey}/publish/`,
|
|
1143
|
+
payload ? { jsonBody: payload } : void 0
|
|
1144
|
+
);
|
|
1145
|
+
}
|
|
1146
|
+
async validateRevision(folderKey, resourceKey, revisionKey) {
|
|
1147
|
+
const fKey = resolveKey(folderKey);
|
|
1148
|
+
const rKey = resolveKey(resourceKey);
|
|
1149
|
+
const rvKey = resolveKey(revisionKey);
|
|
1150
|
+
return this.request(
|
|
1151
|
+
"POST",
|
|
1152
|
+
`${this.paths.revisionBase(fKey, rKey)}/${rvKey}/validate/`
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
async getRevisionData(folderKey, resourceKey, revisionKey) {
|
|
1156
|
+
const fKey = resolveKey(folderKey);
|
|
1157
|
+
const rKey = resolveKey(resourceKey);
|
|
1158
|
+
const rvKey = resolveKey(revisionKey);
|
|
1159
|
+
return this.request("GET", `${this.paths.revisionBase(fKey, rKey)}/${rvKey}/data/`);
|
|
1160
|
+
}
|
|
1161
|
+
// ------------------------------------------------------------------ //
|
|
1162
|
+
// Locale operations
|
|
1163
|
+
// ------------------------------------------------------------------ //
|
|
1164
|
+
async listLocales() {
|
|
1165
|
+
const payload = await this.request("GET", `${this.paths.localesRoot()}/`) ?? [];
|
|
1166
|
+
return Array.isArray(payload) ? payload : [payload];
|
|
1167
|
+
}
|
|
1168
|
+
async createLocale(payload) {
|
|
1169
|
+
return this.request("POST", `${this.paths.localesRoot()}/`, { jsonBody: payload });
|
|
1170
|
+
}
|
|
1171
|
+
async getLocale(code) {
|
|
1172
|
+
return this.request("GET", `${this.paths.localeRoot(code)}/`);
|
|
1173
|
+
}
|
|
1174
|
+
async updateLocale(code, payload) {
|
|
1175
|
+
return this.request("PUT", `${this.paths.localeRoot(code)}/`, { jsonBody: payload });
|
|
1176
|
+
}
|
|
1177
|
+
async deleteLocale(code) {
|
|
1178
|
+
await this.request("DELETE", `${this.paths.localeRoot(code)}/`, { parseJson: false });
|
|
1179
|
+
}
|
|
1180
|
+
// ------------------------------------------------------------------ //
|
|
1181
|
+
// Project operations
|
|
1182
|
+
// ------------------------------------------------------------------ //
|
|
1183
|
+
async listProjects(orgKey, params) {
|
|
1184
|
+
const key = resolveKey(orgKey);
|
|
1185
|
+
return this.request("GET", `${this.paths.projectsBase(key)}/`, { params });
|
|
1186
|
+
}
|
|
1187
|
+
async getProject(orgKey, projectKey) {
|
|
1188
|
+
const oKey = resolveKey(orgKey);
|
|
1189
|
+
const pKey = resolveKey(projectKey);
|
|
1190
|
+
return this.request("GET", `${this.paths.projectRoot(oKey, pKey)}/`);
|
|
1191
|
+
}
|
|
1192
|
+
async createProject(orgKey, payload) {
|
|
1193
|
+
const key = resolveKey(orgKey);
|
|
1194
|
+
return this.request("POST", `${this.paths.projectsBase(key)}/`, { jsonBody: payload });
|
|
1195
|
+
}
|
|
1196
|
+
async updateProject(orgKey, projectKey, payload) {
|
|
1197
|
+
const oKey = resolveKey(orgKey);
|
|
1198
|
+
const pKey = resolveKey(projectKey);
|
|
1199
|
+
return this.request("PUT", `${this.paths.projectRoot(oKey, pKey)}/`, {
|
|
1200
|
+
jsonBody: payload
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
async deleteProject(orgKey, projectKey) {
|
|
1204
|
+
const oKey = resolveKey(orgKey);
|
|
1205
|
+
const pKey = resolveKey(projectKey);
|
|
1206
|
+
await this.request("DELETE", `${this.paths.projectRoot(oKey, pKey)}/`, {
|
|
1207
|
+
parseJson: false
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
// ------------------------------------------------------------------ //
|
|
1211
|
+
// Environment operations
|
|
1212
|
+
// ------------------------------------------------------------------ //
|
|
1213
|
+
async listEnvironments(orgKey, projectKey) {
|
|
1214
|
+
const oKey = resolveKey(orgKey);
|
|
1215
|
+
const pKey = resolveKey(projectKey);
|
|
1216
|
+
const payload = await this.request("GET", `${this.paths.environmentsBase(oKey, pKey)}/`) ?? [];
|
|
1217
|
+
if (Array.isArray(payload)) {
|
|
1218
|
+
return payload;
|
|
1219
|
+
}
|
|
1220
|
+
if (payload && typeof payload === "object" && "results" in payload) {
|
|
1221
|
+
return payload.results;
|
|
1222
|
+
}
|
|
1223
|
+
return [payload];
|
|
1224
|
+
}
|
|
1225
|
+
async getEnvironment(orgKey, projectKey, envKey) {
|
|
1226
|
+
const oKey = resolveKey(orgKey);
|
|
1227
|
+
const pKey = resolveKey(projectKey);
|
|
1228
|
+
const eKey = resolveKey(envKey);
|
|
1229
|
+
return this.request("GET", `${this.paths.environmentRoot(oKey, pKey, eKey)}/`);
|
|
1230
|
+
}
|
|
1231
|
+
async createEnvironment(orgKey, projectKey, payload) {
|
|
1232
|
+
const oKey = resolveKey(orgKey);
|
|
1233
|
+
const pKey = resolveKey(projectKey);
|
|
1234
|
+
return this.request("POST", `${this.paths.environmentsBase(oKey, pKey)}/`, {
|
|
1235
|
+
jsonBody: payload
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
async updateEnvironment(orgKey, projectKey, envKey, payload) {
|
|
1239
|
+
const oKey = resolveKey(orgKey);
|
|
1240
|
+
const pKey = resolveKey(projectKey);
|
|
1241
|
+
const eKey = resolveKey(envKey);
|
|
1242
|
+
return this.request("PUT", `${this.paths.environmentRoot(oKey, pKey, eKey)}/`, {
|
|
1243
|
+
jsonBody: payload
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
async deleteEnvironment(orgKey, projectKey, envKey) {
|
|
1247
|
+
const oKey = resolveKey(orgKey);
|
|
1248
|
+
const pKey = resolveKey(projectKey);
|
|
1249
|
+
const eKey = resolveKey(envKey);
|
|
1250
|
+
await this.request("DELETE", `${this.paths.environmentRoot(oKey, pKey, eKey)}/`, {
|
|
1251
|
+
parseJson: false
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
async toggleEnvironment(orgKey, projectKey, envKey, isEnabled) {
|
|
1255
|
+
const oKey = resolveKey(orgKey);
|
|
1256
|
+
const pKey = resolveKey(projectKey);
|
|
1257
|
+
const eKey = resolveKey(envKey);
|
|
1258
|
+
await this.request(
|
|
1259
|
+
"POST",
|
|
1260
|
+
`${this.paths.environmentRoot(oKey, pKey, eKey)}/toggle/`,
|
|
1261
|
+
{ jsonBody: { is_enabled: isEnabled } }
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
async updateEnvironmentProtection(orgKey, projectKey, envKey, options) {
|
|
1265
|
+
const oKey = resolveKey(orgKey);
|
|
1266
|
+
const pKey = resolveKey(projectKey);
|
|
1267
|
+
const eKey = resolveKey(envKey);
|
|
1268
|
+
const body = { protection_level: options.protectionLevel };
|
|
1269
|
+
if (options.protectionReason) {
|
|
1270
|
+
body.protection_reason = options.protectionReason;
|
|
1271
|
+
}
|
|
1272
|
+
return this.request(
|
|
1273
|
+
"PATCH",
|
|
1274
|
+
`${this.paths.environmentRoot(oKey, pKey, eKey)}/protection/`,
|
|
1275
|
+
{ jsonBody: body }
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
async clearEnvironmentProtection(orgKey, projectKey, envKey) {
|
|
1279
|
+
return this.updateEnvironmentProtection(orgKey, projectKey, envKey, {
|
|
1280
|
+
protectionLevel: "none"
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
// src/flux/client.ts
|
|
1286
|
+
function cleanPrefix(prefix) {
|
|
1287
|
+
const value = prefix.replace(/^\/+|\/+$/g, "");
|
|
1288
|
+
if (!value) {
|
|
1289
|
+
throw new Error("apiPrefix cannot be empty");
|
|
1290
|
+
}
|
|
1291
|
+
return value;
|
|
1292
|
+
}
|
|
1293
|
+
function normalizeFolderPath(folderPath) {
|
|
1294
|
+
return folderPath.replace(/^\/+|\/+$/g, "");
|
|
1295
|
+
}
|
|
1296
|
+
var FluxClient = class {
|
|
1297
|
+
apiPrefix;
|
|
1298
|
+
transport;
|
|
1299
|
+
constructor(options) {
|
|
1300
|
+
this.apiPrefix = cleanPrefix(options.apiPrefix);
|
|
1301
|
+
const config = createConfig({
|
|
1302
|
+
baseUrl: options.baseUrl,
|
|
1303
|
+
timeout: options.timeout ?? 15e3,
|
|
1304
|
+
defaultHeaders: options.defaultHeaders
|
|
1305
|
+
});
|
|
1306
|
+
this.transport = new HttpTransport({
|
|
1307
|
+
config,
|
|
1308
|
+
auth: options.auth,
|
|
1309
|
+
retryConfig: options.retryConfig
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
buildPath(folderPath, suffix = "") {
|
|
1313
|
+
const folder = normalizeFolderPath(folderPath);
|
|
1314
|
+
const base = `/${this.apiPrefix}/${folder}`;
|
|
1315
|
+
return suffix ? `${base}${suffix}` : base;
|
|
1316
|
+
}
|
|
1317
|
+
async listResources(folderPath, params) {
|
|
1318
|
+
const path = this.buildPath(folderPath);
|
|
1319
|
+
return this.transport.request("GET", path, { params });
|
|
1320
|
+
}
|
|
1321
|
+
async getResource(folderPath, resourceKey, params) {
|
|
1322
|
+
const path = this.buildPath(folderPath, `/${resourceKey}`);
|
|
1323
|
+
return this.transport.request("GET", path, { params });
|
|
1324
|
+
}
|
|
1325
|
+
async search(folderPath, body) {
|
|
1326
|
+
const path = this.buildPath(folderPath, "/_search");
|
|
1327
|
+
return this.transport.request("POST", path, { jsonBody: body });
|
|
1328
|
+
}
|
|
1329
|
+
close() {
|
|
1330
|
+
this.transport.close();
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
export {
|
|
1334
|
+
AnonymousAuth,
|
|
1335
|
+
DEFAULT_RETRY_CONFIG,
|
|
1336
|
+
DEFAULT_USER_AGENT,
|
|
1337
|
+
FluxClient,
|
|
1338
|
+
FoxnoseAPIError,
|
|
1339
|
+
FoxnoseAuthError,
|
|
1340
|
+
FoxnoseError,
|
|
1341
|
+
FoxnoseTransportError,
|
|
1342
|
+
HttpTransport,
|
|
1343
|
+
JWTAuth,
|
|
1344
|
+
ManagementClient,
|
|
1345
|
+
SDK_VERSION,
|
|
1346
|
+
SecureKeyAuth,
|
|
1347
|
+
SimpleKeyAuth,
|
|
1348
|
+
StaticTokenProvider,
|
|
1349
|
+
SDK_VERSION as VERSION,
|
|
1350
|
+
createConfig,
|
|
1351
|
+
resolveKey
|
|
1352
|
+
};
|
|
1353
|
+
//# sourceMappingURL=index.js.map
|