@twinfinity/twin 6.1.0 → 6.1.2-ci.30738
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/README.md +63 -2
- package/dist/BuildInfo.js +3 -3
- package/dist/TwinClient.d.ts +312 -9
- package/dist/TwinClient.d.ts.map +1 -1
- package/dist/TwinClient.js +321 -6
- package/dist/TwinClient.js.map +1 -1
- package/dist/errors.d.ts +120 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +116 -2
- package/dist/errors.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/generated.d.ts +93 -31
- package/dist/types/generated.d.ts.map +1 -1
- package/dist/types/twin-api.d.ts +54 -1
- package/dist/types/twin-api.d.ts.map +1 -1
- package/dist/types/twin-permissions-api.d.ts +226 -6
- package/dist/types/twin-permissions-api.d.ts.map +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AssetAttachmentConflictError.html +1 -1
- package/docs/classes/AssetAttachmentNotFoundError.html +1 -1
- package/docs/classes/AssetBatchError.html +1 -1
- package/docs/classes/AssetCatalogTooLargeError.html +1 -1
- package/docs/classes/AssetCategoryConflictError.html +1 -1
- package/docs/classes/AssetCategoryForbiddenError.html +1 -1
- package/docs/classes/AssetCategoryNotFoundError.html +1 -1
- package/docs/classes/AssetCategoryValidationError.html +1 -1
- package/docs/classes/AssetConflictError.html +1 -1
- package/docs/classes/AssetForbiddenError.html +1 -1
- package/docs/classes/AssetNotFoundError.html +1 -1
- package/docs/classes/AssetPermissionsConflictError.html +16 -0
- package/docs/classes/AssetTypeConflictError.html +1 -1
- package/docs/classes/AssetTypeForbiddenError.html +1 -1
- package/docs/classes/AssetTypeNotFoundError.html +1 -1
- package/docs/classes/AssetTypeValidationError.html +1 -1
- package/docs/classes/AssetValidationError.html +1 -1
- package/docs/classes/ProcessorNotFoundError.html +1 -1
- package/docs/classes/TwinClient.html +251 -73
- 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 +4 -2
- package/docs/classes/TwinPermissionsConflictError.html +19 -0
- package/docs/classes/TwinPermissionsForbiddenError.html +12 -0
- package/docs/classes/TwinPrincipalNotFoundError.html +5 -0
- package/docs/classes/TwinTemporarilyUnavailableError.html +10 -0
- package/docs/classes/TwinUnauthenticatedError.html +1 -1
- package/docs/classes/TwinValidationError.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +56 -4
- package/docs/interfaces/AssetCatalogTooLargeErrorBody.html +2 -2
- package/docs/interfaces/AssetGroupGet.html +9 -0
- package/docs/interfaces/AssetGroupsGet.html +3 -0
- package/docs/interfaces/AssetPermissionsConflictErrorBody.html +12 -0
- package/docs/interfaces/AssetPermissionsPut.html +9 -0
- package/docs/interfaces/AssetPrincipalPermissionsGet.html +23 -0
- package/docs/interfaces/Coordinates.html +6 -0
- package/docs/interfaces/EntityCollection.html +7 -2
- package/docs/interfaces/EntityRepresentation.html +12 -0
- package/docs/interfaces/Facility.html +8 -3
- package/docs/interfaces/FacilityPart.html +5 -3
- package/docs/interfaces/ITwinClient.html +251 -73
- package/docs/interfaces/InheritedPermissions.html +8 -0
- package/docs/interfaces/ListTwinItem.html +18 -2
- package/docs/interfaces/Location.html +4 -1
- package/docs/interfaces/MyPermissions.html +2 -2
- package/docs/interfaces/MyTwinPermissions.html +5 -0
- package/docs/interfaces/Site.html +11 -4
- package/docs/interfaces/Space.html +6 -3
- package/docs/interfaces/TwinErrorBody.html +2 -2
- package/docs/interfaces/TwinGet.html +29 -11
- package/docs/interfaces/TwinGroupGet.html +10 -0
- package/docs/interfaces/TwinGroupsGet.html +3 -0
- package/docs/interfaces/TwinPermissionsConflictErrorBody.html +8 -0
- package/docs/interfaces/TwinPermissionsPut.html +11 -0
- package/docs/interfaces/TwinPrincipalPermissionsGet.html +34 -0
- package/docs/interfaces/TwinPut.html +8 -10
- package/docs/interfaces/TwinReference.html +4 -0
- package/docs/interfaces/TwinSpecification.html +7 -9
- package/docs/media/twin-management.md +197 -0
- package/docs/modules.html +1 -1
- package/docs/types/TwinBoundCapabilityName.html +8 -0
- package/docs/types/TwinCapability.html +11 -5
- package/docs/types/TwinCapabilityName.html +8 -0
- package/docs/types/TwinErrorCause.html +1 -1
- package/docs/types/TwinErrorItemKind.html +1 -1
- package/docs/types/TwinPermissionsConflictCause.html +6 -0
- package/docs/types/TwinScopedCapability.html +9 -0
- package/docs/types/TwinScopedCapabilityName.html +8 -0
- package/package.json +3 -3
- package/src/TwinClient.ts +776 -15
- package/src/errors.ts +191 -4
- package/src/types/generated.ts +93 -33
- package/src/types/twin-api.ts +55 -1
- package/src/types/twin-permissions-api.ts +243 -6
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
TwinGet,
|
|
3
|
+
AssetGet,
|
|
4
|
+
TwinFileGet,
|
|
5
|
+
AssetBatchResponse,
|
|
6
|
+
AssetCategoryGet,
|
|
7
|
+
AssetTypeGet,
|
|
8
|
+
TwinPrincipalPermissionsGet,
|
|
9
|
+
AssetPrincipalPermissionsGet
|
|
10
|
+
} from './types';
|
|
2
11
|
import type { AttachmentGet } from './types/asset-attachment-api';
|
|
3
12
|
|
|
4
13
|
/**
|
|
@@ -43,6 +52,10 @@ export type TwinErrorCause =
|
|
|
43
52
|
| 'StringIdInUse'
|
|
44
53
|
| 'CatalogTooLarge'
|
|
45
54
|
| 'EtagRequired'
|
|
55
|
+
| 'InvalidPaginationToken'
|
|
56
|
+
| 'SystemPrincipalImmutable'
|
|
57
|
+
| 'ManagePermissionsNotGrantableToAllAuthenticated'
|
|
58
|
+
| 'ValidationFailed'
|
|
46
59
|
// Anything the server emits that this client doesn't know about yet.
|
|
47
60
|
// (string & {}) keeps the autocomplete on the listed values above.
|
|
48
61
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
@@ -60,6 +73,10 @@ export type TwinErrorItemKind =
|
|
|
60
73
|
| 'DocumentChange'
|
|
61
74
|
| 'AssetCategory'
|
|
62
75
|
| 'AssetType'
|
|
76
|
+
| 'Attachment'
|
|
77
|
+
| 'Document'
|
|
78
|
+
| 'Principal'
|
|
79
|
+
| 'Request'
|
|
63
80
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
64
81
|
| (string & {});
|
|
65
82
|
|
|
@@ -68,7 +85,9 @@ export interface TwinErrorBody {
|
|
|
68
85
|
cause: TwinErrorCause;
|
|
69
86
|
item?: {
|
|
70
87
|
kind: TwinErrorItemKind;
|
|
71
|
-
id
|
|
88
|
+
// Absent when the reference names something that has no id — a `Request` kind
|
|
89
|
+
// carries only `field`, the request member that failed validation.
|
|
90
|
+
id?: string;
|
|
72
91
|
version?: number;
|
|
73
92
|
field?: string;
|
|
74
93
|
};
|
|
@@ -87,8 +106,12 @@ export interface TwinErrorBody {
|
|
|
87
106
|
* that switch on known causes will fall through to a default arm.
|
|
88
107
|
*/
|
|
89
108
|
export async function readErrorBody(response: Response): Promise<TwinErrorBody> {
|
|
109
|
+
// Parse a clone, so that a body which turns out not to be JSON can still be read as text below.
|
|
110
|
+
// `json()` consumes the stream: on a real Response, reading the original here would leave the
|
|
111
|
+
// fallback unreachable and every non-JSON diagnostic would degrade to `statusText`.
|
|
112
|
+
const parseFrom = typeof response.clone === 'function' ? response.clone() : response;
|
|
90
113
|
try {
|
|
91
|
-
const parsed = (await
|
|
114
|
+
const parsed = (await parseFrom.json()) as TwinErrorBody;
|
|
92
115
|
// Defensive shape check — JSON-but-not-our-shape (e.g. an upstream
|
|
93
116
|
// ProblemDetails payload from a non-Twinfinity component) should still
|
|
94
117
|
// surface usefully. `detail` is the only field every consumer reads.
|
|
@@ -121,9 +144,13 @@ export class TwinConflictError extends Error {
|
|
|
121
144
|
}
|
|
122
145
|
|
|
123
146
|
export class TwinNotFoundError extends Error {
|
|
124
|
-
|
|
147
|
+
/** The server's envelope, when there was one — `item.kind` names what was not found. */
|
|
148
|
+
public readonly errorBody?: TwinErrorBody;
|
|
149
|
+
|
|
150
|
+
constructor(message: string, errorBody?: TwinErrorBody) {
|
|
125
151
|
super(message);
|
|
126
152
|
this.name = 'TwinNotFoundError';
|
|
153
|
+
this.errorBody = errorBody;
|
|
127
154
|
}
|
|
128
155
|
}
|
|
129
156
|
|
|
@@ -377,3 +404,163 @@ export class TwinUnauthenticatedError extends Error {
|
|
|
377
404
|
this.name = 'TwinUnauthenticatedError';
|
|
378
405
|
}
|
|
379
406
|
}
|
|
407
|
+
|
|
408
|
+
// ---------- Twin-scoped permissions ----------
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* The `cause` values the twin-scoped permission routes emit on a 409. A subset of
|
|
412
|
+
* `TwinConflictCause` in `backend/services/Twinfinity.Twin/Controllers/Model/TwinStatus.cs`:
|
|
413
|
+
* that enum's `GroupIdAlreadyInUse` and `ScopeIdAlreadyInUse` are raised by twin *creation*,
|
|
414
|
+
* which answers through {@link TwinConflictError}, never through this surface. Carries the same
|
|
415
|
+
* forward-compat tail as {@link TwinErrorCause}.
|
|
416
|
+
*/
|
|
417
|
+
export type TwinPermissionsConflictCause =
|
|
418
|
+
| 'EtagMismatch'
|
|
419
|
+
| 'EtagRequired'
|
|
420
|
+
| 'ScopesNotProvisioned'
|
|
421
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
422
|
+
| (string & {});
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* The 409 envelope of the twin-scoped permission surface: the standard
|
|
426
|
+
* {@link TwinErrorBody} plus the server's view of the entry the caller lost a race on,
|
|
427
|
+
* whenever the service could report it.
|
|
428
|
+
*/
|
|
429
|
+
export interface TwinPermissionsConflictErrorBody extends TwinErrorBody {
|
|
430
|
+
cause: TwinPermissionsConflictCause;
|
|
431
|
+
currentState?: TwinPrincipalPermissionsGet;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Thrown by the twin permission mutation and listing methods on a 409.
|
|
436
|
+
*
|
|
437
|
+
* The three causes need different handling, which is why they are distinguishable
|
|
438
|
+
* rather than collapsed into one "modified by another user":
|
|
439
|
+
* - `EtagMismatch` — the etag is stale; re-read (or use {@link currentState}) and retry.
|
|
440
|
+
* - `EtagRequired` — the write omitted an etag but the principal already held an entry,
|
|
441
|
+
* so it would have replaced state the caller never read. Retried by reading at all.
|
|
442
|
+
* - `ScopesNotProvisioned` — the twin owns no Twinfinity scope, so there is no permission
|
|
443
|
+
* state to read or write. Nothing provisions on read, so retrying will not help.
|
|
444
|
+
*/
|
|
445
|
+
export class TwinPermissionsConflictError extends Error {
|
|
446
|
+
/**
|
|
447
|
+
* Which of the three conflicts this is. Named `conflictCause` rather than `cause` so the
|
|
448
|
+
* standard `Error.cause` — whose consumers expect a wrapped error, not a string — is left
|
|
449
|
+
* alone; the same value is on {@link errorBody}`.cause`.
|
|
450
|
+
*/
|
|
451
|
+
public readonly conflictCause: TwinPermissionsConflictCause;
|
|
452
|
+
/** The entry as the server holds it, including the etag to retry with. */
|
|
453
|
+
public readonly currentState?: TwinPrincipalPermissionsGet;
|
|
454
|
+
public readonly errorBody: TwinPermissionsConflictErrorBody;
|
|
455
|
+
|
|
456
|
+
constructor(message: string, errorBody: TwinPermissionsConflictErrorBody) {
|
|
457
|
+
super(message);
|
|
458
|
+
this.name = 'TwinPermissionsConflictError';
|
|
459
|
+
this.conflictCause = errorBody.cause;
|
|
460
|
+
this.currentState = errorBody.currentState;
|
|
461
|
+
this.errorBody = errorBody;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Thrown on a 403 from the twin-scoped permission surface: the caller can see the twin
|
|
467
|
+
* but does not hold `ManageTwinPermissions` on it. Distinct from
|
|
468
|
+
* {@link TwinNotFoundError}, which is what a twin the caller cannot see at all answers —
|
|
469
|
+
* the surface refuses to confirm such a twin exists.
|
|
470
|
+
*/
|
|
471
|
+
export class TwinPermissionsForbiddenError extends Error {
|
|
472
|
+
/**
|
|
473
|
+
* The server's envelope, when there was one. Its presence is load-bearing: a genuine refusal
|
|
474
|
+
* carries `cause: 'InsufficientPermissions'`, while a Twin service that could not evaluate the
|
|
475
|
+
* request at all (a customer-database lookup that threw, a missing twin feature) falls through
|
|
476
|
+
* to the framework's default forbid handler and answers a 403 with no body. Without this a
|
|
477
|
+
* caller cannot tell "you may not" from "we could not tell", and would report the first.
|
|
478
|
+
*/
|
|
479
|
+
public readonly errorBody?: TwinErrorBody;
|
|
480
|
+
|
|
481
|
+
constructor(message: string, errorBody?: TwinErrorBody) {
|
|
482
|
+
super(message);
|
|
483
|
+
this.name = 'TwinPermissionsForbiddenError';
|
|
484
|
+
this.errorBody = errorBody;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Thrown when a 404 names the principal rather than the twin — an id that no principal
|
|
490
|
+
* in the tenant carries, or one holding nothing on the twin for a `DELETE` to revoke.
|
|
491
|
+
*/
|
|
492
|
+
export class TwinPrincipalNotFoundError extends Error {
|
|
493
|
+
public readonly errorBody?: TwinErrorBody;
|
|
494
|
+
|
|
495
|
+
constructor(message: string, errorBody?: TwinErrorBody) {
|
|
496
|
+
super(message);
|
|
497
|
+
this.name = 'TwinPrincipalNotFoundError';
|
|
498
|
+
this.errorBody = errorBody;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Thrown on a 503: the Twin service could neither carry out the request nor answer it
|
|
504
|
+
* truthfully. The request is unchanged and safe to retry as-is — unlike
|
|
505
|
+
* {@link TwinPermissionsConflictError}, which never clears on its own.
|
|
506
|
+
*/
|
|
507
|
+
export class TwinTemporarilyUnavailableError extends Error {
|
|
508
|
+
public readonly errorBody?: TwinErrorBody;
|
|
509
|
+
/**
|
|
510
|
+
* The `Retry-After` the service sent, in seconds, when it sent one. The Twin service pairs the
|
|
511
|
+
* status with this header deliberately, so that "retrying is worthwhile" does not rest on the
|
|
512
|
+
* status alone — pass it to whatever backoff the caller uses instead of inventing a delay.
|
|
513
|
+
*/
|
|
514
|
+
public readonly retryAfterSeconds?: number;
|
|
515
|
+
|
|
516
|
+
constructor(message: string, errorBody?: TwinErrorBody, retryAfterSeconds?: number) {
|
|
517
|
+
super(message);
|
|
518
|
+
this.name = 'TwinTemporarilyUnavailableError';
|
|
519
|
+
this.errorBody = errorBody;
|
|
520
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// ---------- Asset-domain permissions ----------
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* The 409 envelope of the customer-wide asset permission surface. The same shape as
|
|
528
|
+
* {@link TwinPermissionsConflictErrorBody}, but `currentState` is a domain entry rather than a
|
|
529
|
+
* twin's: the two carry different identity fields (`id` versus `principalId`) and different
|
|
530
|
+
* capability vocabularies, so a caller that acts on the state it was handed has to know which it
|
|
531
|
+
* has.
|
|
532
|
+
*
|
|
533
|
+
* `ScopesNotProvisioned` never appears here — the asset management scope is seeded once per
|
|
534
|
+
* customer rather than provisioned per resource.
|
|
535
|
+
*/
|
|
536
|
+
export interface AssetPermissionsConflictErrorBody extends TwinErrorBody {
|
|
537
|
+
cause: TwinPermissionsConflictCause;
|
|
538
|
+
currentState?: AssetPrincipalPermissionsGet;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Thrown by the asset permission mutation methods on a 409, which on this surface is always an
|
|
543
|
+
* etag failure:
|
|
544
|
+
* - `EtagMismatch` — the etag is stale; re-read (or use {@link currentState}) and retry. Expect
|
|
545
|
+
* this routinely: the scope's etag is customer-wide, so any administrator's write invalidates it.
|
|
546
|
+
* - `EtagRequired` — the write omitted an etag but the principal already held capabilities, so it
|
|
547
|
+
* would have replaced state the caller never read.
|
|
548
|
+
*/
|
|
549
|
+
export class AssetPermissionsConflictError extends Error {
|
|
550
|
+
/**
|
|
551
|
+
* Which of the two conflicts this is. Named `conflictCause` rather than `cause` so the standard
|
|
552
|
+
* `Error.cause` — whose consumers expect a wrapped error, not a string — is left alone.
|
|
553
|
+
*/
|
|
554
|
+
public readonly conflictCause: TwinPermissionsConflictCause;
|
|
555
|
+
/** The entry as the server holds it, including the etag to retry with. */
|
|
556
|
+
public readonly currentState?: AssetPrincipalPermissionsGet;
|
|
557
|
+
public readonly errorBody: AssetPermissionsConflictErrorBody;
|
|
558
|
+
|
|
559
|
+
constructor(message: string, errorBody: AssetPermissionsConflictErrorBody) {
|
|
560
|
+
super(message);
|
|
561
|
+
this.name = 'AssetPermissionsConflictError';
|
|
562
|
+
this.conflictCause = errorBody.cause;
|
|
563
|
+
this.currentState = errorBody.currentState;
|
|
564
|
+
this.errorBody = errorBody;
|
|
565
|
+
}
|
|
566
|
+
}
|
package/src/types/generated.ts
CHANGED
|
@@ -153,10 +153,6 @@ export interface TwinSpecification {
|
|
|
153
153
|
* Spaces that are not part of any facility
|
|
154
154
|
*/
|
|
155
155
|
aggregatedSpaces?: string[];
|
|
156
|
-
/**
|
|
157
|
-
* Ids of Twins that are part of this Twin
|
|
158
|
-
*/
|
|
159
|
-
aggregatedTwins?: string[];
|
|
160
156
|
elementQuantities?: ElementQuantities[];
|
|
161
157
|
/**
|
|
162
158
|
* Collection of entities that are part of the twin
|
|
@@ -170,17 +166,15 @@ export interface TwinSpecification {
|
|
|
170
166
|
* Unique identifier for the twin
|
|
171
167
|
*/
|
|
172
168
|
id?: string;
|
|
169
|
+
propertySets?: PropertySet[];
|
|
173
170
|
/**
|
|
174
|
-
* Twin
|
|
175
|
-
|
|
176
|
-
location?: Location;
|
|
177
|
-
/**
|
|
178
|
-
* Name of the Twin
|
|
171
|
+
* Id of the entity that is the root (top) node of the Twin's entity tree. Must reference a
|
|
172
|
+
* site or facility present in the EntityCollection.
|
|
179
173
|
*/
|
|
180
|
-
|
|
181
|
-
propertySets?: PropertySet[];
|
|
174
|
+
rootEntity: string;
|
|
182
175
|
/**
|
|
183
|
-
* The site of the Twin
|
|
176
|
+
* Legacy. The site of the Twin. Deprecated: use rootEntity, which is authoritative for the
|
|
177
|
+
* root of the Twin's entity tree.
|
|
184
178
|
*/
|
|
185
179
|
site?: string;
|
|
186
180
|
}
|
|
@@ -228,6 +222,11 @@ export interface EntityCollection {
|
|
|
228
222
|
* Facility part entities in the Twin
|
|
229
223
|
*/
|
|
230
224
|
facilityParts?: { [key: string]: FacilityPart };
|
|
225
|
+
/**
|
|
226
|
+
* Representation relations declaring that a twin entity is represented by an entity in a
|
|
227
|
+
* model file, keyed by relation id
|
|
228
|
+
*/
|
|
229
|
+
representations?: { [key: string]: EntityRepresentation };
|
|
231
230
|
/**
|
|
232
231
|
* Site entities in the Twin
|
|
233
232
|
*/
|
|
@@ -236,6 +235,10 @@ export interface EntityCollection {
|
|
|
236
235
|
* Space entities in the Twin
|
|
237
236
|
*/
|
|
238
237
|
spaces?: { [key: string]: Space };
|
|
238
|
+
/**
|
|
239
|
+
* Twin reference entities in the Twin
|
|
240
|
+
*/
|
|
241
|
+
twinReferences?: { [key: string]: TwinReference };
|
|
239
242
|
[property: string]: any;
|
|
240
243
|
}
|
|
241
244
|
|
|
@@ -259,11 +262,18 @@ export interface Facility {
|
|
|
259
262
|
* Type of facility (e.g. IfcBuilding)
|
|
260
263
|
*/
|
|
261
264
|
class: FacilityClass;
|
|
265
|
+
description?: string;
|
|
262
266
|
elementQuantities?: ElementQuantities[];
|
|
263
267
|
/**
|
|
264
268
|
* Unique identifier for the building
|
|
265
269
|
*/
|
|
266
270
|
id: string;
|
|
271
|
+
/**
|
|
272
|
+
* Location of the facility in WGS84. When the facility is the twin's root entity, this is
|
|
273
|
+
* the twin's location.
|
|
274
|
+
*/
|
|
275
|
+
location?: Location;
|
|
276
|
+
longName?: string;
|
|
267
277
|
name?: string;
|
|
268
278
|
propertySets?: PropertySet[];
|
|
269
279
|
}
|
|
@@ -275,6 +285,31 @@ export interface Facility {
|
|
|
275
285
|
*/
|
|
276
286
|
export type FacilityClass = 'IfcBridge' | 'IfcBuilding' | 'IfcMarineFacility' | 'IfcRailway' | 'IfcRoad';
|
|
277
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Location of the facility in WGS84. When the facility is the twin's root entity, this is
|
|
290
|
+
* the twin's location.
|
|
291
|
+
*
|
|
292
|
+
* A location in WGS84
|
|
293
|
+
*
|
|
294
|
+
* Location of the site in WGS84. When the site is the twin's root entity, this is the
|
|
295
|
+
* twin's location.
|
|
296
|
+
*/
|
|
297
|
+
export interface Location {
|
|
298
|
+
/**
|
|
299
|
+
* Metres above sea level
|
|
300
|
+
*/
|
|
301
|
+
elevation?: number;
|
|
302
|
+
epsg: EpsgType;
|
|
303
|
+
latitude: number;
|
|
304
|
+
longitude: number;
|
|
305
|
+
/**
|
|
306
|
+
* Vector pointing to the true north
|
|
307
|
+
*/
|
|
308
|
+
trueNorth?: number[];
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export type EpsgType = '4326';
|
|
312
|
+
|
|
278
313
|
export interface PropertySet {
|
|
279
314
|
name: string;
|
|
280
315
|
/**
|
|
@@ -431,11 +466,13 @@ export interface FacilityPart {
|
|
|
431
466
|
* Type of facility part (e.g. IfcBuildingStorey)
|
|
432
467
|
*/
|
|
433
468
|
class: FacilityPartClass;
|
|
469
|
+
description?: string;
|
|
434
470
|
elementQuantities?: ElementQuantities[];
|
|
435
471
|
/**
|
|
436
472
|
* Unique identifier for the facility part
|
|
437
473
|
*/
|
|
438
474
|
id: string;
|
|
475
|
+
longName?: string;
|
|
439
476
|
name?: string;
|
|
440
477
|
propertySets?: PropertySet[];
|
|
441
478
|
}
|
|
@@ -452,6 +489,26 @@ export type FacilityPartClass =
|
|
|
452
489
|
| 'IfcRailwayPart'
|
|
453
490
|
| 'IfcRoadPart';
|
|
454
491
|
|
|
492
|
+
/**
|
|
493
|
+
* An objectified relation declaring that a twin entity is represented by another entity.
|
|
494
|
+
* Modelled as a relation (not an inline attribute) so it stays addressable and extensible,
|
|
495
|
+
* mirroring how twinReferences objectifies twin-to-twin relations.
|
|
496
|
+
*/
|
|
497
|
+
export interface EntityRepresentation {
|
|
498
|
+
/**
|
|
499
|
+
* Reference to the entity that is represented, e.g. twin~twin:{twinId}.entity:{entityId}
|
|
500
|
+
* for an entity in a twin. Must name an entity: the shared grammar also admits a bare
|
|
501
|
+
* domain (a scope, not an entity), which the service refuses here
|
|
502
|
+
*/
|
|
503
|
+
relatingEntity: string;
|
|
504
|
+
/**
|
|
505
|
+
* Reference to the entity that provides this entity's representation, e.g.
|
|
506
|
+
* twin~twin:{twinId}.file:{fileId}/entities/{ifcGid} for an IFC product within one of the
|
|
507
|
+
* twin's model files. Must name an entity, as relatingEntity must
|
|
508
|
+
*/
|
|
509
|
+
representedBy: string;
|
|
510
|
+
}
|
|
511
|
+
|
|
455
512
|
/**
|
|
456
513
|
* A site is a defined area of land, possibly covered with water, upon which constructions
|
|
457
514
|
* are located
|
|
@@ -469,15 +526,26 @@ export interface Site {
|
|
|
469
526
|
* Spaces that are not part of any facility
|
|
470
527
|
*/
|
|
471
528
|
aggregatedSpaces?: string[];
|
|
529
|
+
/**
|
|
530
|
+
* Twin references nested directly under this site
|
|
531
|
+
*/
|
|
532
|
+
aggregatedTwinReferences?: string[];
|
|
472
533
|
/**
|
|
473
534
|
* Type of site (i.e. IfcSite)
|
|
474
535
|
*/
|
|
475
536
|
class?: SiteType;
|
|
537
|
+
description?: string;
|
|
476
538
|
elementQuantities?: ElementQuantities[];
|
|
477
539
|
/**
|
|
478
540
|
* Unique identifier for the site
|
|
479
541
|
*/
|
|
480
542
|
id?: string;
|
|
543
|
+
/**
|
|
544
|
+
* Location of the site in WGS84. When the site is the twin's root entity, this is the
|
|
545
|
+
* twin's location.
|
|
546
|
+
*/
|
|
547
|
+
location?: Location;
|
|
548
|
+
longName?: string;
|
|
481
549
|
/**
|
|
482
550
|
* Name of the site
|
|
483
551
|
*/
|
|
@@ -507,12 +575,15 @@ export interface Space {
|
|
|
507
575
|
* Type of space (e.g. IfcSpace)
|
|
508
576
|
*/
|
|
509
577
|
class: SpaceType;
|
|
578
|
+
description?: string;
|
|
510
579
|
elementQuantities?: ElementQuantities[];
|
|
511
580
|
/**
|
|
512
581
|
* Unique identifier for the space
|
|
513
582
|
*/
|
|
514
583
|
id: string;
|
|
584
|
+
longName?: string;
|
|
515
585
|
name?: string;
|
|
586
|
+
objectType?: string;
|
|
516
587
|
propertySets?: PropertySet[];
|
|
517
588
|
}
|
|
518
589
|
|
|
@@ -521,6 +592,16 @@ export interface Space {
|
|
|
521
592
|
*/
|
|
522
593
|
export type SpaceType = 'IfcSpace';
|
|
523
594
|
|
|
595
|
+
/**
|
|
596
|
+
* A reference to another Twin nested within this Twin's spatial hierarchy
|
|
597
|
+
*/
|
|
598
|
+
export interface TwinReference {
|
|
599
|
+
/**
|
|
600
|
+
* Id of the referenced (nested) Twin
|
|
601
|
+
*/
|
|
602
|
+
twin: string;
|
|
603
|
+
}
|
|
604
|
+
|
|
524
605
|
export interface FilePatchSet {
|
|
525
606
|
/**
|
|
526
607
|
* Ordered list of patch operations to apply
|
|
@@ -551,24 +632,3 @@ export interface FilePatch {
|
|
|
551
632
|
* The patch operation type
|
|
552
633
|
*/
|
|
553
634
|
export type Op = 'replace' | 'remove';
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* Twin location in WGS84
|
|
557
|
-
*
|
|
558
|
-
* A location in WGS84
|
|
559
|
-
*/
|
|
560
|
-
export interface Location {
|
|
561
|
-
/**
|
|
562
|
-
* Metres above sea level
|
|
563
|
-
*/
|
|
564
|
-
elevation?: number;
|
|
565
|
-
epsg: EpsgType;
|
|
566
|
-
latitude: number;
|
|
567
|
-
longitude: number;
|
|
568
|
-
/**
|
|
569
|
-
* Vector pointing to the true north
|
|
570
|
-
*/
|
|
571
|
-
trueNorth?: number[];
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
export type EpsgType = '4326';
|
package/src/types/twin-api.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { PropertySet, ElementQuantities, TwinSpecification, Diagnostics } from './generated';
|
|
1
|
+
import type { PropertySet, ElementQuantities, TwinSpecification, Diagnostics, EpsgType, Location } from './generated';
|
|
2
|
+
import type { TwinBoundCapabilityName } from './twin-permissions-api';
|
|
2
3
|
|
|
3
4
|
export interface TwinFileReference {
|
|
4
5
|
fileId: string;
|
|
@@ -6,6 +7,14 @@ export interface TwinFileReference {
|
|
|
6
7
|
twinNodeId?: string;
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
/** WGS84 coordinates of a twin, as returned on the list endpoint (coordinates only — the full
|
|
11
|
+
* Location, including elevation and trueNorth, is available on the single-twin GET). */
|
|
12
|
+
export interface Coordinates {
|
|
13
|
+
epsg: EpsgType;
|
|
14
|
+
latitude: number;
|
|
15
|
+
longitude: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
export interface ListTwinItem {
|
|
10
19
|
id: string;
|
|
11
20
|
name: string;
|
|
@@ -20,8 +29,32 @@ export interface ListTwinItem {
|
|
|
20
29
|
createdUtc: string;
|
|
21
30
|
modifiedBy: string;
|
|
22
31
|
modifiedUtc: string;
|
|
32
|
+
/** Ids of the Twins nested within this Twin, derived by the service from its twin references. */
|
|
33
|
+
aggregatedTwins: string[];
|
|
34
|
+
/** Deduplicated, sorted set of IFC entity classes the twin contains (e.g. IfcBuilding, IfcSpace),
|
|
35
|
+
* computed by the service from the specification's entity collection. */
|
|
36
|
+
classes: string[];
|
|
37
|
+
/** Id of the Twin that references this Twin (its parent), or omitted for a root Twin. */
|
|
38
|
+
parentTwin?: string;
|
|
39
|
+
/** WGS84 coordinates, present only when the twin's specification declares a location. */
|
|
40
|
+
location?: Coordinates;
|
|
41
|
+
/**
|
|
42
|
+
* What the *calling principal* may do with this twin — the whole affordance decision for the
|
|
43
|
+
* row, so a list of a thousand twins needs no probe per row. Never the twin's access-control
|
|
44
|
+
* list: that is `listTwinPermissions(twinId)`, which is administration-gated.
|
|
45
|
+
*
|
|
46
|
+
* Mixes both capability vocabularies, as the twin-scoped probe does. Where each capability was
|
|
47
|
+
* granted is answered by `listTwinPermissions(twinId)`, whose rows split `permissions` from
|
|
48
|
+
* `inheritedPermissions`. Absent on `listTwinVersions`, which does not resolve it.
|
|
49
|
+
*/
|
|
50
|
+
effectivePermissions?: TwinBoundCapabilityName[];
|
|
23
51
|
}
|
|
24
52
|
|
|
53
|
+
/**
|
|
54
|
+
* A twin as returned by the service — by `getTwin` and `getTwinVersion`, and by the write methods
|
|
55
|
+
* (`createOrUpdateTwin`, `deleteTwin`, `restoreTwin`), which answer with the same shape. Writing a
|
|
56
|
+
* twin and re-rendering it therefore needs no second fetch.
|
|
57
|
+
*/
|
|
25
58
|
export interface TwinGet extends TwinSpecification {
|
|
26
59
|
id: string;
|
|
27
60
|
etag: string;
|
|
@@ -34,6 +67,27 @@ export interface TwinGet extends TwinSpecification {
|
|
|
34
67
|
modifiedUtc: string;
|
|
35
68
|
fileReferences: TwinFileReference[];
|
|
36
69
|
computedPropertySets?: PropertySet[];
|
|
70
|
+
/** Ids of the Twins nested within this Twin, derived by the service from its twin references. */
|
|
71
|
+
aggregatedTwins: string[];
|
|
72
|
+
/** Id of the Twin that references this Twin (its parent), or omitted for a root Twin. */
|
|
73
|
+
parentTwin?: string;
|
|
74
|
+
/** Name of the Twin, derived by the service from the root entity. Read-only; not part of the
|
|
75
|
+
* stored specification. */
|
|
76
|
+
name: string;
|
|
77
|
+
/** Full WGS84 location of the Twin (including elevation and trueNorth), derived by the service
|
|
78
|
+
* from the root entity. Read-only; not part of the stored specification. */
|
|
79
|
+
location?: Location;
|
|
80
|
+
/**
|
|
81
|
+
* Everything the *calling principal* may do with this twin: the capabilities its own scopes
|
|
82
|
+
* confer, unioned with the twin-bound asset ones held customer-wide. Calculated by the service on
|
|
83
|
+
* every read, never stored, and never accepted in a `TwinPut` body.
|
|
84
|
+
*
|
|
85
|
+
* The verdict, without its provenance — a fetched twin says no more than a listing row does.
|
|
86
|
+
* Which capabilities are granted here and which come from elsewhere is answered by
|
|
87
|
+
* `listTwinPermissions(twinId)`, where they are administered. Never the twin's access-control
|
|
88
|
+
* list either: this describes the caller, not every principal.
|
|
89
|
+
*/
|
|
90
|
+
effectivePermissions: TwinBoundCapabilityName[];
|
|
37
91
|
}
|
|
38
92
|
|
|
39
93
|
export interface TwinPut extends TwinSpecification {
|