@twinfinity/twin 6.0.1 → 6.0.2-ci.29168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BuildInfo.js +3 -3
- package/dist/TwinClient.d.ts +159 -0
- package/dist/TwinClient.d.ts.map +1 -1
- package/dist/TwinClient.js +323 -28
- package/dist/TwinClient.js.map +1 -1
- package/dist/errors.d.ts +114 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +142 -0
- package/dist/errors.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/asset-types-api.d.ts +76 -0
- package/dist/types/asset-types-api.d.ts.map +1 -0
- package/dist/types/asset-types-api.js +5 -0
- package/dist/types/asset-types-api.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/twin-permissions-api.d.ts +20 -0
- package/dist/types/twin-permissions-api.d.ts.map +1 -0
- package/dist/types/twin-permissions-api.js +2 -0
- package/dist/types/twin-permissions-api.js.map +1 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AssetBatchError.html +1 -1
- package/docs/classes/AssetCatalogTooLargeError.html +16 -0
- package/docs/classes/AssetCategoryConflictError.html +3 -0
- package/docs/classes/AssetCategoryForbiddenError.html +2 -0
- package/docs/classes/AssetCategoryNotFoundError.html +2 -0
- package/docs/classes/AssetCategoryValidationError.html +3 -0
- package/docs/classes/AssetConflictError.html +1 -1
- package/docs/classes/AssetForbiddenError.html +1 -1
- package/docs/classes/AssetNotFoundError.html +1 -1
- package/docs/classes/AssetTypeConflictError.html +3 -0
- package/docs/classes/AssetTypeForbiddenError.html +2 -0
- package/docs/classes/AssetTypeNotFoundError.html +2 -0
- package/docs/classes/AssetTypeValidationError.html +3 -0
- package/docs/classes/AssetValidationError.html +1 -1
- package/docs/classes/ProcessorNotFoundError.html +1 -1
- package/docs/classes/TwinClient.html +114 -41
- package/docs/classes/TwinConflictError.html +1 -1
- package/docs/classes/TwinFileConflictError.html +1 -1
- package/docs/classes/TwinFileNotFoundError.html +1 -1
- package/docs/classes/TwinFileValidationError.html +1 -1
- package/docs/classes/TwinNotFoundError.html +1 -1
- package/docs/classes/TwinUnauthenticatedError.html +6 -0
- package/docs/classes/TwinValidationError.html +1 -1
- package/docs/functions/isAssetCatalogTooLargeErrorBody.html +6 -0
- package/docs/functions/readErrorBody.html +10 -0
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/AssetCatalogCategory.html +7 -0
- package/docs/interfaces/AssetCatalogResponse.html +6 -0
- package/docs/interfaces/AssetCatalogTooLargeErrorBody.html +15 -0
- package/docs/interfaces/AssetCategoryDelete.html +2 -0
- package/docs/interfaces/AssetCategoryGet.html +14 -0
- package/docs/interfaces/AssetCategoryPut.html +7 -0
- package/docs/interfaces/AssetTypeDelete.html +2 -0
- package/docs/interfaces/AssetTypeGet.html +16 -0
- package/docs/interfaces/AssetTypePut.html +9 -0
- package/docs/interfaces/ITwinClient.html +115 -42
- package/docs/interfaces/MyPermissions.html +7 -0
- package/docs/interfaces/TwinErrorBody.html +2 -2
- package/docs/interfaces/TwinSpecification.html +1 -1
- package/docs/modules.html +1 -1
- package/docs/types/TwinCapability.html +6 -0
- package/docs/types/TwinErrorCause.html +8 -0
- package/docs/types/TwinErrorItemKind.html +4 -0
- package/package.json +3 -3
- package/src/BuildInfo.ts +41 -41
- package/src/TwinClient.ts +2010 -1496
- package/src/errors.ts +360 -117
- package/src/index.ts +3 -3
- package/src/types/Twin.ts +7 -7
- package/src/types/TwinGeometryInfo.ts +7 -7
- package/src/types/asset-api.ts +60 -60
- package/src/types/asset-batch-api.ts +88 -88
- package/src/types/asset-types-api.ts +86 -0
- package/src/types/common.ts +10 -10
- package/src/types/generated.ts +574 -574
- package/src/types/index.ts +8 -6
- package/src/types/twin-api.ts +99 -99
- package/src/types/twin-file-api.ts +67 -67
- package/src/types/twin-permissions-api.ts +20 -0
package/dist/TwinClient.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { HttpMethod } from '@twinfinity/authentication';
|
|
2
2
|
import { readT8ClientModelWithFactories, readT8ClientModelWithGeometry, readT8GIModelWithFactories, T8EntityType, T8GIMeshDescriptor, T8GIStyle, T8GIRegion, T8Product, T8Project, T8Unit } from '@twinfinity/t8-client-model';
|
|
3
|
-
import { TwinValidationError, TwinConflictError, TwinNotFoundError, ProcessorNotFoundError, AssetValidationError, AssetForbiddenError, AssetConflictError, AssetNotFoundError, AssetBatchError, TwinFileValidationError, TwinFileConflictError, TwinFileNotFoundError } from './errors';
|
|
3
|
+
import { TwinValidationError, TwinConflictError, TwinNotFoundError, ProcessorNotFoundError, AssetValidationError, AssetForbiddenError, AssetConflictError, AssetNotFoundError, AssetBatchError, TwinFileValidationError, TwinFileConflictError, TwinFileNotFoundError, AssetCategoryValidationError, AssetCategoryConflictError, AssetCategoryNotFoundError, AssetCategoryForbiddenError, AssetTypeValidationError, AssetTypeConflictError, AssetTypeNotFoundError, AssetTypeForbiddenError, AssetCatalogTooLargeError, isAssetCatalogTooLargeErrorBody, TwinUnauthenticatedError, readErrorBody } from './errors';
|
|
4
4
|
export class TwinClient {
|
|
5
5
|
_httpClient;
|
|
6
6
|
_baseUrl;
|
|
7
|
+
_assetTypeCatalogUrl;
|
|
7
8
|
constructor(baseUrl, _httpClient) {
|
|
8
9
|
this._httpClient = _httpClient;
|
|
9
|
-
|
|
10
|
+
const base = String(baseUrl).replace(/\/+$/, '');
|
|
11
|
+
this._baseUrl = `${base}/_ps/twins`;
|
|
12
|
+
this._assetTypeCatalogUrl = `${base}/_ps/asset-type-catalog`;
|
|
10
13
|
}
|
|
11
14
|
async listTwins(relatedTo, page = undefined, limit = 100, signal) {
|
|
12
15
|
const params = new URLSearchParams();
|
|
@@ -18,14 +21,14 @@ export class TwinClient {
|
|
|
18
21
|
params.set('limit', limit.toString());
|
|
19
22
|
const url = params.toString() ? `${this._baseUrl}?${params}` : this._baseUrl;
|
|
20
23
|
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
21
|
-
headers: {
|
|
24
|
+
headers: { Accept: 'application/json' },
|
|
22
25
|
signal
|
|
23
26
|
});
|
|
24
27
|
if (response.ok) {
|
|
25
28
|
return (await response.json());
|
|
26
29
|
}
|
|
27
30
|
if (response.status === 400) {
|
|
28
|
-
const errorBody = await response
|
|
31
|
+
const errorBody = await readErrorBody(response);
|
|
29
32
|
throw new TwinValidationError(`Twin listing validation failed: ${errorBody.detail}`, errorBody);
|
|
30
33
|
}
|
|
31
34
|
const errorText = await response.text();
|
|
@@ -50,7 +53,7 @@ export class TwinClient {
|
|
|
50
53
|
const twinId = typeof twin === 'string' ? twin : twin.id;
|
|
51
54
|
const specifiedVersion = typeof twin === 'string' ? undefined : twin.version;
|
|
52
55
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}${specifiedVersion !== undefined ? `/versions/${specifiedVersion}` : ''}`, {
|
|
53
|
-
headers: {
|
|
56
|
+
headers: { Accept: 'application/json' },
|
|
54
57
|
signal
|
|
55
58
|
});
|
|
56
59
|
if (response.ok) {
|
|
@@ -72,14 +75,14 @@ export class TwinClient {
|
|
|
72
75
|
params.set('includeDeleted', 'true');
|
|
73
76
|
const url = `${this._baseUrl}/${id}/versions${params.toString() ? `?${params}` : ''}`;
|
|
74
77
|
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
75
|
-
headers: {
|
|
78
|
+
headers: { Accept: 'application/json' },
|
|
76
79
|
signal
|
|
77
80
|
});
|
|
78
81
|
if (response.ok) {
|
|
79
82
|
return (await response.json());
|
|
80
83
|
}
|
|
81
84
|
if (response.status === 400) {
|
|
82
|
-
const errorBody = await response
|
|
85
|
+
const errorBody = await readErrorBody(response);
|
|
83
86
|
throw new TwinValidationError(`Twin listing validation failed: ${errorBody.detail}`, errorBody);
|
|
84
87
|
}
|
|
85
88
|
const errorText = await response.text();
|
|
@@ -243,7 +246,7 @@ export class TwinClient {
|
|
|
243
246
|
return (await response.json());
|
|
244
247
|
}
|
|
245
248
|
if (response.status === 400) {
|
|
246
|
-
const errorBody = await response
|
|
249
|
+
const errorBody = await readErrorBody(response);
|
|
247
250
|
throw new TwinValidationError(`Twin validation failed: ${errorBody.detail}`, errorBody);
|
|
248
251
|
}
|
|
249
252
|
if (response.status === 409) {
|
|
@@ -295,7 +298,7 @@ export class TwinClient {
|
|
|
295
298
|
throw new Error(`Failed to restore twin: ${response.status} ${response.statusText} - ${errorText}`);
|
|
296
299
|
}
|
|
297
300
|
async getTwinVersionContent(twinId, twinVersion, signal) {
|
|
298
|
-
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/versions/${twinVersion}/contents`, { headers: {
|
|
301
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/versions/${twinVersion}/contents`, { headers: { Accept: 'application/json' }, signal });
|
|
299
302
|
if (response.ok) {
|
|
300
303
|
return (await response.json());
|
|
301
304
|
}
|
|
@@ -307,7 +310,7 @@ export class TwinClient {
|
|
|
307
310
|
}
|
|
308
311
|
async getTwinContent(twinId, signal) {
|
|
309
312
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/contents`, {
|
|
310
|
-
headers: {
|
|
313
|
+
headers: { Accept: 'application/json' },
|
|
311
314
|
signal
|
|
312
315
|
});
|
|
313
316
|
if (response.ok) {
|
|
@@ -321,7 +324,7 @@ export class TwinClient {
|
|
|
321
324
|
}
|
|
322
325
|
async getTwinDiagnostics(twinId, signal) {
|
|
323
326
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/diagnostics`, {
|
|
324
|
-
headers: {
|
|
327
|
+
headers: { Accept: 'application/json' },
|
|
325
328
|
signal
|
|
326
329
|
});
|
|
327
330
|
if (response.ok) {
|
|
@@ -334,7 +337,7 @@ export class TwinClient {
|
|
|
334
337
|
throw new Error(`Failed to get twin diagnostics: ${response.status} ${response.statusText} - ${errorText}`);
|
|
335
338
|
}
|
|
336
339
|
async getTwinVersionDiagnostics(twinId, twinVersion, signal) {
|
|
337
|
-
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/versions/${twinVersion}/diagnostics`, { headers: {
|
|
340
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/versions/${twinVersion}/diagnostics`, { headers: { Accept: 'application/json' }, signal });
|
|
338
341
|
if (response.ok) {
|
|
339
342
|
return (await response.json());
|
|
340
343
|
}
|
|
@@ -347,14 +350,14 @@ export class TwinClient {
|
|
|
347
350
|
async getTwinVersionEvents(twinId, twinVersion, offset = 0, limit = 100, signal) {
|
|
348
351
|
const url = `${this._baseUrl}/${twinId}/versions/${twinVersion}/events?offset=${offset}&limit=${limit}`;
|
|
349
352
|
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
350
|
-
headers: {
|
|
353
|
+
headers: { Accept: 'application/json' },
|
|
351
354
|
signal
|
|
352
355
|
});
|
|
353
356
|
if (response.ok) {
|
|
354
357
|
return (await response.json());
|
|
355
358
|
}
|
|
356
359
|
if (response.status === 400) {
|
|
357
|
-
const errorBody = await response
|
|
360
|
+
const errorBody = await readErrorBody(response);
|
|
358
361
|
throw new TwinValidationError(`Twin events validation failed: ${errorBody.detail}`, errorBody);
|
|
359
362
|
}
|
|
360
363
|
if (response.status === 404) {
|
|
@@ -366,14 +369,14 @@ export class TwinClient {
|
|
|
366
369
|
async getProcessorEvents(twinId, twinVersion, processorId, offset = 0, limit = 100, signal) {
|
|
367
370
|
const url = `${this._baseUrl}/${twinId}/versions/${twinVersion}/processors/${processorId}/events?offset=${offset}&limit=${limit}`;
|
|
368
371
|
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
369
|
-
headers: {
|
|
372
|
+
headers: { Accept: 'application/json' },
|
|
370
373
|
signal
|
|
371
374
|
});
|
|
372
375
|
if (response.ok) {
|
|
373
376
|
return (await response.json());
|
|
374
377
|
}
|
|
375
378
|
if (response.status === 400) {
|
|
376
|
-
const errorBody = await response
|
|
379
|
+
const errorBody = await readErrorBody(response);
|
|
377
380
|
throw new TwinValidationError(`Processor events validation failed: ${errorBody.detail}`, errorBody);
|
|
378
381
|
}
|
|
379
382
|
if (response.status === 404) {
|
|
@@ -386,14 +389,14 @@ export class TwinClient {
|
|
|
386
389
|
const includeDeleted = options?.includeDeleted ?? false;
|
|
387
390
|
const params = `offset=${offset}&limit=${limit}${includeDeleted ? '&includeDeleted=true' : ''}`;
|
|
388
391
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/assets?${params}`, {
|
|
389
|
-
headers: {
|
|
392
|
+
headers: { Accept: 'application/json' },
|
|
390
393
|
signal
|
|
391
394
|
});
|
|
392
395
|
if (response.ok) {
|
|
393
396
|
return (await response.json());
|
|
394
397
|
}
|
|
395
398
|
if (response.status === 400) {
|
|
396
|
-
const errorBody = await response
|
|
399
|
+
const errorBody = await readErrorBody(response);
|
|
397
400
|
throw new AssetValidationError(`Asset listing validation failed: ${errorBody.detail}`, errorBody);
|
|
398
401
|
}
|
|
399
402
|
if (response.status === 404) {
|
|
@@ -404,7 +407,7 @@ export class TwinClient {
|
|
|
404
407
|
}
|
|
405
408
|
async getAsset(twinId, assetId, signal) {
|
|
406
409
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/assets/${assetId}`, {
|
|
407
|
-
headers: {
|
|
410
|
+
headers: { Accept: 'application/json' },
|
|
408
411
|
signal
|
|
409
412
|
});
|
|
410
413
|
if (response.ok) {
|
|
@@ -426,7 +429,7 @@ export class TwinClient {
|
|
|
426
429
|
return (await response.json());
|
|
427
430
|
}
|
|
428
431
|
if (response.status === 400) {
|
|
429
|
-
const errorBody = await response
|
|
432
|
+
const errorBody = await readErrorBody(response);
|
|
430
433
|
throw new AssetValidationError(`Asset validation failed: ${errorBody.detail}`, errorBody);
|
|
431
434
|
}
|
|
432
435
|
const errorText = await response.text();
|
|
@@ -446,7 +449,7 @@ export class TwinClient {
|
|
|
446
449
|
throw new AssetConflictError('Asset has been modified by another user', conflictedAsset);
|
|
447
450
|
}
|
|
448
451
|
if (response.status === 400) {
|
|
449
|
-
const errorBody = await response
|
|
452
|
+
const errorBody = await readErrorBody(response);
|
|
450
453
|
throw new AssetValidationError(`Asset validation failed: ${errorBody.detail}`, errorBody);
|
|
451
454
|
}
|
|
452
455
|
const errorText = await response.text();
|
|
@@ -499,7 +502,7 @@ export class TwinClient {
|
|
|
499
502
|
return (await response.json());
|
|
500
503
|
}
|
|
501
504
|
if (response.status === 400) {
|
|
502
|
-
const errorBody = await response
|
|
505
|
+
const errorBody = await readErrorBody(response);
|
|
503
506
|
throw new AssetValidationError(`Asset batch validation failed: ${errorBody.detail}`, errorBody);
|
|
504
507
|
}
|
|
505
508
|
if (response.status === 403) {
|
|
@@ -523,7 +526,7 @@ export class TwinClient {
|
|
|
523
526
|
return (await response.json());
|
|
524
527
|
}
|
|
525
528
|
if (response.status === 400) {
|
|
526
|
-
const errorBody = await response
|
|
529
|
+
const errorBody = await readErrorBody(response);
|
|
527
530
|
throw new AssetValidationError(`Asset batch-get validation failed: ${errorBody.detail}`, errorBody);
|
|
528
531
|
}
|
|
529
532
|
const errorText = await response.text();
|
|
@@ -549,14 +552,14 @@ export class TwinClient {
|
|
|
549
552
|
? `${this._baseUrl}/${twinId}/files?${params}`
|
|
550
553
|
: `${this._baseUrl}/${twinId}/files`;
|
|
551
554
|
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
552
|
-
headers: {
|
|
555
|
+
headers: { Accept: 'application/json' },
|
|
553
556
|
signal
|
|
554
557
|
});
|
|
555
558
|
if (response.ok) {
|
|
556
559
|
return (await response.json());
|
|
557
560
|
}
|
|
558
561
|
if (response.status === 400) {
|
|
559
|
-
const errorBody = await response
|
|
562
|
+
const errorBody = await readErrorBody(response);
|
|
560
563
|
throw new TwinFileValidationError(`Twin file listing validation failed: ${errorBody.detail}`, errorBody);
|
|
561
564
|
}
|
|
562
565
|
const errorText = await response.text();
|
|
@@ -564,7 +567,7 @@ export class TwinClient {
|
|
|
564
567
|
}
|
|
565
568
|
async getTwinFile(twinId, fileId, signal) {
|
|
566
569
|
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._baseUrl}/${twinId}/files/${fileId}`, {
|
|
567
|
-
headers: {
|
|
570
|
+
headers: { Accept: 'application/json' },
|
|
568
571
|
signal
|
|
569
572
|
});
|
|
570
573
|
if (response.ok) {
|
|
@@ -590,7 +593,7 @@ export class TwinClient {
|
|
|
590
593
|
return (await response.json());
|
|
591
594
|
}
|
|
592
595
|
if (response.status === 400) {
|
|
593
|
-
const errorBody = await response
|
|
596
|
+
const errorBody = await readErrorBody(response);
|
|
594
597
|
throw new TwinFileValidationError(`Twin file validation failed`, errorBody);
|
|
595
598
|
}
|
|
596
599
|
if (response.status === 409) {
|
|
@@ -681,7 +684,7 @@ export class TwinClient {
|
|
|
681
684
|
return (await response.json());
|
|
682
685
|
}
|
|
683
686
|
if (response.status === 400) {
|
|
684
|
-
const errorBody = await response
|
|
687
|
+
const errorBody = await readErrorBody(response);
|
|
685
688
|
throw new TwinFileValidationError(`Twin file version listing validation failed: ${errorBody.detail}`, errorBody);
|
|
686
689
|
}
|
|
687
690
|
const errorText = await response.text();
|
|
@@ -712,5 +715,297 @@ export class TwinClient {
|
|
|
712
715
|
signal
|
|
713
716
|
});
|
|
714
717
|
}
|
|
718
|
+
// ---------- Asset categories ----------
|
|
719
|
+
async getMyPermissions(signal) {
|
|
720
|
+
const url = `${this._baseUrl}/permissions/me`;
|
|
721
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
722
|
+
headers: { Accept: 'application/json' },
|
|
723
|
+
signal
|
|
724
|
+
});
|
|
725
|
+
if (response.ok) {
|
|
726
|
+
return (await response.json());
|
|
727
|
+
}
|
|
728
|
+
// 401: no valid auth context. Throw so consumers can redirect to
|
|
729
|
+
// login / refresh tokens rather than mistake an expired session for
|
|
730
|
+
// "logged-in user with no grants."
|
|
731
|
+
if (response.status === 401) {
|
|
732
|
+
throw new TwinUnauthenticatedError('Not authenticated');
|
|
733
|
+
}
|
|
734
|
+
// 403: authenticated but no Twin-service capabilities. Surface as an
|
|
735
|
+
// empty array so consumers can treat it like a logged-in user with
|
|
736
|
+
// zero grants.
|
|
737
|
+
if (response.status === 403) {
|
|
738
|
+
return { permissions: [] };
|
|
739
|
+
}
|
|
740
|
+
throw new Error(`Failed to fetch permissions: ${response.status} ${response.statusText}`);
|
|
741
|
+
}
|
|
742
|
+
async getAssetTypeMetaSchema(signal) {
|
|
743
|
+
const url = `${this._assetTypeCatalogUrl}/meta-schema`;
|
|
744
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
745
|
+
headers: { Accept: 'application/schema+json, application/json' },
|
|
746
|
+
signal
|
|
747
|
+
});
|
|
748
|
+
if (!response.ok) {
|
|
749
|
+
throw new Error(`Failed to fetch meta-schema: ${response.status} ${response.statusText}`);
|
|
750
|
+
}
|
|
751
|
+
return (await response.json());
|
|
752
|
+
}
|
|
753
|
+
async listAssetCategories(options, signal) {
|
|
754
|
+
const params = new URLSearchParams();
|
|
755
|
+
if (options?.page !== undefined)
|
|
756
|
+
params.set('page', options.page);
|
|
757
|
+
if (options?.limit !== undefined)
|
|
758
|
+
params.set('limit', options.limit.toString());
|
|
759
|
+
if (options?.includeDeleted)
|
|
760
|
+
params.set('includeDeleted', 'true');
|
|
761
|
+
const url = params.toString()
|
|
762
|
+
? `${this._assetTypeCatalogUrl}/categories?${params}`
|
|
763
|
+
: `${this._assetTypeCatalogUrl}/categories`;
|
|
764
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
765
|
+
headers: { Accept: 'application/json' },
|
|
766
|
+
signal
|
|
767
|
+
});
|
|
768
|
+
if (response.ok)
|
|
769
|
+
return (await response.json());
|
|
770
|
+
if (response.status === 403)
|
|
771
|
+
throw new AssetCategoryForbiddenError('Asset category listing forbidden');
|
|
772
|
+
if (response.status === 400) {
|
|
773
|
+
const errorBody = await readErrorBody(response);
|
|
774
|
+
throw new AssetCategoryValidationError(`Asset category listing failed: ${errorBody.detail}`, errorBody);
|
|
775
|
+
}
|
|
776
|
+
throw new Error(`Failed to list asset categories: ${response.status} ${response.statusText}`);
|
|
777
|
+
}
|
|
778
|
+
async getAssetCategory(categoryId, signal) {
|
|
779
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._assetTypeCatalogUrl}/categories/${categoryId}`, {
|
|
780
|
+
headers: { Accept: 'application/json' },
|
|
781
|
+
signal
|
|
782
|
+
});
|
|
783
|
+
if (response.ok)
|
|
784
|
+
return (await response.json());
|
|
785
|
+
if (response.status === 403)
|
|
786
|
+
throw new AssetCategoryForbiddenError(`Asset category ${categoryId} read forbidden`);
|
|
787
|
+
if (response.status === 404)
|
|
788
|
+
throw new AssetCategoryNotFoundError(`Asset category ${categoryId} not found`);
|
|
789
|
+
throw new Error(`Failed to get asset category: ${response.status} ${response.statusText}`);
|
|
790
|
+
}
|
|
791
|
+
async putAssetCategory(categoryId, body, signal) {
|
|
792
|
+
const response = await this._httpClient.fetch(HttpMethod.Put, `${this._assetTypeCatalogUrl}/categories/${categoryId}`, {
|
|
793
|
+
headers: { 'Content-Type': 'application/json' },
|
|
794
|
+
body: JSON.stringify(body),
|
|
795
|
+
signal
|
|
796
|
+
});
|
|
797
|
+
if (response.ok)
|
|
798
|
+
return (await response.json());
|
|
799
|
+
if (response.status === 403)
|
|
800
|
+
throw new AssetCategoryForbiddenError('Asset category upsert forbidden');
|
|
801
|
+
if (response.status === 409) {
|
|
802
|
+
const current = (await response.json());
|
|
803
|
+
throw new AssetCategoryConflictError('Asset category was modified by another user', current);
|
|
804
|
+
}
|
|
805
|
+
if (response.status === 400) {
|
|
806
|
+
const errorBody = await readErrorBody(response);
|
|
807
|
+
throw new AssetCategoryValidationError(`Asset category validation failed: ${errorBody.detail}`, errorBody);
|
|
808
|
+
}
|
|
809
|
+
const errorText = await response.text();
|
|
810
|
+
throw new Error(`Failed to upsert asset category: ${response.status} ${response.statusText} - ${errorText}`);
|
|
811
|
+
}
|
|
812
|
+
async deleteAssetCategory(categoryId, etag, signal) {
|
|
813
|
+
return this._categoryDeleteOrRestore(categoryId, etag, /*isRestore*/ false, signal);
|
|
814
|
+
}
|
|
815
|
+
async restoreAssetCategory(categoryId, etag, signal) {
|
|
816
|
+
return this._categoryDeleteOrRestore(categoryId, etag, /*isRestore*/ true, signal);
|
|
817
|
+
}
|
|
818
|
+
async _categoryDeleteOrRestore(categoryId, etag, isRestore, signal) {
|
|
819
|
+
const url = isRestore
|
|
820
|
+
? `${this._assetTypeCatalogUrl}/categories/${categoryId}/restore`
|
|
821
|
+
: `${this._assetTypeCatalogUrl}/categories/${categoryId}`;
|
|
822
|
+
const method = isRestore ? HttpMethod.Put : HttpMethod.Delete;
|
|
823
|
+
const response = await this._httpClient.fetch(method, url, {
|
|
824
|
+
headers: { 'Content-Type': 'application/json' },
|
|
825
|
+
body: JSON.stringify({ etag }),
|
|
826
|
+
signal
|
|
827
|
+
});
|
|
828
|
+
if (response.ok)
|
|
829
|
+
return (await response.json());
|
|
830
|
+
if (response.status === 403) {
|
|
831
|
+
const op = isRestore ? 'restore' : 'delete';
|
|
832
|
+
throw new AssetCategoryForbiddenError(`Asset category ${op} forbidden`);
|
|
833
|
+
}
|
|
834
|
+
if (response.status === 409) {
|
|
835
|
+
const current = (await response.json());
|
|
836
|
+
throw new AssetCategoryConflictError('Asset category was modified by another user', current);
|
|
837
|
+
}
|
|
838
|
+
if (response.status === 404)
|
|
839
|
+
throw new AssetCategoryNotFoundError(`Asset category ${categoryId} not found`);
|
|
840
|
+
const errorText = await response.text();
|
|
841
|
+
const op = isRestore ? 'restore' : 'delete';
|
|
842
|
+
throw new Error(`Failed to ${op} asset category: ${response.status} ${response.statusText} - ${errorText}`);
|
|
843
|
+
}
|
|
844
|
+
async listAssetCategoryVersions(categoryId, options, signal) {
|
|
845
|
+
const params = new URLSearchParams();
|
|
846
|
+
if (options?.page !== undefined)
|
|
847
|
+
params.set('page', options.page);
|
|
848
|
+
if (options?.limit !== undefined)
|
|
849
|
+
params.set('limit', options.limit.toString());
|
|
850
|
+
if (options?.includeDeleted)
|
|
851
|
+
params.set('includeDeleted', 'true');
|
|
852
|
+
const baseUrl = `${this._assetTypeCatalogUrl}/categories/${categoryId}/versions`;
|
|
853
|
+
const url = params.toString() ? `${baseUrl}?${params}` : baseUrl;
|
|
854
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
855
|
+
headers: { Accept: 'application/json' },
|
|
856
|
+
signal
|
|
857
|
+
});
|
|
858
|
+
if (response.ok)
|
|
859
|
+
return (await response.json());
|
|
860
|
+
if (response.status === 403)
|
|
861
|
+
throw new AssetCategoryForbiddenError('Asset category version listing forbidden');
|
|
862
|
+
if (response.status === 400) {
|
|
863
|
+
const errorBody = await readErrorBody(response);
|
|
864
|
+
throw new AssetCategoryValidationError(`Asset category version listing failed: ${errorBody.detail}`, errorBody);
|
|
865
|
+
}
|
|
866
|
+
if (response.status === 404)
|
|
867
|
+
throw new AssetCategoryNotFoundError(`Asset category ${categoryId} not found`);
|
|
868
|
+
throw new Error(`Failed to list asset category versions: ${response.status} ${response.statusText}`);
|
|
869
|
+
}
|
|
870
|
+
// ---------- Asset types ----------
|
|
871
|
+
async listAssetTypes(categoryId, options, signal) {
|
|
872
|
+
const params = new URLSearchParams();
|
|
873
|
+
if (options?.page !== undefined)
|
|
874
|
+
params.set('page', options.page);
|
|
875
|
+
if (options?.limit !== undefined)
|
|
876
|
+
params.set('limit', options.limit.toString());
|
|
877
|
+
if (options?.includeDeleted)
|
|
878
|
+
params.set('includeDeleted', 'true');
|
|
879
|
+
const baseUrl = `${this._assetTypeCatalogUrl}/categories/${categoryId}/types`;
|
|
880
|
+
const url = params.toString() ? `${baseUrl}?${params}` : baseUrl;
|
|
881
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
882
|
+
headers: { Accept: 'application/json' },
|
|
883
|
+
signal
|
|
884
|
+
});
|
|
885
|
+
if (response.ok)
|
|
886
|
+
return (await response.json());
|
|
887
|
+
if (response.status === 403)
|
|
888
|
+
throw new AssetTypeForbiddenError('Asset type listing forbidden');
|
|
889
|
+
if (response.status === 400) {
|
|
890
|
+
const errorBody = await readErrorBody(response);
|
|
891
|
+
throw new AssetTypeValidationError(`Asset type listing failed: ${errorBody.detail}`, errorBody);
|
|
892
|
+
}
|
|
893
|
+
throw new Error(`Failed to list asset types: ${response.status} ${response.statusText}`);
|
|
894
|
+
}
|
|
895
|
+
async getAssetType(categoryId, typeId, signal) {
|
|
896
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, `${this._assetTypeCatalogUrl}/categories/${categoryId}/types/${typeId}`, { headers: { Accept: 'application/json' }, signal });
|
|
897
|
+
if (response.ok)
|
|
898
|
+
return (await response.json());
|
|
899
|
+
if (response.status === 403)
|
|
900
|
+
throw new AssetTypeForbiddenError(`Asset type ${typeId} read forbidden`);
|
|
901
|
+
if (response.status === 404)
|
|
902
|
+
throw new AssetTypeNotFoundError(`Asset type ${typeId} not found`);
|
|
903
|
+
throw new Error(`Failed to get asset type: ${response.status} ${response.statusText}`);
|
|
904
|
+
}
|
|
905
|
+
async listAssetTypeVersions(categoryId, typeId, options, signal) {
|
|
906
|
+
const params = new URLSearchParams();
|
|
907
|
+
if (options?.page !== undefined)
|
|
908
|
+
params.set('page', options.page);
|
|
909
|
+
if (options?.limit !== undefined)
|
|
910
|
+
params.set('limit', options.limit.toString());
|
|
911
|
+
if (options?.includeDeleted)
|
|
912
|
+
params.set('includeDeleted', 'true');
|
|
913
|
+
const baseUrl = `${this._assetTypeCatalogUrl}/categories/${categoryId}/types/${typeId}/versions`;
|
|
914
|
+
const url = params.toString() ? `${baseUrl}?${params}` : baseUrl;
|
|
915
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, url, {
|
|
916
|
+
headers: { Accept: 'application/json' },
|
|
917
|
+
signal
|
|
918
|
+
});
|
|
919
|
+
if (response.ok)
|
|
920
|
+
return (await response.json());
|
|
921
|
+
if (response.status === 403)
|
|
922
|
+
throw new AssetTypeForbiddenError('Asset type version listing forbidden');
|
|
923
|
+
if (response.status === 400) {
|
|
924
|
+
const errorBody = await readErrorBody(response);
|
|
925
|
+
throw new AssetTypeValidationError(`Asset type version listing failed: ${errorBody.detail}`, errorBody);
|
|
926
|
+
}
|
|
927
|
+
if (response.status === 404)
|
|
928
|
+
throw new AssetTypeNotFoundError(`Asset type ${typeId} not found`);
|
|
929
|
+
throw new Error(`Failed to list asset type versions: ${response.status} ${response.statusText}`);
|
|
930
|
+
}
|
|
931
|
+
async putAssetType(categoryId, typeId, body, signal) {
|
|
932
|
+
const response = await this._httpClient.fetch(HttpMethod.Put, `${this._assetTypeCatalogUrl}/categories/${categoryId}/types/${typeId}`, {
|
|
933
|
+
headers: { 'Content-Type': 'application/json' },
|
|
934
|
+
body: JSON.stringify(body),
|
|
935
|
+
signal
|
|
936
|
+
});
|
|
937
|
+
if (response.ok)
|
|
938
|
+
return (await response.json());
|
|
939
|
+
if (response.status === 403)
|
|
940
|
+
throw new AssetTypeForbiddenError('Asset type upsert forbidden');
|
|
941
|
+
if (response.status === 409) {
|
|
942
|
+
const current = (await response.json());
|
|
943
|
+
throw new AssetTypeConflictError('Asset type was modified by another user', current);
|
|
944
|
+
}
|
|
945
|
+
if (response.status === 400) {
|
|
946
|
+
const errorBody = await readErrorBody(response);
|
|
947
|
+
throw new AssetTypeValidationError(`Asset type validation failed: ${errorBody.detail}`, errorBody);
|
|
948
|
+
}
|
|
949
|
+
const errorText = await response.text();
|
|
950
|
+
throw new Error(`Failed to upsert asset type: ${response.status} ${response.statusText} - ${errorText}`);
|
|
951
|
+
}
|
|
952
|
+
async deleteAssetType(categoryId, typeId, etag, signal) {
|
|
953
|
+
return this._typeDeleteOrRestore(categoryId, typeId, etag, /*isRestore*/ false, signal);
|
|
954
|
+
}
|
|
955
|
+
async restoreAssetType(categoryId, typeId, etag, signal) {
|
|
956
|
+
return this._typeDeleteOrRestore(categoryId, typeId, etag, /*isRestore*/ true, signal);
|
|
957
|
+
}
|
|
958
|
+
async _typeDeleteOrRestore(categoryId, typeId, etag, isRestore, signal) {
|
|
959
|
+
const url = isRestore
|
|
960
|
+
? `${this._assetTypeCatalogUrl}/categories/${categoryId}/types/${typeId}/restore`
|
|
961
|
+
: `${this._assetTypeCatalogUrl}/categories/${categoryId}/types/${typeId}`;
|
|
962
|
+
const method = isRestore ? HttpMethod.Put : HttpMethod.Delete;
|
|
963
|
+
const response = await this._httpClient.fetch(method, url, {
|
|
964
|
+
headers: { 'Content-Type': 'application/json' },
|
|
965
|
+
body: JSON.stringify({ etag }),
|
|
966
|
+
signal
|
|
967
|
+
});
|
|
968
|
+
if (response.ok)
|
|
969
|
+
return (await response.json());
|
|
970
|
+
if (response.status === 403) {
|
|
971
|
+
const op = isRestore ? 'restore' : 'delete';
|
|
972
|
+
throw new AssetTypeForbiddenError(`Asset type ${op} forbidden`);
|
|
973
|
+
}
|
|
974
|
+
if (response.status === 409) {
|
|
975
|
+
const current = (await response.json());
|
|
976
|
+
throw new AssetTypeConflictError('Asset type was modified by another user', current);
|
|
977
|
+
}
|
|
978
|
+
if (response.status === 404)
|
|
979
|
+
throw new AssetTypeNotFoundError(`Asset type ${typeId} not found`);
|
|
980
|
+
const errorText = await response.text();
|
|
981
|
+
const op = isRestore ? 'restore' : 'delete';
|
|
982
|
+
throw new Error(`Failed to ${op} asset type: ${response.status} ${response.statusText} - ${errorText}`);
|
|
983
|
+
}
|
|
984
|
+
async getAssetTypeCatalog(signal) {
|
|
985
|
+
const response = await this._httpClient.fetch(HttpMethod.Get, this._assetTypeCatalogUrl, {
|
|
986
|
+
headers: { Accept: 'application/json' },
|
|
987
|
+
signal
|
|
988
|
+
});
|
|
989
|
+
if (response.ok)
|
|
990
|
+
return (await response.json());
|
|
991
|
+
if (response.status === 403)
|
|
992
|
+
throw new AssetCategoryForbiddenError('Asset type catalog read forbidden');
|
|
993
|
+
if (response.status === 400) {
|
|
994
|
+
// The server emits a single structured 400 here today —
|
|
995
|
+
// `cause: 'CatalogTooLarge'` — to flag a tenant whose catalog
|
|
996
|
+
// overflows the per-customer cap. Surface as a typed error so
|
|
997
|
+
// picker UIs can render "use search" instead of crashing on
|
|
998
|
+
// missing rows. Any other 400 (malformed CatalogTooLarge body,
|
|
999
|
+
// future cause) falls through to the generic error below so the
|
|
1000
|
+
// caller still sees the raw response.
|
|
1001
|
+
const errorBody = await readErrorBody(response);
|
|
1002
|
+
if (isAssetCatalogTooLargeErrorBody(errorBody)) {
|
|
1003
|
+
throw new AssetCatalogTooLargeError(`Asset type catalog too large: ${errorBody.detail}`, errorBody);
|
|
1004
|
+
}
|
|
1005
|
+
throw new Error(`Failed to get asset-type catalog: ${response.status} ${response.statusText} - ${errorBody.detail}`);
|
|
1006
|
+
}
|
|
1007
|
+
const errorText = await response.text();
|
|
1008
|
+
throw new Error(`Failed to get asset-type catalog: ${response.status} ${response.statusText} - ${errorText}`);
|
|
1009
|
+
}
|
|
715
1010
|
}
|
|
716
1011
|
//# sourceMappingURL=TwinClient.js.map
|