core-services-sdk 1.3.82 → 1.3.83

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "core-services-sdk",
3
- "version": "1.3.82",
3
+ "version": "1.3.83",
4
4
  "main": "src/index.js",
5
5
  "type": "module",
6
6
  "types": "types/index.d.ts",
package/src/http/http.js CHANGED
@@ -24,6 +24,7 @@
24
24
  * @property {string} url - The URL to send the request to.
25
25
  * @property {any} body - The request body to send.
26
26
  * @property {Record<string, string>} [headers] - Optional HTTP headers.
27
+ * @property {RequestInit} [extraParams] - Additional fetch options.
27
28
  * @property {ResponseTypeValue} [expectedType] - Expected response type.
28
29
  */
29
30
 
@@ -32,6 +33,7 @@
32
33
  * @property {string} url - The URL to send the request to.
33
34
  * @property {any} body - The request body to send.
34
35
  * @property {Record<string, string>} [headers] - Optional HTTP headers.
36
+ * @property {RequestInit} [extraParams] - Additional fetch options.
35
37
  * @property {ResponseTypeValue} [expectedType] - Expected response type.
36
38
  */
37
39
 
@@ -40,6 +42,7 @@
40
42
  * @property {string} url - The URL to send the request to.
41
43
  * @property {any} body - The request body to send.
42
44
  * @property {Record<string, string>} [headers] - Optional HTTP headers.
45
+ * @property {RequestInit} [extraParams] - Additional fetch options.
43
46
  * @property {ResponseTypeValue} [expectedType] - Expected response type.
44
47
  */
45
48
 
@@ -48,6 +51,7 @@
48
51
  * @property {string} url - The URL to send the request to.
49
52
  * @property {any} [body] - Optional request body to send.
50
53
  * @property {Record<string, string>} [headers] - Optional HTTP headers.
54
+ * @property {RequestInit} [extraParams] - Additional fetch options.
51
55
  * @property {ResponseTypeValue} [expectedType] - Expected response type.
52
56
  */
53
57
 
