auxilium 1.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.
Files changed (62) hide show
  1. package/README.md +374 -0
  2. package/dist/http.d.ts +91 -0
  3. package/dist/http.js +105 -0
  4. package/dist/http.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +20 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/interfaces/common.d.ts +5 -0
  9. package/dist/interfaces/common.js +3 -0
  10. package/dist/interfaces/common.js.map +1 -0
  11. package/dist/interfaces/index.d.ts +2 -0
  12. package/dist/interfaces/index.js +19 -0
  13. package/dist/interfaces/index.js.map +1 -0
  14. package/dist/interfaces/logger.d.ts +11 -0
  15. package/dist/interfaces/logger.js +3 -0
  16. package/dist/interfaces/logger.js.map +1 -0
  17. package/dist/priorityQueue.d.ts +43 -0
  18. package/dist/priorityQueue.js +99 -0
  19. package/dist/priorityQueue.js.map +1 -0
  20. package/dist/queue.d.ts +39 -0
  21. package/dist/queue.js +69 -0
  22. package/dist/queue.js.map +1 -0
  23. package/dist/stack.d.ts +38 -0
  24. package/dist/stack.js +57 -0
  25. package/dist/stack.js.map +1 -0
  26. package/dist/utils/array.d.ts +104 -0
  27. package/dist/utils/array.js +203 -0
  28. package/dist/utils/array.js.map +1 -0
  29. package/dist/utils/async.d.ts +52 -0
  30. package/dist/utils/async.js +127 -0
  31. package/dist/utils/async.js.map +1 -0
  32. package/dist/utils/compare.d.ts +91 -0
  33. package/dist/utils/compare.js +180 -0
  34. package/dist/utils/compare.js.map +1 -0
  35. package/dist/utils/csv.d.ts +31 -0
  36. package/dist/utils/csv.js +57 -0
  37. package/dist/utils/csv.js.map +1 -0
  38. package/dist/utils/date.d.ts +83 -0
  39. package/dist/utils/date.js +179 -0
  40. package/dist/utils/date.js.map +1 -0
  41. package/dist/utils/id.d.ts +5 -0
  42. package/dist/utils/id.js +27 -0
  43. package/dist/utils/id.js.map +1 -0
  44. package/dist/utils/index.d.ts +11 -0
  45. package/dist/utils/index.js +28 -0
  46. package/dist/utils/index.js.map +1 -0
  47. package/dist/utils/json.d.ts +10 -0
  48. package/dist/utils/json.js +29 -0
  49. package/dist/utils/json.js.map +1 -0
  50. package/dist/utils/logger.d.ts +71 -0
  51. package/dist/utils/logger.js +160 -0
  52. package/dist/utils/logger.js.map +1 -0
  53. package/dist/utils/number.d.ts +38 -0
  54. package/dist/utils/number.js +90 -0
  55. package/dist/utils/number.js.map +1 -0
  56. package/dist/utils/object.d.ts +57 -0
  57. package/dist/utils/object.js +107 -0
  58. package/dist/utils/object.js.map +1 -0
  59. package/dist/utils/string.d.ts +45 -0
  60. package/dist/utils/string.js +90 -0
  61. package/dist/utils/string.js.map +1 -0
  62. package/package.json +94 -0
