@twinfinity/twin 0.0.0-feature.31596

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.
Files changed (245) hide show
  1. package/README.md +277 -0
  2. package/dist/BuildInfo.d.ts +25 -0
  3. package/dist/BuildInfo.d.ts.map +1 -0
  4. package/dist/BuildInfo.js +15 -0
  5. package/dist/BuildInfo.js.map +1 -0
  6. package/dist/TwinClient.d.ts +823 -0
  7. package/dist/TwinClient.d.ts.map +1 -0
  8. package/dist/TwinClient.js +1487 -0
  9. package/dist/TwinClient.js.map +1 -0
  10. package/dist/errors.d.ts +289 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +357 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/tsconfig.tsbuildinfo +1 -0
  19. package/dist/types/Twin.d.ts +7 -0
  20. package/dist/types/Twin.d.ts.map +1 -0
  21. package/dist/types/Twin.js +6 -0
  22. package/dist/types/Twin.js.map +1 -0
  23. package/dist/types/TwinGeometryInfo.d.ts +7 -0
  24. package/dist/types/TwinGeometryInfo.d.ts.map +1 -0
  25. package/dist/types/TwinGeometryInfo.js +2 -0
  26. package/dist/types/TwinGeometryInfo.js.map +1 -0
  27. package/dist/types/asset-api.d.ts +66 -0
  28. package/dist/types/asset-api.d.ts.map +1 -0
  29. package/dist/types/asset-api.js +2 -0
  30. package/dist/types/asset-api.js.map +1 -0
  31. package/dist/types/asset-attachment-api.d.ts +51 -0
  32. package/dist/types/asset-attachment-api.d.ts.map +1 -0
  33. package/dist/types/asset-attachment-api.js +8 -0
  34. package/dist/types/asset-attachment-api.js.map +1 -0
  35. package/dist/types/asset-batch-api.d.ts +73 -0
  36. package/dist/types/asset-batch-api.d.ts.map +1 -0
  37. package/dist/types/asset-batch-api.js +2 -0
  38. package/dist/types/asset-batch-api.js.map +1 -0
  39. package/dist/types/asset-types-api.d.ts +76 -0
  40. package/dist/types/asset-types-api.d.ts.map +1 -0
  41. package/dist/types/asset-types-api.js +5 -0
  42. package/dist/types/asset-types-api.js.map +1 -0
  43. package/dist/types/common.d.ts +10 -0
  44. package/dist/types/common.d.ts.map +1 -0
  45. package/dist/types/common.js +2 -0
  46. package/dist/types/common.js.map +1 -0
  47. package/dist/types/generated.d.ts +458 -0
  48. package/dist/types/generated.d.ts.map +1 -0
  49. package/dist/types/generated.js +2 -0
  50. package/dist/types/generated.js.map +1 -0
  51. package/dist/types/index.d.ts +10 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/dist/types/index.js +10 -0
  54. package/dist/types/index.js.map +1 -0
  55. package/dist/types/twin-api.d.ts +141 -0
  56. package/dist/types/twin-api.d.ts.map +1 -0
  57. package/dist/types/twin-api.js +2 -0
  58. package/dist/types/twin-api.js.map +1 -0
  59. package/dist/types/twin-file-api.d.ts +61 -0
  60. package/dist/types/twin-file-api.d.ts.map +1 -0
  61. package/dist/types/twin-file-api.js +2 -0
  62. package/dist/types/twin-file-api.js.map +1 -0
  63. package/dist/types/twin-permissions-api.d.ts +240 -0
  64. package/dist/types/twin-permissions-api.d.ts.map +1 -0
  65. package/dist/types/twin-permissions-api.js +2 -0
  66. package/dist/types/twin-permissions-api.js.map +1 -0
  67. package/docs/.nojekyll +1 -0
  68. package/docs/assets/hierarchy.js +1 -0
  69. package/docs/assets/highlight.css +99 -0
  70. package/docs/assets/icons.js +18 -0
  71. package/docs/assets/icons.svg +1 -0
  72. package/docs/assets/main.js +60 -0
  73. package/docs/assets/navigation.js +1 -0
  74. package/docs/assets/search.js +1 -0
  75. package/docs/assets/style.css +1633 -0
  76. package/docs/classes/AssetAttachmentConflictError.html +3 -0
  77. package/docs/classes/AssetAttachmentNotFoundError.html +2 -0
  78. package/docs/classes/AssetBatchError.html +3 -0
  79. package/docs/classes/AssetCatalogTooLargeError.html +16 -0
  80. package/docs/classes/AssetCategoryConflictError.html +3 -0
  81. package/docs/classes/AssetCategoryForbiddenError.html +2 -0
  82. package/docs/classes/AssetCategoryNotFoundError.html +2 -0
  83. package/docs/classes/AssetCategoryValidationError.html +3 -0
  84. package/docs/classes/AssetConflictError.html +3 -0
  85. package/docs/classes/AssetForbiddenError.html +2 -0
  86. package/docs/classes/AssetNotFoundError.html +2 -0
  87. package/docs/classes/AssetPermissionsConflictError.html +16 -0
  88. package/docs/classes/AssetTypeConflictError.html +3 -0
  89. package/docs/classes/AssetTypeForbiddenError.html +2 -0
  90. package/docs/classes/AssetTypeNotFoundError.html +2 -0
  91. package/docs/classes/AssetTypeValidationError.html +3 -0
  92. package/docs/classes/AssetValidationError.html +3 -0
  93. package/docs/classes/ProcessorNotFoundError.html +2 -0
  94. package/docs/classes/TwinClient.html +409 -0
  95. package/docs/classes/TwinConflictError.html +3 -0
  96. package/docs/classes/TwinFileConflictError.html +3 -0
  97. package/docs/classes/TwinFileNotFoundError.html +2 -0
  98. package/docs/classes/TwinFileValidationError.html +3 -0
  99. package/docs/classes/TwinNotFoundError.html +4 -0
  100. package/docs/classes/TwinPermissionsConflictError.html +19 -0
  101. package/docs/classes/TwinPermissionsForbiddenError.html +12 -0
  102. package/docs/classes/TwinPrincipalNotFoundError.html +5 -0
  103. package/docs/classes/TwinTemporarilyUnavailableError.html +10 -0
  104. package/docs/classes/TwinUnauthenticatedError.html +6 -0
  105. package/docs/classes/TwinValidationError.html +3 -0
  106. package/docs/functions/isAssetCatalogTooLargeErrorBody.html +6 -0
  107. package/docs/functions/readErrorBody.html +10 -0
  108. package/docs/hierarchy.html +1 -0
  109. package/docs/index.html +168 -0
  110. package/docs/interfaces/ApiCreateUploadSessionResponse.html +7 -0
  111. package/docs/interfaces/AssetAttachmentPut.html +6 -0
  112. package/docs/interfaces/AssetBatchDeleteOperation.html +4 -0
  113. package/docs/interfaces/AssetBatchGetRequest.html +2 -0
  114. package/docs/interfaces/AssetBatchGetResponse.html +3 -0
  115. package/docs/interfaces/AssetBatchRequest.html +2 -0
  116. package/docs/interfaces/AssetBatchResponse.html +3 -0
  117. package/docs/interfaces/AssetBatchRestoreOperation.html +4 -0
  118. package/docs/interfaces/AssetBatchUpsertItem.html +12 -0
  119. package/docs/interfaces/AssetBatchUpsertOperation.html +4 -0
  120. package/docs/interfaces/AssetCatalogCategory.html +7 -0
  121. package/docs/interfaces/AssetCatalogResponse.html +6 -0
  122. package/docs/interfaces/AssetCatalogTooLargeErrorBody.html +15 -0
  123. package/docs/interfaces/AssetCategoryDelete.html +2 -0
  124. package/docs/interfaces/AssetCategoryGet.html +14 -0
  125. package/docs/interfaces/AssetCategoryPut.html +7 -0
  126. package/docs/interfaces/AssetGet.html +18 -0
  127. package/docs/interfaces/AssetGroupGet.html +9 -0
  128. package/docs/interfaces/AssetGroupsGet.html +3 -0
  129. package/docs/interfaces/AssetListItem.html +14 -0
  130. package/docs/interfaces/AssetPermissionsConflictErrorBody.html +12 -0
  131. package/docs/interfaces/AssetPermissionsPut.html +9 -0
  132. package/docs/interfaces/AssetPosition.html +4 -0
  133. package/docs/interfaces/AssetPost.html +12 -0
  134. package/docs/interfaces/AssetPrincipalPermissionsGet.html +23 -0
  135. package/docs/interfaces/AssetPut.html +12 -0
  136. package/docs/interfaces/AssetTypeDelete.html +2 -0
  137. package/docs/interfaces/AssetTypeGet.html +16 -0
  138. package/docs/interfaces/AssetTypePut.html +9 -0
  139. package/docs/interfaces/AttachmentGet.html +20 -0
  140. package/docs/interfaces/AttachmentPost.html +4 -0
  141. package/docs/interfaces/BatchItemError.html +4 -0
  142. package/docs/interfaces/BatchItemResult.html +6 -0
  143. package/docs/interfaces/BatchSummary.html +4 -0
  144. package/docs/interfaces/Coordinates.html +6 -0
  145. package/docs/interfaces/Diagnostics.html +4 -0
  146. package/docs/interfaces/DiagnosticsSummary.html +4 -0
  147. package/docs/interfaces/ElementQuantities.html +3 -0
  148. package/docs/interfaces/EntityCollection.html +15 -0
  149. package/docs/interfaces/EntityRepresentation.html +12 -0
  150. package/docs/interfaces/Facility.html +22 -0
  151. package/docs/interfaces/FacilityPart.html +18 -0
  152. package/docs/interfaces/FilePatch.html +7 -0
  153. package/docs/interfaces/FilePatchSet.html +5 -0
  154. package/docs/interfaces/GenericDiagnosticEntry.html +4 -0
  155. package/docs/interfaces/ITwinClient.html +404 -0
  156. package/docs/interfaces/IfcDiagnosticEntry.html +5 -0
  157. package/docs/interfaces/IfcDiagnosticNode.html +6 -0
  158. package/docs/interfaces/IfcDiagnosticNodeData.html +6 -0
  159. package/docs/interfaces/InheritedPermissions.html +8 -0
  160. package/docs/interfaces/ListTwinItem.html +30 -0
  161. package/docs/interfaces/Location.html +13 -0
  162. package/docs/interfaces/MyPermissions.html +7 -0
  163. package/docs/interfaces/MyTwinPermissions.html +5 -0
  164. package/docs/interfaces/PaginatedResponse.html +3 -0
  165. package/docs/interfaces/Pagination.html +4 -0
  166. package/docs/interfaces/Property.html +4 -0
  167. package/docs/interfaces/PropertySet.html +6 -0
  168. package/docs/interfaces/SimpleQuantity.html +6 -0
  169. package/docs/interfaces/SinglePropertyValue.html +5 -0
  170. package/docs/interfaces/Site.html +27 -0
  171. package/docs/interfaces/Space.html +16 -0
  172. package/docs/interfaces/TwinComputedPropertySetsResponse.html +4 -0
  173. package/docs/interfaces/TwinContentResponse.html +6 -0
  174. package/docs/interfaces/TwinDelete.html +2 -0
  175. package/docs/interfaces/TwinDiagnosticEntry.html +5 -0
  176. package/docs/interfaces/TwinDiagnosticNode.html +4 -0
  177. package/docs/interfaces/TwinDiagnosticNodeData.html +9 -0
  178. package/docs/interfaces/TwinDiagnosticsResponse.html +5 -0
  179. package/docs/interfaces/TwinErrorBody.html +4 -0
  180. package/docs/interfaces/TwinFileDelete.html +2 -0
  181. package/docs/interfaces/TwinFileGet.html +15 -0
  182. package/docs/interfaces/TwinFileListOptions.html +6 -0
  183. package/docs/interfaces/TwinFilePut.html +8 -0
  184. package/docs/interfaces/TwinFileReference.html +4 -0
  185. package/docs/interfaces/TwinFileRestore.html +2 -0
  186. package/docs/interfaces/TwinFileSource.html +4 -0
  187. package/docs/interfaces/TwinFileTransform.html +11 -0
  188. package/docs/interfaces/TwinFileVersionListOptions.html +4 -0
  189. package/docs/interfaces/TwinGet.html +48 -0
  190. package/docs/interfaces/TwinGroupGet.html +10 -0
  191. package/docs/interfaces/TwinGroupsGet.html +3 -0
  192. package/docs/interfaces/TwinPermissionsConflictErrorBody.html +8 -0
  193. package/docs/interfaces/TwinPermissionsPut.html +11 -0
  194. package/docs/interfaces/TwinPrincipalPermissionsGet.html +34 -0
  195. package/docs/interfaces/TwinProcessorEvent.html +7 -0
  196. package/docs/interfaces/TwinProcessorResponse.html +5 -0
  197. package/docs/interfaces/TwinPut.html +21 -0
  198. package/docs/interfaces/TwinReference.html +4 -0
  199. package/docs/interfaces/TwinSpecification.html +18 -0
  200. package/docs/interfaces/TwinVersionContentResponse.html +7 -0
  201. package/docs/interfaces/UploadStatusGet.html +3 -0
  202. package/docs/media/twin-management.md +399 -0
  203. package/docs/modules.html +1 -0
  204. package/docs/types/AssetBatchGetStatus.html +1 -0
  205. package/docs/types/AssetBatchOperation.html +1 -0
  206. package/docs/types/AssetBatchOperationStatus.html +1 -0
  207. package/docs/types/DiagnosticCategory.html +2 -0
  208. package/docs/types/DiagnosticLevel.html +2 -0
  209. package/docs/types/EpsgType.html +1 -0
  210. package/docs/types/FacilityClass.html +3 -0
  211. package/docs/types/FacilityPartClass.html +3 -0
  212. package/docs/types/IfcDiagnosticCode.html +1 -0
  213. package/docs/types/Op.html +2 -0
  214. package/docs/types/SinglePropertyValueType.html +3 -0
  215. package/docs/types/SingleQuantityValueType.html +3 -0
  216. package/docs/types/SiteType.html +3 -0
  217. package/docs/types/SpaceType.html +2 -0
  218. package/docs/types/TwinBoundCapabilityName.html +8 -0
  219. package/docs/types/TwinCapability.html +12 -0
  220. package/docs/types/TwinCapabilityName.html +8 -0
  221. package/docs/types/TwinDiagnosticCode.html +1 -0
  222. package/docs/types/TwinErrorCause.html +8 -0
  223. package/docs/types/TwinErrorItemKind.html +4 -0
  224. package/docs/types/TwinPermissionsConflictCause.html +6 -0
  225. package/docs/types/TwinScopedCapability.html +9 -0
  226. package/docs/types/TwinScopedCapabilityName.html +8 -0
  227. package/docs/types/UploadStatus.html +1 -0
  228. package/package.json +52 -0
  229. package/src/BuildInfo.ts +41 -0
  230. package/src/TwinClient.ts +3113 -0
  231. package/src/errors.ts +567 -0
  232. package/src/index.ts +3 -0
  233. package/src/tsconfig.json +13 -0
  234. package/src/types/Twin.ts +7 -0
  235. package/src/types/TwinGeometryInfo.ts +7 -0
  236. package/src/types/asset-api.ts +69 -0
  237. package/src/types/asset-attachment-api.ts +56 -0
  238. package/src/types/asset-batch-api.ts +90 -0
  239. package/src/types/asset-types-api.ts +86 -0
  240. package/src/types/common.ts +10 -0
  241. package/src/types/generated.ts +655 -0
  242. package/src/types/index.ts +9 -0
  243. package/src/types/twin-api.ts +153 -0
  244. package/src/types/twin-file-api.ts +67 -0
  245. package/src/types/twin-permissions-api.ts +257 -0