@@ -205,9 +209,11 @@ export const post = async ({
205
209
  url,
206
210
  body,
207
211
  headers = {},
212
+ extraParams = {},
208
213
  expectedType = ResponseType.json,
209
214
  }) => {
210
215
  const response = await fetch(url, {
216
+ ...extraParams,
211
217
  method: HTTP_METHODS.POST,
212
218
  headers: { ...JSON_HEADER, ...headers },
213
219
  body: JSON.stringify(body),
@@ -227,9 +233,11 @@ export const put = async ({
227
233
  url,
228
234
  body,
229
235
  headers = {},
236
+ extraParams = {},
230
237
  expectedType = ResponseType.json,
231
238
  }) => {
232
239
  const response = await fetch(url, {
240
+ ...extraParams,
233
241
  method: HTTP_METHODS.PUT,
234
242
  headers: { ...JSON_HEADER, ...headers },
235
243
  body: expectedType === ResponseType.json ? JSON.stringify(body) : body,
@@ -249,9 +257,11 @@ export const patch = async ({
249
257
  url,
250
258
  body,
251
259
  headers = {},
260
+ extraParams = {},
252
261
  expectedType = ResponseType.json,
253
262
  }) => {
254
263
  const response = await fetch(url, {
264
+ ...extraParams,
255
265
  method: HTTP_METHODS.PATCH,
256
266
  headers: { ...JSON_HEADER, ...headers },
257
267
  body: JSON.stringify(body),
@@ -271,9 +281,11 @@ export const deleteApi = async ({
271
281
  url,
272
282
  body,
273
283
  headers = {},
284
+ extraParams = {},
274
285
  expectedType = ResponseType.json,
275
286
  }) => {
276
287
  const response = await fetch(url, {
288
+ ...extraParams,
277
289
  method: HTTP_METHODS.DELETE,
278
290
  headers: { ...JSON_HEADER, ...headers },
279
291
  ...(body ? { body: JSON.stringify(body) } : {}),
@@ -185,3 +185,73 @@ describe('http client (native fetch)', () => {
185
185
  })
186
186
  })
187
187
  })
188
+
189
+ describe('extraParams support', () => {
190
+ it('should pass extraParams to fetch in GET', async () => {
191
+ mockFetch.mockResolvedValueOnce(
192
+ createMockResponse({ body: JSON.stringify({ ok: true }) }),
193
+ )
194
+
195
+ const controller = new AbortController()
196
+
197
+ await http.get({
198
+ url: 'http://test.com',
199
+ extraParams: {
200
+ signal: controller.signal,
201
+ redirect: 'follow',
202
+ },
203
+ })
204
+
205
+ expect(mockFetch).toHaveBeenCalledWith(
206
+ 'http://test.com',
207
+ expect.objectContaining({
208
+ method: HTTP_METHODS.GET,
209
+ signal: controller.signal,
210
+ redirect: 'follow',
211
+ }),
212
+ )
213
+ })
214
+
215
+ it('should pass extraParams to fetch in POST', async () => {
216
+ mockFetch.mockResolvedValueOnce(
217
+ createMockResponse({ body: JSON.stringify({ ok: true }) }),
218
+ )
219
+
220
+ await http.post({
221
+ url: 'http://test.com',
222
+ body: { a: 1 },
223
+ extraParams: {
224
+ credentials: 'include',
225
+ },
226
+ })
227
+
228
+ expect(mockFetch).toHaveBeenCalledWith(
229
+ 'http://test.com',
230
+ expect.objectContaining({
231
+ method: HTTP_METHODS.POST,
232
+ credentials: 'include',
233
+ }),
234
+ )
235
+ })
236
+
237
+ it('should pass extraParams to fetch in DELETE', async () => {
238
+ mockFetch.mockResolvedValueOnce(
239
+ createMockResponse({ body: JSON.stringify({ ok: true }) }),
240
+ )
241
+
242
+ await http.deleteApi({
243
+ url: 'http://test.com',
244
+ extraParams: {
245
+ keepalive: true,
246
+ },
247
+ })
248
+
249
+ expect(mockFetch).toHaveBeenCalledWith(
250
+ 'http://test.com',
251
+ expect.objectContaining({
252
+ method: HTTP_METHODS.DELETE,
253
+ keepalive: true,
254
+ }),
255
+ )
256
+ })
257
+ })
@@ -3,60 +3,157 @@ export function get({
3
3
  headers,
4
4
  extraParams,
5
5
  expectedType,
6
- }: {
7
- url: any
8
- headers?: {}
9
- extraParams?: {}
10
- expectedType?: 'json'
11
- }): Promise<any>
6
+ }: HttpGetOptions): Promise<any>
12
7
  export function post({
13
8
  url,
14
9
  body,
15
10
  headers,
11
+ extraParams,
16
12
  expectedType,
17
- }: {
18
- url: any
19
- body: any
20
- headers?: {}
21
- expectedType?: 'json'
22
- }): Promise<any>
13
+ }: HttpPostOptions): Promise<any>
23
14
  export function put({
24
15
  url,
25
16
  body,
26
17
  headers,
18
+ extraParams,
27
19
  expectedType,
28
- }: {
29
- url: any
30
- body: any
31
- headers?: {}
32
- expectedType?: 'json'
33
- }): Promise<any>
20
+ }: HttpPutOptions): Promise<any>
34
21
  export function patch({
35
22
  url,
36
23
  body,
37
24
  headers,
25
+ extraParams,
38
26
  expectedType,
39
- }: {
40
- url: any
41
- body: any
42
- headers?: {}
43
- expectedType?: 'json'
44
- }): Promise<any>
27
+ }: HttpPatchOptions): Promise<any>
45
28
  export function deleteApi({
46
29
  url,
47
30
  body,
48
31
  headers,
32
+ extraParams,
49
33
  expectedType,
50
- }: {
51
- url: any
34
+ }: HttpDeleteOptions): Promise<any>
35
+ /**
36
+ * Consolidated HTTP client with methods for common HTTP operations.
37
+ *
38
+ * @type {{
39
+ * get: (options: HttpGetOptions) => Promise<any>,
40
+ * put: (options: HttpPutOptions) => Promise<any>,
41
+ * post: (options: HttpPostOptions) => Promise<any>,
42
+ * patch: (options: HttpPatchOptions) => Promise<any>,
43
+ * deleteApi: (options: HttpDeleteOptions) => Promise<any>
44
+ * }}
45
+ */
46
+ export const http: {
47
+ get: (options: HttpGetOptions) => Promise<any>
48
+ put: (options: HttpPutOptions) => Promise<any>
49
+ post: (options: HttpPostOptions) => Promise<any>
50
+ patch: (options: HttpPatchOptions) => Promise<any>
51
+ deleteApi: (options: HttpDeleteOptions) => Promise<any>
52
+ }
53
+ export type ResponseTypeValue = 'json' | 'xml' | 'text' | 'raw' | 'file'
54
+ export type HttpGetOptions = {
55
+ /**
56
+ * - The URL to send the request to.
57
+ */
58
+ url: string
59
+ /**
60
+ * - Optional HTTP headers.
61
+ */
62
+ headers?: Record<string, string>
63
+ /**
64
+ * - Additional fetch options.
65
+ */
66
+ extraParams?: RequestInit
67
+ /**
68
+ * - Expected response type.
69
+ */
70
+ expectedType?: ResponseTypeValue
71
+ }
72
+ export type HttpPostOptions = {
73
+ /**
74
+ * - The URL to send the request to.
75
+ */
76
+ url: string
77
+ /**
78
+ * - The request body to send.
79
+ */
80
+ body: any
81
+ /**
82
+ * - Optional HTTP headers.
83
+ */
84
+ headers?: Record<string, string>
85
+ /**
86
+ * - Additional fetch options.
87
+ */
88
+ extraParams?: RequestInit
89
+ /**
90
+ * - Expected response type.
91
+ */
92
+ expectedType?: ResponseTypeValue
93
+ }
94
+ export type HttpPutOptions = {
95
+ /**
96
+ * - The URL to send the request to.
97
+ */
98
+ url: string
99
+ /**
100
+ * - The request body to send.
101
+ */
52
102
  body: any
53
- headers?: {}
54
- expectedType?: 'json'
55
- }): Promise<any>
56
- export namespace http {
57
- export { get }
58
- export { put }
59
- export { post }
60
- export { patch }
61
- export { deleteApi }
103
+ /**
104
+ * - Optional HTTP headers.
105
+ */
106
+ headers?: Record<string, string>
107
+ /**
108
+ * - Additional fetch options.
109
+ */
110
+ extraParams?: RequestInit
111
+ /**
112
+ * - Expected response type.
113
+ */
114
+ expectedType?: ResponseTypeValue
115
+ }
116
+ export type HttpPatchOptions = {
117
+ /**
118
+ * - The URL to send the request to.
119
+ */
120
+ url: string
121
+ /**
122
+ * - The request body to send.
123
+ */
124
+ body: any
125
+ /**
126
+ * - Optional HTTP headers.
127
+ */
128
+ headers?: Record<string, string>
129
+ /**
130
+ * - Additional fetch options.
131
+ */
132
+ extraParams?: RequestInit
133
+ /**
134
+ * - Expected response type.
135
+ */
136
+ expectedType?: ResponseTypeValue
137
+ }
138
+ export type HttpDeleteOptions = {
139
+ /**
140
+ * - The URL to send the request to.
141
+ */
142
+ url: string
143
+ /**
144
+ * - Optional request body to send.
145
+ */
146
+ body?: any
147
+ /**
148
+ * - Optional HTTP headers.
149
+ */
150
+ headers?: Record<string, string>
151
+ /**
152
+ * - Additional fetch options.
153
+ */
154
+ extraParams?: RequestInit
155
+ /**
156
+ * - Expected response type.
157
+ */
158
+ expectedType?: ResponseTypeValue
62
159
  }