package/README.md ADDED
@@ -0,0 +1,374 @@
1
+ # auxilium
2
+
3
+ A small, framework‑agnostic utility toolkit for everyday JavaScript/TypeScript work.
4
+ Includes string/array/number/object helpers, async utilities, date helpers, a structured logger, and basic data structures (queue, stack, priority queue).
5
+
6
+ *Auxilium* (Latin: "help/assistance") — a collection of practical utilities for modern JavaScript/TypeScript development.
7
+
8
+ ```ts
9
+ import * as aux from 'auxilium';
10
+ import { Queue } from 'auxilium/queue';
11
+ import { Stack } from 'auxilium/stack';
12
+ import { PriorityQueue } from 'auxilium/priority-queue';
13
+ import { createClient, buildQuery, withAbort } from 'auxilium';
14
+ ```
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install auxilium
20
+ ```
21
+
22
+ ## String utilities
23
+
24
+ Source: `src/utils/string.ts`
25
+
26
+ - **`trim(text)`** – safely trims, treating `null`/`undefined` as `''`.
27
+ - **`toLower(text)` / `toUpper(text)`** – lower/upper‑case after trimming.
28
+ - **`isEmpty(text)`** – `true` if empty or only whitespace.
29
+ - **`capitalize(text)`** – `"hello WORLD"` → `"Hello world"`.
30
+ - **`slug(text)`** – URL‑friendly slug, `"Hello World!"` → `"hello-world"`.
31
+ - **`includes(text, search)`** – safe wrapper around `String.prototype.includes`.
32
+ - **`startsWith(text, prefix)`** – safe wrapper around `startsWith`.
33
+ - **`endsWith(text, suffix)`** – safe wrapper around `endsWith`.
34
+ - **`words(text)`** – splits on whitespace, collapsing multiples.
35
+
36
+ ```ts
37
+ trim(' hi '); // 'hi'
38
+ capitalize('hELLO'); // 'Hello'
39
+ slug('Hello World!'); // 'hello-world'
40
+ ```
41
+
42
+ ## Number utilities
43
+
44
+ Source: `src/utils/number.ts`
45
+
46
+ - **`clamp(value, min, max)`** – clamps into `[min, max]` (NaN → `min`).
47
+ - **`toNumber(value, fallback?)`** – safe `Number()` with fallback.
48
+ - **`between(value, min, max)`** – inclusive range check.
49
+ - **`round(value, decimals?)`** – round to N decimals.
50
+ - **`floor(value, decimals?)`** – floor to N decimals.
51
+ - **`ceil(value, decimals?)`** – ceil to N decimals.
52
+ - **`randomInt(min, max)`** – random integer in `[min, max]`.
53
+ - **`sum(numbers)`** – sum of an array.
54
+ - **`avg(numbers)`** – average, `0` for empty.
55
+
56
+ ```ts
57
+ clamp(15, 0, 10); // 10
58
+ between(5, 0, 10); // true
59
+ round(1.2345, 2); // 1.23
60
+ randomInt(1, 6); // 1..6
61
+ avg([1, 2, 3, 4]); // 2.5
62
+ ```
63
+
64
+ ## Array utilities
65
+
66
+ Source: `src/utils/array.ts`
67
+
68
+ - **`uniq(items)`** – unique items, first occurrence wins.
69
+ - **`chunk(items, size)`** – splits into chunks.
70
+ - **`compact(items)`** – removes `null`/`undefined`/`false` (keeps `0` and `''`).
71
+ - **`flat(items)`** – flattens one level.
72
+ - **`first(items)` / `last(items)`** – first/last item or `undefined`.
73
+ - **`groupBy(objects, key)`** – group array of objects by a key.
74
+ - **`partition(items, predicate)`** – `[matches, nonMatches]`.
75
+ - **`intersect(a, b)`** – items in both arrays.
76
+ - **`difference(a, b)`** – items in `a` that are not in `b`.
77
+ - **`uniqueBy(items, keyFn)`** – unique items by computed key.
78
+ - **`sortBy(items, selector, direction?)`** – returns a new array sorted by a selector (`'asc'`/`'desc'`, default `'asc'`).
79
+
80
+ ```ts
81
+ uniq([1, 2, 2, 3]); // [1, 2, 3]
82
+ chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
83
+
84
+ const users = [
85
+ { id: 1, role: 'admin' },
86
+ { id: 2, role: 'user' },
87
+ { id: 3, role: 'admin' },
88
+ ];
89
+
90
+ groupBy(users, 'role');
91
+ // { admin: [...], user: [...] }
92
+
93
+ partition([1,2,3,4], n => n % 2 === 0);
94
+ // [[2,4],[1,3]]
95
+
96
+ sortBy(users, u => u.age);
97
+ sortBy(users, u => u.name.toLowerCase(), 'desc');
98
+ ```
99
+
100
+ ## Object utilities
101
+
102
+ Source: `src/utils/object.ts`
103
+
104
+ - **`merge(a, b)`** – shallow merge, `b` overrides `a`.
105
+ - **`get(obj, path, fallback?)`** – safe deep property access (`'a.b.c'`).
106
+ - **`isEmptyObject(value)`** – own enumerable keys length is `0`.
107
+ - **`pick(obj, keys)`** – new object with only selected keys.
108
+ - **`omit(obj, keys)`** – new object without selected keys.
109
+ - **`keys(obj)`** – typed keys array.
110
+ - **`values(obj)`** – typed values array.
111
+
112
+ ```ts
113
+ merge({ a: 1, b: 2 }, { b: 3 }); // { a:1, b:3 }
114
+ get({ a: { b: 1 } }, 'a.b'); // 1
115
+ pick(user, ['id', 'name']);
116
+ omit(user, ['password']);
117
+ ```
118
+
119
+ ## Async utilities
120
+
121
+ Source: `src/utils/async.ts`
122
+
123
+ - **`sleep(ms)`** – Promise that resolves after `ms`.
124
+ - **`handlePromise(fn)`** – wraps any async function and returns `{ success, data, error }`, auto-unwrapping `.data` when present (e.g. axios).
125
+ - **`timeout(promise, ms)`** – reject if promise doesn’t settle in `ms`.
126
+ - **`debounce(fn, delay)`** – debounced function wrapper.
127
+ - **`throttle(fn, interval)`** – throttled function wrapper.
128
+
129
+ ```ts
130
+ await sleep(500);
131
+
132
+ const usersResult = await handlePromise(() =>
133
+ axios.get('/api/users')
134
+ );
135
+ // usersResult.data is axiosResponse.data
136
+
137
+ const onSearch = debounce(q => doSearch(q), 300);
138
+ const onScroll = throttle(() => console.log('scroll'), 100);
139
+ ```
140
+
141
+ ## HTTP / API utilities
142
+
143
+ Source: `src/http.ts`
144
+
145
+ - **`buildQuery(params)`** – builds a query string from a flat object.
146
+ - **`withAbort()`** – returns `{ signal, abort }` using `AbortController`.
147
+ - **`createClient(options)`** – creates a small HTTP client on top of fetch + `handlePromise`.
148
+
149
+ ```ts
150
+ import { createClient } from 'toolkit';
151
+
152
+ const api = createClient({
153
+ baseUrl: 'https://api.example.com',
154
+ headers: { 'X-App': 'toolkit' },
155
+ getAuthToken: () => localStorage.getItem('token')
156
+ });
157
+
158
+ // GET /users?active=true
159
+ const users = await api.get('/users', {
160
+ query: { active: true }
161
+ });
162
+
163
+ // POST /users with JSON body
164
+ const newUser = await api.post('/users', { name: 'Alice' });
165
+ ```
166
+
167
+ ## Date utilities
168
+
169
+ Source: `src/utils/date.ts`
170
+
171
+ - **`now()`** – `new Date()`.
172
+ - **`nowIso()` / `utcIso()`** – ISO time in UTC.
173
+ - **`formatDate(date, format)`** – formats a date using preset formats like `'yyyy-MM-dd'`, `'yyyy-MM-dd HH:mm:ss'`, `'MM/dd/yyyy'`, etc.
174
+ - **`formatUtc(date, options?)`** – formatted UTC string.
175
+ - **`formatTz(date, timeZone, options?)`** – formatted string for IANA timezone, e.g. `"Asia/Kolkata"`.
176
+ - **`addDays(date, days)`**, **`addMonths(date, months)`**, **`addYears(date, years)`**.
177
+ - **`getYear(date)`**, **`getMonth(date)`** (1–12), **`getDaysInMonth(date)`**.
178
+ - **`getTodayDate()`** – today's date in `YYYY-MM-DD` format (UTC).
179
+ - **`getYesterdayDate()`** – yesterday's date in `YYYY-MM-DD` format (UTC).
180
+ - **`startOfDay(date)`** – midnight for that day.
181
+ - **`isBefore(a, b)`** – true if `a < b`.
182
+
183
+ ```ts
184
+ utcIso(); // "2026-02-19T13:30:00.000Z"
185
+ formatDate(new Date(), 'yyyy-MM-dd'); // "2026-02-19"
186
+ formatDate(new Date(), 'yyyy-MM-dd HH:mm:ss'); // "2026-02-19 14:30:45"
187
+ formatDate(new Date(), 'MM/dd/yyyy'); // "02/19/2026"
188
+ formatTz(new Date(), 'Asia/Kolkata');
189
+ addMonths(new Date(), 1);
190
+ getDaysInMonth(new Date());
191
+ getTodayDate(); // "2026-02-19"
192
+ ```
193
+
194
+ ## JSON utilities
195
+
196
+ Source: `src/utils/json.ts`
197
+
198
+ - **`parseJson(text)`** – safe `JSON.parse`, returns `undefined` on error.
199
+ - **`stringifyJson(value, replacer?, space?)`** – safe `JSON.stringify`, returns `undefined` on error.
200
+
201
+ ```ts
202
+ parseJson('{"a":1}'); // { a:1 }
203
+ parseJson('{bad}'); // undefined
204
+ stringifyJson({ a: 1 }); // '{"a":1}'
205
+ ```
206
+
207
+ ## CSV utilities
208
+
209
+ Source: `src/utils/csv.ts`
210
+
211
+ - **`escapeCsv(value)`** – escapes a single value for use in a CSV cell (quotes, commas, newlines).
212
+ - **`convertToCsv(data, headers)`** – converts an array of objects to a CSV string with labeled headers.
213
+
214
+ ```ts
215
+ const data = [
216
+ { id: 1, name: 'Alice' },
217
+ { id: 2, name: 'Bob' }
218
+ ];
219
+
220
+ const headers = [
221
+ { key: 'id', label: 'ID' },
222
+ { key: 'name', label: 'Name' }
223
+ ];
224
+
225
+ const csv = convertToCsv(data, headers);
226
+ // ID,Name\r\n1,Alice\r\n2,Bob\r\n
227
+ ```
228
+
229
+ ## Comparison utilities
230
+
231
+ Source: `src/utils/compare.ts`
232
+
233
+ Safely compares any two values, handling numbers, strings, objects, and mixed types.
234
+
235
+ - **`compare(a, b, key?)`** – returns `-1` if `a < b`, `0` if `a === b`, `1` if `a > b`.
236
+ - **`isEqual(a, b, key?)`** / **`eq(a, b, key?)`** – safely checks if two values are equal.
237
+ - **`isLessThan(a, b, key?)`** / **`lt(a, b, key?)`** – checks if `a < b`.
238
+ - **`isGreaterThan(a, b, key?)`** / **`gt(a, b, key?)`** – checks if `a > b`.
239
+ - **`isLessThanOrEqual(a, b, key?)`** / **`lte(a, b, key?)`** – checks if `a <= b`.
240
+ - **`isGreaterThanOrEqual(a, b, key?)`** / **`gte(a, b, key?)`** – checks if `a >= b`.
241
+
242
+ The `key` parameter can be a property name or a function to extract the value to compare from objects.
243
+
244
+ ```ts
245
+ compare(5, 10); // -1
246
+ compare('apple', 'banana'); // -1
247
+ compare('5', 5); // 0 (coerced)
248
+
249
+ const users = [
250
+ { id: 1, age: 25 },
251
+ { id: 2, age: 30 }
252
+ ];
253
+
254
+ compare(users[0], users[1], 'age'); // -1
255
+ eq(users[0], users[1], u => u.age); // false
256
+ lt({ value: 5 }, { value: 10 }, 'value'); // true
257
+ gt(10, 5); // true
258
+ lte(5, 5); // true
259
+ gte(10, 5); // true
260
+ ```
261
+
262
+ ## ID utility
263
+
264
+ Source: `src/utils/id.ts`
265
+
266
+ - **`id(length = 16)`** – random alphanumeric ID, using `crypto.getRandomValues` when available, otherwise `Math.random`.
267
+
268
+ ```ts
269
+ id(); // e.g. 'f3Gk9P...'
270
+ id(8); // shorter id
271
+ ```
272
+
273
+ ## Logger
274
+
275
+ Source: `src/utils/logger.ts`
276
+
277
+ The logger prints colored, timestamped logs and returns a structured `LogEntry` for each call.
278
+
279
+ - **`log(message, data?, meta?)`** – info level.
280
+ - **`log.info(...)`**, **`log.success(...)`**, **`log.warn(...)`**, **`log.error(...)`** – level helpers.
281
+ - **`log.withColor(color, message, data?, meta?)`** – custom color (`'red'`, `'green'`, `'yellow'`, `'blue'`, `'magenta'`, `'cyan'`, `'white'`, `'gray'`).
282
+
283
+ ```ts
284
+ import { log } from 'toolkit';
285
+
286
+ log('Server started', { port: 3000 });
287
+ log.success('User created', { id: 1 });
288
+ log.warn('Slow response', { ms: 1200 }, { context: 'GET /api/users' });
289
+ log.error('Failed to save', new Error('DB error'));
290
+ log.withColor('magenta', 'Custom log', { foo: 'bar' });
291
+ ```
292
+
293
+ ## Data structures
294
+
295
+ ### Queue – `toolkit/queue`
296
+
297
+ Source: `src/queue.ts`
298
+
299
+ ```ts
300
+ import { Queue } from 'toolkit/queue';
301
+
302
+ const q = new Queue<number>();
303
+ q.enqueue(1);
304
+ q.enqueue(2);
305
+ q.dequeue(); // 1
306
+ q.peek(); // 2
307
+ ```
308
+
309
+ API:
310
+
311
+ - `enqueue(item)`
312
+ - `dequeue()` → `T | undefined`
313
+ - `peek()` → `T | undefined`
314
+ - `length` (getter)
315
+ - `isEmpty()`
316
+ - `clear()`
317
+
318
+ ### Stack – `toolkit/stack`
319
+
320
+ Source: `src/stack.ts`
321
+
322
+ ```ts
323
+ import { Stack } from 'toolkit/stack';
324
+
325
+ const s = new Stack<number>();
326
+ s.push(1);
327
+ s.push(2);
328
+ s.pop(); // 2
329
+ s.peek(); // 1
330
+ ```
331
+
332
+ API:
333
+
334
+ - `push(item)`
335
+ - `pop()` → `T | undefined`
336
+ - `peek()` → `T | undefined`
337
+ - `length` (getter)
338
+ - `isEmpty()`
339
+ - `clear()`
340
+
341
+ ### PriorityQueue – `toolkit/priority-queue`
342
+
343
+ Source: `src/priorityQueue.ts`
344
+
345
+ ```ts
346
+ import { PriorityQueue } from 'toolkit/priority-queue';
347
+
348
+ const pq = new PriorityQueue<number>(); // min-heap by default
349
+ pq.enqueue(3);
350
+ pq.enqueue(1);
351
+ pq.enqueue(2);
352
+ pq.dequeue(); // 1
353
+ ```
354
+
355
+ API:
356
+
357
+ - `constructor(compare?: (a, b) => number)` – custom comparison function.
358
+ - `enqueue(item)`
359
+ - `dequeue()` → `T | undefined`
360
+ - `peek()` → `T | undefined`
361
+ - `length` (getter)
362
+ - `isEmpty()`
363
+ - `clear()`
364
+
365
+ ## Testing
366
+
367
+ The package includes a very small runtime smoke test:
368
+
369
+ ```bash
370
+ npm test
371
+ ```
372
+
373
+ This builds the TypeScript sources and runs `test/basic.mjs` against the compiled output in `dist/`.
374
+
package/dist/http.d.ts ADDED
@@ -0,0 +1,91 @@
1
+ import type { NexusResult } from './interfaces';
2
+ import { UnwrapData } from './utils/async';
3
+ /**
4
+ * Supported HTTP methods for the built-in client.
5
+ */
6
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
7
+ /**
8
+ * Allowed query parameter value types.
9
+ */
10
+ export type QueryValue = string | number | boolean | null | undefined;
11
+ /**
12
+ * Flat query parameter object.
13
+ */
14
+ export type QueryParams = Record<string, QueryValue>;
15
+ /**
16
+ * Options for creating an HTTP client.
17
+ */
18
+ export interface CreateClientOptions {
19
+ baseUrl?: string;
20
+ /**
21
+ * Default headers applied to every request.
22
+ */
23
+ headers?: Record<string, string>;
24
+ /**
25
+ * Optional function that returns the current auth token (e.g. JWT).
26
+ * When provided, an Authorization header will be added as:
27
+ * `Authorization: Bearer <token>`.
28
+ */
29
+ getAuthToken?: () => string | null | undefined;
30
+ }
31
+ export interface RequestOptions {
32
+ method?: HttpMethod;
33
+ path: string;
34
+ query?: QueryParams;
35
+ /**
36
+ * JSON-serializable body for non-GET requests.
37
+ */
38
+ body?: unknown;
39
+ headers?: Record<string, string>;
40
+ signal?: AbortSignal;
41
+ }
42
+ /**
43
+ * Simple HTTP client interface built on top of fetch and handlePromise.
44
+ * All methods return a NexusResult<UnwrapData<T>> where common { data } envelopes are unwrapped.
45
+ */
46
+ export interface HttpClient {
47
+ request<T = unknown>(options: RequestOptions): Promise<NexusResult<UnwrapData<T>>>;
48
+ get<T = unknown>(path: string, opts?: Omit<RequestOptions, 'method' | 'path' | 'body'>): Promise<NexusResult<UnwrapData<T>>>;
49
+ post<T = unknown>(path: string, body?: unknown, opts?: Omit<RequestOptions, 'method' | 'path' | 'body'>): Promise<NexusResult<UnwrapData<T>>>;
50
+ put<T = unknown>(path: string, body?: unknown, opts?: Omit<RequestOptions, 'method' | 'path' | 'body'>): Promise<NexusResult<UnwrapData<T>>>;
51
+ patch<T = unknown>(path: string, body?: unknown, opts?: Omit<RequestOptions, 'method' | 'path' | 'body'>): Promise<NexusResult<UnwrapData<T>>>;
52
+ delete<T = unknown>(path: string, opts?: Omit<RequestOptions, 'method' | 'path' | 'body'>): Promise<NexusResult<UnwrapData<T>>>;
53
+ }
54
+ /**
55
+ * Builds a query string from a flat object of params.
56
+ * Skips keys with null/undefined values.
57
+ */
58
+ export declare function buildQuery(params: QueryParams | null | undefined): string;
59
+ export interface AbortHandle {
60
+ signal: AbortSignal;
61
+ abort: () => void;
62
+ }
63
+ /**
64
+ * Creates an AbortController wrapper that exposes { signal, abort }.
65
+ * Useful for wiring into fetch or other APIs that accept AbortSignal.
66
+ */
67
+ export declare function withAbort(): AbortHandle;
68
+ /**
69
+ * Creates a small HTTP client on top of fetch + handlePromise.
70
+ * - Supports base URL and default headers
71
+ * - Automatically stringifies JSON bodies and parses JSON responses
72
+ * - Optionally injects an Authorization Bearer token via getAuthToken
73
+ *
74
+ * Note: relies on the global fetch API being available (Node 18+ or browser).
75
+ *
76
+ * @example
77
+ * const api = createClient({
78
+ * baseUrl: 'https://api.example.com',
79
+ * headers: { 'X-App': 'toolkit' },
80
+ * getAuthToken: () => localStorage.getItem('token')
81
+ * });
82
+ *
83
+ * // GET /users?active=true
84
+ * const users = await api.get('/users', {
85
+ * query: { active: true }
86
+ * });
87
+ *
88
+ * // POST /users with JSON body
89
+ * const newUser = await api.post('/users', { name: 'Alice' });
90
+ */
91
+ export declare function createClient(options?: CreateClientOptions): HttpClient;
package/dist/http.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildQuery = buildQuery;
4
+ exports.withAbort = withAbort;
5
+ exports.createClient = createClient;
6
+ const async_1 = require("./utils/async");
7
+ /**
8
+ * Builds a query string from a flat object of params.
9
+ * Skips keys with null/undefined values.
10
+ */
11
+ function buildQuery(params) {
12
+ if (!params)
13
+ return '';
14
+ const searchParams = new URLSearchParams();
15
+ for (const [key, value] of Object.entries(params)) {
16
+ if (value === null || value === undefined)
17
+ continue;
18
+ searchParams.append(key, String(value));
19
+ }
20
+ const qs = searchParams.toString();
21
+ return qs ? `?${qs}` : '';
22
+ }
23
+ /**
24
+ * Creates an AbortController wrapper that exposes { signal, abort }.
25
+ * Useful for wiring into fetch or other APIs that accept AbortSignal.
26
+ */
27
+ function withAbort() {
28
+ const controller = new AbortController();
29
+ return {
30
+ signal: controller.signal,
31
+ abort: () => controller.abort()
32
+ };
33
+ }
34
+ /**
35
+ * Creates a small HTTP client on top of fetch + handlePromise.
36
+ * - Supports base URL and default headers
37
+ * - Automatically stringifies JSON bodies and parses JSON responses
38
+ * - Optionally injects an Authorization Bearer token via getAuthToken
39
+ *
40
+ * Note: relies on the global fetch API being available (Node 18+ or browser).
41
+ *
42
+ * @example
43
+ * const api = createClient({
44
+ * baseUrl: 'https://api.example.com',
45
+ * headers: { 'X-App': 'toolkit' },
46
+ * getAuthToken: () => localStorage.getItem('token')
47
+ * });
48
+ *
49
+ * // GET /users?active=true
50
+ * const users = await api.get('/users', {
51
+ * query: { active: true }
52
+ * });
53
+ *
54
+ * // POST /users with JSON body
55
+ * const newUser = await api.post('/users', { name: 'Alice' });
56
+ */
57
+ function createClient(options = {}) {
58
+ const { baseUrl = '', headers: defaultHeaders = {}, getAuthToken } = options;
59
+ const doRequest = async (opts) => {
60
+ var _a;
61
+ const url = `${baseUrl}${opts.path}${buildQuery(opts.query)}`;
62
+ const headers = {
63
+ ...defaultHeaders,
64
+ ...opts.headers
65
+ };
66
+ const token = getAuthToken?.();
67
+ if (token) {
68
+ headers.Authorization = `Bearer ${token}`;
69
+ }
70
+ const init = {
71
+ method: opts.method ?? 'GET',
72
+ headers,
73
+ signal: opts.signal
74
+ };
75
+ if (opts.body !== undefined && init.method !== 'GET') {
76
+ init.body = JSON.stringify(opts.body);
77
+ if (!init.headers) {
78
+ init.headers = {};
79
+ }
80
+ (_a = init.headers)['Content-Type'] ?? (_a['Content-Type'] = 'application/json');
81
+ }
82
+ const res = await fetch(url, init);
83
+ const contentType = res.headers.get('content-type') ?? '';
84
+ if (!res.ok) {
85
+ const text = await res.text().catch(() => '');
86
+ const errorMessage = text || `${res.status} ${res.statusText}`;
87
+ throw new Error(errorMessage);
88
+ }
89
+ if (contentType.includes('application/json')) {
90
+ return (await res.json());
91
+ }
92
+ // For non-JSON responses, return text
93
+ return (await res.text());
94
+ };
95
+ const request = (opts) => (0, async_1.handlePromise)(() => doRequest(opts));
96
+ return {
97
+ request,
98
+ get: (path, opts) => request({ ...(opts ?? {}), method: 'GET', path }),
99
+ post: (path, body, opts) => request({ ...(opts ?? {}), method: 'POST', path, body }),
100
+ put: (path, body, opts) => request({ ...(opts ?? {}), method: 'PUT', path, body }),
101
+ patch: (path, body, opts) => request({ ...(opts ?? {}), method: 'PATCH', path, body }),
102
+ delete: (path, opts) => request({ ...(opts ?? {}), method: 'DELETE', path })
103
+ };
104
+ }
105
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './interfaces';
2
+ export * from './utils';
3
+ export * from './http';
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./interfaces"), exports);
18
+ __exportStar(require("./utils"), exports);
19
+ __exportStar(require("./http"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,0CAAwB;AACxB,yCAAuB"}
@@ -0,0 +1,5 @@
1
+ export interface NexusResult<T = unknown> {
2
+ success: boolean;
3
+ data?: T;
4
+ error?: string;
5
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/interfaces/common.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './logger';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./common"), exports);
18
+ __exportStar(require("./logger"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,2CAAyB"}
@@ -0,0 +1,11 @@
1
+ export type LogLevel = 'info' | 'success' | 'warn' | 'error';
2
+ export interface LogMeta {
3
+ context?: string;
4
+ }
5
+ export interface LogEntry<T = unknown> {
6
+ level: LogLevel;
7
+ timestamp: string;
8
+ message: string;
9
+ data?: T;
10
+ meta?: LogMeta;
11
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/interfaces/logger.ts"],"names":[],"mappings":""}