swoop-common 2.1.48 → 2.1.50

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.
@@ -1,29 +1,62 @@
1
1
  import fs from "fs";
2
- // Super lazy bundler, just sticks models onto the end of specs and updates refs
3
- const bundle = (sdk) => {
4
- const specs = fs.readFileSync(`./openapi/${sdk}_service.yaml`, "utf-8");
5
- const models = fs.readFileSync("./openapi/models.yaml", "utf-8");
6
- // Remove header of models
7
- const clean = models.split("\n");
8
- let reached = false;
9
- let full = "";
10
- for (let i = 0; i < clean.length; i++) {
11
- if (!reached && clean[i].startsWith("components"))
12
- reached = true;
13
- // Removes tags
14
- if (clean[i].startsWith("tags"))
15
- break;
16
- if (reached)
17
- full += "\n" + clean[i];
2
+ import yaml from "js-yaml";
3
+ /**
4
+ * Merge all `components` subsections (schemas, parameters, responses, etc.)
5
+ */
6
+ function mergeComponents(target, source) {
7
+ if (!(source === null || source === void 0 ? void 0 : source.components))
8
+ return;
9
+ if (!target.components) {
10
+ target.components = {};
18
11
  }
19
- // Dont need to parse specs, can just look for references
20
- const updatedSpecs = specs.replace(/\.\/models\.yaml/g, "") + "\n" + full;
21
- // Make sure all refs are wrapped in '
22
- const cleanedSpecs = updatedSpecs.split("\n").map(line => line.replace(/(\$ref:\s*)(["']?)([^"'\s]+)\2/, (_, prefix, _q, path) => {
23
- return `${prefix}'${path}'`;
24
- })).join("\n");
12
+ for (const key of Object.keys(source.components)) {
13
+ if (!target.components[key]) {
14
+ target.components[key] = {};
15
+ }
16
+ Object.assign(target.components[key], source.components[key]);
17
+ }
18
+ }
19
+ /**
20
+ * Fix $ref pointers from external file refs (e.g. ./models.yaml#/...)
21
+ * to internal refs (#/components/...)
22
+ */
23
+ function fixRefs(obj) {
24
+ if (Array.isArray(obj)) {
25
+ return obj.map(fixRefs);
26
+ }
27
+ else if (obj && typeof obj === "object") {
28
+ for (const key of Object.keys(obj)) {
29
+ if (key === "$ref" && typeof obj[key] === "string") {
30
+ obj[key] = obj[key]
31
+ .replace("./models.yaml#", "#")
32
+ .replace("./error.yaml#", "#");
33
+ }
34
+ else {
35
+ obj[key] = fixRefs(obj[key]);
36
+ }
37
+ }
38
+ }
39
+ return obj;
40
+ }
41
+ function bundle(sdk) {
42
+ const servicePath = `./openapi/${sdk}_service.yaml`;
43
+ const modelsPath = "./openapi/models.yaml";
44
+ const errorsPath = "./openapi/error.yaml";
45
+ const outputPath = `./openapi/generated/${sdk}_bundled.yaml`;
46
+ // Load YAML files
47
+ const service = yaml.load(fs.readFileSync(servicePath, "utf-8"));
48
+ const models = yaml.load(fs.readFileSync(modelsPath, "utf-8"));
49
+ const errors = yaml.load(fs.readFileSync(errorsPath, "utf-8"));
50
+ // Merge all components
51
+ mergeComponents(service, models);
52
+ mergeComponents(service, errors);
53
+ // Fix refs
54
+ const fixed = fixRefs(service);
55
+ // Dump back to YAML
56
+ const bundled = yaml.dump(fixed, { noRefs: true, lineWidth: -1 });
25
57
  fs.mkdirSync("./openapi/generated", { recursive: true });
26
- fs.writeFileSync(`./openapi/generated/${sdk}_bundled.yaml`, cleanedSpecs);
27
- };
58
+ fs.writeFileSync(outputPath, bundled);
59
+ console.log(`✅ Bundled ${sdk} -> ${outputPath}`);
60
+ }
28
61
  bundle("core");
29
62
  bundle("itinerary");
@@ -39,6 +39,7 @@ export type { DTOTemplateEntity } from './index';
39
39
  export type { DTOTemplateRead } from './index';
40
40
  export type { DTOTemplateUpdate } from './index';
41
41
  export type { enquiryId } from './index';
42
+ export type { Error } from './index';
42
43
  export type { Fee } from './index';
43
44
  export type { Field } from './index';
44
45
  export type { IBEvent } from './index';
@@ -41,6 +41,7 @@ export type { DTOTemplateEntity } from './models/DTOTemplateEntity';
41
41
  export type { DTOTemplateRead } from './models/DTOTemplateRead';
42
42
  export type { DTOTemplateUpdate } from './models/DTOTemplateUpdate';
43
43
  export type { enquiryId } from './models/enquiryId';
44
+ export type { Error } from './models/Error';
44
45
  export type { Fee } from './models/Fee';
45
46
  export type { Field } from './models/Field';
46
47
  export type { IBEvent } from './models/IBEvent';
@@ -0,0 +1 @@
1
+ export type Error = Record<string, any>;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  export const OpenAPI = {
2
- BASE: 'https://placeholder.com',
3
- VERSION: '1.1',
2
+ BASE: 'https://data-api-dev.swoop-adventures.com/itinerary-builder-service/v1',
3
+ VERSION: '1',
4
4
  WITH_CREDENTIALS: false,
5
5
  CREDENTIALS: 'include',
6
6
  TOKEN: undefined,
@@ -41,6 +41,7 @@ export type { DTOTemplateEntity } from './models/DTOTemplateEntity';
41
41
  export type { DTOTemplateRead } from './models/DTOTemplateRead';
42
42
  export type { DTOTemplateUpdate } from './models/DTOTemplateUpdate';
43
43
  export type { enquiryId } from './models/enquiryId';
44
+ export type { Error } from './models/Error';
44
45
  export type { Fee } from './models/Fee';
45
46
  export type { Field } from './models/Field';
46
47
  export type { IBEvent } from './models/IBEvent';
@@ -0,0 +1 @@
1
+ export type Error = Record<string, any>;
@@ -0,0 +1 @@
1
+ export {};
@@ -8,11 +8,20 @@ import type { DTOSnapshotRead } from '../models/DTOSnapshotRead';
8
8
  import type { Pagination } from '../models/Pagination';
9
9
  import type { CancelablePromise } from '../core/CancelablePromise';
10
10
  export declare class ItineraryService {
11
+ /**
12
+ * Audit a Copy to Clipboard
13
+ * Audits when a user copies something to their clipboard
14
+ * @param itineraryId Itinerary id
15
+ * @param content Base64 encoding of the copied content
16
+ * @returns void
17
+ * @throws ApiError
18
+ */
19
+ auditCopyClipboard(itineraryId: string, content: string): CancelablePromise<void>;
11
20
  /**
12
21
  * Create a Snapshot
13
22
  * Creates a new snapshot. A snapshot is a reference to a specific itinerary revision group id.
14
23
  * @param requestBody
15
- * @returns DTOSnapshotRead OK
24
+ * @returns DTOSnapshotRead When a snapshot is created
16
25
  * @throws ApiError
17
26
  */
18
27
  snapshotCreate(requestBody: DTOSnapshotCreate): CancelablePromise<DTOSnapshotRead>;
@@ -22,42 +31,37 @@ export declare class ItineraryService {
22
31
  * @param page Pagination, starting at page 1
23
32
  * @param limit Number of items per page
24
33
  * @param sort List of fields to sort by
25
- * @param itineraryId Itinerary Id
26
- * @returns any OK
34
+ * @returns any The list of all snapshots given the parameters used
27
35
  * @throws ApiError
28
36
  */
29
- snapshotList(page?: number, limit?: number, sort?: any[], itineraryId?: string): CancelablePromise<{
30
- data: Array<DTOSnapshotRead>;
37
+ snapshotList(page?: number, limit?: number, sort?: any[]): CancelablePromise<{
38
+ data?: Array<DTOSnapshotRead>;
31
39
  pagination?: Pagination;
32
40
  }>;
33
41
  /**
34
42
  * Get Snapshot va ID
35
- * Returns the specific snapshot
43
+ * Returns the specific snapshot given its Id
36
44
  * @param snapshotId
37
45
  * @returns any OK
38
46
  * @throws ApiError
39
47
  */
40
- snapshotGet(snapshotId: string): CancelablePromise<{
41
- data: Array<DTOSnapshotRead>;
42
- }>;
48
+ snapshotGet(snapshotId: string): CancelablePromise<any>;
43
49
  /**
44
50
  * Delete Snapshot via ID
45
- * Deletes a specific snapshot
51
+ * Deletes a specific snapshot given its Id
46
52
  * @param snapshotId
47
- * @returns any OK
53
+ * @returns void
48
54
  * @throws ApiError
49
55
  */
50
- snapshotDelete(snapshotId: string): CancelablePromise<any>;
56
+ snapshotDelete(snapshotId: string): CancelablePromise<void>;
51
57
  /**
52
58
  * Restore Snapshot
53
59
  * Creates a new itinerary revision given the content the snapshot refers to
54
60
  * @param snapshotId
55
- * @returns any OK
61
+ * @returns any When a snapshot is restored as the latest version
56
62
  * @throws ApiError
57
63
  */
58
- snapshotRestore(snapshotId: string): CancelablePromise<{
59
- data: Array<DTOSnapshotRead>;
60
- }>;
64
+ snapshotRestore(snapshotId: string): CancelablePromise<any>;
61
65
  /**
62
66
  * List Itineraries
63
67
  * List all itineraries
@@ -66,18 +70,18 @@ export declare class ItineraryService {
66
70
  * @param search Search term
67
71
  * @param sort List of fields to sort by
68
72
  * @param enquiryId Filter itineraries via enquiryId
69
- * @returns any OK
73
+ * @returns any The list of all itineraries given the parameters used
70
74
  * @throws ApiError
71
75
  */
72
76
  itineraryList(page?: number, limit?: number, search?: string, sort?: any[], enquiryId?: string): CancelablePromise<{
73
- data: Array<DTOItineraryRead>;
77
+ data?: Array<DTOItineraryRead>;
74
78
  pagination?: Pagination;
75
79
  }>;
76
80
  /**
77
- * Create Itinerary
78
- * Creates an itinerary
81
+ * Create an Itinerary
82
+ * Creates a new itinerary
79
83
  * @param requestBody
80
- * @returns DTOItineraryRead OK
84
+ * @returns DTOItineraryRead When a itinerary is created
81
85
  * @throws ApiError
82
86
  */
83
87
  itineraryCreate(requestBody: DTOItineraryCreate): CancelablePromise<DTOItineraryRead>;
@@ -85,35 +89,35 @@ export declare class ItineraryService {
85
89
  * Get Itinerary
86
90
  * Get itinerary via ID
87
91
  * @param itineraryId Itinerary id
88
- * @returns DTOItineraryRead OK
92
+ * @returns any OK
89
93
  * @throws ApiError
90
94
  */
91
- itineraryGet(itineraryId: string): CancelablePromise<DTOItineraryRead>;
95
+ itineraryGet(itineraryId: string): CancelablePromise<any>;
92
96
  /**
93
- * Update Itinerary
97
+ * Update Itinerary as New Revision
94
98
  * Updates an itinerary as a new revision
95
99
  * @param itineraryId Itinerary id
96
100
  * @param requestBody
97
- * @returns DTOItineraryRead OK
101
+ * @returns DTOItineraryRead When a new revision is created successfully
98
102
  * @throws ApiError
99
103
  */
100
- itineraryUpdate(itineraryId: string, requestBody: DTOItineraryUpdate): CancelablePromise<DTOItineraryRead>;
104
+ itineraryUpdateAsNewRevision(itineraryId: string, requestBody: DTOItineraryUpdate): CancelablePromise<DTOItineraryRead>;
101
105
  /**
102
- * Delete Itinerary
103
- * Delete itinerary via ID
106
+ * Delete Itinerary via ID
107
+ * Deletes a specific itinerary given its Id
104
108
  * @param itineraryId Itinerary id
105
- * @returns any OK
109
+ * @returns void
106
110
  * @throws ApiError
107
111
  */
108
- itineraryDelete(itineraryId: string): CancelablePromise<any>;
112
+ itineraryDelete(itineraryId: string): CancelablePromise<void>;
109
113
  /**
110
114
  * Sync Itinerary
111
115
  * Sync an itinerary with swoop
112
116
  * @param itineraryId Itinerary id
113
- * @returns DTOItineraryRead OK
117
+ * @returns DTOItineraryRead When an itinerary has been posted to pub/sub successfully
114
118
  * @throws ApiError
115
119
  */
116
- sync(itineraryId: string): CancelablePromise<DTOItineraryRead>;
120
+ syncItinerary(itineraryId: string): CancelablePromise<DTOItineraryRead>;
117
121
  /**
118
122
  * List Regions
119
123
  * List all regions
@@ -124,8 +128,8 @@ export declare class ItineraryService {
124
128
  * @throws ApiError
125
129
  */
126
130
  regionList(page?: number, limit?: number, sort?: any[]): CancelablePromise<{
127
- data: Array<DTORegionRead>;
128
- pagination: Pagination;
131
+ data?: Array<DTORegionRead>;
132
+ pagination?: Pagination;
129
133
  }>;
130
134
  /**
131
135
  * Create Region
@@ -1,11 +1,35 @@
1
1
  import { OpenAPI } from '../core/OpenAPI';
2
2
  import { request as __request } from '../core/request';
3
3
  export class ItineraryService {
4
+ /**
5
+ * Audit a Copy to Clipboard
6
+ * Audits when a user copies something to their clipboard
7
+ * @param itineraryId Itinerary id
8
+ * @param content Base64 encoding of the copied content
9
+ * @returns void
10
+ * @throws ApiError
11
+ */
12
+ auditCopyClipboard(itineraryId, content) {
13
+ return __request(OpenAPI, {
14
+ method: 'POST',
15
+ url: '/audit/copyClipboard/{itineraryId}',
16
+ path: {
17
+ 'itineraryId': itineraryId,
18
+ },
19
+ query: {
20
+ 'content': content,
21
+ },
22
+ errors: {
23
+ 400: `When the content query b64 string is invalid`,
24
+ 401: `Unauthorized - Missing or invalid Authorization header`,
25
+ },
26
+ });
27
+ }
4
28
  /**
5
29
  * Create a Snapshot
6
30
  * Creates a new snapshot. A snapshot is a reference to a specific itinerary revision group id.
7
31
  * @param requestBody
8
- * @returns DTOSnapshotRead OK
32
+ * @returns DTOSnapshotRead When a snapshot is created
9
33
  * @throws ApiError
10
34
  */
11
35
  snapshotCreate(requestBody) {
@@ -14,6 +38,12 @@ export class ItineraryService {
14
38
  url: '/snapshots',
15
39
  body: requestBody,
16
40
  mediaType: 'application/json',
41
+ errors: {
42
+ 400: `If the payload is malformed`,
43
+ 401: `Unauthorized - Missing or invalid Authorization header`,
44
+ 500: `When an internal server error occurs when creating a snapshot entity`,
45
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
46
+ },
17
47
  });
18
48
  }
19
49
  /**
@@ -22,11 +52,10 @@ export class ItineraryService {
22
52
  * @param page Pagination, starting at page 1
23
53
  * @param limit Number of items per page
24
54
  * @param sort List of fields to sort by
25
- * @param itineraryId Itinerary Id
26
- * @returns any OK
55
+ * @returns any The list of all snapshots given the parameters used
27
56
  * @throws ApiError
28
57
  */
29
- snapshotList(page, limit, sort, itineraryId) {
58
+ snapshotList(page, limit, sort) {
30
59
  return __request(OpenAPI, {
31
60
  method: 'GET',
32
61
  url: '/snapshots',
@@ -34,13 +63,18 @@ export class ItineraryService {
34
63
  'page': page,
35
64
  'limit': limit,
36
65
  'sort': sort,
37
- 'itineraryId': itineraryId,
66
+ },
67
+ errors: {
68
+ 400: `If the filter options or query parameters contain invalid values`,
69
+ 401: `Unauthorized - Missing or invalid Authorization header`,
70
+ 500: `When an internal server error occurs when listing all related snapshots`,
71
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
38
72
  },
39
73
  });
40
74
  }
41
75
  /**
42
76
  * Get Snapshot va ID
43
- * Returns the specific snapshot
77
+ * Returns the specific snapshot given its Id
44
78
  * @param snapshotId
45
79
  * @returns any OK
46
80
  * @throws ApiError
@@ -52,13 +86,18 @@ export class ItineraryService {
52
86
  path: {
53
87
  'snapshotId': snapshotId,
54
88
  },
89
+ errors: {
90
+ 401: `Unauthorized - Missing or invalid Authorization header`,
91
+ 404: `If the snapshot does not exist`,
92
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
93
+ },
55
94
  });
56
95
  }
57
96
  /**
58
97
  * Delete Snapshot via ID
59
- * Deletes a specific snapshot
98
+ * Deletes a specific snapshot given its Id
60
99
  * @param snapshotId
61
- * @returns any OK
100
+ * @returns void
62
101
  * @throws ApiError
63
102
  */
64
103
  snapshotDelete(snapshotId) {
@@ -68,13 +107,19 @@ export class ItineraryService {
68
107
  path: {
69
108
  'snapshotId': snapshotId,
70
109
  },
110
+ errors: {
111
+ 400: `When the snapshot doesn't exist in the first place, or when a before hook fails before deleting the item`,
112
+ 401: `Unauthorized - Missing or invalid Authorization header`,
113
+ 500: `When the snapshot fails to delete due to an internal server error`,
114
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
115
+ },
71
116
  });
72
117
  }
73
118
  /**
74
119
  * Restore Snapshot
75
120
  * Creates a new itinerary revision given the content the snapshot refers to
76
121
  * @param snapshotId
77
- * @returns any OK
122
+ * @returns any When a snapshot is restored as the latest version
78
123
  * @throws ApiError
79
124
  */
80
125
  snapshotRestore(snapshotId) {
@@ -84,6 +129,13 @@ export class ItineraryService {
84
129
  path: {
85
130
  'snapshotId': snapshotId,
86
131
  },
132
+ errors: {
133
+ 400: `If the payload is malformed`,
134
+ 401: `Unauthorized - Missing or invalid Authorization header`,
135
+ 404: `If the snapshot or itinerary to restore to does not exist`,
136
+ 500: `When the snapshot fails to restore due to an internal server error`,
137
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
138
+ },
87
139
  });
88
140
  }
89
141
  /**
@@ -94,7 +146,7 @@ export class ItineraryService {
94
146
  * @param search Search term
95
147
  * @param sort List of fields to sort by
96
148
  * @param enquiryId Filter itineraries via enquiryId
97
- * @returns any OK
149
+ * @returns any The list of all itineraries given the parameters used
98
150
  * @throws ApiError
99
151
  */
100
152
  itineraryList(page, limit, search, sort, enquiryId) {
@@ -108,13 +160,19 @@ export class ItineraryService {
108
160
  'sort': sort,
109
161
  'enquiryId': enquiryId,
110
162
  },
163
+ errors: {
164
+ 400: `If the filter options or query parameters contain invalid values`,
165
+ 401: `Unauthorized - Missing or invalid Authorization header`,
166
+ 500: `When an internal server error occurs when listing all related itineraries`,
167
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
168
+ },
111
169
  });
112
170
  }
113
171
  /**
114
- * Create Itinerary
115
- * Creates an itinerary
172
+ * Create an Itinerary
173
+ * Creates a new itinerary
116
174
  * @param requestBody
117
- * @returns DTOItineraryRead OK
175
+ * @returns DTOItineraryRead When a itinerary is created
118
176
  * @throws ApiError
119
177
  */
120
178
  itineraryCreate(requestBody) {
@@ -123,13 +181,19 @@ export class ItineraryService {
123
181
  url: '/itineraries',
124
182
  body: requestBody,
125
183
  mediaType: 'application/json',
184
+ errors: {
185
+ 400: `If the payload is malformed`,
186
+ 401: `Unauthorized - Missing or invalid Authorization header`,
187
+ 500: `When an internal server error occurs when creating a itinerary entity`,
188
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
189
+ },
126
190
  });
127
191
  }
128
192
  /**
129
193
  * Get Itinerary
130
194
  * Get itinerary via ID
131
195
  * @param itineraryId Itinerary id
132
- * @returns DTOItineraryRead OK
196
+ * @returns any OK
133
197
  * @throws ApiError
134
198
  */
135
199
  itineraryGet(itineraryId) {
@@ -139,17 +203,22 @@ export class ItineraryService {
139
203
  path: {
140
204
  'itineraryId': itineraryId,
141
205
  },
206
+ errors: {
207
+ 401: `Unauthorized - Missing or invalid Authorization header`,
208
+ 404: `If the itinerary does not exist`,
209
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
210
+ },
142
211
  });
143
212
  }
144
213
  /**
145
- * Update Itinerary
214
+ * Update Itinerary as New Revision
146
215
  * Updates an itinerary as a new revision
147
216
  * @param itineraryId Itinerary id
148
217
  * @param requestBody
149
- * @returns DTOItineraryRead OK
218
+ * @returns DTOItineraryRead When a new revision is created successfully
150
219
  * @throws ApiError
151
220
  */
152
- itineraryUpdate(itineraryId, requestBody) {
221
+ itineraryUpdateAsNewRevision(itineraryId, requestBody) {
153
222
  return __request(OpenAPI, {
154
223
  method: 'PATCH',
155
224
  url: '/itineraries/{itineraryId}',
@@ -158,13 +227,20 @@ export class ItineraryService {
158
227
  },
159
228
  body: requestBody,
160
229
  mediaType: 'application/json',
230
+ errors: {
231
+ 400: `If the payload is malformed`,
232
+ 401: `Unauthorized - Missing or invalid Authorization header`,
233
+ 404: `When the itinerary id to create a new revision from is not found`,
234
+ 500: `When an internal server error occurs updating an itinerary as a new revision`,
235
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
236
+ },
161
237
  });
162
238
  }
163
239
  /**
164
- * Delete Itinerary
165
- * Delete itinerary via ID
240
+ * Delete Itinerary via ID
241
+ * Deletes a specific itinerary given its Id
166
242
  * @param itineraryId Itinerary id
167
- * @returns any OK
243
+ * @returns void
168
244
  * @throws ApiError
169
245
  */
170
246
  itineraryDelete(itineraryId) {
@@ -174,22 +250,35 @@ export class ItineraryService {
174
250
  path: {
175
251
  'itineraryId': itineraryId,
176
252
  },
253
+ errors: {
254
+ 400: `When the itinerary doesn't exist in the first place, or when a before hook fails before deleting the item`,
255
+ 401: `Unauthorized - Missing or invalid Authorization header`,
256
+ 500: `When the itinerary fails to delete due to an internal server error`,
257
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
258
+ },
177
259
  });
178
260
  }
179
261
  /**
180
262
  * Sync Itinerary
181
263
  * Sync an itinerary with swoop
182
264
  * @param itineraryId Itinerary id
183
- * @returns DTOItineraryRead OK
265
+ * @returns DTOItineraryRead When an itinerary has been posted to pub/sub successfully
184
266
  * @throws ApiError
185
267
  */
186
- sync(itineraryId) {
268
+ syncItinerary(itineraryId) {
187
269
  return __request(OpenAPI, {
188
270
  method: 'POST',
189
271
  url: '/sync/{itineraryId}',
190
272
  path: {
191
273
  'itineraryId': itineraryId,
192
274
  },
275
+ errors: {
276
+ 400: `When the itinerary to sync does not exist`,
277
+ 401: `Unauthorized - Missing or invalid Authorization header`,
278
+ 404: `Related entity not found`,
279
+ 500: `When an internal server error occurs whilst syncing`,
280
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
281
+ },
193
282
  });
194
283
  }
195
284
  /**
@@ -210,6 +299,12 @@ export class ItineraryService {
210
299
  'limit': limit,
211
300
  'sort': sort,
212
301
  },
302
+ errors: {
303
+ 400: `If the filter options or query parameters contain invalid values`,
304
+ 401: `Unauthorized - Missing or invalid Authorization header`,
305
+ 500: `When an internal server error occurs when listing all related regions`,
306
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
307
+ },
213
308
  });
214
309
  }
215
310
  /**
@@ -225,6 +320,12 @@ export class ItineraryService {
225
320
  url: '/regions',
226
321
  body: requestBody,
227
322
  mediaType: 'application/json',
323
+ errors: {
324
+ 400: `If the payload is malformed`,
325
+ 401: `Unauthorized - Missing or invalid Authorization header`,
326
+ 500: `When an internal server error occurs when creating a region entity`,
327
+ 503: `Service Unavailable - The server is temporarily unable to handle the request`,
328
+ },
228
329
  });
229
330
  }
230
331
  }
@@ -7,5 +7,5 @@ interface ComponentPickerModalProps {
7
7
  selectedComponent?: DTOComponentRead | null;
8
8
  parentIdsFilter?: Array<string>;
9
9
  }
10
- export default function ComponentPickerModal({ open, onClose, onSelect, selectedComponent, parentIdsFilter }: ComponentPickerModalProps): React.JSX.Element;
10
+ export default function ComponentPickerModal({ open, onClose, onSelect, selectedComponent, parentIdsFilter, }: ComponentPickerModalProps): React.JSX.Element;
11
11
  export {};
@@ -13,7 +13,7 @@ import { Search as SearchIcon, Clear as ClearIcon, FilterList as FilterIcon, } f
13
13
  import { PARTNER_REGION_READABLE } from "../consts/region";
14
14
  import { fetchComponents, getAllPartners } from "../util/api";
15
15
  import { InternalServices } from "../../api/init";
16
- export default function ComponentPickerModal({ open, onClose, onSelect, selectedComponent, parentIdsFilter }) {
16
+ export default function ComponentPickerModal({ open, onClose, onSelect, selectedComponent, parentIdsFilter, }) {
17
17
  const [searchTerm, setSearchTerm] = useState("");
18
18
  const [selectedRegion, setSelectedRegion] = useState("");
19
19
  const [selectedPartner, setSelectedPartner] = useState("");
@@ -43,7 +43,14 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
43
43
  if (open) {
44
44
  fetchFilteredComponents();
45
45
  }
46
- }, [open, debouncedSearchTerm, selectedRegion, selectedPartner, selectedTemplate, page]);
46
+ }, [
47
+ open,
48
+ debouncedSearchTerm,
49
+ selectedRegion,
50
+ selectedPartner,
51
+ selectedTemplate,
52
+ page,
53
+ ]);
47
54
  useEffect(() => {
48
55
  if (open) {
49
56
  setPage(1);
@@ -67,7 +74,7 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
67
74
  ]);
68
75
  setTemplates(templatesData.data);
69
76
  setPartners(partnersData);
70
- setRegions(regionsData.data);
77
+ setRegions((regionsData.data || []));
71
78
  }
72
79
  catch (error) {
73
80
  console.error("Error loading initial data:", error);
@@ -121,9 +128,9 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
121
128
  onClose();
122
129
  };
123
130
  const getComponentDetails = (component) => {
124
- const template = templates.find(t => t.id === component.templateId);
125
- const componentPartners = partners.filter(p => { var _a; return p.id && ((_a = component.partners) === null || _a === void 0 ? void 0 : _a.includes(p.id)); });
126
- const componentRegions = regions.filter(r => { var _a; return (_a = component.regions) === null || _a === void 0 ? void 0 : _a.includes(r.id); });
131
+ const template = templates.find((t) => t.id === component.templateId);
132
+ const componentPartners = partners.filter((p) => { var _a; return p.id && ((_a = component.partners) === null || _a === void 0 ? void 0 : _a.includes(p.id)); });
133
+ const componentRegions = regions.filter((r) => { var _a; return (_a = component.regions) === null || _a === void 0 ? void 0 : _a.includes(r.id); });
127
134
  return { template, partners: componentPartners, regions: componentRegions };
128
135
  };
129
136
  const hasActiveFilters = selectedRegion || selectedPartner || selectedTemplate;
@@ -141,24 +148,23 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
141
148
  hasActiveFilters && (React.createElement(Button, { size: "small", startIcon: React.createElement(ClearIcon, null), onClick: handleClearFilters }, "Clear Filters")))),
142
149
  React.createElement(DialogContent, { dividers: true },
143
150
  React.createElement(TextField, { fullWidth: true, placeholder: "Search components...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), InputProps: {
144
- startAdornment: React.createElement(InputAdornment, { position: "start" },
145
- React.createElement(SearchIcon, null)),
151
+ startAdornment: (React.createElement(InputAdornment, { position: "start" },
152
+ React.createElement(SearchIcon, null))),
146
153
  endAdornment: searchTerm && (React.createElement(InputAdornment, { position: "end" },
147
154
  React.createElement(IconButton, { size: "small", onClick: handleClearSearch },
148
155
  React.createElement(ClearIcon, null)))),
149
156
  }, sx: { mb: 2 } }),
150
157
  React.createElement(Box, { display: "flex", gap: 2, mb: 2, flexWrap: "wrap" },
151
- React.createElement(Autocomplete, { size: "small", options: usedRegions, getOptionLabel: (option) => option.name, value: usedRegions.find(r => r.id === selectedRegion) || null, onChange: (_, newValue) => setSelectedRegion((newValue === null || newValue === void 0 ? void 0 : newValue.id) || ""), renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { label: "Region" })), sx: { minWidth: 160 }, isOptionEqualToValue: (option, value) => option.id === value.id }),
158
+ React.createElement(Autocomplete, { size: "small", options: usedRegions, getOptionLabel: (option) => option.name, value: usedRegions.find((r) => r.id === selectedRegion) || null, onChange: (_, newValue) => setSelectedRegion((newValue === null || newValue === void 0 ? void 0 : newValue.id) || ""), renderInput: (params) => React.createElement(TextField, Object.assign({}, params, { label: "Region" })), sx: { minWidth: 160 }, isOptionEqualToValue: (option, value) => option.id === value.id }),
152
159
  React.createElement(TextField, { select: true, size: "small", label: "Partner", value: selectedPartner, onChange: (e) => setSelectedPartner(e.target.value), sx: { minWidth: 160 } },
153
160
  React.createElement(MenuItem, { value: "" }, "All Partners"),
154
161
  usedPartners.map((partner) => (React.createElement(MenuItem, { key: partner.id, value: partner.id }, partner.name)))),
155
- !(parentIdsFilter === null || parentIdsFilter === void 0 ? void 0 : parentIdsFilter.length) &&
156
- React.createElement(TextField, { select: true, size: "small", label: "Type", value: selectedTemplate, onChange: (e) => setSelectedTemplate(e.target.value), sx: { minWidth: 160 } },
157
- React.createElement(MenuItem, { value: "" }, "All Types"),
158
- usedTemplates.map((template) => (React.createElement(MenuItem, { key: template.id, value: template.id },
159
- template.name,
160
- " v",
161
- template.revision))))),
162
+ !(parentIdsFilter === null || parentIdsFilter === void 0 ? void 0 : parentIdsFilter.length) && (React.createElement(TextField, { select: true, size: "small", label: "Type", value: selectedTemplate, onChange: (e) => setSelectedTemplate(e.target.value), sx: { minWidth: 160 } },
163
+ React.createElement(MenuItem, { value: "" }, "All Types"),
164
+ usedTemplates.map((template) => (React.createElement(MenuItem, { key: template.id, value: template.id },
165
+ template.name,
166
+ " v",
167
+ template.revision)))))),
162
168
  React.createElement(Box, { display: "flex", alignItems: "center", gap: 2, mb: 1 },
163
169
  React.createElement(Typography, { variant: "body2", color: "text.secondary" },
164
170
  totalCount,
@@ -166,7 +172,12 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
166
172
  totalCount !== 1 ? "s" : "",
167
173
  " found"),
168
174
  loading && React.createElement(CircularProgress, { size: 16 })),
169
- React.createElement(List, { sx: { display: "flex", flexDirection: "column", flex: 1, overflow: "auto" } }, loading && components.length === 0 ? (React.createElement(Box, { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", py: 4 },
175
+ React.createElement(List, { sx: {
176
+ display: "flex",
177
+ flexDirection: "column",
178
+ flex: 1,
179
+ overflow: "auto",
180
+ } }, loading && components.length === 0 ? (React.createElement(Box, { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", py: 4 },
170
181
  React.createElement(CircularProgress, { size: 48, sx: { mb: 2 } }),
171
182
  React.createElement(Typography, { variant: "body1", color: "text.secondary" }, "Loading components..."))) : components.length === 0 ? (React.createElement(Box, { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", py: 4 },
172
183
  React.createElement(FilterIcon, { sx: { fontSize: 48, color: "text.secondary", mb: 2 } }),
@@ -193,10 +204,12 @@ export default function ComponentPickerModal({ open, onClose, onSelect, selected
193
204
  details.template.name)),
194
205
  details.regions.length > 0 && (React.createElement(Box, { display: "flex", alignItems: "center", gap: 1, mt: 0.5 },
195
206
  React.createElement(Typography, { variant: "body2", color: "text.secondary" }, "Regions:"),
196
- details.regions.map(region => (React.createElement(Chip, { key: region.id, label: region.name, size: "small", variant: "outlined" }))))),
207
+ details.regions.map((region) => (React.createElement(Chip, { key: region.id, label: region.name, size: "small", variant: "outlined" }))))),
197
208
  details.partners.length > 0 && (React.createElement(Box, { display: "flex", alignItems: "center", gap: 1, mt: 0.5 },
198
209
  React.createElement(Typography, { variant: "body2", color: "text.secondary" }, "Partners:"),
199
- details.partners.slice(0, 3).map(partner => (React.createElement(Chip, { key: partner.id, label: `${partner.name} - ${PARTNER_REGION_READABLE[partner.id || "".split("-")[0]]}`, size: "small", variant: "outlined", color: "secondary" }))),
210
+ details.partners
211
+ .slice(0, 3)
212
+ .map((partner) => (React.createElement(Chip, { key: partner.id, label: `${partner.name} - ${PARTNER_REGION_READABLE[partner.id || "".split("-")[0]]}`, size: "small", variant: "outlined", color: "secondary" }))),
200
213
  details.partners.length > 3 && (React.createElement(Typography, { variant: "body2", color: "text.secondary" },
201
214
  "+",
202
215
  details.partners.length - 3,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swoop-common",
3
- "version": "2.1.48",
3
+ "version": "2.1.50",
4
4
  "main": "dist/api/index.js",
5
5
  "types": "dist/api/index.d.ts",
6
6
  "exports": {
@@ -42,6 +42,7 @@
42
42
  "@jsonforms/react": "^3.5.1",
43
43
  "ajv": "^8.17.1",
44
44
  "js-yaml": "^4.1.0",
45
+ "lodash.merge": "^4.6.2",
45
46
  "openapi-ts": "^0.3.4",
46
47
  "react": "^19.0.0",
47
48
  "rimraf": "^6.0.1"
@@ -49,6 +50,8 @@
49
50
  "devDependencies": {
50
51
  "@apidevtools/swagger-cli": "^4.0.4",
51
52
  "@hey-api/openapi-ts": "^0.80.2",
53
+ "@types/js-yaml": "^4.0.9",
54
+ "@types/lodash.merge": "^4.6.9",
52
55
  "@types/node": "^24.0.14",
53
56
  "@types/react": "^19",
54
57
  "openapi-typescript-codegen": "^0.29.0",