@@ -5,4 +5,6 @@ export * from './filters/apply-filter.js'
5
5
  export * from './modifiers/apply-order-by.js'
6
6
  export * from './start-stop-postgres-docker.js'
7
7
  export * from './modifiers/apply-pagination.js'
8
+ export * from './repositories/BaseRepository.js'
8
9
  export * from './filters/apply-filter-snake-case.js'
10
+ export * from './repositories/TenantScopedRepository.js'
@@ -69,6 +69,7 @@ export function sqlPaginate({
69
69
  limit,
70
70
  filter,
71
71
  snakeCase,
72
+ distinctOn,
72
73
  }: {
73
74
  baseQuery: import('knex').Knex.QueryBuilder
74
75
  filter?: any
@@ -0,0 +1,50 @@
1
+ /**
2
+ * BaseRepository
3
+ *
4
+ * Provides:
5
+ * - tableName getter (static + instance support)
6
+ * - baseQuery(options)
7
+ * - constructor-level query shaping (optional)
8
+ * - generic find() with pagination
9
+ *
10
+ * Does NOT enforce tenant isolation.
11
+ */
12
+ export class BaseRepository {
13
+ constructor({ db, log, baseQueryBuilder }?: {})
14
+ db: any
15
+ log: any
16
+ _baseQueryBuilder: any
17
+ /**
18
+ * Each concrete repository must define:
19
+ * static tableName = 'table_name'
20
+ */
21
+ get tableName(): any
22
+ /**
23
+ * Builds the base knex query.
24
+ * Applies constructor-level baseQueryBuilder if provided.
25
+ */
26
+ baseQuery(options: {}, params: any): any
27
+ /**
28
+ * Generic paginated find
29
+ */
30
+ find({
31
+ page,
32
+ limit,
33
+ filter,
34
+ orderBy,
35
+ options,
36
+ mapRow,
37
+ ...restParams
38
+ }: {
39
+ [x: string]: any
40
+ page?: number
41
+ limit?: number
42
+ filter?: {}
43
+ orderBy?: {
44
+ column: string
45
+ direction: string
46
+ }
47
+ options?: {}
48
+ mapRow?: (row: any) => any
49
+ }): Promise<any>
50
+ }
@@ -0,0 +1,11 @@
1
+ export class TenantScopedRepository extends BaseRepository {
2
+ /**
3
+ * Extracts and validates tenantId from filter
4
+ */
5
+ getRequiredTenantId(filter?: {}): any
6
+ /**
7
+ * Overrides find to enforce tenant presence
8
+ */
9
+ find(params?: {}): Promise<any>
10
+ }
11
+ import { BaseRepository } from './BaseRepository.js'