@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
package/README.md ADDED
@@ -0,0 +1,277 @@
1
+ # @twinfinity/twin
2
+
3
+ TypeScript client for the Twinfinity Twin Service API. Provides typed access to twins, assets, and twin files with optimistic concurrency control and structured error handling.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @twinfinity/twin
9
+ ```
10
+
11
+ ### Peer Dependencies
12
+
13
+ - `@twinfinity/authentication` - provides `TwinfinityHttpClient` for authenticated HTTP requests
14
+ - `@twinfinity/t8-client-model` - provides T8 client model types used by `loadTwin` / `loadGeometryInfo`
15
+
16
+ ## Usage
17
+
18
+ ### Creating a Client
19
+
20
+ ```typescript
21
+ import { TwinClient } from '@twinfinity/twin';
22
+
23
+ const client = new TwinClient(baseUrl, httpClient);
24
+ ```
25
+
26
+ The `baseUrl` is the API root (e.g. `https://api.twinfinity.com`). The client appends `/_ps/twins` internally.
27
+
28
+ ### Twin Operations
29
+
30
+ ```typescript
31
+ // List twins (paginated)
32
+ const page = await client.listTwins();
33
+
34
+ // List all twins (auto-paginates)
35
+ const allTwins = await client.listAllTwins();
36
+
37
+ // Get a specific twin
38
+ const twin = await client.getTwin('twin-id');
39
+
40
+ // Get a specific version
41
+ const twinV2 = await client.getTwin({ id: 'twin-id', version: 2 });
42
+
43
+ // Create or update
44
+ const updated = await client.createOrUpdateTwin('twin-id', {
45
+ relatedContainerIds: ['container-1'],
46
+ rootEntity: '0Site00000000000000000',
47
+ entities: {
48
+ sites: {
49
+ '0Site00000000000000000': { id: '0Site00000000000000000', name: 'My site' }
50
+ }
51
+ },
52
+ etag: twin.etag // required for updates
53
+ });
54
+
55
+ // Soft-delete and restore
56
+ const deleted = await client.deleteTwin('twin-id', twin.etag);
57
+ const restored = await client.restoreTwin('twin-id', deleted.etag);
58
+ ```
59
+
60
+ #### Nesting twins
61
+
62
+ A twin can nest other twins as children. Declare each child in `entities.twinReferences`
63
+ and place it under a site via that site's `aggregatedTwinReferences`:
64
+
65
+ ```typescript
66
+ await client.createOrUpdateTwin('parent-id', {
67
+ relatedContainerIds: ['container-1'],
68
+ rootEntity: '0Site00000000000000000',
69
+ entities: {
70
+ sites: {
71
+ '0Site00000000000000000': {
72
+ id: '0Site00000000000000000',
73
+ name: 'Campus site',
74
+ aggregatedTwinReferences: ['ref-a']
75
+ }
76
+ },
77
+ twinReferences: {
78
+ 'ref-a': { twin: 'child-id' } // id of the nested twin
79
+ }
80
+ }
81
+ // Omit `etag` when creating; supply the current twin's etag only when updating.
82
+ });
83
+
84
+ // The parent/child edge is computed and read back on the twin:
85
+ const parent = await client.getTwin('parent-id');
86
+ parent.aggregatedTwins; // ['child-id'] — twins this twin parents
87
+ const child = await client.getTwin('child-id');
88
+ child.parentTwin; // 'parent-id' — the twin that references this one
89
+ ```
90
+
91
+ `aggregatedTwins` and `parentTwin` are computed by the service, not authored — sending
92
+ them in a write has no effect. A twin may have at most one parent, may not reference
93
+ itself, and references may not form a cycle. Adding a reference requires `View` on the
94
+ referenced twin (in addition to `Edit` on the twin being written); a referenced twin you
95
+ cannot read is reported as not found. See
96
+ [Twin Management → Nested Twins](../../docs/specs/backend/services/twin/twin-management.md#nested-twins-twin-references)
97
+ for the full rules.
98
+
99
+ ### Loading Twin Models
100
+
101
+ The client can download and deserialize processed twin content (T8CM/T8GI formats):
102
+
103
+ ```typescript
104
+ // Load client model with default types
105
+ const { id, version, model } = await client.loadTwin('twin-id');
106
+
107
+ // Load with custom factory functions for domain-specific types
108
+ const custom = await client.loadTwinWithFactories(
109
+ 'twin-id',
110
+ myProjectFactory,
111
+ myProductFactory,
112
+ myEntityTypeFactory,
113
+ myUnitFactory,
114
+ myConnectProject,
115
+ myConnectProduct
116
+ );
117
+
118
+ // Load geometry info
119
+ const geometry = await client.loadGeometryInfo('twin-id');
120
+
121
+ // Load client model with geometry combined
122
+ const withGeometry = await client.loadTwinWithGeometry('twin-id');
123
+ ```
124
+
125
+ When no version is specified, the client searches versions (newest first) for one that has the requested content format.
126
+
127
+ ### Asset Operations
128
+
129
+ ```typescript
130
+ // List assets in a twin
131
+ const assets = await client.listAssets('twin-id');
132
+
133
+ // Include soft-deleted assets
134
+ const allAssets = await client.listAssets('twin-id', 0, 100, { includeDeleted: true });
135
+
136
+ // Create assets
137
+ const created = await client.createAssets('twin-id', [{ name: 'Pump A', category: 'HVAC', type: 'Pump' }]);
138
+
139
+ // Update with optimistic concurrency
140
+ const updated = await client.updateAsset('twin-id', 'asset-id', {
141
+ etag: asset.etag,
142
+ name: 'Pump A (Updated)'
143
+ });
144
+
145
+ // Batch operations (atomic - all succeed or all roll back)
146
+ const result = await client.batchAssets('twin-id', [
147
+ { operation: 'upsert', id: 'asset-1', item: { name: 'New Asset' } },
148
+ { operation: 'delete', id: 'asset-2', item: { etag: 'etag-2' } },
149
+ { operation: 'restore', id: 'asset-3', item: { etag: 'etag-3' } }
150
+ ]);
151
+
152
+ // Batch get multiple assets by ID
153
+ const fetched = await client.batchGetAssets('twin-id', ['id-1', 'id-2']);
154
+ ```
155
+
156
+ ### Twin File Operations
157
+
158
+ ```typescript
159
+ // List files (with filtering)
160
+ const files = await client.listTwinFiles('twin-id', { checkedIn: true });
161
+
162
+ // Create or update a file
163
+ const file = await client.createOrUpdateTwinFile('twin-id', 'file-id', {
164
+ source: { changeId: 'doc-id', changeVersion: 1, sourceType: 'DocumentChange' },
165
+ name: 'model.ifc',
166
+ quality: 100
167
+ });
168
+
169
+ // Download file content
170
+ const blob = await client.getTwinFileContent('twin-id', 'file-id');
171
+ ```
172
+
173
+ ## Error Handling
174
+
175
+ All methods throw typed errors for specific HTTP failure codes. Unexpected status codes throw a generic `Error`.
176
+
177
+ ### Error Classes
178
+
179
+ | Error | HTTP Status | Context Attached |
180
+ | ------------------------- | ----------- | ------------------------------ |
181
+ | `TwinValidationError` | 400 | `errorBody?: TwinErrorBody` |
182
+ | `TwinNotFoundError` | 404 | `errorBody?: TwinErrorBody` |
183
+ | `TwinConflictError` | 409 | `currentTwin: TwinGet` |
184
+ | `AssetValidationError` | 400 | `errorBody?: TwinErrorBody` |
185
+ | `AssetForbiddenError` | 403 | - |
186
+ | `AssetNotFoundError` | 404 | - |
187
+ | `AssetConflictError` | 409 | `currentAsset: AssetGet` |
188
+ | `AssetBatchError` | 404, 409 | `response: AssetBatchResponse` |
189
+ | `TwinFileValidationError` | 400 | `errorBody?: TwinErrorBody` |
190
+ | `TwinFileNotFoundError` | 404 | - |
191
+ | `TwinFileConflictError` | 409 | `currentTwinFile: TwinFileGet` |
192
+ | `ProcessorNotFoundError` | 404 | - |
193
+
194
+ Twin-scoped permissions (`/twins/{twinId}/permissions`, `/twins/{twinId}/groups`):
195
+
196
+ | Error | HTTP Status | Context Attached |
197
+ | --------------------------------------- | ----------- | --------------------------------------------------------- |
198
+ | `TwinPermissionsForbiddenError` | 403 | `errorBody?: TwinErrorBody` |
199
+ | `TwinPrincipalNotFoundError` | 404 | `errorBody?: TwinErrorBody` |
200
+ | `TwinPermissionsConflictError` | 409 | `conflictCause`, `currentState?`, `errorBody` |
201
+ | `TwinTemporarilyUnavailableError` | 503 | `errorBody?: TwinErrorBody`, `retryAfterSeconds?: number` |
202
+
203
+ `TwinPermissionsConflictError` names the conflict on `conflictCause` rather than on `cause`, leaving
204
+ the standard `Error.cause` free: `EtagMismatch` is retried by re-reading, `EtagRequired` by reading
205
+ at all, and `ScopesNotProvisioned` is not retryable. `currentState` carries the entry as the server
206
+ holds it, including the etag to retry with.
207
+
208
+ Asset-domain permissions (`/twins/permissions`, `/twins/groups`) reuse the errors above, except that
209
+ a 409 arrives as `AssetPermissionsConflictError` — the same shape, but its `currentState` is an
210
+ `AssetPrincipalPermissionsGet` rather than a twin's entry, and `ScopesNotProvisioned` never occurs
211
+ because the domain's scope is seeded once per customer rather than provisioned per resource.
212
+
213
+ ### Conflict Handling
214
+
215
+ Conflict errors (409) carry the current server-side state, enabling retry logic:
216
+
217
+ ```typescript
218
+ import { TwinConflictError } from '@twinfinity/twin';
219
+
220
+ try {
221
+ await client.createOrUpdateTwin('twin-id', twinData);
222
+ } catch (e) {
223
+ if (e instanceof TwinConflictError) {
224
+ // e.currentTwin contains the server's current version
225
+ // Use it to merge changes and retry
226
+ const merged = mergeChanges(twinData, e.currentTwin);
227
+ await client.createOrUpdateTwin('twin-id', {
228
+ ...merged,
229
+ etag: e.currentTwin.etag
230
+ });
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### Validation Error Body
236
+
237
+ `TwinValidationError`, `TwinFileValidationError`, and `AssetValidationError` may include a structured error body:
238
+
239
+ ```typescript
240
+ interface TwinErrorBody {
241
+ detail: string;
242
+ cause: string;
243
+ item?: {
244
+ kind: string;
245
+ id: string;
246
+ version?: number;
247
+ field?: string;
248
+ };
249
+ }
250
+ ```
251
+
252
+ ### Batch Error Handling
253
+
254
+ `AssetBatchError` carries the full batch response with per-item results, including which operations were reverted:
255
+
256
+ ```typescript
257
+ import { AssetBatchError } from '@twinfinity/twin';
258
+
259
+ try {
260
+ await client.batchAssets('twin-id', operations);
261
+ } catch (e) {
262
+ if (e instanceof AssetBatchError) {
263
+ for (const result of e.response.results) {
264
+ if (result.status === 'conflicted') {
265
+ console.log(`Item ${result.index} conflicted: ${result.error?.detail}`);
266
+ }
267
+ }
268
+ }
269
+ }
270
+ ```
271
+
272
+ ## Exports
273
+
274
+ The package has two export paths:
275
+
276
+ - `@twinfinity/twin` - Public API: `TwinClient`, `ITwinClient`, all types, all error classes
277
+ - `@twinfinity/twin/internal/*` - Internal modules (no stability guarantees)
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Represents either production or development build type
3
+ */
4
+ export type BuildType = 'Dev' | 'Prod';
5
+ /**
6
+ * Contains property metadata for the Twinfinity build
7
+ */
8
+ export interface BuildInfo {
9
+ /** Major version number */
10
+ readonly major: number;
11
+ /** Minor version number */
12
+ readonly minor: number;
13
+ /** Patch version number */
14
+ readonly patch: number;
15
+ /** Unique build id */
16
+ readonly id: number;
17
+ /** The commit checksum */
18
+ readonly commit: string;
19
+ /** String that uniquely identifies the current version */
20
+ readonly version: string;
21
+ /** The build type */
22
+ readonly buildType: BuildType;
23
+ }
24
+ export declare const BUILD_INFO: Readonly<BuildInfo>;
25
+ //# sourceMappingURL=BuildInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildInfo.d.ts","sourceRoot":"","sources":["../src/BuildInfo.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qBAAqB;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CACjC;AAiBD,eAAO,MAAM,UAAU,qBAAqB,CAAC"}
@@ -0,0 +1,15 @@
1
+ const gBi = {
2
+ major: 0,
3
+ minor: 0,
4
+ patch: 0,
5
+ id: 31596,
6
+ commit: 'b8846e12b',
7
+ version: '',
8
+ buildType: 'Prod'
9
+ };
10
+ gBi.version = `${gBi.major}.${gBi.minor}.${gBi.patch}.${gBi.id}-[${gBi.commit}]`;
11
+ if (gBi.commit === 'unknownCommit') {
12
+ gBi.buildType = 'Dev';
13
+ }
14
+ export const BUILD_INFO = Object.freeze(gBi);
15
+ //# sourceMappingURL=BuildInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BuildInfo.js","sourceRoot":"","sources":["../src/BuildInfo.ts"],"names":[],"mappings":"AAyBA,MAAM,GAAG,GAAc;IACnB,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,MAAM;IACb,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,MAAM;CACpB,CAAC;AAED,GAAG,CAAC,OAAkB,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC;AAC7F,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;IAChC,GAAG,CAAC,SAAuB,GAAG,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC"}