@@ -0,0 +1,823 @@
1
+ import { TwinfinityHttpClient } from '@twinfinity/authentication';
2
+ import { T8ClientEntityTypeDTO, T8ClientModelDTO, T8ClientProductConnectionsDTO, T8ClientProductDTO, T8ClientProjectConnectionsDTO, T8ClientProjectDTO, T8ClientUnitDTO, T8EntityType, T8GIMeshDescriptor, T8GIMeshDescriptorDTO, T8GIStyle, T8GIStyleDTO, T8GIRegion, T8GIRegionDTO, T8Product, T8ProductWithGeometry, T8Project, T8Unit } from '@twinfinity/t8-client-model';
3
+ import type { T8ProjectWithGeometry } from '@twinfinity/t8-client-model';
4
+ import type { PaginatedResponse, ListTwinItem, TwinGet, TwinPut, TwinVersionContentResponse, TwinProcessorEvent, TwinDiagnosticsResponse, AssetListItem, AssetGet, AssetPost, AssetPut, AssetBatchOperation, AssetBatchResponse, AssetBatchGetResponse, TwinFileGet, TwinFilePut, TwinFileDelete, TwinFileListOptions, TwinFileVersionListOptions, TwinContentResponse } from './types';
5
+ import type { AssetCategoryGet, AssetCategoryPut, AssetCatalogResponse, AssetTypeGet, AssetTypePut } from './types/asset-types-api';
6
+ import type { AttachmentGet, AttachmentPost, AssetAttachmentPut, ApiCreateUploadSessionResponse, UploadStatusGet } from './types/asset-attachment-api';
7
+ import type { MyPermissions, MyTwinPermissions, TwinGroupGet, TwinGroupsGet, TwinPermissionsPut, TwinPrincipalPermissionsGet, AssetGroupGet, AssetGroupsGet, AssetPermissionsPut, AssetPrincipalPermissionsGet } from './types/twin-permissions-api';
8
+ import { Twin } from './types/Twin';
9
+ import { TwinGeometryInfo } from './types/TwinGeometryInfo';
10
+ export interface ITwinClient {
11
+ /**
12
+ * Rooted twins base URL — typically `<host>/sites/<container>/_ps/twins`.
13
+ * Use this when constructing related URLs (e.g. twin content) that need
14
+ * to live in the same auth scope as the metadata calls.
15
+ */
16
+ readonly baseUrl: string;
17
+ /**
18
+ * @param options - `relatedTo` filters by container ID; `includeDeleted` includes soft-deleted twins
19
+ * (returned redacted, default false); `page`/`limit` control pagination.
20
+ * @throws {TwinValidationError} On invalid query parameters (400).
21
+ */
22
+ listTwins(options?: {
23
+ relatedTo?: string;
24
+ includeDeleted?: boolean;
25
+ page?: string;
26
+ limit?: number;
27
+ }, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
28
+ /**
29
+ * @deprecated Use the options-object form: `listTwins({ relatedTo, page, limit }, signal)`.
30
+ * The positional form has no `includeDeleted` parameter; that is only reachable via the options object.
31
+ */
32
+ listTwins(relatedTo?: string, page?: string, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
33
+ /**
34
+ * Fetches all twins by auto-paginating through {@link listTwins}. Caps at 1000 pages.
35
+ * @param options - `relatedTo` filters by container ID; `includeDeleted` includes soft-deleted twins
36
+ * (returned redacted, default false).
37
+ */
38
+ listAllTwins(options?: {
39
+ relatedTo?: string;
40
+ includeDeleted?: boolean;
41
+ }, signal?: AbortSignal): Promise<ListTwinItem[]>;
42
+ /**
43
+ * @deprecated Use the options-object form: `listAllTwins({ relatedTo }, signal)`.
44
+ * The positional form has no `includeDeleted` parameter; that is only reachable via the options object.
45
+ */
46
+ listAllTwins(relatedTo?: string, signal?: AbortSignal): Promise<ListTwinItem[]>;
47
+ /**
48
+ * @param twin - Twin ID string, or `{id, version}` to fetch a specific version.
49
+ * @throws {TwinNotFoundError} When the twin or version does not exist (404).
50
+ */
51
+ getTwin(twin: string | {
52
+ id: string;
53
+ version: number;
54
+ }, signal?: AbortSignal): Promise<TwinGet>;
55
+ /**
56
+ * @throws {TwinValidationError} On invalid query parameters (400).
57
+ */
58
+ listTwinVersions(id: string, options?: {
59
+ includeDeleted?: boolean;
60
+ page?: string;
61
+ limit?: number;
62
+ }, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
63
+ downloadTwinContent(twinId: string, twinVersion: number, content: TwinContentResponse, signal?: AbortSignal): Promise<ArrayBuffer>;
64
+ /**
65
+ * Downloads and deserializes the T8 client model (t8cm + t8cm-ext) using default types.
66
+ * When no version is specified, searches versions newest-first for one containing t8cm content.
67
+ *
68
+ * @param twin - Twin ID string, or `{id, version}` to load a specific version.
69
+ * @throws {Error} When no version has t8cm content.
70
+ */
71
+ loadTwin(twin: string | {
72
+ id: string;
73
+ version: number;
74
+ }, signal?: AbortSignal): Promise<Twin<T8Project, T8Product<T8EntityType>, T8EntityType, T8Unit>>;
75
+ /**
76
+ * Downloads and deserializes the T8 client model using custom factory functions for domain-specific types.
77
+ * When no version is specified, searches versions newest-first for one containing t8cm content.
78
+ *
79
+ * @param twin - Twin ID string, or `{id, version}` to load a specific version.
80
+ * @throws {Error} When no version has t8cm content.
81
+ */
82
+ loadTwinWithFactories<TProject, TProduct, TEntityType, TUnit>(twin: string | {
83
+ id: string;
84
+ version: number;
85
+ }, projectFactory: (dto: T8ClientProjectDTO<TUnit>) => TProject, productFactory: (dto: T8ClientProductDTO<TUnit>) => TProduct, entityTypeFactory: (dto: T8ClientEntityTypeDTO<TUnit>) => TEntityType, unitFactory: (dto: T8ClientUnitDTO, dataModel: T8ClientModelDTO) => TUnit, connectProject: (dto: T8ClientProjectConnectionsDTO<TProduct>, project: TProject) => void, connectProduct: (dto: T8ClientProductConnectionsDTO<TProduct, TEntityType>, product: TProduct) => void, signal?: AbortSignal): Promise<Twin<TProject, TProduct, TEntityType, TUnit>>;
86
+ /**
87
+ * Downloads and deserializes geometry info (t8gi) using default types.
88
+ * When no version is specified, searches versions newest-first for one containing t8gi content.
89
+ *
90
+ * @param twin - Twin ID string, or `{id, version}` to load a specific version.
91
+ * @throws {Error} When no version has t8gi content.
92
+ */
93
+ loadGeometryInfo(twin: string | {
94
+ id: string;
95
+ version: number;
96
+ }, signal?: AbortSignal): Promise<TwinGeometryInfo<T8GIMeshDescriptor, T8GIStyle, T8GIRegion>>;
97
+ /**
98
+ * Downloads and deserializes geometry info (t8gi) using custom factory functions.
99
+ * When no version is specified, searches versions newest-first for one containing t8gi content.
100
+ *
101
+ * @param twin - Twin ID string, or `{id, version}` to load a specific version.
102
+ * @throws {Error} When no version has t8gi content.
103
+ */
104
+ loadGeometryInfoWithFactories<TMeshDescriptor, TStyle, TRegion>(twin: string | {
105
+ id: string;
106
+ version: number;
107
+ }, meshDescriptorFactory: (dto: T8GIMeshDescriptorDTO) => TMeshDescriptor, styleFactory: (dto: T8GIStyleDTO) => TStyle, regionFactory: (dto: T8GIRegionDTO) => TRegion, signal?: AbortSignal): Promise<TwinGeometryInfo<TMeshDescriptor, TStyle, TRegion>>;
108
+ /**
109
+ * Downloads and deserializes both the client model (t8cm) and geometry (t8gi/t8gd) into a combined result.
110
+ * When no version is specified, searches versions newest-first for one containing both t8cm and t8gi content.
111
+ *
112
+ * @param twin - Twin ID string, or `{id, version}` to load a specific version.
113
+ * @throws {Error} When no version has both t8cm and t8gi content.
114
+ */
115
+ loadTwinWithGeometry(twin: string | {
116
+ id: string;
117
+ version: number;
118
+ }, signal?: AbortSignal): Promise<Twin<T8ProjectWithGeometry, T8ProductWithGeometry, T8EntityType, T8Unit>>;
119
+ /**
120
+ * Creates a new twin or updates an existing one (upsert). Provide `etag` in the twin body to update.
121
+ *
122
+ * @throws {TwinValidationError} On invalid request body (400).
123
+ * @throws {TwinConflictError} On etag mismatch (409). The error's `currentTwin` contains the server's current state.
124
+ */
125
+ createOrUpdateTwin(twinId: string, twin: TwinPut, signal?: AbortSignal): Promise<TwinGet>;
126
+ /** Alias for {@link createOrUpdateTwin}. */
127
+ updateTwin(twinId: string, twin: TwinPut, signal?: AbortSignal): Promise<TwinGet>;
128
+ /**
129
+ * @throws {TwinNotFoundError} When the twin does not exist (404).
130
+ * @throws {TwinConflictError} On etag mismatch (409). The error's `currentTwin` contains the server's current state.
131
+ */
132
+ restoreTwin(twinId: string, etag: string, signal?: AbortSignal): Promise<TwinGet>;
133
+ /**
134
+ * @throws {TwinNotFoundError} When the twin or version does not exist (404).
135
+ */
136
+ getTwinVersionContent(twinId: string, twinVersion: number, signal?: AbortSignal): Promise<TwinVersionContentResponse>;
137
+ /**
138
+ * Returns content for the latest twin version.
139
+ * @throws {TwinNotFoundError} When the twin does not exist (404).
140
+ */
141
+ getTwinContent(twinId: string, signal?: AbortSignal): Promise<TwinVersionContentResponse>;
142
+ /** @throws {TwinNotFoundError} When the twin does not exist (404). */
143
+ getTwinDiagnostics(twinId: string, signal?: AbortSignal): Promise<TwinDiagnosticsResponse>;
144
+ /** @throws {TwinNotFoundError} When the twin or version does not exist (404). */
145
+ getTwinVersionDiagnostics(twinId: string, twinVersion: number, signal?: AbortSignal): Promise<TwinDiagnosticsResponse>;
146
+ /**
147
+ * @throws {TwinValidationError} On invalid query parameters (400).
148
+ * @throws {TwinNotFoundError} When the twin or version does not exist (404).
149
+ */
150
+ getTwinVersionEvents(twinId: string, twinVersion: number, offset?: number, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<TwinProcessorEvent>>;
151
+ /**
152
+ * @throws {TwinValidationError} On invalid query parameters (400).
153
+ * @throws {ProcessorNotFoundError} When the processor does not exist for this twin version (404).
154
+ */
155
+ getProcessorEvents(twinId: string, twinVersion: number, processorId: string, offset?: number, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<TwinProcessorEvent>>;
156
+ /**
157
+ * @throws {AssetValidationError} On invalid query parameters (400).
158
+ * @throws {AssetNotFoundError} When the twin does not exist (404).
159
+ */
160
+ listAssets(twinId: string, offset?: number, limit?: number, options?: {
161
+ includeDeleted?: boolean;
162
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetListItem>>;
163
+ /** @throws {AssetNotFoundError} When the asset does not exist (404). */
164
+ getAsset(twinId: string, assetId: string, signal?: AbortSignal): Promise<AssetGet>;
165
+ /** @throws {AssetValidationError} On invalid request body (400). The error's `errorBody` has structured detail. */
166
+ createAssets(twinId: string, assets: AssetPost[], signal?: AbortSignal): Promise<AssetGet[]>;
167
+ /**
168
+ * @throws {AssetValidationError} On invalid request body (400). The error's `errorBody` has structured detail.
169
+ * @throws {AssetConflictError} On etag mismatch (409). The error's `currentAsset` contains the server's current state.
170
+ */
171
+ updateAsset(twinId: string, assetId: string, asset: AssetPut, signal?: AbortSignal): Promise<AssetGet>;
172
+ /**
173
+ * @throws {AssetNotFoundError} When the asset does not exist (404).
174
+ * @throws {AssetConflictError} On etag mismatch (409). The error's `currentAsset` contains the server's current state.
175
+ */
176
+ deleteAsset(twinId: string, assetId: string, etag: string, signal?: AbortSignal): Promise<AssetGet>;
177
+ /**
178
+ * @throws {AssetNotFoundError} When the asset does not exist (404).
179
+ * @throws {AssetConflictError} On etag mismatch (409). The error's `currentAsset` contains the server's current state.
180
+ */
181
+ restoreAsset(twinId: string, assetId: string, etag: string, signal?: AbortSignal): Promise<AssetGet>;
182
+ /**
183
+ * Executes a batch of asset operations (upsert, delete, restore) atomically.
184
+ * All operations succeed or all are rolled back.
185
+ *
186
+ * @param operations - Array of batch operations (max 1000).
187
+ * @throws {AssetBatchError} When the batch rolled back. The error's `response` has per-item
188
+ * results with reverted statuses, and is thrown for any status the failing item carried --
189
+ * 400, 404 or 409.
190
+ * @throws {AssetValidationError} When the whole request was rejected before any item ran (400):
191
+ * an empty batch, duplicate ids, a body/URL twin mismatch, oversized metadata.
192
+ * @throws {AssetForbiddenError} On insufficient permissions (403).
193
+ */
194
+ batchAssets(twinId: string, operations: AssetBatchOperation[], signal?: AbortSignal): Promise<AssetBatchResponse>;
195
+ /**
196
+ * Retrieves multiple assets by ID in a single request.
197
+ *
198
+ * @param ids - Array of asset IDs (max 1000).
199
+ * @throws {AssetValidationError} On validation failure (400).
200
+ */
201
+ batchGetAssets(twinId: string, ids: string[], signal?: AbortSignal): Promise<AssetBatchGetResponse>;
202
+ /** Lists attachments for a single asset. */
203
+ listAssetAttachments(twinId: string, assetId: string, options?: {
204
+ includeDeleted?: boolean;
205
+ offset?: number;
206
+ limit?: number;
207
+ page?: string;
208
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AttachmentGet>>;
209
+ /**
210
+ * Downloads an attachment's blob as a `Response`. The caller decides
211
+ * whether to consume it as text, ArrayBuffer, or Blob.
212
+ * @throws {AssetAttachmentNotFoundError} When the attachment does not exist (404).
213
+ */
214
+ getAssetAttachmentBlob(twinId: string, assetId: string, attachmentId: string, signal?: AbortSignal): Promise<Response>;
215
+ /**
216
+ * Creates an upload session for a new attachment. The actual file bytes
217
+ * are uploaded out-of-band to {@link ApiCreateUploadSessionResponse.uploadUrl};
218
+ * use {@link uploadAssetAttachmentFile} for the canonical chunked-upload flow.
219
+ * The attachment row is materialized server-side when the blob lands.
220
+ * @throws {AssetAttachmentConflictError} When an attachment already exists
221
+ * for the given id (409); retries must use a new attachmentId.
222
+ */
223
+ createAssetAttachmentUploadSession(twinId: string, assetId: string, attachmentId: string, body: AttachmentPost, signal?: AbortSignal): Promise<ApiCreateUploadSessionResponse>;
224
+ /**
225
+ * Uploads a `File` / `Blob` to an existing upload session in one or more
226
+ * chunks, then resolves the upload token so the caller can poll
227
+ * {@link getAssetAttachmentUploadStatus}.
228
+ */
229
+ uploadAssetAttachmentFile(session: ApiCreateUploadSessionResponse, file: Blob, signal?: AbortSignal): Promise<{
230
+ token: string;
231
+ }>;
232
+ /** Polls the in-memory upload-session cache for an attachment that's being uploaded. */
233
+ getAssetAttachmentUploadStatus(twinId: string, assetId: string, token: string, signal?: AbortSignal): Promise<UploadStatusGet>;
234
+ /**
235
+ * Updates an attachment's description / soft-delete flag. `documentId`
236
+ * is immutable — rebinding is rejected.
237
+ * @throws {AssetAttachmentConflictError} On etag mismatch (409). The
238
+ * error's `currentAttachment` carries the server's current state.
239
+ * @throws {AssetAttachmentNotFoundError} When the attachment does not exist (404).
240
+ */
241
+ putAssetAttachment(twinId: string, assetId: string, attachmentId: string, body: AssetAttachmentPut, signal?: AbortSignal): Promise<AttachmentGet>;
242
+ /**
243
+ * Soft-deletes an attachment.
244
+ * @throws {AssetAttachmentConflictError} On etag mismatch (409).
245
+ * @throws {AssetAttachmentNotFoundError} When the attachment does not exist (404).
246
+ */
247
+ deleteAssetAttachment(twinId: string, assetId: string, attachmentId: string, etag: string, signal?: AbortSignal): Promise<AttachmentGet>;
248
+ /**
249
+ * Restores a soft-deleted attachment.
250
+ * @throws {AssetAttachmentConflictError} On etag mismatch (409).
251
+ * @throws {AssetAttachmentNotFoundError} When the attachment does not exist (404).
252
+ */
253
+ restoreAssetAttachment(twinId: string, assetId: string, attachmentId: string, etag: string, signal?: AbortSignal): Promise<AttachmentGet>;
254
+ /**
255
+ * @throws {TwinNotFoundError} When the twin does not exist (404).
256
+ * @throws {TwinConflictError} On etag mismatch (409). The error's `currentTwin` contains the server's current state.
257
+ */
258
+ deleteTwin(twinId: string, etag: string, signal?: AbortSignal): Promise<TwinGet>;
259
+ /** @throws {TwinFileValidationError} On invalid query parameters (400). */
260
+ listTwinFiles(twinId: string, options?: TwinFileListOptions, signal?: AbortSignal): Promise<PaginatedResponse<TwinFileGet>>;
261
+ /**
262
+ * @throws {TwinFileNotFoundError} When the file does not exist (404).
263
+ * @throws {TwinFileValidationError} On invalid request (400).
264
+ */
265
+ getTwinFile(twinId: string, fileId: string, signal?: AbortSignal): Promise<TwinFileGet>;
266
+ /**
267
+ * @throws {TwinFileValidationError} On invalid request body (400).
268
+ * @throws {TwinFileConflictError} On etag mismatch (409). The error's `currentTwinFile` contains the server's current state.
269
+ */
270
+ createOrUpdateTwinFile(twinId: string, fileId: string, twinFile: TwinFilePut, signal?: AbortSignal): Promise<TwinFileGet>;
271
+ /**
272
+ * @throws {TwinFileNotFoundError} When the file does not exist (404).
273
+ * @throws {TwinFileConflictError} On etag mismatch (409). The error's `currentTwinFile` contains the server's current state.
274
+ * @throws {TwinFileValidationError} On invalid request (400).
275
+ */
276
+ deleteTwinFile(twinId: string, fileId: string, deleteRequest: TwinFileDelete, signal?: AbortSignal): Promise<TwinFileGet>;
277
+ /**
278
+ * @throws {TwinFileNotFoundError} When the file does not exist (404).
279
+ * @throws {TwinFileConflictError} On etag mismatch (409). The error's `currentTwinFile` contains the server's current state.
280
+ * @throws {TwinFileValidationError} On invalid request (400).
281
+ */
282
+ restoreTwinFile(twinId: string, fileId: string, etag: string, signal?: AbortSignal): Promise<TwinFileGet>;
283
+ /** @throws {TwinFileNotFoundError} When the file does not exist (404). */
284
+ getTwinFileContent(twinId: string, fileId: string, signal?: AbortSignal): Promise<Blob>;
285
+ /** @throws {TwinFileNotFoundError} When the file or version does not exist (404). */
286
+ getTwinFileVersion(twinId: string, fileId: string, version: number, signal?: AbortSignal): Promise<TwinFileGet>;
287
+ /** @throws {TwinFileValidationError} On invalid query parameters (400). */
288
+ listTwinFileVersions(twinId: string, fileId: string, options?: TwinFileVersionListOptions, signal?: AbortSignal): Promise<PaginatedResponse<TwinFileGet>>;
289
+ /** @throws {TwinFileNotFoundError} When the file or version does not exist (404). */
290
+ getTwinFileVersionContent(twinId: string, fileId: string, version: number, signal?: AbortSignal): Promise<Blob>;
291
+ /**
292
+ * Returns the caller's named, customer-scoped capabilities against the
293
+ * Twin service — the asset-domain vocabulary `ViewAssets`, `EditAssets`,
294
+ * `DeleteAssets`, `EditAssetTypes` and `ManageAssetPermissions`.
295
+ * The admin app uses this to enable or disable
296
+ * buttons instead of letting the user click through to a 403.
297
+ *
298
+ * No client-side cache — every call hits the wire. Underlying scope
299
+ * grants don't shift within a session, so callers are expected to
300
+ * memoise the result themselves (e.g. via React Query / a once-on-mount
301
+ * fetch) rather than calling this on every render.
302
+ *
303
+ * Throws {@link TwinUnauthenticatedError} on 401 (no valid auth context;
304
+ * caller should redirect to login). Returns an empty `permissions` array
305
+ * on 403 (authenticated but no Twin-service capabilities). Unknown
306
+ * capability strings should be ignored — adding a new capability is a
307
+ * non-breaking change.
308
+ *
309
+ * A 503 throws rather than answering with an empty array: the Permission
310
+ * service gave no answer, so the capabilities are unknown rather than
311
+ * absent, and the call is safe to retry unchanged.
312
+ */
313
+ getMyPermissions(signal?: AbortSignal): Promise<MyPermissions>;
314
+ /**
315
+ * Returns the capabilities the caller holds on one specific twin. Open to every
316
+ * authenticated caller — an empty list is an honest answer rather than a refusal —
317
+ * so a UI can gate its controls on this before it knows anything about the caller.
318
+ *
319
+ * The answer mixes vocabularies: the twin's own `TwinScopedCapability` values, plus the
320
+ * asset-instance capabilities `ViewAssets`, `EditAssets` and `DeleteAssets`, which gate the
321
+ * assets hanging off this twin. The catalog capabilities and `ManageAssetPermissions` are not
322
+ * twin-bound and are absent here.
323
+ *
324
+ * Distinct from {@link getMyPermissions}, which answers the customer-scoped question over the
325
+ * whole asset domain. That one returns an empty list on 403; this route has no capability gate
326
+ * to refuse at, so a 403 here means something outside the Twin service refused, and is thrown.
327
+ *
328
+ * @throws {TwinNotFoundError} The twin does not exist, or the caller cannot see it — the
329
+ * surface does not distinguish the two.
330
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
331
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
332
+ * safe to retry unchanged.
333
+ */
334
+ getMyTwinPermissions(twinId: string, signal?: AbortSignal): Promise<MyTwinPermissions>;
335
+ /**
336
+ * Lists one page of the permission entries on every scope the twin owns. Each entry carries
337
+ * the etag of the scope it lives on, which is the value to send back when mutating that
338
+ * principal.
339
+ *
340
+ * `pagination.nextPage` is emitted unconditionally — it is non-null on the last page too — so
341
+ * it is not a termination signal. Page until a response comes back with fewer entries than the
342
+ * limit asked for, or use {@link listAllTwinPermissions}, which does that. On an access-review
343
+ * surface, stopping early under-reports who holds capabilities on the twin.
344
+ *
345
+ * @throws {TwinPermissionsForbiddenError} The caller may see the twin but does not hold
346
+ * `ManageTwinPermissions` on it (403).
347
+ * @throws {TwinNotFoundError} The twin does not exist or the caller cannot see it (404).
348
+ * @throws {TwinValidationError} The limit is out of range, or the pagination token is invalid
349
+ * or does not match the query it was issued for (400).
350
+ * @throws {TwinPermissionsConflictError} `ScopesNotProvisioned` — the twin owns no Twinfinity
351
+ * scope, so there is no permission state to read (409). Retrying will not help.
352
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
353
+ * safe to retry unchanged.
354
+ */
355
+ listTwinPermissions(twinId: string, options?: {
356
+ page?: string;
357
+ limit?: number;
358
+ }, signal?: AbortSignal): Promise<PaginatedResponse<TwinPrincipalPermissionsGet>>;
359
+ /**
360
+ * Every permission entry on the twin, following the pagination to the end. The whole
361
+ * access-control list of one twin is a handful of entries, and reviewing it is the point of
362
+ * the surface, so this — rather than {@link listTwinPermissions} — is what most callers want.
363
+ *
364
+ * Throws whatever {@link listTwinPermissions} throws, from whichever page hit it.
365
+ */
366
+ listAllTwinPermissions(twinId: string, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet[]>;
367
+ /**
368
+ * Replaces the principal's capabilities on the twin, and returns the entry as stored
369
+ * along with the etag to chain the next write on. `permissions: []` revokes all four
370
+ * capabilities without removing an entry that carries bits outside this vocabulary.
371
+ *
372
+ * `body.etag` may be omitted only for a principal that holds nothing on the twin yet;
373
+ * see {@link TwinPermissionsPut}. Both etag refusals arrive as
374
+ * {@link TwinPermissionsConflictError}, carrying the current state to retry from.
375
+ *
376
+ * @throws {TwinValidationError} The target is immutable through this surface — the twin's own
377
+ * default groups and the seeded system principals, marked by
378
+ * {@link TwinPrincipalPermissionsGet.readOnly} (cause `SystemPrincipalImmutable`) — or the
379
+ * write asked for `ManageTwinPermissions` on the all-authenticated principal (cause
380
+ * `ManagePermissionsNotGrantableToAllAuthenticated`), which would make the whole tenant an
381
+ * administrator of the twin (400).
382
+ * @throws {TwinPrincipalNotFoundError} No principal carries this id (404).
383
+ * @throws {TwinNotFoundError} The twin does not exist or the caller cannot see it (404).
384
+ * @throws {TwinPermissionsForbiddenError} `ManageTwinPermissions` is required (403).
385
+ * @throws {TwinPermissionsConflictError} `EtagRequired`, `EtagMismatch` or
386
+ * `ScopesNotProvisioned` (409); the first two carry `currentState`.
387
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
388
+ * safe to retry unchanged.
389
+ */
390
+ setTwinPermissions(twinId: string, principalId: string, body: TwinPermissionsPut, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet>;
391
+ /**
392
+ * Removes the principal from the twin's access control list entirely — including any
393
+ * bits outside this capability vocabulary, which is what separates it from a
394
+ * {@link setTwinPermissions} call with an empty list.
395
+ *
396
+ * The etag is always required: a delete always replaces existing grants.
397
+ *
398
+ * @throws {TwinPrincipalNotFoundError} The principal holds nothing on the twin, so there is
399
+ * nothing to revoke and no entry to have read an etag from — whatever value was sent (404).
400
+ * @throws {TwinValidationError} The principal is immutable through this surface (400), decided
401
+ * before the etag is looked at.
402
+ * @throws {TwinNotFoundError} The twin does not exist or the caller cannot see it (404).
403
+ * @throws {TwinPermissionsForbiddenError} `ManageTwinPermissions` is required (403).
404
+ * @throws {TwinPermissionsConflictError} `EtagMismatch` or `ScopesNotProvisioned` (409).
405
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
406
+ * safe to retry unchanged.
407
+ */
408
+ deleteTwinPermissions(twinId: string, principalId: string, etag: string, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet>;
409
+ /**
410
+ * Returns the three default groups the twin owns — `TwinReaders`, `TwinContributors`,
411
+ * `TwinAdministrators` — under the ids to name in {@link setTwinPermissions}.
412
+ *
413
+ * Not a picker for the principals a twin can be granted to: that is every group in the
414
+ * tenant, which the Permission service lists. These are the groups the twin itself
415
+ * owns, whose membership confers its preset capability levels.
416
+ *
417
+ * @throws {TwinPermissionsForbiddenError} `ManageTwinPermissions` is required (403).
418
+ * @throws {TwinNotFoundError} The twin does not exist or the caller cannot see it (404).
419
+ * @throws {TwinPermissionsConflictError} `ScopesNotProvisioned` (409).
420
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
421
+ * safe to retry unchanged.
422
+ */
423
+ listTwinGroups(twinId: string, signal?: AbortSignal): Promise<TwinGroupsGet>;
424
+ /**
425
+ * Returns one of the twin's own default groups.
426
+ *
427
+ * @throws {TwinPrincipalNotFoundError} The twin does not own this group — thrown even when the
428
+ * group exists in the tenant and holds capabilities on this twin, since ownership, not
429
+ * existence, is what this route answers (404).
430
+ * @throws {TwinNotFoundError} The twin does not exist or the caller cannot see it (404).
431
+ * @throws {TwinPermissionsForbiddenError} `ManageTwinPermissions` is required (403).
432
+ * @throws {TwinPermissionsConflictError} `ScopesNotProvisioned` (409).
433
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
434
+ * safe to retry unchanged.
435
+ */
436
+ getTwinGroup(twinId: string, groupId: string, signal?: AbortSignal): Promise<TwinGroupGet>;
437
+ /**
438
+ * Lists one page of the principals holding capabilities on the customer-wide asset domain, with
439
+ * the capabilities each of them holds. The companion administration surface to
440
+ * {@link getMyPermissions}, which answers only for the caller.
441
+ *
442
+ * `pagination.nextPage` is emitted unconditionally — it is non-null on the last page too — so it
443
+ * is not a termination signal. Page until a response comes back with fewer entries than the
444
+ * limit asked for, or use {@link listAllAssetPermissions}, which does that. On an access-review
445
+ * surface, stopping early under-reports who holds capabilities.
446
+ *
447
+ * @throws {TwinPermissionsForbiddenError} The caller does not hold `ManageAssetPermissions`
448
+ * (403).
449
+ * @throws {TwinValidationError} The limit is out of range, or the pagination token is invalid
450
+ * (400).
451
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
452
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
453
+ * safe to retry unchanged.
454
+ */
455
+ listAssetPermissions(options?: {
456
+ page?: string;
457
+ limit?: number;
458
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetPrincipalPermissionsGet>>;
459
+ /** Every entry of {@link listAssetPermissions}, paged to exhaustion. */
460
+ listAllAssetPermissions(signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet[]>;
461
+ /**
462
+ * Replaces what one principal holds on the asset domain. Capabilities absent from
463
+ * `body.permissions` are revoked, and an empty list revokes everything — leaving the principal
464
+ * with no listing entry at all, exactly as {@link deleteAssetPermissions} does.
465
+ *
466
+ * `body.etag` is required whenever the principal already holds capabilities, and may be omitted
467
+ * only to create the grants of one that holds none.
468
+ *
469
+ * @throws {TwinPrincipalNotFoundError} No group in the tenant carries this id (404).
470
+ * @throws {TwinValidationError} `SystemPrincipalImmutable` — a seeded default group, whose
471
+ * preset is conferred by membership rather than by writing here — or
472
+ * `ManagePermissionsNotGrantableToAllAuthenticated` (400).
473
+ * @throws {AssetPermissionsConflictError} `EtagRequired` or `EtagMismatch` (409), carrying the
474
+ * current state to retry from.
475
+ * @throws {TwinPermissionsForbiddenError} The caller does not hold `ManageAssetPermissions`
476
+ * (403).
477
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
478
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
479
+ * safe to retry unchanged.
480
+ */
481
+ setAssetPermissions(principalId: string, body: AssetPermissionsPut, signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet>;
482
+ /**
483
+ * Removes the principal from the domain's access control list entirely, answering with it and
484
+ * an empty capability list.
485
+ *
486
+ * The answer carries the `etag` the revocation wrote: it belongs to the domain, not to the
487
+ * principal, so a revoked principal having no listing entry does not cost the caller one. Chain
488
+ * the next write on it exactly as with {@link setAssetPermissions}, without re-reading
489
+ * {@link listAssetPermissions}.
490
+ *
491
+ * The etag is always required — a revocation always replaces existing grants — and a request
492
+ * naming none is refused with a `400` rather than a conflict, before anything else is asked.
493
+ *
494
+ * @throws {TwinPrincipalNotFoundError} No group in the tenant carries this id, or it holds
495
+ * nothing here for a revocation to remove (404).
496
+ * @throws {TwinValidationError} `SystemPrincipalImmutable` or `EtagRequired` (400).
497
+ * @throws {AssetPermissionsConflictError} `EtagMismatch` (409).
498
+ * @throws {TwinPermissionsForbiddenError} The caller does not hold `ManageAssetPermissions`
499
+ * (403).
500
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
501
+ * @throws {TwinTemporarilyUnavailableError} The request could not be completed (503);
502
+ * safe to retry unchanged.
503
+ */
504
+ deleteAssetPermissions(principalId: string, etag: string, signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet>;
505
+ /**
506
+ * Returns the asset domain's default groups — `AssetsReaders`, `AssetsContributors`,
507
+ * `AssetsAdministrators` — under the ids whose membership confers their preset capabilities.
508
+ *
509
+ * A group whose seeding has not completed for this customer is omitted rather than listed under
510
+ * a placeholder title, so a short list is a state to poll rather than an error.
511
+ *
512
+ * @throws {TwinPermissionsForbiddenError} The caller does not hold `ManageAssetPermissions`
513
+ * (403).
514
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
515
+ * @throws {TwinTemporarilyUnavailableError} The titles could not be resolved (503); safe to
516
+ * retry unchanged.
517
+ */
518
+ listAssetGroups(signal?: AbortSignal): Promise<AssetGroupsGet>;
519
+ /**
520
+ * Returns one default group by its stable name, case-insensitively.
521
+ *
522
+ * @throws {TwinPrincipalNotFoundError} The name is one of the three but its group has not been
523
+ * seeded for this customer yet — safe to retry (404).
524
+ * @throws {TwinNotFoundError} The name is not one of the three; retrying will not help (404).
525
+ * @throws {TwinPermissionsForbiddenError} The caller does not hold `ManageAssetPermissions`
526
+ * (403).
527
+ * @throws {TwinUnauthenticatedError} No valid auth context (401).
528
+ * @throws {TwinTemporarilyUnavailableError} The title could not be resolved (503); safe to
529
+ * retry unchanged.
530
+ */
531
+ getAssetGroup(name: string, signal?: AbortSignal): Promise<AssetGroupGet>;
532
+ /**
533
+ * Returns the Twinfinity meta-schema document — the JSON Schema describing
534
+ * valid asset-type metadata schemas. The bytes the backend itself
535
+ * validates against, served verbatim. Power-user tools (Monaco-backed
536
+ * JSON editors, schema-aware tooling) fetch this at runtime so their
537
+ * in-editor diagnostics line up with what the server will accept,
538
+ * decoupled from the FE bundle's build time.
539
+ */
540
+ getAssetTypeMetaSchema(signal?: AbortSignal): Promise<Record<string, unknown>>;
541
+ /**
542
+ * @throws {AssetCategoryValidationError} On invalid query parameters (400).
543
+ */
544
+ listAssetCategories(options?: {
545
+ page?: string;
546
+ limit?: number;
547
+ includeDeleted?: boolean;
548
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetCategoryGet>>;
549
+ /** @throws {AssetCategoryNotFoundError} When the category does not exist (404). */
550
+ getAssetCategory(categoryId: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
551
+ /**
552
+ * Upserts an asset category. Provide an empty/missing etag for first writes
553
+ * and the existing etag to update.
554
+ *
555
+ * @throws {AssetCategoryValidationError} On invalid request body (400).
556
+ * @throws {AssetCategoryConflictError} On etag mismatch (409). The error's `currentCategory` contains the server's current state.
557
+ */
558
+ putAssetCategory(categoryId: string, body: AssetCategoryPut, signal?: AbortSignal): Promise<AssetCategoryGet>;
559
+ /**
560
+ * Returns every version of a single asset category, newest first. Mirrors
561
+ * `listAssetTypeVersions` and `twin.get_twin_versions`.
562
+ *
563
+ * @throws {AssetCategoryNotFoundError} When the category's header row does not exist (404).
564
+ */
565
+ listAssetCategoryVersions(categoryId: string, options?: {
566
+ page?: string;
567
+ limit?: number;
568
+ includeDeleted?: boolean;
569
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetCategoryGet>>;
570
+ /**
571
+ * Soft-deletes a category. Inserts a new asset_category_versions row with
572
+ * `is_deleted=true`; the previous version is retained as an audit trail.
573
+ *
574
+ * @throws {AssetCategoryNotFoundError} When the category does not exist (404).
575
+ * @throws {AssetCategoryConflictError} On etag mismatch (409).
576
+ */
577
+ deleteAssetCategory(categoryId: string, etag: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
578
+ /**
579
+ * Restores a soft-deleted category. Inserts a new asset_category_versions
580
+ * row with `is_deleted=false`; mirrors twin restore.
581
+ *
582
+ * @throws {AssetCategoryNotFoundError} When the category does not exist (404).
583
+ * @throws {AssetCategoryConflictError} On etag mismatch (409).
584
+ */
585
+ restoreAssetCategory(categoryId: string, etag: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
586
+ /** @throws {AssetTypeValidationError} On invalid query parameters (400). */
587
+ listAssetTypes(categoryId: string, options?: {
588
+ page?: string;
589
+ limit?: number;
590
+ includeDeleted?: boolean;
591
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetTypeGet>>;
592
+ /** @throws {AssetTypeNotFoundError} When the category or type does not exist (404). */
593
+ getAssetType(categoryId: string, typeId: string, signal?: AbortSignal): Promise<AssetTypeGet>;
594
+ /**
595
+ * Returns every version of a single asset type, newest first. Mirrors
596
+ * `twin.get_twin_versions`.
597
+ *
598
+ * @throws {AssetTypeNotFoundError} When the type's header row does not exist (404).
599
+ */
600
+ listAssetTypeVersions(categoryId: string, typeId: string, options?: {
601
+ page?: string;
602
+ limit?: number;
603
+ includeDeleted?: boolean;
604
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetTypeGet>>;
605
+ /**
606
+ * Upserts an asset type. The metadata schema is validated against the
607
+ * Twinfinity meta-schema at the API boundary; invalid schemas surface as
608
+ * a 400 with `cause: MetadataSchemaInvalid`.
609
+ *
610
+ * @throws {AssetTypeValidationError} On invalid request body (400). The error's `errorBody` carries the structured cause.
611
+ * @throws {AssetTypeConflictError} On etag mismatch (409). The error's `currentType` contains the server's current state.
612
+ */
613
+ putAssetType(categoryId: string, typeId: string, body: AssetTypePut, signal?: AbortSignal): Promise<AssetTypeGet>;
614
+ /**
615
+ * Soft-deletes a type. Inserts a new asset_type_versions row with
616
+ * `is_deleted=true`; the previous version is retained as an audit trail.
617
+ *
618
+ * @throws {AssetTypeNotFoundError} When the type does not exist (404).
619
+ * @throws {AssetTypeConflictError} On etag mismatch (409).
620
+ */
621
+ deleteAssetType(categoryId: string, typeId: string, etag: string, signal?: AbortSignal): Promise<AssetTypeGet>;
622
+ /**
623
+ * Restores a soft-deleted type. Inserts a new asset_type_versions row with
624
+ * `is_deleted=false`; mirrors twin restore.
625
+ *
626
+ * @throws {AssetTypeNotFoundError} When the type does not exist (404).
627
+ * @throws {AssetTypeConflictError} On etag mismatch (409).
628
+ */
629
+ restoreAssetType(categoryId: string, typeId: string, etag: string, signal?: AbortSignal): Promise<AssetTypeGet>;
630
+ /**
631
+ * Returns the customer's asset-type catalog: categories nested with
632
+ * their latest non-deleted types and full metadata schemas inline. One
633
+ * round-trip is enough to populate a picker dropdown and render any
634
+ * per-type metadata form.
635
+ */
636
+ getAssetTypeCatalog(signal?: AbortSignal): Promise<AssetCatalogResponse>;
637
+ }
638
+ export declare class TwinClient implements ITwinClient {
639
+ private readonly _httpClient;
640
+ private readonly _baseUrl;
641
+ private readonly _assetTypeCatalogUrl;
642
+ constructor(baseUrl: string | URL, _httpClient: TwinfinityHttpClient);
643
+ /**
644
+ * Rooted twins base URL — typically `<host>/sites/<container>/_ps/twins`.
645
+ * Exposed so callers that want to build content URLs in the same auth
646
+ * scope as the metadata calls can derive them from here. The bare
647
+ * `<host>/_ps/twins/...` variant is not necessarily an authorized route
648
+ * on all deployments.
649
+ */
650
+ get baseUrl(): string;
651
+ listTwins(options?: {
652
+ relatedTo?: string;
653
+ includeDeleted?: boolean;
654
+ page?: string;
655
+ limit?: number;
656
+ }, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
657
+ /**
658
+ * @deprecated Use the options-object form: `listTwins({ relatedTo, page, limit }, signal)`.
659
+ * The positional form has no `includeDeleted` parameter; that is only reachable via the options object.
660
+ */
661
+ listTwins(relatedTo?: string, page?: string, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
662
+ listAllTwins(options?: {
663
+ relatedTo?: string;
664
+ includeDeleted?: boolean;
665
+ }, signal?: AbortSignal): Promise<ListTwinItem[]>;
666
+ /**
667
+ * @deprecated Use the options-object form: `listAllTwins({ relatedTo }, signal)`.
668
+ * The positional form has no `includeDeleted` parameter; that is only reachable via the options object.
669
+ */
670
+ listAllTwins(relatedTo?: string, signal?: AbortSignal): Promise<ListTwinItem[]>;
671
+ getTwin(twin: string | {
672
+ id: string;
673
+ version: number;
674
+ }, signal?: AbortSignal): Promise<TwinGet>;
675
+ listTwinVersions(id: string, options?: {
676
+ includeDeleted?: boolean;
677
+ page: string | undefined;
678
+ limit?: number;
679
+ }, signal?: AbortSignal): Promise<PaginatedResponse<ListTwinItem>>;
680
+ downloadTwinContent(twinId: string, twinVersion: number, content: TwinContentResponse, signal?: AbortSignal): Promise<ArrayBuffer>;
681
+ private loadTwinVersion;
682
+ loadTwin(twin: string | {
683
+ id: string;
684
+ version: number;
685
+ }, signal?: AbortSignal): Promise<Twin<T8Project, T8Product<T8EntityType>, T8EntityType, T8Unit>>;
686
+ loadTwinWithFactories<TProject, TProduct, TEntityType, TUnit>(twin: string | {
687
+ id: string;
688
+ version: number;
689
+ }, projectFactory: (dto: T8ClientProjectDTO<TUnit>) => TProject, productFactory: (dto: T8ClientProductDTO<TUnit>) => TProduct, entityTypeFactory: (dto: T8ClientEntityTypeDTO<TUnit>) => TEntityType, unitFactory: (dto: T8ClientUnitDTO, dataModel: T8ClientModelDTO) => TUnit, connectProject: (dto: T8ClientProjectConnectionsDTO<TProduct>, project: TProject) => void, connectProduct: (dto: T8ClientProductConnectionsDTO<TProduct, TEntityType>, product: TProduct) => void, signal?: AbortSignal): Promise<Twin<TProject, TProduct, TEntityType, TUnit>>;
690
+ private loadGeometryInfoVersion;
691
+ loadGeometryInfo(twin: string | {
692
+ id: string;
693
+ version: number;
694
+ }, signal?: AbortSignal): Promise<TwinGeometryInfo<T8GIMeshDescriptor, T8GIStyle, T8GIRegion>>;
695
+ loadGeometryInfoWithFactories<TMeshDescriptor, TStyle, TRegion>(twin: string | {
696
+ id: string;
697
+ version: number;
698
+ }, meshDescriptorFactory: (dto: T8GIMeshDescriptorDTO) => TMeshDescriptor, styleFactory: (dto: T8GIStyleDTO) => TStyle, regionFactory: (dto: T8GIRegionDTO) => TRegion, signal?: AbortSignal): Promise<TwinGeometryInfo<TMeshDescriptor, TStyle, TRegion>>;
699
+ private loadTwinWithGeometryVersion;
700
+ loadTwinWithGeometry(twin: string | {
701
+ id: string;
702
+ version: number;
703
+ }, signal?: AbortSignal): Promise<Twin<T8ProjectWithGeometry, T8ProductWithGeometry, T8EntityType, T8Unit>>;
704
+ createOrUpdateTwin(twinId: string, twin: TwinPut, signal?: AbortSignal): Promise<TwinGet>;
705
+ updateTwin(twinId: string, twin: TwinPut, signal?: AbortSignal): Promise<TwinGet>;
706
+ deleteTwin(twinId: string, etag: string, signal?: AbortSignal): Promise<TwinGet>;
707
+ restoreTwin(twinId: string, etag: string, signal?: AbortSignal): Promise<TwinGet>;
708
+ getTwinVersionContent(twinId: string, twinVersion: number, signal?: AbortSignal): Promise<TwinVersionContentResponse>;
709
+ getTwinContent(twinId: string, signal?: AbortSignal): Promise<TwinVersionContentResponse>;
710
+ getTwinDiagnostics(twinId: string, signal?: AbortSignal): Promise<TwinDiagnosticsResponse>;
711
+ getTwinVersionDiagnostics(twinId: string, twinVersion: number, signal?: AbortSignal): Promise<TwinDiagnosticsResponse>;
712
+ getTwinVersionEvents(twinId: string, twinVersion: number, offset?: number, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<TwinProcessorEvent>>;
713
+ getProcessorEvents(twinId: string, twinVersion: number, processorId: string, offset?: number, limit?: number, signal?: AbortSignal): Promise<PaginatedResponse<TwinProcessorEvent>>;
714
+ listAssets(twinId: string, offset?: number, limit?: number, options?: {
715
+ includeDeleted?: boolean;
716
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetListItem>>;
717
+ getAsset(twinId: string, assetId: string, signal?: AbortSignal): Promise<AssetGet>;
718
+ createAssets(twinId: string, assets: AssetPost[], signal?: AbortSignal): Promise<AssetGet[]>;
719
+ updateAsset(twinId: string, assetId: string, asset: AssetPut, signal?: AbortSignal): Promise<AssetGet>;
720
+ deleteAsset(twinId: string, assetId: string, etag: string, signal?: AbortSignal): Promise<AssetGet>;
721
+ restoreAsset(twinId: string, assetId: string, etag: string): Promise<AssetGet>;
722
+ batchAssets(twinId: string, operations: AssetBatchOperation[], signal?: AbortSignal): Promise<AssetBatchResponse>;
723
+ batchGetAssets(twinId: string, ids: string[], signal?: AbortSignal): Promise<AssetBatchGetResponse>;
724
+ listAssetAttachments(twinId: string, assetId: string, options?: {
725
+ includeDeleted?: boolean;
726
+ offset?: number;
727
+ limit?: number;
728
+ page?: string;
729
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AttachmentGet>>;
730
+ getAssetAttachmentBlob(twinId: string, assetId: string, attachmentId: string, signal?: AbortSignal): Promise<Response>;
731
+ createAssetAttachmentUploadSession(twinId: string, assetId: string, attachmentId: string, body: AttachmentPost, signal?: AbortSignal): Promise<ApiCreateUploadSessionResponse>;
732
+ uploadAssetAttachmentFile(session: ApiCreateUploadSessionResponse, file: Blob, signal?: AbortSignal): Promise<{
733
+ token: string;
734
+ }>;
735
+ getAssetAttachmentUploadStatus(twinId: string, assetId: string, token: string, signal?: AbortSignal): Promise<UploadStatusGet>;
736
+ putAssetAttachment(twinId: string, assetId: string, attachmentId: string, body: AssetAttachmentPut, signal?: AbortSignal): Promise<AttachmentGet>;
737
+ deleteAssetAttachment(twinId: string, assetId: string, attachmentId: string, etag: string, signal?: AbortSignal): Promise<AttachmentGet>;
738
+ restoreAssetAttachment(twinId: string, assetId: string, attachmentId: string, etag: string, signal?: AbortSignal): Promise<AttachmentGet>;
739
+ listTwinFiles(twinId: string, options?: TwinFileListOptions, signal?: AbortSignal): Promise<PaginatedResponse<TwinFileGet>>;
740
+ getTwinFile(twinId: string, fileId: string, signal?: AbortSignal): Promise<TwinFileGet>;
741
+ createOrUpdateTwinFile(twinId: string, fileId: string, twinFile: TwinFilePut, signal?: AbortSignal): Promise<TwinFileGet>;
742
+ deleteTwinFile(twinId: string, fileId: string, deleteRequest: TwinFileDelete, signal?: AbortSignal): Promise<TwinFileGet>;
743
+ restoreTwinFile(twinId: string, fileId: string, etag: string, signal?: AbortSignal): Promise<TwinFileGet>;
744
+ getTwinFileContent(twinId: string, fileId: string, signal?: AbortSignal): Promise<Blob>;
745
+ getTwinFileVersion(twinId: string, fileId: string, version: number, signal?: AbortSignal): Promise<TwinFileGet>;
746
+ listTwinFileVersions(twinId: string, fileId: string, options?: TwinFileVersionListOptions, signal?: AbortSignal): Promise<PaginatedResponse<TwinFileGet>>;
747
+ getTwinFileVersionContent(twinId: string, fileId: string, version: number, signal?: AbortSignal): Promise<Blob>;
748
+ createOrUpdateTwinRaw(twinId: string, twin: unknown, signal?: AbortSignal): Promise<Response>;
749
+ createOrUpdateTwinFileRaw(twinId: string, fileId: string, twinFile: unknown, signal?: AbortSignal): Promise<Response>;
750
+ getMyPermissions(signal?: AbortSignal): Promise<MyPermissions>;
751
+ getMyTwinPermissions(twinId: string, signal?: AbortSignal): Promise<MyTwinPermissions>;
752
+ listTwinPermissions(twinId: string, options?: {
753
+ page?: string;
754
+ limit?: number;
755
+ }, signal?: AbortSignal): Promise<PaginatedResponse<TwinPrincipalPermissionsGet>>;
756
+ listAllTwinPermissions(twinId: string, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet[]>;
757
+ setTwinPermissions(twinId: string, principalId: string, body: TwinPermissionsPut, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet>;
758
+ deleteTwinPermissions(twinId: string, principalId: string, etag: string, signal?: AbortSignal): Promise<TwinPrincipalPermissionsGet>;
759
+ listTwinGroups(twinId: string, signal?: AbortSignal): Promise<TwinGroupsGet>;
760
+ getTwinGroup(twinId: string, groupId: string, signal?: AbortSignal): Promise<TwinGroupGet>;
761
+ listAssetPermissions(options?: {
762
+ page?: string;
763
+ limit?: number;
764
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetPrincipalPermissionsGet>>;
765
+ listAllAssetPermissions(signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet[]>;
766
+ setAssetPermissions(principalId: string, body: AssetPermissionsPut, signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet>;
767
+ deleteAssetPermissions(principalId: string, etag: string, signal?: AbortSignal): Promise<AssetPrincipalPermissionsGet>;
768
+ listAssetGroups(signal?: AbortSignal): Promise<AssetGroupsGet>;
769
+ getAssetGroup(name: string, signal?: AbortSignal): Promise<AssetGroupGet>;
770
+ /**
771
+ * Maps a refusal from the customer-wide asset permission surface onto the typed error its
772
+ * status and cause name. The twin-scoped counterpart of this cannot be reused: its 404s are
773
+ * about a twin, and this surface has none — a 404 naming no principal means the *name* was
774
+ * unknown, not that a resource was missing.
775
+ *
776
+ * A 404 is dispatched on `item.kind`, which is what separates "that group has not been seeded
777
+ * for this customer yet", which is worth retrying, from "no such group name", which is not.
778
+ */
779
+ private _failAssetPermissionsRequest;
780
+ /**
781
+ * Maps a refusal from the twin-scoped permission surface onto the typed error its status
782
+ * and cause name. Shared by all six methods because the surface answers them uniformly:
783
+ * the status is decided by the request's shape and the caller's grants, not by the route.
784
+ *
785
+ * A 404 is dispatched on `item.kind`, which is the only thing separating "no such twin, or
786
+ * none you may see" from "the principal you named is not there" — the two arrive on the
787
+ * same status from the same route.
788
+ */
789
+ private _failTwinPermissionsRequest;
790
+ getAssetTypeMetaSchema(signal?: AbortSignal): Promise<Record<string, unknown>>;
791
+ listAssetCategories(options?: {
792
+ page?: string;
793
+ limit?: number;
794
+ includeDeleted?: boolean;
795
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetCategoryGet>>;
796
+ getAssetCategory(categoryId: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
797
+ putAssetCategory(categoryId: string, body: AssetCategoryPut, signal?: AbortSignal): Promise<AssetCategoryGet>;
798
+ deleteAssetCategory(categoryId: string, etag: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
799
+ restoreAssetCategory(categoryId: string, etag: string, signal?: AbortSignal): Promise<AssetCategoryGet>;
800
+ private _categoryDeleteOrRestore;
801
+ listAssetCategoryVersions(categoryId: string, options?: {
802
+ page?: string;
803
+ limit?: number;
804
+ includeDeleted?: boolean;
805
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetCategoryGet>>;
806
+ listAssetTypes(categoryId: string, options?: {
807
+ page?: string;
808
+ limit?: number;
809
+ includeDeleted?: boolean;
810
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetTypeGet>>;
811
+ getAssetType(categoryId: string, typeId: string, signal?: AbortSignal): Promise<AssetTypeGet>;
812
+ listAssetTypeVersions(categoryId: string, typeId: string, options?: {
813
+ page?: string;
814
+ limit?: number;
815
+ includeDeleted?: boolean;
816
+ }, signal?: AbortSignal): Promise<PaginatedResponse<AssetTypeGet>>;
817
+ putAssetType(categoryId: string, typeId: string, body: AssetTypePut, signal?: AbortSignal): Promise<AssetTypeGet>;
818
+ deleteAssetType(categoryId: string, typeId: string, etag: string, signal?: AbortSignal): Promise<AssetTypeGet>;
819
+ restoreAssetType(categoryId: string, typeId: string, etag: string, signal?: AbortSignal): Promise<AssetTypeGet>;
820
+ private _typeDeleteOrRestore;
821
+ getAssetTypeCatalog(signal?: AbortSignal): Promise<AssetCatalogResponse>;
822
+ }
823
+ //# sourceMappingURL=TwinClient.d.ts.map