rotacloud 2.1.4 → 2.2.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/dist/endpoint.d.ts +6 -1
- package/dist/{models/SDKError.model.d.ts → error.d.ts} +3 -0
- package/dist/{models/SDKError.model.js → error.js} +3 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.js +1 -0
- package/dist/interfaces/message.interface.d.ts +27 -0
- package/dist/interfaces/message.interface.js +1 -0
- package/dist/main.d.ts +9 -1
- package/dist/main.js +1 -1
- package/dist/ops.d.ts +3 -1
- package/dist/ops.js +105 -1
- package/dist/ops.test.js +17 -2
- package/dist/service.d.ts +9 -0
- package/dist/service.js +9 -1
- package/dist/utils.d.ts +11 -1
- package/dist/utils.js +16 -6
- package/package.json +1 -1
- package/src/client-builder.test.ts +1 -1
- package/src/endpoint.ts +10 -1
- package/src/{models/SDKError.model.ts → error.ts} +4 -0
- package/src/interfaces/index.ts +1 -0
- package/src/interfaces/message.interface.ts +27 -0
- package/src/main.ts +1 -1
- package/src/ops.test.ts +20 -2
- package/src/ops.ts +117 -2
- package/src/service.ts +10 -0
- package/src/utils.ts +16 -6
- package/dist/models/index.d.ts +0 -1
- package/dist/models/index.js +0 -1
- package/src/models/index.ts +0 -1
package/dist/endpoint.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Account, Attendance, Auth, Availability, DailyBudgets, DailyRevenue, DayNote, DaysOff, Group, Leave, Role, Shift, TimeZone, Document, LeaveEmbargo, LeaveRequest, LeaveType, Location, Pin, Terminal, ToilAccrual, ToilAllowance, UserClockedIn, User, Settings, LogbookCategory, DayNoteV2, DayNoteV2QueryParameters } from './interfaces/index.js';
|
|
2
2
|
import { LogbookEntry, LogbookQueryParameters } from './interfaces/logbook.interface.js';
|
|
3
|
+
import { Message } from './interfaces/message.interface.js';
|
|
3
4
|
import { AttendanceQueryParams, AvailabilityQueryParams, DailyBudgetsQueryParams, DailyRevenueQueryParams, DayNotesQueryParams, DaysOffQueryParams, DocumentsQueryParams, GroupsQueryParams, LeaveEmbargoesQueryParams, LeaveQueryParams, LeaveRequestsQueryParams, LocationsQueryParams, RolesQueryParams, SettingsQueryParams, ShiftsQueryParams, TerminalsQueryParams, ToilAccrualsQueryParams, ToilAllowanceQueryParams, UsersQueryParams } from './interfaces/query-params/index.js';
|
|
4
5
|
import { RequirementsOf } from './utils.js';
|
|
5
6
|
/** Endpoint versions supported by the API */
|
|
6
7
|
export type EndpointVersion = 'v1' | 'v2';
|
|
7
8
|
/** Associated types for a given API endpoint */
|
|
8
|
-
export type Endpoint<Entity, QueryParameters = undefined, CreateEntity extends keyof Entity |
|
|
9
|
+
export type Endpoint<Entity, QueryParameters = undefined, CreateEntity extends keyof Entity | object = any, RequiredFields extends keyof Entity = CreateEntity extends keyof Entity ? CreateEntity : never> = {
|
|
9
10
|
/** The type returned by an endpoint */
|
|
10
11
|
type: Entity;
|
|
11
12
|
/** The query parameters for endpoints that support listing */
|
|
@@ -35,6 +36,10 @@ export interface EndpointEntityMap extends Record<EndpointVersion, Record<string
|
|
|
35
36
|
leave_types: Endpoint<LeaveType>;
|
|
36
37
|
leave: Endpoint<Leave, LeaveQueryParams, 'users' | 'type' | 'start_date' | 'end_date'>;
|
|
37
38
|
locations: Endpoint<Location, LocationsQueryParams, 'name'>;
|
|
39
|
+
messages: Endpoint<Message, undefined, Pick<Message, 'message' | 'subject'> & {
|
|
40
|
+
users: number[];
|
|
41
|
+
attachments?: Pick<Message['attachments'][number], 'key' | 'bucket' | 'name' | 'extension'>[];
|
|
42
|
+
}>;
|
|
38
43
|
pins: Endpoint<Pin>;
|
|
39
44
|
roles: Endpoint<Role, RolesQueryParams, 'name'>;
|
|
40
45
|
settings: Endpoint<Settings, SettingsQueryParams>;
|
package/dist/interfaces/index.js
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface Message {
|
|
2
|
+
id: number;
|
|
3
|
+
/** Unix timestamp in seconds */
|
|
4
|
+
sent_at: number;
|
|
5
|
+
sent_by: number;
|
|
6
|
+
subject: string;
|
|
7
|
+
message: string;
|
|
8
|
+
/** User recipients of the message */
|
|
9
|
+
users: {
|
|
10
|
+
/** ID of user */
|
|
11
|
+
user: number;
|
|
12
|
+
sent: boolean;
|
|
13
|
+
opened: boolean;
|
|
14
|
+
/** Unix timestamp in seconds */
|
|
15
|
+
opened_at: boolean;
|
|
16
|
+
error: string | null;
|
|
17
|
+
}[];
|
|
18
|
+
attachments: {
|
|
19
|
+
name: string;
|
|
20
|
+
extension: string;
|
|
21
|
+
type: string;
|
|
22
|
+
/** rounded integer value */
|
|
23
|
+
size_kb: number;
|
|
24
|
+
bucket: string;
|
|
25
|
+
key: string;
|
|
26
|
+
}[];
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/main.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './interfaces/index.js';
|
|
2
2
|
export * from './interfaces/query-params/index.js';
|
|
3
|
-
export * from './
|
|
3
|
+
export * from './error.js';
|
|
4
4
|
export declare const createRotaCloudClient: (config: import("./interfaces/sdk-config.interface.js").SDKConfig) => import("./client-builder.js").SdkClient<{
|
|
5
5
|
account: {
|
|
6
6
|
endpoint: "accounts";
|
|
@@ -115,6 +115,14 @@ export declare const createRotaCloudClient: (config: import("./interfaces/sdk-co
|
|
|
115
115
|
};
|
|
116
116
|
};
|
|
117
117
|
};
|
|
118
|
+
message: {
|
|
119
|
+
endpoint: "messages";
|
|
120
|
+
endpointVersion: "v1";
|
|
121
|
+
operations: ("list" | "listAll" | "listByPage")[];
|
|
122
|
+
customOperations: {
|
|
123
|
+
send: (ctx: import("./ops.js").OperationContext, message: import("./endpoint.js").EndpointEntityMap["v1"]["messages"]["createType"]) => import("./ops.js").RequestConfig<unknown, import("./interfaces/message.interface.js").Message>;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
118
126
|
pin: {
|
|
119
127
|
endpoint: "pins";
|
|
120
128
|
endpointVersion: "v1";
|
package/dist/main.js
CHANGED
|
@@ -2,5 +2,5 @@ import { createSdkClient } from './client-builder.js';
|
|
|
2
2
|
import { SERVICES } from './service.js';
|
|
3
3
|
export * from './interfaces/index.js';
|
|
4
4
|
export * from './interfaces/query-params/index.js';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './error.js';
|
|
6
6
|
export const createRotaCloudClient = createSdkClient(SERVICES);
|
package/dist/ops.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Axios, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
|
2
2
|
import { ServiceSpecification } from './service.js';
|
|
3
3
|
import { RequestOptions, QueryParameterValue, RequirementsOf } from './utils.js';
|
|
4
4
|
import { Endpoint } from './endpoint.js';
|
|
5
|
-
import { SDKConfig } from './
|
|
5
|
+
import { SDKConfig } from './interfaces/index.js';
|
|
6
6
|
/** Supported common operations */
|
|
7
7
|
export type Operation = 'get' | 'list' | 'listAll' | 'listByPage' | 'delete' | 'deleteBatch' | 'create' | 'update' | 'updateBatch';
|
|
8
8
|
/** Context provided to all operations */
|
|
@@ -105,6 +105,8 @@ interface PagedResponse<T> {
|
|
|
105
105
|
}
|
|
106
106
|
/** Utility for creating a query params map needed by most API requests */
|
|
107
107
|
export declare function paramsFromOptions<T>(opts: RequestOptions<T>): Record<string, QueryParameterValue>;
|
|
108
|
+
/** Operation for creating an entity */
|
|
109
|
+
export declare function createOp<T = unknown, NewEntity = unknown>(ctx: OperationContext, newEntity: NewEntity): RequestConfig<NewEntity, T>;
|
|
108
110
|
/** Operation for deleting an entity */
|
|
109
111
|
declare function deleteOp(ctx: OperationContext, id: number): RequestConfig<unknown, void>;
|
|
110
112
|
/** Operation for deleting a list of entities */
|
package/dist/ops.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import { assert } from './utils.js';
|
|
2
|
+
import { ValidationError } from './error.js';
|
|
3
|
+
/** For validating the query parameter supplied to list ops
|
|
4
|
+
*
|
|
5
|
+
* @throws {ValidationError} if invalid
|
|
6
|
+
*/
|
|
7
|
+
function validateQueryParameter(query) {
|
|
8
|
+
// undefined is an accepted type for query
|
|
9
|
+
if (query !== undefined && (typeof query !== 'object' || query === null)) {
|
|
10
|
+
throw new ValidationError('Invalid type for query', {
|
|
11
|
+
cause: {
|
|
12
|
+
type: typeof query,
|
|
13
|
+
value: query,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
2
18
|
/** Utility for creating a query params map needed by most API requests */
|
|
3
19
|
export function paramsFromOptions(opts) {
|
|
4
20
|
return {
|
|
@@ -30,6 +46,21 @@ function* requestPaginated(response, requestConfig) {
|
|
|
30
46
|
}
|
|
31
47
|
/** Operation for getting an entity */
|
|
32
48
|
function getOp(ctx, id) {
|
|
49
|
+
if (typeof id !== 'number') {
|
|
50
|
+
throw new ValidationError('Invalid type for id', {
|
|
51
|
+
cause: {
|
|
52
|
+
type: typeof id,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (!Number.isSafeInteger(id)) {
|
|
57
|
+
throw new ValidationError('Invalid value for id', {
|
|
58
|
+
cause: {
|
|
59
|
+
reason: 'Not a safe integer',
|
|
60
|
+
value: id,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
33
64
|
return {
|
|
34
65
|
...ctx.request,
|
|
35
66
|
method: 'GET',
|
|
@@ -37,7 +68,15 @@ function getOp(ctx, id) {
|
|
|
37
68
|
};
|
|
38
69
|
}
|
|
39
70
|
/** Operation for creating an entity */
|
|
40
|
-
function createOp(ctx, newEntity) {
|
|
71
|
+
export function createOp(ctx, newEntity) {
|
|
72
|
+
if (typeof newEntity !== 'object' || newEntity === null) {
|
|
73
|
+
throw new ValidationError('Invalid type for entity', {
|
|
74
|
+
cause: {
|
|
75
|
+
type: typeof newEntity,
|
|
76
|
+
value: newEntity,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
41
80
|
return {
|
|
42
81
|
...ctx.request,
|
|
43
82
|
method: 'POST',
|
|
@@ -47,6 +86,22 @@ function createOp(ctx, newEntity) {
|
|
|
47
86
|
}
|
|
48
87
|
/** Operation for updating an entity for v1 endpoints */
|
|
49
88
|
function updateV1Op(ctx, entity) {
|
|
89
|
+
if (typeof entity !== 'object' || entity === null || !('id' in entity)) {
|
|
90
|
+
throw new ValidationError('Invalid type for entity', {
|
|
91
|
+
cause: {
|
|
92
|
+
type: typeof entity,
|
|
93
|
+
value: entity,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (!Number.isSafeInteger(entity.id)) {
|
|
98
|
+
throw new ValidationError('Invalid value for entity id', {
|
|
99
|
+
cause: {
|
|
100
|
+
reason: 'Not a safe integer',
|
|
101
|
+
value: entity.id,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
50
105
|
return {
|
|
51
106
|
...ctx.request,
|
|
52
107
|
method: 'POST',
|
|
@@ -56,6 +111,22 @@ function updateV1Op(ctx, entity) {
|
|
|
56
111
|
}
|
|
57
112
|
/** Operation for updating an entity for v2 endpoints */
|
|
58
113
|
function updateV2Op(ctx, entity) {
|
|
114
|
+
if (typeof entity !== 'object' || entity === null || !('id' in entity)) {
|
|
115
|
+
throw new ValidationError('Invalid type for entity', {
|
|
116
|
+
cause: {
|
|
117
|
+
type: typeof entity,
|
|
118
|
+
value: entity,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (!Number.isSafeInteger(entity.id)) {
|
|
123
|
+
throw new ValidationError('Invalid value for entity id', {
|
|
124
|
+
cause: {
|
|
125
|
+
reason: 'Not a safe integer',
|
|
126
|
+
value: entity.id,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
59
130
|
return {
|
|
60
131
|
...ctx.request,
|
|
61
132
|
method: 'PUT',
|
|
@@ -65,6 +136,13 @@ function updateV2Op(ctx, entity) {
|
|
|
65
136
|
}
|
|
66
137
|
/** Operation for deleting a list of entities */
|
|
67
138
|
async function updateBatchOp(ctx, entities) {
|
|
139
|
+
if (!Array.isArray(entities)) {
|
|
140
|
+
throw new ValidationError('Invalid type for entity array', {
|
|
141
|
+
cause: {
|
|
142
|
+
type: typeof entities,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
68
146
|
const res = await ctx.client.request({
|
|
69
147
|
...ctx.request,
|
|
70
148
|
method: 'POST',
|
|
@@ -83,6 +161,21 @@ async function updateBatchOp(ctx, entities) {
|
|
|
83
161
|
}
|
|
84
162
|
/** Operation for deleting an entity */
|
|
85
163
|
function deleteOp(ctx, id) {
|
|
164
|
+
if (typeof id !== 'number') {
|
|
165
|
+
throw new ValidationError('Invalid type for id', {
|
|
166
|
+
cause: {
|
|
167
|
+
type: typeof id,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!Number.isSafeInteger(id)) {
|
|
172
|
+
throw new ValidationError('Invalid value for id', {
|
|
173
|
+
cause: {
|
|
174
|
+
reason: 'Not a safe integer',
|
|
175
|
+
value: id,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
}
|
|
86
179
|
return {
|
|
87
180
|
...ctx.request,
|
|
88
181
|
method: 'DELETE',
|
|
@@ -91,6 +184,13 @@ function deleteOp(ctx, id) {
|
|
|
91
184
|
}
|
|
92
185
|
/** Operation for deleting a list of entities */
|
|
93
186
|
function deleteBatchOp(ctx, ids) {
|
|
187
|
+
if (!Array.isArray(ids)) {
|
|
188
|
+
throw new ValidationError('Invalid type for id array', {
|
|
189
|
+
cause: {
|
|
190
|
+
type: typeof ids,
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
}
|
|
94
194
|
return {
|
|
95
195
|
...ctx.request,
|
|
96
196
|
method: 'DELETE',
|
|
@@ -104,6 +204,7 @@ function deleteBatchOp(ctx, ids) {
|
|
|
104
204
|
export async function* listOp(ctx, query,
|
|
105
205
|
// NOTE: offset is only supported in v1
|
|
106
206
|
opts) {
|
|
207
|
+
validateQueryParameter(query);
|
|
107
208
|
const queriedRequest = {
|
|
108
209
|
...ctx.request,
|
|
109
210
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -134,6 +235,7 @@ opts) {
|
|
|
134
235
|
* automatically handling pagination as and when needed
|
|
135
236
|
*/
|
|
136
237
|
export async function* listV2Op(ctx, query, opts) {
|
|
238
|
+
validateQueryParameter(query);
|
|
137
239
|
const queriedRequest = {
|
|
138
240
|
...ctx.request,
|
|
139
241
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -194,6 +296,7 @@ export async function listAllV2Op(ctx, query, opts) {
|
|
|
194
296
|
async function* listByPageOp(ctx, query,
|
|
195
297
|
// NOTE: offset is only supported in v1
|
|
196
298
|
opts) {
|
|
299
|
+
validateQueryParameter(query);
|
|
197
300
|
const queriedRequest = {
|
|
198
301
|
...ctx.request,
|
|
199
302
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -222,6 +325,7 @@ opts) {
|
|
|
222
325
|
* automatically handling pagination as and when needed
|
|
223
326
|
*/
|
|
224
327
|
async function* listByPageV2Op(ctx, query, opts) {
|
|
328
|
+
validateQueryParameter(query);
|
|
225
329
|
const queriedRequest = {
|
|
226
330
|
...ctx.request,
|
|
227
331
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
package/dist/ops.test.js
CHANGED
|
@@ -21,7 +21,7 @@ describe('Operations', () => {
|
|
|
21
21
|
const serviceV1 = {
|
|
22
22
|
endpoint: 'settings',
|
|
23
23
|
endpointVersion: 'v1',
|
|
24
|
-
operations: ['get', 'list'],
|
|
24
|
+
operations: ['get', 'delete', 'list'],
|
|
25
25
|
customOperations: {
|
|
26
26
|
promiseOp: async () => 3,
|
|
27
27
|
},
|
|
@@ -29,7 +29,7 @@ describe('Operations', () => {
|
|
|
29
29
|
const serviceV2 = {
|
|
30
30
|
endpoint: 'logbook',
|
|
31
31
|
endpointVersion: 'v2',
|
|
32
|
-
operations: ['get', 'list'],
|
|
32
|
+
operations: ['get', 'delete', 'list'],
|
|
33
33
|
customOperations: {
|
|
34
34
|
promiseOp: async () => 3,
|
|
35
35
|
},
|
|
@@ -60,6 +60,21 @@ describe('Operations', () => {
|
|
|
60
60
|
const promiseOpRes = await serviceV1.customOperations.promiseOp();
|
|
61
61
|
expect(promiseOpRes).toStrictEqual(await client.service.promiseOp());
|
|
62
62
|
});
|
|
63
|
+
describe('validation', () => {
|
|
64
|
+
const invalidIds = ['id', { id: 1 }, undefined, null, Infinity, -Infinity, 2.1, NaN];
|
|
65
|
+
test('getOp rejects invalid IDs', () => {
|
|
66
|
+
for (const invalidId of invalidIds) {
|
|
67
|
+
expect(() => client.service.get(invalidId)).toThrowError();
|
|
68
|
+
expect(() => client.serviceV2.get(invalidId)).toThrowError();
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
test('deleteOp rejects invalid IDs', () => {
|
|
72
|
+
for (const invalidId of invalidIds) {
|
|
73
|
+
expect(() => client.service.delete(invalidId)).toThrowError();
|
|
74
|
+
expect(() => client.serviceV2.delete(invalidId)).toThrowError();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
63
78
|
describe('list', () => {
|
|
64
79
|
describe('v1 ops', () => {
|
|
65
80
|
test('respects `maxResults` parameter in pagination', async () => {
|
package/dist/service.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { ShiftSwapRequest } from './interfaces/swap-request.interface.js';
|
|
|
8
8
|
import { ShiftDropRequest } from './interfaces/drop-request.interface.js';
|
|
9
9
|
import { ToilAllowanceQueryParams } from './interfaces/query-params/index.js';
|
|
10
10
|
import { LogbookEntry, LogbookQueryParameters } from './interfaces/logbook.interface.js';
|
|
11
|
+
import { Message } from './interfaces/message.interface.js';
|
|
11
12
|
export type ServiceSpecification<CustomOp extends OpDef<unknown> = OpDef<any>> = {
|
|
12
13
|
/** Operations allowed and usable for the endpoint */
|
|
13
14
|
operations: Operation[];
|
|
@@ -156,6 +157,14 @@ export declare const SERVICES: {
|
|
|
156
157
|
};
|
|
157
158
|
};
|
|
158
159
|
};
|
|
160
|
+
message: {
|
|
161
|
+
endpoint: "messages";
|
|
162
|
+
endpointVersion: "v1";
|
|
163
|
+
operations: ("list" | "listAll" | "listByPage")[];
|
|
164
|
+
customOperations: {
|
|
165
|
+
send: (ctx: OperationContext, message: EndpointEntityMap["v1"]["messages"]["createType"]) => RequestConfig<unknown, Message>;
|
|
166
|
+
};
|
|
167
|
+
};
|
|
159
168
|
pin: {
|
|
160
169
|
endpoint: "pins";
|
|
161
170
|
endpointVersion: "v1";
|
package/dist/service.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { listAllOp, listAllV2Op, listOp, listV2Op, paramsFromOptions, } from './ops.js';
|
|
1
|
+
import { createOp, listAllOp, listAllV2Op, listOp, listV2Op, paramsFromOptions, } from './ops.js';
|
|
2
2
|
/**
|
|
3
3
|
* Map of all officially supported service specifications used to generate the
|
|
4
4
|
* SDK client where each key is the service name and each value is the service
|
|
@@ -184,6 +184,14 @@ export const SERVICES = {
|
|
|
184
184
|
},
|
|
185
185
|
},
|
|
186
186
|
},
|
|
187
|
+
message: {
|
|
188
|
+
endpoint: 'messages',
|
|
189
|
+
endpointVersion: 'v1',
|
|
190
|
+
operations: ['list', 'listAll', 'listByPage'],
|
|
191
|
+
customOperations: {
|
|
192
|
+
send: (ctx, message) => createOp(ctx, message),
|
|
193
|
+
},
|
|
194
|
+
},
|
|
187
195
|
pin: {
|
|
188
196
|
endpoint: 'pins',
|
|
189
197
|
endpointVersion: 'v1',
|
package/dist/utils.d.ts
CHANGED
|
@@ -23,7 +23,17 @@ export interface RequestOptions<T> {
|
|
|
23
23
|
dryRun?: boolean;
|
|
24
24
|
fields?: T extends Object ? (keyof T)[] : never;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/** Ensures the provided value resolves to `true` before continuing
|
|
27
|
+
*
|
|
28
|
+
* If the value doesn't resolve to `true` then the provided `error` will be thrown
|
|
29
|
+
*
|
|
30
|
+
* Intended to be run in production and not removed on build
|
|
31
|
+
*
|
|
32
|
+
* @param assertion assertion to verify
|
|
33
|
+
* @param error error to throw. If `undefined` or a `string` then an {@link AssertionError}
|
|
34
|
+
* will be thrown instead
|
|
35
|
+
*/
|
|
36
|
+
export declare function assert(assertion: unknown, error?: string | Error): asserts assertion;
|
|
27
37
|
/** Creates and configures an Axios client for use in all calls to API endpoints
|
|
28
38
|
* according to the provided {@see SDKConfig}
|
|
29
39
|
*/
|
package/dist/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
2
|
import axiosRetry, { isNetworkOrIdempotentRequestError } from 'axios-retry';
|
|
3
3
|
import { RetryStrategy } from './interfaces/index.js';
|
|
4
|
-
import { SDKError } from './
|
|
4
|
+
import { SDKError } from './error.js';
|
|
5
5
|
import pkg from '../package.json' with { type: 'json' };
|
|
6
6
|
const DEFAULT_RETRIES = 3;
|
|
7
7
|
const DEFAULT_RETRY_DELAY = 2000;
|
|
@@ -19,12 +19,22 @@ const DEFAULT_RETRY_STRATEGY_OPTIONS = {
|
|
|
19
19
|
class AssertionError extends Error {
|
|
20
20
|
name = AssertionError.prototype.name;
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
/** Ensures the provided value resolves to `true` before continuing
|
|
23
|
+
*
|
|
24
|
+
* If the value doesn't resolve to `true` then the provided `error` will be thrown
|
|
25
|
+
*
|
|
26
|
+
* Intended to be run in production and not removed on build
|
|
27
|
+
*
|
|
28
|
+
* @param assertion assertion to verify
|
|
29
|
+
* @param error error to throw. If `undefined` or a `string` then an {@link AssertionError}
|
|
30
|
+
* will be thrown instead
|
|
31
|
+
*/
|
|
32
|
+
export function assert(assertion, error) {
|
|
33
|
+
if (assertion)
|
|
24
34
|
return;
|
|
25
|
-
if (
|
|
26
|
-
throw new AssertionError(
|
|
27
|
-
throw
|
|
35
|
+
if (error === undefined || typeof error === 'string')
|
|
36
|
+
throw new AssertionError(error ?? `Assertion failed - value = ${assertion}`);
|
|
37
|
+
throw error;
|
|
28
38
|
}
|
|
29
39
|
/** Converts a map of query parameter key/values into API compatible {@see URLSearchParams} */
|
|
30
40
|
function toSearchParams(parameters) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { test, expect, describe, vi } from 'vitest';
|
|
2
2
|
import { Axios } from 'axios';
|
|
3
3
|
import { createSdkClient, DEFAULT_CONFIG } from './client-builder.js';
|
|
4
|
-
import { SDKConfig } from './
|
|
4
|
+
import { SDKConfig } from './interfaces/index.js';
|
|
5
5
|
import pkg from '../package.json' with { type: 'json' };
|
|
6
6
|
|
|
7
7
|
let mockAxiosClient: Axios;
|
package/src/endpoint.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
DayNoteV2QueryParameters,
|
|
30
30
|
} from './interfaces/index.js';
|
|
31
31
|
import { LogbookEntry, LogbookQueryParameters } from './interfaces/logbook.interface.js';
|
|
32
|
+
import { Message } from './interfaces/message.interface.js';
|
|
32
33
|
import {
|
|
33
34
|
AttendanceQueryParams,
|
|
34
35
|
AvailabilityQueryParams,
|
|
@@ -58,7 +59,7 @@ export type EndpointVersion = 'v1' | 'v2';
|
|
|
58
59
|
export type Endpoint<
|
|
59
60
|
Entity,
|
|
60
61
|
QueryParameters = undefined,
|
|
61
|
-
CreateEntity extends keyof Entity |
|
|
62
|
+
CreateEntity extends keyof Entity | object = any,
|
|
62
63
|
// NOTE: introduced to work around TS inferring `RequirementsOf<Entity, CreateEntity>` incorrectly
|
|
63
64
|
// TS resolves type to:
|
|
64
65
|
// `RequirementsOf<Entity, "key 1"> | RequirementsOf<Entity "key 2">`
|
|
@@ -96,6 +97,14 @@ export interface EndpointEntityMap extends Record<EndpointVersion, Record<string
|
|
|
96
97
|
leave_types: Endpoint<LeaveType>;
|
|
97
98
|
leave: Endpoint<Leave, LeaveQueryParams, 'users' | 'type' | 'start_date' | 'end_date'>;
|
|
98
99
|
locations: Endpoint<Location, LocationsQueryParams, 'name'>;
|
|
100
|
+
messages: Endpoint<
|
|
101
|
+
Message,
|
|
102
|
+
undefined,
|
|
103
|
+
Pick<Message, 'message' | 'subject'> & {
|
|
104
|
+
users: number[];
|
|
105
|
+
attachments?: Pick<Message['attachments'][number], 'key' | 'bucket' | 'name' | 'extension'>[];
|
|
106
|
+
}
|
|
107
|
+
>;
|
|
99
108
|
pins: Endpoint<Pin>;
|
|
100
109
|
roles: Endpoint<Role, RolesQueryParams, 'name'>;
|
|
101
110
|
settings: Endpoint<Settings, SettingsQueryParams>;
|
package/src/interfaces/index.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface Message {
|
|
2
|
+
id: number;
|
|
3
|
+
/** Unix timestamp in seconds */
|
|
4
|
+
sent_at: number;
|
|
5
|
+
sent_by: number;
|
|
6
|
+
subject: string;
|
|
7
|
+
message: string;
|
|
8
|
+
/** User recipients of the message */
|
|
9
|
+
users: {
|
|
10
|
+
/** ID of user */
|
|
11
|
+
user: number;
|
|
12
|
+
sent: boolean;
|
|
13
|
+
opened: boolean;
|
|
14
|
+
/** Unix timestamp in seconds */
|
|
15
|
+
opened_at: boolean;
|
|
16
|
+
error: string | null;
|
|
17
|
+
}[];
|
|
18
|
+
attachments: {
|
|
19
|
+
name: string;
|
|
20
|
+
extension: string;
|
|
21
|
+
type: string;
|
|
22
|
+
/** rounded integer value */
|
|
23
|
+
size_kb: number;
|
|
24
|
+
bucket: string;
|
|
25
|
+
key: string;
|
|
26
|
+
}[];
|
|
27
|
+
}
|
package/src/main.ts
CHANGED
package/src/ops.test.ts
CHANGED
|
@@ -25,7 +25,7 @@ describe('Operations', () => {
|
|
|
25
25
|
const serviceV1 = {
|
|
26
26
|
endpoint: 'settings',
|
|
27
27
|
endpointVersion: 'v1',
|
|
28
|
-
operations: ['get', 'list'],
|
|
28
|
+
operations: ['get', 'delete', 'list'],
|
|
29
29
|
customOperations: {
|
|
30
30
|
promiseOp: async () => 3,
|
|
31
31
|
},
|
|
@@ -33,7 +33,7 @@ describe('Operations', () => {
|
|
|
33
33
|
const serviceV2 = {
|
|
34
34
|
endpoint: 'logbook',
|
|
35
35
|
endpointVersion: 'v2',
|
|
36
|
-
operations: ['get', 'list'],
|
|
36
|
+
operations: ['get', 'delete', 'list'],
|
|
37
37
|
customOperations: {
|
|
38
38
|
promiseOp: async () => 3,
|
|
39
39
|
},
|
|
@@ -74,6 +74,24 @@ describe('Operations', () => {
|
|
|
74
74
|
expect(promiseOpRes).toStrictEqual(await client.service.promiseOp());
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
+
describe('validation', () => {
|
|
78
|
+
const invalidIds = ['id', { id: 1 }, undefined, null, Infinity, -Infinity, 2.1, NaN];
|
|
79
|
+
|
|
80
|
+
test('getOp rejects invalid IDs', () => {
|
|
81
|
+
for (const invalidId of invalidIds) {
|
|
82
|
+
expect(() => client.service.get(invalidId as number)).toThrowError();
|
|
83
|
+
expect(() => client.serviceV2.get(invalidId as number)).toThrowError();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('deleteOp rejects invalid IDs', () => {
|
|
88
|
+
for (const invalidId of invalidIds) {
|
|
89
|
+
expect(() => client.service.delete(invalidId as number)).toThrowError();
|
|
90
|
+
expect(() => client.serviceV2.delete(invalidId as number)).toThrowError();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
77
95
|
describe('list', () => {
|
|
78
96
|
describe('v1 ops', () => {
|
|
79
97
|
test('respects `maxResults` parameter in pagination', async () => {
|
package/src/ops.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { Axios, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
|
2
2
|
import { ServiceSpecification } from './service.js';
|
|
3
3
|
import { RequestOptions, QueryParameterValue, RequirementsOf, assert } from './utils.js';
|
|
4
4
|
import { Endpoint, EndpointVersion } from './endpoint.js';
|
|
5
|
-
import { SDKConfig } from './
|
|
5
|
+
import { SDKConfig } from './interfaces/index.js';
|
|
6
|
+
import { ValidationError } from './error.js';
|
|
6
7
|
|
|
7
8
|
/** Supported common operations */
|
|
8
9
|
export type Operation =
|
|
@@ -163,6 +164,22 @@ interface PagedResponse<T> {
|
|
|
163
164
|
};
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
/** For validating the query parameter supplied to list ops
|
|
168
|
+
*
|
|
169
|
+
* @throws {ValidationError} if invalid
|
|
170
|
+
*/
|
|
171
|
+
function validateQueryParameter(query: unknown) {
|
|
172
|
+
// undefined is an accepted type for query
|
|
173
|
+
if (query !== undefined && (typeof query !== 'object' || query === null)) {
|
|
174
|
+
throw new ValidationError('Invalid type for query', {
|
|
175
|
+
cause: {
|
|
176
|
+
type: typeof query,
|
|
177
|
+
value: query,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
166
183
|
/** Utility for creating a query params map needed by most API requests */
|
|
167
184
|
export function paramsFromOptions<T>(opts: RequestOptions<T>): Record<string, QueryParameterValue> {
|
|
168
185
|
return {
|
|
@@ -200,6 +217,22 @@ function* requestPaginated<T>(
|
|
|
200
217
|
|
|
201
218
|
/** Operation for getting an entity */
|
|
202
219
|
function getOp<T = undefined>(ctx: OperationContext, id: number): RequestConfig<unknown, T> {
|
|
220
|
+
if (typeof id !== 'number') {
|
|
221
|
+
throw new ValidationError('Invalid type for id', {
|
|
222
|
+
cause: {
|
|
223
|
+
type: typeof id,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (!Number.isSafeInteger(id)) {
|
|
228
|
+
throw new ValidationError('Invalid value for id', {
|
|
229
|
+
cause: {
|
|
230
|
+
reason: 'Not a safe integer',
|
|
231
|
+
value: id,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
203
236
|
return {
|
|
204
237
|
...ctx.request,
|
|
205
238
|
method: 'GET',
|
|
@@ -208,10 +241,19 @@ function getOp<T = undefined>(ctx: OperationContext, id: number): RequestConfig<
|
|
|
208
241
|
}
|
|
209
242
|
|
|
210
243
|
/** Operation for creating an entity */
|
|
211
|
-
function createOp<T = unknown, NewEntity = unknown>(
|
|
244
|
+
export function createOp<T = unknown, NewEntity = unknown>(
|
|
212
245
|
ctx: OperationContext,
|
|
213
246
|
newEntity: NewEntity,
|
|
214
247
|
): RequestConfig<NewEntity, T> {
|
|
248
|
+
if (typeof newEntity !== 'object' || newEntity === null) {
|
|
249
|
+
throw new ValidationError('Invalid type for entity', {
|
|
250
|
+
cause: {
|
|
251
|
+
type: typeof newEntity,
|
|
252
|
+
value: newEntity,
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
215
257
|
return {
|
|
216
258
|
...ctx.request,
|
|
217
259
|
method: 'POST',
|
|
@@ -225,6 +267,23 @@ function updateV1Op<Return, Entity extends { id: number } & Partial<Return>>(
|
|
|
225
267
|
ctx: OperationContext,
|
|
226
268
|
entity: Entity,
|
|
227
269
|
): RequestConfig<Entity, Return> {
|
|
270
|
+
if (typeof entity !== 'object' || entity === null || !('id' in entity)) {
|
|
271
|
+
throw new ValidationError('Invalid type for entity', {
|
|
272
|
+
cause: {
|
|
273
|
+
type: typeof entity,
|
|
274
|
+
value: entity,
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (!Number.isSafeInteger(entity.id)) {
|
|
279
|
+
throw new ValidationError('Invalid value for entity id', {
|
|
280
|
+
cause: {
|
|
281
|
+
reason: 'Not a safe integer',
|
|
282
|
+
value: entity.id,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
228
287
|
return {
|
|
229
288
|
...ctx.request,
|
|
230
289
|
method: 'POST',
|
|
@@ -238,6 +297,23 @@ function updateV2Op<Return, Entity extends { id: number } & Partial<Return>>(
|
|
|
238
297
|
ctx: OperationContext,
|
|
239
298
|
entity: Entity,
|
|
240
299
|
): RequestConfig<Entity, Return> {
|
|
300
|
+
if (typeof entity !== 'object' || entity === null || !('id' in entity)) {
|
|
301
|
+
throw new ValidationError('Invalid type for entity', {
|
|
302
|
+
cause: {
|
|
303
|
+
type: typeof entity,
|
|
304
|
+
value: entity,
|
|
305
|
+
},
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (!Number.isSafeInteger(entity.id)) {
|
|
309
|
+
throw new ValidationError('Invalid value for entity id', {
|
|
310
|
+
cause: {
|
|
311
|
+
reason: 'Not a safe integer',
|
|
312
|
+
value: entity.id,
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
241
317
|
return {
|
|
242
318
|
...ctx.request,
|
|
243
319
|
method: 'PUT',
|
|
@@ -251,6 +327,14 @@ async function updateBatchOp<Return, Entity extends { id: number } & Partial<Ret
|
|
|
251
327
|
ctx: OperationContext,
|
|
252
328
|
entities: Entity[],
|
|
253
329
|
): Promise<{ success: Return[]; failed: { id: number; error: string }[] }> {
|
|
330
|
+
if (!Array.isArray(entities)) {
|
|
331
|
+
throw new ValidationError('Invalid type for entity array', {
|
|
332
|
+
cause: {
|
|
333
|
+
type: typeof entities,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
254
338
|
const res = await ctx.client.request<{ code: number; data?: Return; error?: string }[]>({
|
|
255
339
|
...ctx.request,
|
|
256
340
|
method: 'POST',
|
|
@@ -273,6 +357,22 @@ async function updateBatchOp<Return, Entity extends { id: number } & Partial<Ret
|
|
|
273
357
|
|
|
274
358
|
/** Operation for deleting an entity */
|
|
275
359
|
function deleteOp(ctx: OperationContext, id: number): RequestConfig<unknown, void> {
|
|
360
|
+
if (typeof id !== 'number') {
|
|
361
|
+
throw new ValidationError('Invalid type for id', {
|
|
362
|
+
cause: {
|
|
363
|
+
type: typeof id,
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (!Number.isSafeInteger(id)) {
|
|
368
|
+
throw new ValidationError('Invalid value for id', {
|
|
369
|
+
cause: {
|
|
370
|
+
reason: 'Not a safe integer',
|
|
371
|
+
value: id,
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
276
376
|
return {
|
|
277
377
|
...ctx.request,
|
|
278
378
|
method: 'DELETE',
|
|
@@ -282,6 +382,14 @@ function deleteOp(ctx: OperationContext, id: number): RequestConfig<unknown, voi
|
|
|
282
382
|
|
|
283
383
|
/** Operation for deleting a list of entities */
|
|
284
384
|
function deleteBatchOp(ctx: OperationContext, ids: number[]): RequestConfig<unknown, void> {
|
|
385
|
+
if (!Array.isArray(ids)) {
|
|
386
|
+
throw new ValidationError('Invalid type for id array', {
|
|
387
|
+
cause: {
|
|
388
|
+
type: typeof ids,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
285
393
|
return {
|
|
286
394
|
...ctx.request,
|
|
287
395
|
method: 'DELETE',
|
|
@@ -299,6 +407,7 @@ export async function* listOp<T, Query>(
|
|
|
299
407
|
// NOTE: offset is only supported in v1
|
|
300
408
|
opts?: RequestOptions<T[]> & { offset?: number },
|
|
301
409
|
): AsyncGenerator<T> {
|
|
410
|
+
validateQueryParameter(query);
|
|
302
411
|
const queriedRequest = {
|
|
303
412
|
...ctx.request,
|
|
304
413
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -334,6 +443,8 @@ export async function* listV2Op<T, Query>(
|
|
|
334
443
|
query: Query,
|
|
335
444
|
opts?: RequestOptions<T[]>,
|
|
336
445
|
): AsyncGenerator<T> {
|
|
446
|
+
validateQueryParameter(query);
|
|
447
|
+
|
|
337
448
|
const queriedRequest = {
|
|
338
449
|
...ctx.request,
|
|
339
450
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -403,6 +514,8 @@ async function* listByPageOp<T, Query>(
|
|
|
403
514
|
// NOTE: offset is only supported in v1
|
|
404
515
|
opts?: RequestOptions<T[]> & { offset?: number },
|
|
405
516
|
): AsyncGenerator<AxiosResponse<T[]>> {
|
|
517
|
+
validateQueryParameter(query);
|
|
518
|
+
|
|
406
519
|
const queriedRequest = {
|
|
407
520
|
...ctx.request,
|
|
408
521
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
|
@@ -436,6 +549,8 @@ async function* listByPageV2Op<T, Query>(
|
|
|
436
549
|
query: Query,
|
|
437
550
|
opts?: RequestOptions<T[]>,
|
|
438
551
|
): AsyncGenerator<AxiosResponse<PagedResponse<T>>> {
|
|
552
|
+
validateQueryParameter(query);
|
|
553
|
+
|
|
439
554
|
const queriedRequest = {
|
|
440
555
|
...ctx.request,
|
|
441
556
|
url: `${ctx.service.endpointVersion}/${ctx.service.endpoint}`,
|
package/src/service.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
Operation,
|
|
20
20
|
OperationContext,
|
|
21
21
|
RequestConfig,
|
|
22
|
+
createOp,
|
|
22
23
|
listAllOp,
|
|
23
24
|
listAllV2Op,
|
|
24
25
|
listOp,
|
|
@@ -31,6 +32,7 @@ import { ShiftSwapRequest } from './interfaces/swap-request.interface.js';
|
|
|
31
32
|
import { ShiftDropRequest } from './interfaces/drop-request.interface.js';
|
|
32
33
|
import { ToilAllowanceQueryParams } from './interfaces/query-params/index.js';
|
|
33
34
|
import { LogbookEntry, LogbookQueryParameters } from './interfaces/logbook.interface.js';
|
|
35
|
+
import { Message } from './interfaces/message.interface.js';
|
|
34
36
|
|
|
35
37
|
export type ServiceSpecification<CustomOp extends OpDef<unknown> = OpDef<any>> = {
|
|
36
38
|
/** Operations allowed and usable for the endpoint */
|
|
@@ -266,6 +268,14 @@ export const SERVICES = {
|
|
|
266
268
|
},
|
|
267
269
|
},
|
|
268
270
|
},
|
|
271
|
+
message: {
|
|
272
|
+
endpoint: 'messages',
|
|
273
|
+
endpointVersion: 'v1',
|
|
274
|
+
operations: ['list', 'listAll', 'listByPage'],
|
|
275
|
+
customOperations: {
|
|
276
|
+
send: (ctx, message: EndpointEntityMap['v1']['messages']['createType']) => createOp<Message>(ctx, message),
|
|
277
|
+
},
|
|
278
|
+
},
|
|
269
279
|
pin: {
|
|
270
280
|
endpoint: 'pins',
|
|
271
281
|
endpointVersion: 'v1',
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import axios, { Axios, AxiosError, AxiosRequestConfig, isAxiosError } from 'axios';
|
|
2
2
|
import axiosRetry, { isNetworkOrIdempotentRequestError } from 'axios-retry';
|
|
3
3
|
import { RetryOptions, RetryStrategy, SDKConfig } from './interfaces/index.js';
|
|
4
|
-
import { SDKError } from './
|
|
4
|
+
import { SDKError } from './error.js';
|
|
5
5
|
import pkg from '../package.json' with { type: 'json' };
|
|
6
6
|
|
|
7
7
|
/** Creates a `Partial<T>` where all properties specified by `K` are required
|
|
@@ -50,11 +50,21 @@ class AssertionError extends Error {
|
|
|
50
50
|
override name = AssertionError.prototype.name;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
/** Ensures the provided value resolves to `true` before continuing
|
|
54
|
+
*
|
|
55
|
+
* If the value doesn't resolve to `true` then the provided `error` will be thrown
|
|
56
|
+
*
|
|
57
|
+
* Intended to be run in production and not removed on build
|
|
58
|
+
*
|
|
59
|
+
* @param assertion assertion to verify
|
|
60
|
+
* @param error error to throw. If `undefined` or a `string` then an {@link AssertionError}
|
|
61
|
+
* will be thrown instead
|
|
62
|
+
*/
|
|
63
|
+
export function assert(assertion: unknown, error?: string | Error): asserts assertion {
|
|
64
|
+
if (assertion) return;
|
|
65
|
+
if (error === undefined || typeof error === 'string')
|
|
66
|
+
throw new AssertionError(error ?? `Assertion failed - value = ${assertion}`);
|
|
67
|
+
throw error;
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
/** Converts a map of query parameter key/values into API compatible {@see URLSearchParams} */
|
package/dist/models/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './SDKError.model.js';
|
package/dist/models/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './SDKError.model.js';
|
package/src/models/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './SDKError.model.js';
|