dalux-build-api 1.1.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  API clients for the [Dalux Build REST API](https://app.swaggerhub.com/apis-docs/Dalux/DaluxBuild-api/4.14), available in two languages:
4
4
 
5
- | Language | Location | Documentation |
6
- |---|---|---|
7
- | Node.js | [`/`](.) | See below |
8
- | Python | [`/python`](python/) | [python/README.md](python/README.md) |
5
+ | Language | Location | Documentation |
6
+ | -------- | -------------------- | ------------------------------------ |
7
+ | Node.js | [`/`](.) | See below |
8
+ | Python | [`/python`](python/) | [python/README.md](python/README.md) |
9
9
 
10
10
  ---
11
11
 
@@ -20,7 +20,7 @@ A lightweight Node.js client for the Dalux Build REST API.
20
20
  ## Installation
21
21
 
22
22
  ```bash
23
- npm install @bruadam/dalux-build-api
23
+ npm install dalux-build-api
24
24
  ```
25
25
 
26
26
  ## Getting Started
@@ -31,11 +31,11 @@ To access the API you need:
31
31
  2. An **API key** — managed via _Settings › Integrations › API Identities_ inside the Dalux Build UI.
32
32
 
33
33
  ```js
34
- const { createClient } = require('@bruadam/dalux-build-api');
34
+ const { createClient } = require("dalux-build-api");
35
35
 
36
36
  const dalux = createClient({
37
- baseUrl: 'https://<your-company>.dalux.com/api',
38
- apiKey: 'YOUR_API_KEY',
37
+ baseUrl: "https://<your-company>.dalux.com/api",
38
+ apiKey: "YOUR_API_KEY",
39
39
  });
40
40
  ```
41
41
 
@@ -44,21 +44,24 @@ The returned object exposes one namespace per API group (see [API Reference](#ap
44
44
  ### Examples
45
45
 
46
46
  **List all projects**
47
+
47
48
  ```js
48
49
  const projects = await dalux.projects.listProjects();
49
50
  console.log(projects);
50
51
  ```
51
52
 
52
53
  **Get a specific project**
54
+
53
55
  ```js
54
- const project = await dalux.projects.getProject('my-project-id');
56
+ const project = await dalux.projects.getProject("my-project-id");
55
57
  console.log(project);
56
58
  ```
57
59
 
58
60
  **List tasks on a project**
61
+
59
62
  ```js
60
- const tasks = await dalux.tasks.getProjectTasks('my-project-id', {
61
- updatedAfter: '2024-01-01',
63
+ const tasks = await dalux.tasks.getProjectTasks("my-project-id", {
64
+ updatedAfter: "2024-01-01",
62
65
  });
63
66
  console.log(tasks);
64
67
  ```
@@ -68,10 +71,16 @@ console.log(tasks);
68
71
  `getProjectTasks` forwards OData query options (for example `$filter`). You can also pass `typeId`; it is expanded to `$filter=data/type/typeId eq '<typeId>'` unless you already set `$filter`.
69
72
 
70
73
  ```js
71
- const byType = await dalux.tasks.getProjectTasks('my-project-id', { typeId: 'some-type-guid' });
74
+ const byType = await dalux.tasks.getProjectTasks("my-project-id", {
75
+ typeId: "some-type-guid",
76
+ });
72
77
 
73
78
  // All pages merged (bookmark pagination; matches Python client behaviour)
74
- const allTasks = await dalux.tasks.getAllProjectTasks('my-project-id', { typeId: 'some-type-guid' }, false);
79
+ const allTasks = await dalux.tasks.getAllProjectTasks(
80
+ "my-project-id",
81
+ { typeId: "some-type-guid" },
82
+ false,
83
+ );
75
84
  ```
76
85
 
77
86
  **Files: browse (6.1), fetch all pages, download**
@@ -79,44 +88,69 @@ const allTasks = await dalux.tasks.getAllProjectTasks('my-project-id', { typeId:
79
88
  `listFiles` and `getAllFiles` call **GET `/6.1/projects/{projectId}/file_areas/{fileAreaId}/files`** (Dalux `listFiles`). Supported query parameters include `folderId`, `updatedAfter`, and `includeProperties` (see the official spec). Single-file metadata still uses **GET `/5.0/.../files/{fileId}`** (`getFile`).
80
89
 
81
90
  ```js
82
- const allFiles = await dalux.files.getAllFiles('my-project-id', 'my-file-area-id', { folderId: 'folder-guid' });
91
+ const allFiles = await dalux.files.getAllFiles(
92
+ "my-project-id",
93
+ "my-file-area-id",
94
+ { folderId: "folder-guid" },
95
+ );
83
96
 
84
- const file = await dalux.files.getFile('my-project-id', 'my-file-area-id', 'file-guid', {
85
- download: true,
86
- savePath: './downloads',
87
- });
97
+ const file = await dalux.files.getFile(
98
+ "my-project-id",
99
+ "my-file-area-id",
100
+ "file-guid",
101
+ {
102
+ download: true,
103
+ savePath: "./downloads",
104
+ },
105
+ );
88
106
 
89
- const saved = await dalux.files.downloadFileFromLink(downloadUrl, 'model.ifc', './downloads');
107
+ const saved = await dalux.files.downloadFileFromLink(
108
+ downloadUrl,
109
+ "model.ifc",
110
+ "./downloads",
111
+ );
90
112
 
91
- await dalux.files.bulkDownloadFolder('my-project-id', 'my-file-area-id', 'folder-guid', './out', {
92
- filenameExtensions: ['.ifc'],
93
- verbose: true,
94
- });
113
+ await dalux.files.bulkDownloadFolder(
114
+ "my-project-id",
115
+ "my-file-area-id",
116
+ "folder-guid",
117
+ "./out",
118
+ {
119
+ filenameExtensions: [".ifc"],
120
+ verbose: true,
121
+ },
122
+ );
95
123
  ```
96
124
 
97
125
  **Upload a file (chunked)**
126
+
98
127
  ```js
99
- const fs = require('fs');
128
+ const fs = require("fs");
100
129
 
101
130
  // 1. Create an upload slot
102
131
  const { uploadGuid } = await dalux.fileUpload.createUpload(
103
- 'my-project-id',
104
- 'my-file-area-id',
105
- { fileName: 'drawing.pdf', mimeType: 'application/pdf' },
132
+ "my-project-id",
133
+ "my-file-area-id",
134
+ { fileName: "drawing.pdf", mimeType: "application/pdf" },
106
135
  );
107
136
 
108
137
  // 2. Upload the file in one chunk
109
- const content = fs.readFileSync('./drawing.pdf');
110
- await dalux.fileUpload.uploadFilePart('my-project-id', 'my-file-area-id', uploadGuid, content);
138
+ const content = fs.readFileSync("./drawing.pdf");
139
+ await dalux.fileUpload.uploadFilePart(
140
+ "my-project-id",
141
+ "my-file-area-id",
142
+ uploadGuid,
143
+ content,
144
+ );
111
145
 
112
146
  // 3. Finalize the upload
113
147
  const result = await dalux.fileUpload.finishUpload(
114
- 'my-project-id',
115
- 'my-file-area-id',
148
+ "my-project-id",
149
+ "my-file-area-id",
116
150
  uploadGuid,
117
- { folderId: 'target-folder-id' },
151
+ { folderId: "target-folder-id" },
118
152
  );
119
- console.log('New file ID:', result.fileId);
153
+ console.log("New file ID:", result.fileId);
120
154
  ```
121
155
 
122
156
  ## Authentication
@@ -129,7 +163,7 @@ All methods return Promises. Network or HTTP errors (4xx / 5xx) are thrown as Ax
129
163
 
130
164
  ```js
131
165
  try {
132
- const project = await dalux.projects.getProject('unknown-id');
166
+ const project = await dalux.projects.getProject("unknown-id");
133
167
  } catch (err) {
134
168
  console.error(err.response?.status, err.response?.data);
135
169
  }
@@ -139,173 +173,173 @@ try {
139
173
 
140
174
  All API namespaces are accessible on the object returned by `createClient`:
141
175
 
142
- | Namespace | Class | Description |
143
- |---|---|---|
144
- | `projects` | `ProjectsApi` | List, get, create and update projects; manage project metadata |
145
- | `companies` | `CompaniesApi` | Project companies (CRUD) |
146
- | `companyCatalog` | `CompanyCatalogApi` | Company catalog (CRUD + metadata) |
147
- | `tasks` | `TasksApi` | Tasks, approvals, safety issues, observations & good practices |
148
- | `fileAreas` | `FileAreasApi` | File areas on a project |
149
- | `files` | `FilesApi` | Files within a file area |
150
- | `folders` | `FoldersApi` | Folders within a file area |
151
- | `fileUpload` | `FileUploadApi` | Chunked file upload (create slot → upload parts → finalize) |
152
- | `fileRevisions` | `FileRevisionsApi` | Download file revision content |
153
- | `forms` | `FormsApi` | Forms and form attachments |
154
- | `users` | `UsersApi` | Company and project users |
155
- | `projectTemplates` | `ProjectTemplatesApi` | Available project templates |
156
- | `inspectionPlans` | `InspectionPlansApi` | Inspection plans, items, zones and registrations |
157
- | `testPlans` | `TestPlansApi` | Test plans, items, zones and registrations |
158
- | `versionSets` | `VersionSetsApi` | Version sets and version set files |
159
- | `workPackages` | `WorkPackagesApi` | Work packages on a project |
176
+ | Namespace | Class | Description |
177
+ | ------------------ | --------------------- | -------------------------------------------------------------- |
178
+ | `projects` | `ProjectsApi` | List, get, create and update projects; manage project metadata |
179
+ | `companies` | `CompaniesApi` | Project companies (CRUD) |
180
+ | `companyCatalog` | `CompanyCatalogApi` | Company catalog (CRUD + metadata) |
181
+ | `tasks` | `TasksApi` | Tasks, approvals, safety issues, observations & good practices |
182
+ | `fileAreas` | `FileAreasApi` | File areas on a project |
183
+ | `files` | `FilesApi` | Files within a file area |
184
+ | `folders` | `FoldersApi` | Folders within a file area |
185
+ | `fileUpload` | `FileUploadApi` | Chunked file upload (create slot → upload parts → finalize) |
186
+ | `fileRevisions` | `FileRevisionsApi` | Download file revision content |
187
+ | `forms` | `FormsApi` | Forms and form attachments |
188
+ | `users` | `UsersApi` | Company and project users |
189
+ | `projectTemplates` | `ProjectTemplatesApi` | Available project templates |
190
+ | `inspectionPlans` | `InspectionPlansApi` | Inspection plans, items, zones and registrations |
191
+ | `testPlans` | `TestPlansApi` | Test plans, items, zones and registrations |
192
+ | `versionSets` | `VersionSetsApi` | Version sets and version set files |
193
+ | `workPackages` | `WorkPackagesApi` | Work packages on a project |
160
194
 
161
195
  ### ProjectsApi
162
196
 
163
- | Method | HTTP | Path |
164
- |---|---|---|
165
- | `listProjects(params?)` | GET | `/5.1/projects` |
166
- | `getProject(projectId)` | GET | `/5.0/projects/{projectId}` |
167
- | `createProject(body)` | POST | `/5.0/projects` |
168
- | `updateProject(projectId, body)` | PATCH | `/5.0/projects/{projectId}` |
169
- | `listMetadataMappingsForProjects()` | GET | `/1.0/projects/metadata/1.0/mappings` |
170
- | `listMetadataValuesForProjects(key)` | GET | `/1.0/projects/metadata/1.0/mappings/{key}/values` |
171
- | `listProjectMetadata(projectId)` | GET | `/1.0/projects/{projectId}/metadata` |
172
- | `listProjectMetadataMappings(projectId)` | GET | `/1.0/projects/{projectId}/metadata/1.0/mappings` |
173
- | `listProjectMetadataValues(projectId, key)` | GET | `/1.0/projects/{projectId}/metadata/1.0/mappings/{key}/values` |
197
+ | Method | HTTP | Path |
198
+ | ------------------------------------------- | ----- | -------------------------------------------------------------- |
199
+ | `listProjects(params?)` | GET | `/5.1/projects` |
200
+ | `getProject(projectId)` | GET | `/5.0/projects/{projectId}` |
201
+ | `createProject(body)` | POST | `/5.0/projects` |
202
+ | `updateProject(projectId, body)` | PATCH | `/5.0/projects/{projectId}` |
203
+ | `listMetadataMappingsForProjects()` | GET | `/1.0/projects/metadata/1.0/mappings` |
204
+ | `listMetadataValuesForProjects(key)` | GET | `/1.0/projects/metadata/1.0/mappings/{key}/values` |
205
+ | `listProjectMetadata(projectId)` | GET | `/1.0/projects/{projectId}/metadata` |
206
+ | `listProjectMetadataMappings(projectId)` | GET | `/1.0/projects/{projectId}/metadata/1.0/mappings` |
207
+ | `listProjectMetadataValues(projectId, key)` | GET | `/1.0/projects/{projectId}/metadata/1.0/mappings/{key}/values` |
174
208
 
175
209
  ### CompaniesApi
176
210
 
177
- | Method | HTTP | Path |
178
- |---|---|---|
179
- | `listProjectCompanies(projectId, params?)` | GET | `/3.1/projects/{projectId}/companies` |
180
- | `getProjectCompany(projectId, companyId)` | GET | `/3.0/projects/{projectId}/companies/{companyId}` |
181
- | `createProjectCompany(projectId, body)` | POST | `/3.1/projects/{projectId}/companies` |
211
+ | Method | HTTP | Path |
212
+ | -------------------------------------------------- | ----- | ------------------------------------------------- |
213
+ | `listProjectCompanies(projectId, params?)` | GET | `/3.1/projects/{projectId}/companies` |
214
+ | `getProjectCompany(projectId, companyId)` | GET | `/3.0/projects/{projectId}/companies/{companyId}` |
215
+ | `createProjectCompany(projectId, body)` | POST | `/3.1/projects/{projectId}/companies` |
182
216
  | `updateProjectCompany(projectId, companyId, body)` | PATCH | `/3.0/projects/{projectId}/companies/{companyId}` |
183
217
 
184
218
  ### CompanyCatalogApi
185
219
 
186
- | Method | HTTP | Path |
187
- |---|---|---|
188
- | `getCompanies(params?)` | GET | `/2.2/companyCatalog` |
189
- | `getCompany(catalogCompanyId)` | GET | `/1.2/companyCatalog/{catalogCompanyId}` |
190
- | `createCompany(body)` | POST | `/2.2/companyCatalog` |
191
- | `updateCompany(catalogCompanyId, body)` | PATCH | `/2.1/companyCatalog/{catalogCompanyId}` |
192
- | `listCompanyMetadata(catalogCompanyId)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata` |
193
- | `listCompanyMetadataMappings(catalogCompanyId)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata/1.0/mappings` |
194
- | `listCompanyMetadataValues(catalogCompanyId, key)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata/1.0/mappings/{key}/values` |
195
- | `listMetadataMappingsForCompanies()` | GET | `/1.0/companyCatalog/metadata/1.0/mappings` |
196
- | `listMetadataValuesForCompanies(key)` | GET | `/1.0/companyCatalog/metadata/1.0/mappings/{key}/values` |
220
+ | Method | HTTP | Path |
221
+ | -------------------------------------------------- | ----- | --------------------------------------------------------------------------- |
222
+ | `getCompanies(params?)` | GET | `/2.2/companyCatalog` |
223
+ | `getCompany(catalogCompanyId)` | GET | `/1.2/companyCatalog/{catalogCompanyId}` |
224
+ | `createCompany(body)` | POST | `/2.2/companyCatalog` |
225
+ | `updateCompany(catalogCompanyId, body)` | PATCH | `/2.1/companyCatalog/{catalogCompanyId}` |
226
+ | `listCompanyMetadata(catalogCompanyId)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata` |
227
+ | `listCompanyMetadataMappings(catalogCompanyId)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata/1.0/mappings` |
228
+ | `listCompanyMetadataValues(catalogCompanyId, key)` | GET | `/1.0/companyCatalog/{catalogCompanyId}/metadata/1.0/mappings/{key}/values` |
229
+ | `listMetadataMappingsForCompanies()` | GET | `/1.0/companyCatalog/metadata/1.0/mappings` |
230
+ | `listMetadataValuesForCompanies(key)` | GET | `/1.0/companyCatalog/metadata/1.0/mappings/{key}/values` |
197
231
 
198
232
  ### TasksApi
199
233
 
200
- | Method | HTTP | Path |
201
- |---|---|---|
202
- | `getProjectTasks(projectId, params?)` | GET | `/5.2/projects/{projectId}/tasks` |
234
+ | Method | HTTP | Path |
235
+ | -------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
236
+ | `getProjectTasks(projectId, params?)` | GET | `/5.2/projects/{projectId}/tasks` |
203
237
  | `getAllProjectTasks(projectId, params?, verbose?)` | GET (paginated) | `/5.2/projects/{projectId}/tasks` — collects all `items` via `nextPage` / `bookmark`; respects `metadata.totalRemainingItems` or `metadata.totalItems` (Python parity) |
204
- | `getTask(projectId, taskId)` | GET | `/3.3/projects/{projectId}/tasks/{taskId}` |
205
- | `getProjectTaskChanges(projectId, params?)` | GET | `/2.2/projects/{projectId}/tasks/changes` |
206
- | `getProjectTaskAttachments(projectId, params?)` | GET | `/1.1/projects/{projectId}/tasks/attachments` |
238
+ | `getTask(projectId, taskId)` | GET | `/3.3/projects/{projectId}/tasks/{taskId}` |
239
+ | `getProjectTaskChanges(projectId, params?)` | GET | `/2.2/projects/{projectId}/tasks/changes` |
240
+ | `getProjectTaskAttachments(projectId, params?)` | GET | `/1.1/projects/{projectId}/tasks/attachments` |
207
241
 
208
242
  Query params: pass OData options on `getProjectTasks` / `getAllProjectTasks` (for example `$filter`). Shorthand: `typeId` is translated to `$filter=data/type/typeId eq '…'` when `$filter` is not set. `TasksApi.normalizeTaskParams` applies the same rules if you build requests manually.
209
243
 
210
244
  ### FileAreasApi
211
245
 
212
- | Method | HTTP | Path |
213
- |---|---|---|
214
- | `getFileAreas(projectId, params?)` | GET | `/5.1/projects/{projectId}/file_areas` |
215
- | `getFileArea(projectId, fileAreaId)` | GET | `/1.0/projects/{projectId}/file_areas/{fileAreaId}` |
246
+ | Method | HTTP | Path |
247
+ | ------------------------------------ | ---- | --------------------------------------------------- |
248
+ | `getFileAreas(projectId, params?)` | GET | `/5.1/projects/{projectId}/file_areas` |
249
+ | `getFileArea(projectId, fileAreaId)` | GET | `/1.0/projects/{projectId}/file_areas/{fileAreaId}` |
216
250
 
217
251
  ### FilesApi
218
252
 
219
253
  Browse and paginated helpers use **route version 6.1** for the file collection. `getFile` (one file by id) uses **5.0**, as in the [Dalux Build API](https://app.swaggerhub.com/apis-docs/Dalux/DaluxBuild-api/4.14).
220
254
 
221
- | Method | HTTP | Path |
222
- |---|---|---|
223
- | `listFiles(projectId, fileAreaId, params?)` | GET | `/6.1/projects/{projectId}/file_areas/{fileAreaId}/files` |
224
- | `getAllFiles(projectId, fileAreaId, params?, verbose?)` | GET (paginated) | Same — all file `items` via bookmark / `metadata.totalRemainingItems` |
225
- | `getAllFilesInFolder(projectId, fileAreaId, folderId, params?, verbose?)` | — | Uses `getAllFiles` then filters by `data.folderId` |
226
- | `getFile(projectId, fileAreaId, fileId, options?)` | GET | `/5.0/.../files/{fileId}` — optional `{ download: true, savePath }` streams to disk (adds `downloadedFilePath`) |
227
- | `downloadFileFromLink(downloadLink, fileName, savePath?)` | GET | Direct download URL with `X-API-KEY` |
228
- | `bulkDownloadFolder(projectId, fileAreaId, folderId, savePath?, opts?)` | — | Optional `filenameKeywords`, `filenameKeywordsMatch` (`any` / `all`), `filenameExtensions`, `params`, `verbose` |
229
- | `bulkDownloadByIds(projectId, fileAreaId, fileIds, savePath?, options?)` | GET + download | Per-id `getFile` then stream from `downloadLink` |
230
- | `getFilePropertiesMapping(projectId, fileAreaId, fileId)` | GET | `/1.0/.../files/{fileId}/properties/1.0/mappings` |
231
- | `getFilePropertyMappingValues(projectId, fileAreaId, filePropertyId)` | GET | `/1.0/.../files/properties/1.0/mappings/{filePropertyId}/values` |
255
+ | Method | HTTP | Path |
256
+ | ------------------------------------------------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------- |
257
+ | `listFiles(projectId, fileAreaId, params?)` | GET | `/6.1/projects/{projectId}/file_areas/{fileAreaId}/files` |
258
+ | `getAllFiles(projectId, fileAreaId, params?, verbose?)` | GET (paginated) | Same — all file `items` via bookmark / `metadata.totalRemainingItems` |
259
+ | `getAllFilesInFolder(projectId, fileAreaId, folderId, params?, verbose?)` | — | Uses `getAllFiles` then filters by `data.folderId` |
260
+ | `getFile(projectId, fileAreaId, fileId, options?)` | GET | `/5.0/.../files/{fileId}` — optional `{ download: true, savePath }` streams to disk (adds `downloadedFilePath`) |
261
+ | `downloadFileFromLink(downloadLink, fileName, savePath?)` | GET | Direct download URL with `X-API-KEY` |
262
+ | `bulkDownloadFolder(projectId, fileAreaId, folderId, savePath?, opts?)` | — | Optional `filenameKeywords`, `filenameKeywordsMatch` (`any` / `all`), `filenameExtensions`, `params`, `verbose` |
263
+ | `bulkDownloadByIds(projectId, fileAreaId, fileIds, savePath?, options?)` | GET + download | Per-id `getFile` then stream from `downloadLink` |
264
+ | `getFilePropertiesMapping(projectId, fileAreaId, fileId)` | GET | `/1.0/.../files/{fileId}/properties/1.0/mappings` |
265
+ | `getFilePropertyMappingValues(projectId, fileAreaId, filePropertyId)` | GET | `/1.0/.../files/properties/1.0/mappings/{filePropertyId}/values` |
232
266
 
233
267
  ### FoldersApi
234
268
 
235
- | Method | HTTP | Path |
236
- |---|---|---|
237
- | `listFolders(projectId, fileAreaId, params?)` | GET | `/5.1/projects/{projectId}/file_areas/{fileAreaId}/folders` |
238
- | `getFolder(projectId, fileAreaId, folderId)` | GET | `/5.0/projects/{projectId}/file_areas/{fileAreaId}/folders/{folderId}` |
239
- | `getFolderFilesProperties(projectId, fileAreaId, folderId)` | GET | `/1.0/.../folders/{folderId}/files/properties/1.0/mappings` |
269
+ | Method | HTTP | Path |
270
+ | ----------------------------------------------------------- | ---- | ---------------------------------------------------------------------- |
271
+ | `listFolders(projectId, fileAreaId, params?)` | GET | `/5.1/projects/{projectId}/file_areas/{fileAreaId}/folders` |
272
+ | `getFolder(projectId, fileAreaId, folderId)` | GET | `/5.0/projects/{projectId}/file_areas/{fileAreaId}/folders/{folderId}` |
273
+ | `getFolderFilesProperties(projectId, fileAreaId, folderId)` | GET | `/1.0/.../folders/{folderId}/files/properties/1.0/mappings` |
240
274
 
241
275
  ### FileUploadApi
242
276
 
243
- | Method | HTTP | Path |
244
- |---|---|---|
245
- | `createUpload(projectId, fileAreaId, body)` | POST | `/1.0/projects/{projectId}/file_areas/{fileAreaId}/upload` |
246
- | `uploadFilePart(projectId, fileAreaId, uploadGuid, chunk)` | POST | `/1.0/.../upload/{uploadGuid}` |
247
- | `finishUpload(projectId, fileAreaId, uploadGuid, body)` | POST | `/2.0/.../upload/{uploadGuid}/finalize` |
277
+ | Method | HTTP | Path |
278
+ | ---------------------------------------------------------- | ---- | ---------------------------------------------------------- |
279
+ | `createUpload(projectId, fileAreaId, body)` | POST | `/1.0/projects/{projectId}/file_areas/{fileAreaId}/upload` |
280
+ | `uploadFilePart(projectId, fileAreaId, uploadGuid, chunk)` | POST | `/1.0/.../upload/{uploadGuid}` |
281
+ | `finishUpload(projectId, fileAreaId, uploadGuid, body)` | POST | `/2.0/.../upload/{uploadGuid}/finalize` |
248
282
 
249
283
  ### FileRevisionsApi
250
284
 
251
- | Method | HTTP | Path |
252
- |---|---|---|
253
- | `getFileRevisionContent(projectId, fileAreaId, fileId, fileRevisionId)` | GET | `/2.0/.../files/{fileId}/revisions/{fileRevisionId}/content` |
285
+ | Method | HTTP | Path |
286
+ | ----------------------------------------------------------------------- | ---- | ------------------------------------------------------------ |
287
+ | `getFileRevisionContent(projectId, fileAreaId, fileId, fileRevisionId)` | GET | `/2.0/.../files/{fileId}/revisions/{fileRevisionId}/content` |
254
288
 
255
289
  ### FormsApi
256
290
 
257
- | Method | HTTP | Path |
258
- |---|---|---|
259
- | `getProjectForms(projectId, params?)` | GET | `/2.1/projects/{projectId}/forms` |
260
- | `getForm(projectId, formId)` | GET | `/1.2/projects/{projectId}/forms/{formId}` |
261
- | `getProjectFormAttachments(projectId, params?)` | GET | `/2.1/projects/{projectId}/forms/attachments` |
291
+ | Method | HTTP | Path |
292
+ | ----------------------------------------------- | ---- | --------------------------------------------- |
293
+ | `getProjectForms(projectId, params?)` | GET | `/2.1/projects/{projectId}/forms` |
294
+ | `getForm(projectId, formId)` | GET | `/1.2/projects/{projectId}/forms/{formId}` |
295
+ | `getProjectFormAttachments(projectId, params?)` | GET | `/2.1/projects/{projectId}/forms/attachments` |
262
296
 
263
297
  ### UsersApi
264
298
 
265
- | Method | HTTP | Path |
266
- |---|---|---|
267
- | `getUser(userId)` | GET | `/1.1/users/{userId}` |
268
- | `listProjectUsers(projectId, params?)` | GET | `/1.2/projects/{projectId}/users` |
269
- | `getProjectUser(projectId, userId)` | GET | `/1.1/projects/{projectId}/users/{userId}` |
299
+ | Method | HTTP | Path |
300
+ | -------------------------------------- | ---- | ------------------------------------------ |
301
+ | `getUser(userId)` | GET | `/1.1/users/{userId}` |
302
+ | `listProjectUsers(projectId, params?)` | GET | `/1.2/projects/{projectId}/users` |
303
+ | `getProjectUser(projectId, userId)` | GET | `/1.1/projects/{projectId}/users/{userId}` |
270
304
 
271
305
  ### ProjectTemplatesApi
272
306
 
273
- | Method | HTTP | Path |
274
- |---|---|---|
275
- | `listProjectTemplates(params?)` | GET | `/1.1/projectTemplates` |
307
+ | Method | HTTP | Path |
308
+ | ------------------------------- | ---- | ----------------------- |
309
+ | `listProjectTemplates(params?)` | GET | `/1.1/projectTemplates` |
276
310
 
277
311
  ### InspectionPlansApi
278
312
 
279
- | Method | HTTP | Path |
280
- |---|---|---|
281
- | `listInspectionPlans(projectId, params?)` | GET | `/1.2/projects/{projectId}/inspectionPlans` |
282
- | `listInspectionPlanItems(projectId, params?)` | GET | `/1.1/projects/{projectId}/inspectionPlanItems` |
283
- | `listInspectionPlanItemZones(projectId, params?)` | GET | `/1.1/projects/{projectId}/inspectionPlanItemZones` |
284
- | `listInspectionPlanRegistrations(projectId, params?)` | GET | `/2.1/projects/{projectId}/inspectionPlanRegistrations` |
313
+ | Method | HTTP | Path |
314
+ | ----------------------------------------------------- | ---- | ------------------------------------------------------- |
315
+ | `listInspectionPlans(projectId, params?)` | GET | `/1.2/projects/{projectId}/inspectionPlans` |
316
+ | `listInspectionPlanItems(projectId, params?)` | GET | `/1.1/projects/{projectId}/inspectionPlanItems` |
317
+ | `listInspectionPlanItemZones(projectId, params?)` | GET | `/1.1/projects/{projectId}/inspectionPlanItemZones` |
318
+ | `listInspectionPlanRegistrations(projectId, params?)` | GET | `/2.1/projects/{projectId}/inspectionPlanRegistrations` |
285
319
 
286
320
  ### TestPlansApi
287
321
 
288
- | Method | HTTP | Path |
289
- |---|---|---|
290
- | `listTestPlans(projectId, params?)` | GET | `/1.2/projects/{projectId}/testPlans` |
291
- | `listTestPlanItems(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanItems` |
292
- | `listTestPlanItemZones(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanItemZones` |
293
- | `listTestPlanRegistrations(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanRegistrations` |
322
+ | Method | HTTP | Path |
323
+ | ----------------------------------------------- | ---- | ------------------------------------------------- |
324
+ | `listTestPlans(projectId, params?)` | GET | `/1.2/projects/{projectId}/testPlans` |
325
+ | `listTestPlanItems(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanItems` |
326
+ | `listTestPlanItemZones(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanItemZones` |
327
+ | `listTestPlanRegistrations(projectId, params?)` | GET | `/1.1/projects/{projectId}/testPlanRegistrations` |
294
328
 
295
329
  ### VersionSetsApi
296
330
 
297
- | Method | HTTP | Path |
298
- |---|---|---|
299
- | `getVersionSets(projectId, params?)` | GET | `/2.1/projects/{projectId}/version_sets` |
300
- | `getVersionSet(projectId, versionSetId)` | GET | `/2.0/projects/{projectId}/version_sets/{versionSetId}` |
301
- | `listFileAreaVersionSets(projectId, fileAreaId, params?)` | GET | `/2.1/projects/{projectId}/file_areas/{fileAreaId}/version_sets` |
302
- | `listVersionSetFiles(projectId, versionSetId, params?)` | GET | `/3.0/projects/{projectId}/version_sets/{versionSetId}/files` |
331
+ | Method | HTTP | Path |
332
+ | --------------------------------------------------------- | ---- | ---------------------------------------------------------------- |
333
+ | `getVersionSets(projectId, params?)` | GET | `/2.1/projects/{projectId}/version_sets` |
334
+ | `getVersionSet(projectId, versionSetId)` | GET | `/2.0/projects/{projectId}/version_sets/{versionSetId}` |
335
+ | `listFileAreaVersionSets(projectId, fileAreaId, params?)` | GET | `/2.1/projects/{projectId}/file_areas/{fileAreaId}/version_sets` |
336
+ | `listVersionSetFiles(projectId, versionSetId, params?)` | GET | `/3.0/projects/{projectId}/version_sets/{versionSetId}/files` |
303
337
 
304
338
  ### WorkPackagesApi
305
339
 
306
- | Method | HTTP | Path |
307
- |---|---|---|
308
- | `listWorkPackages(projectId, params?)` | GET | `/1.0/projects/{projectId}/workpackages` |
340
+ | Method | HTTP | Path |
341
+ | -------------------------------------- | ---- | ---------------------------------------- |
342
+ | `listWorkPackages(projectId, params?)` | GET | `/1.0/projects/{projectId}/workpackages` |
309
343
 
310
344
  ## Advanced Usage
311
345
 
@@ -314,16 +348,21 @@ Browse and paginated helpers use **route version 6.1** for the file collection.
314
348
  You can also instantiate API classes directly with a shared `ApiClient`:
315
349
 
316
350
  ```js
317
- const { Configuration, ApiClient, ProjectsApi, TasksApi } = require('@bruadam/dalux-build-api');
351
+ const {
352
+ Configuration,
353
+ ApiClient,
354
+ ProjectsApi,
355
+ TasksApi,
356
+ } = require("dalux-build-api");
318
357
 
319
358
  const config = new Configuration({
320
- baseUrl: 'https://<your-company>.dalux.com/api',
321
- apiKey: 'YOUR_API_KEY',
359
+ baseUrl: "https://<your-company>.dalux.com/api",
360
+ apiKey: "YOUR_API_KEY",
322
361
  });
323
362
  const apiClient = new ApiClient(config);
324
363
 
325
364
  const projects = new ProjectsApi(apiClient);
326
- const tasks = new TasksApi(apiClient);
365
+ const tasks = new TasksApi(apiClient);
327
366
  ```
328
367
 
329
368
  ## Development
@@ -355,10 +394,10 @@ Create a GitHub **environment** named `npm` with secret **`NPM_TOKEN`**. If push
355
394
 
356
395
  ### First publish and `E404` on `npm publish`
357
396
 
358
- If CI fails with **`404 Not Found - PUT …/@bruadam/dalux-build-api`** and **`is not in this registry`**, the package does not exist on npm yet **or** your token is not allowed to **create** it.
397
+ If CI fails with **`404 Not Found - PUT …/dalux-build-api`** and **`is not in this registry`**, the package does not exist on npm yet **or** your token is not allowed to **create** it.
359
398
 
360
399
  - **Classic [Automation](https://docs.npmjs.com/about-access-tokens#automation-tokens)** tokens only publish packages your account **already** maintains. They cannot create a **new** package name. Fix: use a **granular access token** with write access to the `@bruadam` scope (or all packages), or run **`npm publish --access public`** once locally while logged in as the owner, then switch CI back to an automation token.
361
- - Confirm the package is not taken by someone else: [https://www.npmjs.com/package/@bruadam/dalux-build-api](https://www.npmjs.com/package/@bruadam/dalux-build-api).
400
+ - Confirm the package is not taken by someone else: [https://www.npmjs.com/package/dalux-build-api](https://www.npmjs.com/package/dalux-build-api).
362
401
 
363
402
  ## License
364
403
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dalux-build-api",
3
- "version": "1.1.5",
3
+ "version": "2.0.0",
4
4
  "description": "Node.js client for the Dalux Build API",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -34,7 +34,8 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "axios": "^1.7.7"
37
+ "axios": "^1.7.7",
38
+ "zod": "^3.23.8"
38
39
  },
39
40
  "devDependencies": {
40
41
  "axios-mock-adapter": "^2.1.0",
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ const { convertToModel } = require('../models/convert');
4
+ const { CompaniesListResponseSchema, CompanyResponseSchema } = require('../models/companies');
5
+
3
6
  /**
4
7
  * API methods for managing companies on a project.
5
8
  */
@@ -16,10 +19,11 @@ class CompaniesApi {
16
19
  * GET /3.1/projects/{projectId}/companies
17
20
  * @param {string} projectId
18
21
  * @param {object} [params]
19
- * @returns {Promise<object>}
22
+ * @returns {Promise<object>} CompaniesListResponse ({ items: ProjectCompany[], metadata?, links? })
20
23
  */
21
- listProjectCompanies(projectId, params = {}) {
22
- return this._client.get(`/3.1/projects/${projectId}/companies`, params);
24
+ async listProjectCompanies(projectId, params = {}) {
25
+ const response = await this._client.get(`/3.1/projects/${projectId}/companies`, params);
26
+ return convertToModel(response, CompaniesListResponseSchema, 'CompaniesListResponse');
23
27
  }
24
28
 
25
29
  /**
@@ -27,10 +31,11 @@ class CompaniesApi {
27
31
  * GET /3.0/projects/{projectId}/companies/{companyId}
28
32
  * @param {string} projectId
29
33
  * @param {string} companyId
30
- * @returns {Promise<object>}
34
+ * @returns {Promise<object>} CompanyResponse ({ data: ProjectCompany, links? })
31
35
  */
32
- getProjectCompany(projectId, companyId) {
33
- return this._client.get(`/3.0/projects/${projectId}/companies/${companyId}`);
36
+ async getProjectCompany(projectId, companyId) {
37
+ const response = await this._client.get(`/3.0/projects/${projectId}/companies/${companyId}`);
38
+ return convertToModel(response, CompanyResponseSchema, 'CompanyResponse');
34
39
  }
35
40
 
36
41
  /**
@@ -38,10 +43,11 @@ class CompaniesApi {
38
43
  * POST /3.1/projects/{projectId}/companies
39
44
  * @param {string} projectId
40
45
  * @param {object} body
41
- * @returns {Promise<object>}
46
+ * @returns {Promise<object>} CompanyResponse
42
47
  */
43
- createProjectCompany(projectId, body) {
44
- return this._client.post(`/3.1/projects/${projectId}/companies`, body);
48
+ async createProjectCompany(projectId, body) {
49
+ const response = await this._client.post(`/3.1/projects/${projectId}/companies`, body);
50
+ return convertToModel(response, CompanyResponseSchema, 'CompanyResponse');
45
51
  }
46
52
 
47
53
  /**
@@ -50,10 +56,11 @@ class CompaniesApi {
50
56
  * @param {string} projectId
51
57
  * @param {string} companyId
52
58
  * @param {object} body
53
- * @returns {Promise<object>}
59
+ * @returns {Promise<object>} CompanyResponse
54
60
  */
55
- updateProjectCompany(projectId, companyId, body) {
56
- return this._client.patch(`/3.0/projects/${projectId}/companies/${companyId}`, body);
61
+ async updateProjectCompany(projectId, companyId, body) {
62
+ const response = await this._client.patch(`/3.0/projects/${projectId}/companies/${companyId}`, body);
63
+ return convertToModel(response, CompanyResponseSchema, 'CompanyResponse');
57
64
  }
58
65
  }
59
66